test: adjust `ComputeMerkleRoot` tests
What changed, and why it matters
This commit only changes test code. It updates two unit tests for the merkle-root calculation helper: one fuzz test now moves its input vector instead of copying it, and another test now uses an odd number of transactions and witness hashes to better match real production behavior. There are no changes to the actual Bitcoin Core consensus or networking code, so this cannot directly affect live node security.
No security action required. Treat as a normal test-quality improvement. Reviewers may optionally verify that the new odd-count test vector correctly covers the duplicated-leaf merkle branch, but this is a test-coverage concern, not a vulnerability.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff modifies src/test/fuzz/integer.cpp and src/test/merkle_tests.cpp. In integer.cpp, the fuzz target now constructs a non-const std::vector and passes it to ComputeMerkleRoot via std::move, matching the production API where the vector is consumed/mutated. In merkle_tests.cpp, merkle_test_BlockWitness is changed from 2 transactions to 3 transactions so the test exercises the odd-count leaf-duplication path, and the manual hash vector now uses GetWitnessHash() instead of GetHash() to align with BlockWitnessMerkleRoot semantics. The resize remains explicit to verify exact-size behavior. No production code is changed.
Changed components
src/test/fuzz/integer.cppsrc/test/merkle_tests.cppInspect captured patch +9 / −8
diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp
index 89c29dbc..3effc1c1 100644
--- a/src/test/fuzz/integer.cpp
+++ b/src/test/fuzz/integer.cpp
@@ -80,8 +80,8 @@ FUZZ_TARGET(integer, .init = initialize_integer)
}
constexpr uint256 u256_min{"0000000000000000000000000000000000000000000000000000000000000000"};
constexpr uint256 u256_max{"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"};
- const std::vector<uint256> v256{u256, u256_min, u256_max};
- (void)ComputeMerkleRoot(v256);
+ std::vector v256{u256, u256_min, u256_max};
+ (void)ComputeMerkleRoot(std::move(v256));
(void)DecompressAmount(u64);
{
if (std::optional<CAmount> parsed = ParseMoney(FormatMoney(i64))) {
diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp
index 649da07c..3a5720fe 100644
--- a/src/test/merkle_tests.cpp
+++ b/src/test/merkle_tests.cpp
@@ -232,8 +232,9 @@ BOOST_AUTO_TEST_CASE(merkle_test_BlockWitness)
{
CBlock block;
- block.vtx.resize(2);
- for (std::size_t pos = 0; pos < block.vtx.size(); pos++) {
+ constexpr size_t vtx_count{3};
+ block.vtx.resize(vtx_count);
+ for (std::size_t pos = 0; pos < vtx_count; pos++) {
CMutableTransaction mtx;
mtx.nLockTime = pos;
block.vtx[pos] = MakeTransactionRef(std::move(mtx));
@@ -242,12 +243,12 @@ BOOST_AUTO_TEST_CASE(merkle_test_BlockWitness)
uint256 blockWitness = BlockWitnessMerkleRoot(block);
std::vector<uint256> hashes;
- hashes.resize(block.vtx.size());
- hashes[0].SetNull();
- hashes[1] = block.vtx[1]->GetHash().ToUint256();
+ hashes.resize(vtx_count); // Note: leaving odd count to exercise old behavior
+ for (size_t pos{1}; pos < vtx_count; ++pos) {
+ hashes[pos] = block.vtx[pos]->GetWitnessHash().ToUint256();
+ }
uint256 merkleRootofHashes = ComputeMerkleRoot(hashes);
-
BOOST_CHECK_EQUAL(merkleRootofHashes, blockWitness);
}
BOOST_AUTO_TEST_SUITE_END()
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.