The existing test vectors are construction-only: script tree in; leaf hashes, Merkle root, scriptPubKey, address and control blocks out. There are no spending transactions or signatures, unlike BIP 341's wallet-test-vectors.json, so everyone implementing consensus has to invent their own spend coverage. This PR adds the spend-path vectors offered in the Delving write-up (https://delvingbitcoin.org/t/bip-360-p2mr-implemented-in-bitcoin-core-on-regtest-vector-results-measurements-spec-feedback/2751). I generated them from the regtest implementation discussed there.
The schema mirrors bip-0341/wallet-test-vectors.json, adapted to an
output type whose only spend path is the script path. One transaction
with six inputs covers the valid cases, with per-input
given/intermediary/expected and the BIP 341 sighash midstate
pieces at the group level. A separate invalidSpending array has nine
self-contained transactions that must fail validation. The error
field uses short spec-level descriptions; implementations map them
onto their own error codes (several deliberately collapse onto one code
in ours). For inputs spent without a signature,
privkey/hashType/annex/sigMsg/sigHash are null rather than absent.
Valid cases:
- depth-1 leaf, SIGHASH_DEFAULT
- depth-2 leaf of a three-leaf tree, SIGHASH_ALL (65-byte signature)
- annex present, covered by the signature
p2mr_single_leaf_script_tree(from p2mr_construction.json) spent at depth 0 with no signature: demonstrates the v0.12.0 anyone-can-spend rule on a published treep2mr_different_version_leaves(also from p2mr_construction.json) spent through its 0xfa leaf: unknown leaf versions are unencumbered- a depth-128 leaf whose control block is exactly the 4097-byte maximum, pinning the accepting side of the depth limit
Invalid cases: bit-flipped signature, tampered Merkle path, control byte with the low bit unset, single-element witness, two-element witness ending in an annex, empty witness, and control blocks of 0, 34 and 1+32*129 bytes. That covers all three clauses of the control block size rule, so the depth limit is pinned from both sides.
Everything can be regenerated from scratch: private keys are
sha256("p2mr_spending/key/<n>"), prevout txids
sha256("p2mr_spending/prevout/<n>"), and signing is BIP 340 with an
all-zero aux. The two reused trees are asserted to reproduce their
published construction vectors, so the two files cross-check each
other.
One case bakes in an interpretation the spec text leaves implicit:
p2mr_spend_control_byte_low_bit_zero expects failure when the control
byte's low bit is 0. Script Validation says the bit "is unused and must
be 1" and the footnote describes it catching deserialization bugs "with
an immediate error", but the validation steps have no explicit "Fail
if" clause for it, unlike every other rule in that section. If the
intended reading is non-enforcement, this vector should be dropped and
the footnote reworded; either way the text could make it explicit.
Verified against a Bitcoin Core implementation of the BIP: every valid input passes VerifyScript and every invalid case fails with the expected script error (https://github.com/jeanpablojp/bitcoin/tree/p2mr-regtest, src/test/p2mr_vector_tests.cpp). The generator is test/functional/tool_p2mr_spend_vectors.py on the same branch.