diff --git a/src/nodejs_pool_rpc.cpp b/src/nodejs_pool_rpc.cpp index a687ed0..306b083 100644 --- a/src/nodejs_pool_rpc.cpp +++ b/src/nodejs_pool_rpc.cpp @@ -30,7 +30,7 @@ static constexpr int DEFAULT_BACKLOG = 64; static constexpr size_t MAX_CACHED_WORK_ITEMS = 8; static constexpr size_t NODEJS_POOL_RPC_CALLBACK_BUF_SIZE = 65536; static constexpr size_t EXTERNAL_EXTRA_NONCE_SIZE = 4; -static constexpr uint32_t HASHING_BLOB_BATCH_COUNT = 128; +static constexpr uint32_t MIN_HASHING_BLOB_BATCH_COUNT = 128; static thread_local const char* log_category_prefix = "NodejsPoolRpc "; namespace { @@ -156,6 +156,33 @@ bool extract_submitblock_blob(const rapidjson::Value& params, std::vectorvalue.IsUint64()) { + expected_workers = it->value.GetUint64(); + } + else if (it->value.IsInt64() && (it->value.GetInt64() > 0)) { + expected_workers = static_cast(it->value.GetInt64()); + } + else { + return MIN_HASHING_BLOB_BATCH_COUNT; + } + + const uint64_t scaled = (expected_workers * 13ULL + 9ULL) / 10ULL; + const uint64_t batch_count = std::max(MIN_HASHING_BLOB_BATCH_COUNT, scaled); + return (batch_count > std::numeric_limits::max()) ? std::numeric_limits::max() : static_cast(batch_count); +} + } // namespace NodejsPoolRpc::NodejsPoolRpc(p2pool* pool, const std::string& listen_addresses) @@ -246,7 +273,7 @@ bool NodejsPoolRpc::find_cached_work_by_block_blob(const std::vector& b return false; } -bool NodejsPoolRpc::make_work_snapshot(WorkSnapshot& out) const +bool NodejsPoolRpc::make_work_snapshot(WorkSnapshot& out, uint32_t hashing_blob_batch_count) const { const MinerData miner_data = m_pool->miner_data(); if (!miner_data.height || miner_data.prev_id.empty()) { @@ -308,9 +335,9 @@ bool NodejsPoolRpc::make_work_snapshot(WorkSnapshot& out) const uint8_t batch_blob[128] = {}; out.hashing_blob_size = 0; out.hashing_blobs.clear(); - out.hashing_blobs.reserve(static_cast(HASHING_BLOB_BATCH_COUNT) * sizeof(batch_blob)); + out.hashing_blobs.reserve(static_cast(hashing_blob_batch_count) * sizeof(batch_blob)); - for (uint32_t i = 0; i < HASHING_BLOB_BATCH_COUNT; ++i) { + for (uint32_t i = 0; i < hashing_blob_batch_count; ++i) { const uint32_t current_extra_nonce = out.hashing_blob_extra_nonce_start + i; const uint32_t current_blob_size = m_pool->block_template().get_hashing_blob( template_id, @@ -444,7 +471,7 @@ bool NodejsPoolRpc::handle_http_request(RpcClient* client) std::string NodejsPoolRpc::build_get_height_response() const { WorkSnapshot work; - if (!make_work_snapshot(work)) { + if (!make_work_snapshot(work, MIN_HASHING_BLOB_BATCH_COUNT)) { return "{\"status\":\"BUSY\"}"; } @@ -492,7 +519,7 @@ std::string NodejsPoolRpc::build_json_rpc_response(const std::string& body) cons if (method == "getlastblockheader") { WorkSnapshot work; - if (!make_work_snapshot(work)) { + if (!make_work_snapshot(work, MIN_HASHING_BLOB_BATCH_COUNT)) { return json_error_response(id, 0, "not_ready"); } @@ -506,7 +533,8 @@ std::string NodejsPoolRpc::build_json_rpc_response(const std::string& body) cons if (method == "getblocktemplate") { WorkSnapshot work; - if (!make_work_snapshot(work)) { + const uint32_t hashing_blob_batch_count = (doc.HasMember("params") ? get_requested_hashing_blob_batch_count(doc["params"]) : MIN_HASHING_BLOB_BATCH_COUNT); + if (!make_work_snapshot(work, hashing_blob_batch_count)) { return json_error_response(id, 0, "not_ready"); } diff --git a/src/nodejs_pool_rpc.h b/src/nodejs_pool_rpc.h index 8e4e4ad..a66b529 100644 --- a/src/nodejs_pool_rpc.h +++ b/src/nodejs_pool_rpc.h @@ -85,7 +85,7 @@ private: const char* get_log_category() const override; - bool make_work_snapshot(WorkSnapshot& out) const; + bool make_work_snapshot(WorkSnapshot& out, uint32_t hashing_blob_batch_count) const; void remember_work_snapshot(const WorkSnapshot& work) const; bool find_cached_work_by_block_blob(const std::vector& blob, WorkSnapshot& out) const; bool handle_http_request(RpcClient* client);