primitives: witness commitment regression test
What changed, and why it matters
This commit only adds a new automated test to the codebase. It does not change any production code. The test verifies that a Bitcoin block containing a fake witness commitment but missing the required reserved value is correctly rejected by existing validation logic. There is no security fix or vulnerability being introduced here.
No action required. This is a benign test-only commit. If reviewing a larger series, ensure the actual validation logic being tested was previously reviewed for correctness.
Security signals we found
Adds regression test for BIP-141 witness commitment validation
No production code changes
No bug fix or vulnerability patch present in diff
Evidence from the diff
The diff adds a unit test in primitives/src/block.rs named block_rejects_empty_coinbase_witness_commitment. The test constructs a coinbase transaction whose scriptPubKey contains the 38-byte BIP-141 witness commitment structure (WITNESS_COMMITMENT_MAGIC + 32 zero bytes) but whose coinbase input witness does not contain the required 32-byte witness reserved value. It then asserts that check_witness_commitment() returns (false, None) and that block.validate() returns InvalidWitnessCommitment. This is purely a regression/behavioral test; no implementation code is modified.
Changed components
primitives/src/block.rs (test module only)Inspect captured patch +25 / −0
diff --git a/primitives/src/block.rs b/primitives/src/block.rs
index 65806740..77e8f0e6 100644
--- a/primitives/src/block.rs
+++ b/primitives/src/block.rs
@@ -1318,6 +1318,31 @@ mod tests {
assert_eq!(result, (true, None));
}
+ #[test]
+ #[cfg(feature = "alloc")]
+ fn block_rejects_empty_coinbase_witness_commitment() {
+ let mut script = Vec::from(WITNESS_COMMITMENT_MAGIC);
+ script.extend_from_slice(&[0; 32]);
+
+ let coinbase = Transaction {
+ version: crate::transaction::Version::ONE,
+ lock_time: crate::absolute::LockTime::ZERO,
+ inputs: vec![crate::TxIn::EMPTY_COINBASE],
+ outputs: vec![crate::TxOut {
+ amount: units::Amount::ZERO,
+ script_pubkey: crate::script::ScriptBuf::from_bytes(script),
+ }],
+ };
+
+ let transactions = vec![coinbase];
+ let mut header = dummy_header();
+ header.merkle_root = compute_merkle_root(&transactions).unwrap();
+
+ let block = Block::new_unchecked(header, transactions);
+ assert_eq!(block.check_witness_commitment(), (false, None));
+ assert!(matches!(block.validate(), Err(InvalidBlockError::InvalidWitnessCommitment)));
+ }
+
#[test]
#[cfg(feature = "alloc")]
fn block_block_hash() {
Why this scored 14/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.