diff --git a/docs/MERGE_MINING.MD b/docs/MERGE_MINING.MD index c019c0c..bcadc06 100644 --- a/docs/MERGE_MINING.MD +++ b/docs/MERGE_MINING.MD @@ -121,4 +121,4 @@ Field|Description Example response 1: `{"jsonrpc":"2.0","id":"0","result":{"status":"accepted"}}` -Example response 2: `{"jsonrpc":"2.0","id":"0","error":"something went wrong"}` +Example response 2: `{"jsonrpc":"2.0","id":"0","error":{"code":-1,"message":"Block not accepted"}}` diff --git a/src/merge_mining_client_json_rpc.cpp b/src/merge_mining_client_json_rpc.cpp index ef6350d..a9822ad 100644 --- a/src/merge_mining_client_json_rpc.cpp +++ b/src/merge_mining_client_json_rpc.cpp @@ -354,7 +354,17 @@ bool MergeMiningClientJSON_RPC::parse_merge_mining_submit_solution(const char* d } if (doc.HasMember("error")) { - return err(doc["error"].IsString() ? doc["error"].GetString() : "an unknown error occurred"); + const auto& error_result = doc["error"]; + + if (error_result.IsString()) { + return err(error_result.GetString()); + } + else if (error_result.IsObject() && error_result.HasMember("message") && error_result["message"].IsString()) { + return err(error_result["message"].GetString()); + } + else { + return err("an unknown error occurred"); + } } if (!doc.HasMember("result")) { @@ -372,6 +382,12 @@ bool MergeMiningClientJSON_RPC::parse_merge_mining_submit_solution(const char* d } const char* status = result["status"].GetString(); + + // Empty string means no errors and the block was accepted + if (strlen(status) == 0) { + status = "accepted"; + } + LOGINFO(0, log::LightGreen() << "merge_mining_submit_solution to " << m_host << ':' << m_port << ": " << status); // Get new mining job diff --git a/src/miner.cpp b/src/miner.cpp index cb3bac7..ecd82c6 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -242,12 +242,19 @@ void Miner::run(WorkerData* data) } if (j.m_auxDiff.check_pow(h)) { + std::vector aux_blocks; + aux_blocks.reserve(j.m_auxChains.size()); + for (const AuxChainData& aux_data : j.m_auxChains) { if (aux_data.difficulty.check_pow(h)) { LOGINFO(0, log::Green() << "AUX BLOCK FOUND: chain_id " << aux_data.unique_id << ", diff " << aux_data.difficulty << ", worker thread " << data->m_index << '/' << data->m_count); - m_pool->submit_aux_block_async(aux_data.unique_id, j.m_templateId, j.m_nonce, j.m_extraNonce); + aux_blocks.emplace_back(p2pool::SubmitAuxBlockData{ aux_data.unique_id, j.m_templateId, j.m_nonce, j.m_extraNonce }); } } + + if (!aux_blocks.empty()) { + m_pool->submit_aux_block_async(aux_blocks); + } } if (j.m_sidechainDiff.check_pow(h)) { diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 6284245..5eb0742 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -644,11 +644,11 @@ void p2pool::submit_block_async(std::vector&& blob) } } -void p2pool::submit_aux_block_async(const hash& chain_id, uint32_t template_id, uint32_t nonce, uint32_t extra_nonce) +void p2pool::submit_aux_block_async(const std::vector& aux_blocks) { { MutexLock lock(m_submitAuxBlockDataLock); - m_submitAuxBlockData.emplace_back(SubmitAuxBlockData{ chain_id, template_id, nonce, extra_nonce }); + m_submitAuxBlockData.insert(m_submitAuxBlockData.end(), aux_blocks.begin(), aux_blocks.end()); } // If p2pool is stopped, m_submitAuxBlockAsync is most likely already closed @@ -738,7 +738,7 @@ void p2pool::submit_aux_block() const LOGWARN(3, "submit_aux_block: failed to get merkle proof for chain_id " << chain_id); } - return; + break; } } } diff --git a/src/p2pool.h b/src/p2pool.h index 73a3b21..561d649 100644 --- a/src/p2pool.h +++ b/src/p2pool.h @@ -91,7 +91,15 @@ public: void submit_block_async(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce); void submit_block_async(std::vector&& blob); - void submit_aux_block_async(const hash& chain_id, uint32_t template_id, uint32_t nonce, uint32_t extra_nonce); + struct SubmitAuxBlockData + { + hash chain_id; + uint32_t template_id = 0; + uint32_t nonce = 0; + uint32_t extra_nonce = 0; + }; + + void submit_aux_block_async(const std::vector& aux_blocks); bool submit_sidechain_block(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce); @@ -223,14 +231,6 @@ private: mutable uv_mutex_t m_submitBlockDataLock; SubmitBlockData m_submitBlockData; - struct SubmitAuxBlockData - { - hash chain_id; - uint32_t template_id = 0; - uint32_t nonce = 0; - uint32_t extra_nonce = 0; - }; - mutable uv_mutex_t m_submitAuxBlockDataLock; mutable std::vector m_submitAuxBlockData; diff --git a/src/stratum_server.cpp b/src/stratum_server.cpp index f290ddf..65ed84a 100644 --- a/src/stratum_server.cpp +++ b/src/stratum_server.cpp @@ -403,13 +403,22 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo } if (aux_diff.check_pow(resultHash)) { - for (const AuxChainData& aux_data : block.get_aux_chains(template_id)) { + const std::vector aux_chains = block.get_aux_chains(template_id); + + std::vector aux_blocks; + aux_blocks.reserve(aux_chains.size()); + + for (const AuxChainData& aux_data : aux_chains) { if (aux_data.difficulty.check_pow(resultHash)) { const char* s = client->m_customUser; LOGINFO(0, log::Green() << "client " << static_cast(client->m_addrString) << (*s ? " user " : "") << s << " found an aux block for chain_id " << aux_data.unique_id << ", diff " << aux_data.difficulty << ", submitting it"); - m_pool->submit_aux_block_async(aux_data.unique_id, template_id, nonce, extra_nonce); + aux_blocks.emplace_back(p2pool::SubmitAuxBlockData{ aux_data.unique_id, template_id, nonce, extra_nonce }); } } + + if (!aux_blocks.empty()) { + m_pool->submit_aux_block_async(aux_blocks); + } } SubmittedShare* share;