Use SHA256D64 in Merkle root computation

Zcash: Excluding change to `BlockWitnessMerkleRoot` as we don't have
SegWit (deploying non-malleable txs via ZIP 244 instead).

(cherry picked from commit bitcoin/bitcoin@1f0e7ca09c)
This commit is contained in:
Pieter Wuille 2017-09-27 18:50:31 -07:00 committed by Jack Grigg
parent fb70e9286a
commit 3a75a55573
3 changed files with 20 additions and 7 deletions

View File

@ -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;
}
}

View File

@ -126,10 +126,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, NULL);
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) {
@ -158,7 +171,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);
}
std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position)

View File

@ -12,7 +12,7 @@
#include "primitives/block.h"
#include "uint256.h"
uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated = NULL);
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);