diff options
-rw-r--r-- | src/bench/merkle_root.cpp | 2 | ||||
-rw-r--r-- | src/consensus/merkle.cpp | 25 | ||||
-rw-r--r-- | src/consensus/merkle.h | 2 |
3 files changed, 21 insertions, 8 deletions
diff --git a/src/bench/merkle_root.cpp b/src/bench/merkle_root.cpp index 027b19125d..ae2a0a28dc 100644 --- a/src/bench/merkle_root.cpp +++ b/src/bench/merkle_root.cpp @@ -18,7 +18,7 @@ static void MerkleRoot(benchmark::State& state) } while (state.KeepRunning()) { bool mutation = false; - uint256 hash = ComputeMerkleRoot(leaves, &mutation); + uint256 hash = ComputeMerkleRoot(std::vector<uint256>(leaves), &mutation); leaves[mutation] = hash; } } diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index 74a9ebb2e3..a23dd00144 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -130,10 +130,23 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot if (proot) *proot = h; } -uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated) { - uint256 hash; - MerkleComputation(leaves, &hash, mutated, -1, nullptr); - return hash; +uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated) { + bool mutation = false; + while (hashes.size() > 1) { + if (mutated) { + for (size_t pos = 0; pos + 1 < hashes.size(); pos += 2) { + if (hashes[pos] == hashes[pos + 1]) mutation = true; + } + } + if (hashes.size() & 1) { + hashes.push_back(hashes.back()); + } + SHA256D64(hashes[0].begin(), hashes[0].begin(), hashes.size() / 2); + hashes.resize(hashes.size() / 2); + } + if (mutated) *mutated = mutation; + if (hashes.size() == 0) return uint256(); + return hashes[0]; } std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position) { @@ -162,7 +175,7 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated) for (size_t s = 0; s < block.vtx.size(); s++) { leaves[s] = block.vtx[s]->GetHash(); } - return ComputeMerkleRoot(leaves, mutated); + return ComputeMerkleRoot(std::move(leaves), mutated); } uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated) @@ -173,7 +186,7 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated) for (size_t s = 1; s < block.vtx.size(); s++) { leaves[s] = block.vtx[s]->GetWitnessHash(); } - return ComputeMerkleRoot(leaves, mutated); + return ComputeMerkleRoot(std::move(leaves), mutated); } std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position) diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h index 0afb73adb5..f2559d458e 100644 --- a/src/consensus/merkle.h +++ b/src/consensus/merkle.h @@ -12,7 +12,7 @@ #include <primitives/block.h> #include <uint256.h> -uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated = nullptr); +uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated); std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position); uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& branch, uint32_t position); |