diff options
Diffstat (limited to 'src/consensus/merkle.cpp')
-rw-r--r-- | src/consensus/merkle.cpp | 25 |
1 files changed, 19 insertions, 6 deletions
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) |