diff --git a/src/common.h b/src/common.h index 2707988..f2d9203 100644 --- a/src/common.h +++ b/src/common.h @@ -201,8 +201,16 @@ struct alignas(uint64_t) hash friend std::istream& operator>>(std::istream& s, hash& d); }; +struct root_hash : public hash +{ + FORCEINLINE root_hash() : hash() {} + explicit FORCEINLINE root_hash(const hash& h) : hash(h) {} +}; + static_assert(sizeof(hash) == HASH_SIZE, "struct hash has invalid size, check your compiler options"); +static_assert(sizeof(root_hash) == HASH_SIZE, "struct root_hash has invalid size, check your compiler options"); static_assert(std::is_standard_layout::value, "struct hash is not a POD, check your compiler options"); +static_assert(std::is_standard_layout::value, "struct root_hash is not a POD, check your compiler options"); struct #ifdef __GNUC__ diff --git a/src/merkle.cpp b/src/merkle.cpp index 1156364..feca288 100644 --- a/src/merkle.cpp +++ b/src/merkle.cpp @@ -23,13 +23,13 @@ namespace p2pool { -void merkle_hash(const std::vector& hashes, hash& root) +void merkle_hash(const std::vector& hashes, root_hash& root) { const size_t count = hashes.size(); const uint8_t* h = hashes[0].h; if (count == 1) { - root = hashes[0]; + root = root_hash(hashes[0]); } else if (count == 2) { keccak(h, HASH_SIZE * 2, root.h); @@ -175,21 +175,21 @@ bool get_merkle_proof(const std::vector>& tree, const hash& h, return true; } -hash get_root_from_proof(hash h, const std::vector& proof, size_t index, size_t count) +root_hash get_root_from_proof(hash h, const std::vector& proof, size_t index, size_t count) { if (count == 1) { - return h; + return root_hash(h); } if (index >= count) { - return hash(); + return root_hash(); } hash tmp[2]; if (count == 2) { if (proof.empty()) { - return hash(); + return root_hash(); } if (index & 1) { @@ -216,7 +216,7 @@ hash get_root_from_proof(hash h, const std::vector& proof, size_t index, s index -= k; if (proof.empty()) { - return hash(); + return root_hash(); } if (index & 1) { @@ -236,7 +236,7 @@ hash get_root_from_proof(hash h, const std::vector& proof, size_t index, s for (; cnt >= 2; ++proof_index, index >>= 1, cnt >>= 1) { if (proof_index >= proof.size()) { - return hash(); + return root_hash(); } if (index & 1) { @@ -252,10 +252,10 @@ hash get_root_from_proof(hash h, const std::vector& proof, size_t index, s } } - return h; + return root_hash(h); } -bool verify_merkle_proof(hash h, const std::vector& proof, size_t index, size_t count, const hash& root) +bool verify_merkle_proof(hash h, const std::vector& proof, size_t index, size_t count, const root_hash& root) { return get_root_from_proof(h, proof, index, count) == root; } diff --git a/src/merkle.h b/src/merkle.h index dc5a55f..5d44d04 100644 --- a/src/merkle.h +++ b/src/merkle.h @@ -19,13 +19,13 @@ namespace p2pool { -void merkle_hash(const std::vector& hashes, hash& root); +void merkle_hash(const std::vector& hashes, root_hash& root); void merkle_hash_full_tree(const std::vector& hashes, std::vector>& tree); bool get_merkle_proof(const std::vector>& tree, const hash& h, std::vector& proof); -hash get_root_from_proof(hash h, const std::vector& proof, size_t index, size_t count); -bool verify_merkle_proof(hash h, const std::vector& proof, size_t index, size_t count, const hash& root); +root_hash get_root_from_proof(hash h, const std::vector& proof, size_t index, size_t count); +bool verify_merkle_proof(hash h, const std::vector& proof, size_t index, size_t count, const root_hash& root); uint32_t get_aux_slot(const hash &id, uint32_t nonce, uint32_t n_aux_chains); bool find_aux_nonce(const std::vector& aux_id, uint32_t& nonce, uint32_t max_nonce = 0xFFFF); diff --git a/src/p2pool.cpp b/src/p2pool.cpp index d801881..005b0d2 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 merkle_root; + root_hash merkle_root; if (extra) { const size_t n = strlen(extra); if (n >= HASH_SIZE * 2) { @@ -610,7 +610,7 @@ void p2pool::submit_aux_block(const hash& chain_id, uint32_t template_id, uint32 size_t nonce_offset = 0; size_t extra_nonce_offset = 0; size_t merkle_root_offset = 0; - hash merge_mining_root; + root_hash merge_mining_root; std::vector blob = m_blockTemplate->get_block_template_blob(template_id, extra_nonce, nonce_offset, extra_nonce_offset, merkle_root_offset, merge_mining_root); diff --git a/src/pool_block.cpp b/src/pool_block.cpp index 38c941c..118bd32 100644 --- a/src/pool_block.cpp +++ b/src/pool_block.cpp @@ -337,8 +337,9 @@ bool PoolBlock::get_pow_hash(RandomX_Hasher_Base* hasher, uint64_t height, const keccak(reinterpret_cast(hashes), HASH_SIZE * 3, tmp.h); memcpy(h, tmp.h, HASH_SIZE); - merkle_hash(m_transactions, tmp); - memcpy(blob + blob_size, tmp.h, HASH_SIZE); + root_hash tmp_root; + merkle_hash(m_transactions, tmp_root); + memcpy(blob + blob_size, tmp_root.h, HASH_SIZE); } blob_size += HASH_SIZE; diff --git a/src/pool_block.h b/src/pool_block.h index 33b8b71..0ea66c2 100644 --- a/src/pool_block.h +++ b/src/pool_block.h @@ -103,7 +103,7 @@ struct PoolBlock uint32_t m_merkleTreeDataSize; uint64_t m_merkleTreeData; - hash m_merkleRoot; + root_hash m_merkleRoot; // All block transaction hashes including the miner transaction hash at index 0 std::vector m_transactions; diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 2ca9fdd..4eab861 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -63,7 +63,7 @@ SideChain::SideChain(p2pool* pool, NetworkType type, const char* pool_name) , m_poolName(pool_name ? pool_name : "default") , m_targetBlockTime(10) , m_minDifficulty(MIN_DIFFICULTY, 0) - , m_chainWindowSize(2160) + , m_chainWindowSize(216) , m_unclePenalty(20) , m_precalcFinished(false) #ifdef DEV_TEST_SYNC @@ -735,7 +735,7 @@ PoolBlock* SideChain::find_block(const hash& id) const return nullptr; } -PoolBlock* SideChain::find_block_by_merkle_root(const hash& merkle_root) const +PoolBlock* SideChain::find_block_by_merkle_root(const root_hash& merkle_root) const { ReadLock lock(m_sidechainLock); @@ -2120,7 +2120,7 @@ void SideChain::prune_old_blocks() auto it3 = m_blocksByMerkleRoot.find(block->m_merkleRoot); if (it3 != m_blocksByMerkleRoot.end()) { - m_blocksByMerkleRoot.erase(it2); + m_blocksByMerkleRoot.erase(it3); } else { LOGERR(1, "m_blocksByHeight and m_blocksByMerkleRoot are inconsistent at height " << height << ". Fix the code!"); diff --git a/src/side_chain.h b/src/side_chain.h index dcfe26d..5710ba9 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -55,7 +55,7 @@ public: void get_missing_blocks(unordered_set& missing_blocks) const; PoolBlock* find_block(const hash& id) const; - PoolBlock* find_block_by_merkle_root(const hash& merkle_root) const; + PoolBlock* find_block_by_merkle_root(const root_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; @@ -118,7 +118,7 @@ private: std::atomic m_chainTip; std::map> m_blocksByHeight; unordered_map m_blocksById; - unordered_map m_blocksByMerkleRoot; + unordered_map m_blocksByMerkleRoot; uv_mutex_t m_seenWalletsLock; unordered_map m_seenWallets; diff --git a/src/util.h b/src/util.h index 9ac31bb..010ed0c 100644 --- a/src/util.h +++ b/src/util.h @@ -378,6 +378,15 @@ struct hash } }; +template<> +struct hash +{ + FORCEINLINE size_t operator()(const p2pool::root_hash& value) const noexcept + { + return hash_bytes(value.h, p2pool::HASH_SIZE); + } +}; + template struct hash> { diff --git a/tests/src/merkle_tests.cpp b/tests/src/merkle_tests.cpp index 435a950..156bc89 100644 --- a/tests/src/merkle_tests.cpp +++ b/tests/src/merkle_tests.cpp @@ -32,7 +32,7 @@ TEST(merkle, tree) keccak(data, sizeof(data) - 1, input[i].h); } - hash root; + root_hash root; std::vector hashes(1, input[0]); auto check_full_tree = [&hashes, &root]() {