Skip to content

Commit 1f0e7ca

Browse files
committed
Use SHA256D64 in Merkle root computation
1 parent d0c9632 commit 1f0e7ca

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

src/bench/merkle_root.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ static void MerkleRoot(benchmark::State& state)
1818
}
1919
while (state.KeepRunning()) {
2020
bool mutation = false;
21-
uint256 hash = ComputeMerkleRoot(leaves, &mutation);
21+
uint256 hash = ComputeMerkleRoot(std::vector<uint256>(leaves), &mutation);
2222
leaves[mutation] = hash;
2323
}
2424
}

src/consensus/merkle.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,23 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
130130
if (proot) *proot = h;
131131
}
132132

133-
uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated) {
134-
uint256 hash;
135-
MerkleComputation(leaves, &hash, mutated, -1, nullptr);
136-
return hash;
133+
uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated) {
134+
bool mutation = false;
135+
while (hashes.size() > 1) {
136+
if (mutated) {
137+
for (size_t pos = 0; pos + 1 < hashes.size(); pos += 2) {
138+
if (hashes[pos] == hashes[pos + 1]) mutation = true;
139+
}
140+
}
141+
if (hashes.size() & 1) {
142+
hashes.push_back(hashes.back());
143+
}
144+
SHA256D64(hashes[0].begin(), hashes[0].begin(), hashes.size() / 2);
145+
hashes.resize(hashes.size() / 2);
146+
}
147+
if (mutated) *mutated = mutation;
148+
if (hashes.size() == 0) return uint256();
149+
return hashes[0];
137150
}
138151

139152
std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position) {
@@ -162,7 +175,7 @@ uint256 BlockMerkleRoot(const CBlock& block, bool* mutated)
162175
for (size_t s = 0; s < block.vtx.size(); s++) {
163176
leaves[s] = block.vtx[s]->GetHash();
164177
}
165-
return ComputeMerkleRoot(leaves, mutated);
178+
return ComputeMerkleRoot(std::move(leaves), mutated);
166179
}
167180

168181
uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
@@ -173,7 +186,7 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
173186
for (size_t s = 1; s < block.vtx.size(); s++) {
174187
leaves[s] = block.vtx[s]->GetWitnessHash();
175188
}
176-
return ComputeMerkleRoot(leaves, mutated);
189+
return ComputeMerkleRoot(std::move(leaves), mutated);
177190
}
178191

179192
std::vector<uint256> BlockMerkleBranch(const CBlock& block, uint32_t position)

src/consensus/merkle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include <primitives/block.h>
1313
#include <uint256.h>
1414

15-
uint256 ComputeMerkleRoot(const std::vector<uint256>& leaves, bool* mutated = nullptr);
15+
uint256 ComputeMerkleRoot(std::vector<uint256> hashes, bool* mutated);
1616
std::vector<uint256> ComputeMerkleBranch(const std::vector<uint256>& leaves, uint32_t position);
1717
uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector<uint256>& branch, uint32_t position);
1818

0 commit comments

Comments
 (0)