merkle: migrate `path` arg of `MerkleComputation` to a reference
What changed, and why it matters
This is a small internal code cleanup in Bitcoin Core's merkle tree calculation. It changes one function so that a list of hash values is passed by reference instead of by pointer, removing optional null-pointer checks that were no longer needed. There is no change to network behavior, consensus rules, or user-visible security.
No security action needed. Treat as ordinary code-quality refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors MerkleComputation in src/consensus/merkle.cpp so its path parameter changes from std::vector<uint256>* (nullable pointer) to std::vector<uint256>& (non-null reference). The only caller, ComputeMerklePath, always supplies a local vector, so all if (path) guards become unnecessary and are removed. The diff is purely a simplification/cleanup with no functional change to merkle root or path computation.
Changed components
src/consensus/merkle.cppInspect captured patch +15 / −19
diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp
index e274ed82..94e8effe 100644
--- a/src/consensus/merkle.cpp
+++ b/src/consensus/merkle.cpp
@@ -85,9 +85,9 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
}
/* This implements a constant-space merkle root/path calculator, limited to 2^32 leaves. */
-static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot, bool* pmutated, uint32_t leaf_pos, std::vector<uint256>* path)
+static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot, bool* pmutated, uint32_t leaf_pos, std::vector<uint256>& path)
{
- if (path) path->clear();
+ path.clear();
Assume(leaves.size() <= UINT32_MAX);
if (leaves.size() == 0) {
if (pmutated) *pmutated = false;
@@ -115,13 +115,11 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
// corresponds to an inner value that existed before processing the
// current leaf, and each needs a hash to combine it.
for (level = 0; !(count & ((uint32_t{1}) << level)); level++) {
- if (path) {
- if (matchh) {
- path->push_back(inner[level]);
- } else if (matchlevel == level) {
- path->push_back(h);
- matchh = true;
- }
+ if (matchh) {
+ path.push_back(inner[level]);
+ } else if (matchlevel == level) {
+ path.push_back(h);
+ matchh = true;
}
mutated |= (inner[level] == h);
h = Hash(inner[level], h);
@@ -147,8 +145,8 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
// If we reach this point, h is an inner value that is not the top.
// We combine it with itself (Bitcoin's special rule for odd levels in
// the tree) to produce a higher level one.
- if (path && matchh) {
- path->push_back(h);
+ if (matchh) {
+ path.push_back(h);
}
h = Hash(h, h);
// Increment count to the value it would have if two entries at this
@@ -157,13 +155,11 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
level++;
// And propagate the result upwards accordingly.
while (!(count & ((uint32_t{1}) << level))) {
- if (path) {
- if (matchh) {
- path->push_back(inner[level]);
- } else if (matchlevel == level) {
- path->push_back(h);
- matchh = true;
- }
+ if (matchh) {
+ path.push_back(inner[level]);
+ } else if (matchlevel == level) {
+ path.push_back(h);
+ matchh = true;
}
h = Hash(inner[level], h);
level++;
@@ -176,7 +172,7 @@ static void MerkleComputation(const std::vector<uint256>& leaves, uint256* proot
static std::vector<uint256> ComputeMerklePath(const std::vector<uint256>& leaves, uint32_t position) {
std::vector<uint256> ret;
- MerkleComputation(leaves, nullptr, nullptr, position, &ret);
+ MerkleComputation(leaves, nullptr, nullptr, position, ret);
return ret;
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.