@@ -3642,35 +3642,59 @@ static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& st
36423642static 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. */
36583672static 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