diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index 0f3f9c6..baa1c12 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -810,7 +810,6 @@ void P2PServer::broadcast(const PoolBlock& block, const PoolBlock* parent) writeVarint(total_reward, data->pruned_blob); writeVarint(outputs_blob_size, data->pruned_blob); - data->pruned_blob.insert(data->pruned_blob.end(), block.m_sidechainId.h, block.m_sidechainId.h + HASH_SIZE); data->pruned_blob.insert(data->pruned_blob.end(), mainchain_data.begin() + outputs_offset + outputs_blob_size, mainchain_data.end()); diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 9428c14..d801881 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -456,7 +456,7 @@ void p2pool::handle_chain_main(ChainMain& data, const char* extra) } update_median_timestamp(); - hash sidechain_id; + hash merkle_root; if (extra) { const size_t n = strlen(extra); if (n >= HASH_SIZE * 2) { @@ -464,10 +464,10 @@ void p2pool::handle_chain_main(ChainMain& data, const char* extra) for (size_t i = 0; i < HASH_SIZE; ++i) { uint8_t d[2]; if (!from_hex(s[i * 2], d[0]) || !from_hex(s[i * 2 + 1], d[1])) { - sidechain_id = {}; + merkle_root = {}; break; } - sidechain_id.h[i] = (d[0] << 4) | d[1]; + merkle_root.h[i] = (d[0] << 4) | d[1]; } } } @@ -477,8 +477,8 @@ void p2pool::handle_chain_main(ChainMain& data, const char* extra) ", timestamp = " << log::Gray() << data.timestamp << log::NoColor() << ", reward = " << log::Gray() << log::XMRAmount(data.reward)); - if (!sidechain_id.empty()) { - const PoolBlock* block = side_chain().find_block(sidechain_id); + if (!merkle_root.empty()) { + const PoolBlock* block = side_chain().find_block_by_merkle_root(merkle_root); if (block) { const Wallet& w = params().m_wallet; @@ -496,7 +496,7 @@ void p2pool::handle_chain_main(ChainMain& data, const char* extra) api_update_block_found(&data, block); } else { - side_chain().watch_mainchain_block(data, sidechain_id); + side_chain().watch_mainchain_block(data, merkle_root); } } diff --git a/src/pool_block_parser.inl b/src/pool_block_parser.inl index ea3f03a..f5829be 100644 --- a/src/pool_block_parser.inl +++ b/src/pool_block_parser.inl @@ -129,8 +129,6 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si outputs_blob_size = static_cast(data - data_begin) - outputs_offset; outputs_blob.assign(data_begin + outputs_offset, data); - - m_sidechainId.clear(); } else { // Outputs are not in the buffer and must be calculated from sidechain data @@ -146,8 +144,6 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si } outputs_blob_size = static_cast(tmp); - - READ_BUF(m_sidechainId.h, HASH_SIZE); } // Technically some p2pool node could keep stuffing block with transactions until reward is less than 0.6 XMR diff --git a/src/side_chain.cpp b/src/side_chain.cpp index c2dd95e..2ca9fdd 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -636,13 +636,13 @@ bool SideChain::add_external_block(PoolBlock& block, std::vector& missing_ } } - if (block.m_sidechainId == m_watchBlockSidechainId) { + if (block.m_merkleRoot == m_watchBlockMerkleRoot) { const Wallet& w = m_pool->params().m_wallet; const char* who = (block.m_minerWallet == w) ? "you" : "someone else in this p2pool"; LOGINFO(0, log::LightGreen() << "BLOCK FOUND: main chain block at height " << m_watchBlock.height << " was mined by " << who << BLOCK_FOUND); - m_watchBlockSidechainId = {}; + m_watchBlockMerkleRoot = {}; data = m_watchBlock; block_found = true; @@ -702,6 +702,7 @@ bool SideChain::add_block(const PoolBlock& block) } m_blocksByHeight[new_block->m_sidechainHeight].push_back(new_block); + m_blocksByMerkleRoot.insert({ new_block->m_merkleRoot, new_block }); update_depths(new_block); @@ -734,11 +735,23 @@ PoolBlock* SideChain::find_block(const hash& id) const return nullptr; } -void SideChain::watch_mainchain_block(const ChainMain& data, const hash& possible_id) +PoolBlock* SideChain::find_block_by_merkle_root(const hash& merkle_root) const +{ + ReadLock lock(m_sidechainLock); + + auto it = m_blocksByMerkleRoot.find(merkle_root); + if (it != m_blocksByMerkleRoot.end()) { + return it->second; + } + + return nullptr; +} + +void SideChain::watch_mainchain_block(const ChainMain& data, const hash& possible_merkle_root) { WriteLock lock(m_sidechainLock); m_watchBlock = data; - m_watchBlockSidechainId = possible_id; + m_watchBlockMerkleRoot = possible_merkle_root; } const PoolBlock* SideChain::get_block_blob(const hash& id, std::vector& blob) const @@ -2104,6 +2117,15 @@ void SideChain::prune_old_blocks() else { LOGERR(1, "m_blocksByHeight and m_blocksById are inconsistent at height " << height << ". Fix the code!"); } + + auto it3 = m_blocksByMerkleRoot.find(block->m_merkleRoot); + if (it3 != m_blocksByMerkleRoot.end()) { + m_blocksByMerkleRoot.erase(it2); + } + else { + LOGERR(1, "m_blocksByHeight and m_blocksByMerkleRoot are inconsistent at height " << height << ". Fix the code!"); + } + return true; } return false; diff --git a/src/side_chain.h b/src/side_chain.h index d1753fd..dcfe26d 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -55,7 +55,8 @@ public: void get_missing_blocks(unordered_set& missing_blocks) const; PoolBlock* find_block(const hash& id) const; - void watch_mainchain_block(const ChainMain& data, const hash& possible_id); + PoolBlock* find_block_by_merkle_root(const hash& merkle_root) const; + void watch_mainchain_block(const ChainMain& data, const hash& possible_merkle_root); const PoolBlock* get_block_blob(const hash& id, std::vector& blob) const; bool get_outputs_blob(PoolBlock* block, uint64_t total_reward, std::vector& blob, uv_loop_t* loop) const; @@ -117,6 +118,7 @@ private: std::atomic m_chainTip; std::map> m_blocksByHeight; unordered_map m_blocksById; + unordered_map m_blocksByMerkleRoot; uv_mutex_t m_seenWalletsLock; unordered_map m_seenWallets; @@ -142,7 +144,7 @@ private: difficulty_type m_curDifficulty; ChainMain m_watchBlock; - hash m_watchBlockSidechainId; + hash m_watchBlockMerkleRoot; struct PrecalcJob {