Skip to content

Commit e7669e1

Browse files
committed
[refactor] Cleanup merkle root checks
1 parent 95bddb9 commit e7669e1

File tree

1 file changed

+41
-14
lines changed

1 file changed

+41
-14
lines changed

src/validation.cpp

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,35 +3642,59 @@ static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& st
36423642
static bool CheckMerkleRoot(const CBlock& block, BlockValidationState& state)
36433643
{
36443644
bool mutated;
3645-
uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated);
3646-
if (block.hashMerkleRoot != hashMerkleRoot2)
3647-
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-txnmrklroot", "hashMerkleRoot mismatch");
3645+
uint256 merkle_root = BlockMerkleRoot(block, &mutated);
3646+
if (block.hashMerkleRoot != merkle_root) {
3647+
return state.Invalid(
3648+
/*result=*/BlockValidationResult::BLOCK_MUTATED,
3649+
/*reject_reason=*/"bad-txnmrklroot",
3650+
/*debug_message=*/"hashMerkleRoot mismatch");
3651+
}
36483652

36493653
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences
36503654
// of transactions in a block without affecting the merkle root of a block,
36513655
// while still invalidating it.
3652-
if (mutated)
3653-
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-txns-duplicate", "duplicate transaction");
3656+
if (mutated) {
3657+
return state.Invalid(
3658+
/*result=*/BlockValidationResult::BLOCK_MUTATED,
3659+
/*reject_reason=*/"bad-txns-duplicate",
3660+
/*debug_message=*/"duplicate transaction");
3661+
}
36543662

36553663
return true;
36563664
}
36573665

3666+
/** CheckWitnessMalleation performs checks for block malleation with regard to
3667+
* its witnesses.
3668+
*
3669+
* Note: If the witness commitment is expected (i.e. `expect_witness_commitment
3670+
* = true`), then the block is required to have at least one transaction and the
3671+
* first transaction needs to have at least one input. */
36583672
static bool CheckWitnessMalleation(const CBlock& block, bool expect_witness_commitment, BlockValidationState& state)
36593673
{
36603674
if (expect_witness_commitment) {
36613675
int commitpos = GetWitnessCommitmentIndex(block);
36623676
if (commitpos != NO_WITNESS_COMMITMENT) {
3663-
bool malleated = false;
3664-
uint256 hashWitness = BlockWitnessMerkleRoot(block, &malleated);
3677+
assert(!block.vtx.empty() && !block.vtx[0]->vin.empty());
3678+
const auto& witness_stack{block.vtx[0]->vin[0].scriptWitness.stack};
3679+
3680+
if (witness_stack.size() != 1 || witness_stack[0].size() != 32) {
3681+
return state.Invalid(
3682+
/*result=*/BlockValidationResult::BLOCK_MUTATED,
3683+
/*reject_reason=*/"bad-witness-nonce-size",
3684+
/*debug_message=*/strprintf("%s : invalid witness reserved value size", __func__));
3685+
}
3686+
36653687
// The malleation check is ignored; as the transaction tree itself
36663688
// already does not permit it, it is impossible to trigger in the
36673689
// witness tree.
3668-
if (block.vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
3669-
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-witness-nonce-size", strprintf("%s : invalid witness reserved value size", __func__));
3670-
}
3671-
CHash256().Write(hashWitness).Write(block.vtx[0]->vin[0].scriptWitness.stack[0]).Finalize(hashWitness);
3672-
if (memcmp(hashWitness.begin(), &block.vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3673-
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-witness-merkle-match", strprintf("%s : witness merkle commitment mismatch", __func__));
3690+
uint256 hash_witness = BlockWitnessMerkleRoot(block, /*mutated=*/nullptr);
3691+
3692+
CHash256().Write(hash_witness).Write(witness_stack[0]).Finalize(hash_witness);
3693+
if (memcmp(hash_witness.begin(), &block.vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
3694+
return state.Invalid(
3695+
/*result=*/BlockValidationResult::BLOCK_MUTATED,
3696+
/*reject_reason=*/"bad-witness-merkle-match",
3697+
/*debug_message=*/strprintf("%s : witness merkle commitment mismatch", __func__));
36743698
}
36753699

36763700
return true;
@@ -3680,7 +3704,10 @@ static bool CheckWitnessMalleation(const CBlock& block, bool expect_witness_comm
36803704
// No witness data is allowed in blocks that don't commit to witness data, as this would otherwise leave room for spam
36813705
for (const auto& tx : block.vtx) {
36823706
if (tx->HasWitness()) {
3683-
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "unexpected-witness", strprintf("%s : unexpected witness data found", __func__));
3707+
return state.Invalid(
3708+
/*result=*/BlockValidationResult::BLOCK_MUTATED,
3709+
/*reject_reason=*/"unexpected-witness",
3710+
/*debug_message=*/strprintf("%s : unexpected witness data found", __func__));
36843711
}
36853712
}
36863713

0 commit comments

Comments
 (0)