From 1f0e7ca09c9d7c5787c218156fa5096a1bdf2ea8 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 27 Sep 2017 18:50:31 -0700 Subject: Use SHA256D64 in Merkle root computation --- src/consensus/merkle.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'src/consensus/merkle.cpp') 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& leaves, uint256* proot if (proot) *proot = h; } -uint256 ComputeMerkleRoot(const std::vector& leaves, bool* mutated) { - uint256 hash; - MerkleComputation(leaves, &hash, mutated, -1, nullptr); - return hash; +uint256 ComputeMerkleRoot(std::vector 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 ComputeMerkleBranch(const std::vector& 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 BlockMerkleBranch(const CBlock& block, uint32_t position) -- cgit v1.2.3