Use SHA256D64 in Merkle root computation

This commit is contained in:
Pieter Wuille 2017-09-27 18:50:31 -07:00
parent d0c9632883
commit 1f0e7ca09c
3 changed files with 21 additions and 8 deletions

View file

@ -18,7 +18,7 @@ static void MerkleRoot(benchmark::State& state)
} }
while (state.KeepRunning()) { while (state.KeepRunning()) {
bool mutation = false; bool mutation = false;
uint256 hash = ComputeMerkleRoot(leaves, &mutation); uint256 hash = ComputeMerkleRoot(std::vector<uint256>(leaves), &mutation);
leaves[mutation] = hash; leaves[mutation] = hash;
} }
} }

View file

@ -130,10 +130,23 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
if (proot) *proot = h; if (proot) *proot = h;
} }
uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated) { uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated) {
uint256 hash; bool mutation = false;
MerkleComputation(leaves, &hash, mutated, -1, nullptr); while (hashes.size() > 1) {
return hash; 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) { 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++) { for (size_t s = 0; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetHash(); leaves[s] = block.vtx[s]->GetHash();
} }
return ComputeMerkleRoot(leaves, mutated); return ComputeMerkleRoot(std::move(leaves), mutated);
} }
uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* 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++) { for (size_t s = 1; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetWitnessHash(); 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) std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position)

View file

@ -12,7 +12,7 @@
#include <primitives/block.h> #include <primitives/block.h>
#include <uint256.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); 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); uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& branch, uint32_t position);