@@ -459,7 +459,7 @@ def to_script(elem):
459459 scriptsig_list = flatten (get (ctx , "scriptsig" ))
460460 scriptsig = CScript (b"" .join (bytes (to_script (elem )) for elem in scriptsig_list ))
461461 witness_stack = flatten (get (ctx , "witness" ))
462- return (scriptsig , witness_stack )
462+ return (scriptsig , witness_stack , get ( ctx , "annex" ) )
463463
464464
465465# === Spender objects ===
@@ -708,14 +708,23 @@ def spenders_taproot_active():
708708
709709 # == Tests for signature hashing ==
710710
711- # Run all tests once with no annex, and once with a valid random annex.
712- for annex in [None , lambda _ : bytes ([ANNEX_TAG ]) + random .randbytes (random .randrange (0 , 250 ))]:
713- # Non-empty annex is non-standard
714- no_annex = annex is None
711+ # No annex is standard.
712+ no_annex = (None , True )
715713
714+ # An empty annex is standard.
715+ empty_annex = (lambda _ : bytes ([ANNEX_TAG ]), True )
716+
717+ # An annex is standard if it starts with 0x00; any length is allowed.
718+ std_unstructured_annex = (lambda _ : bytes ([ANNEX_TAG , 0 ]) + random .randbytes (random .randint (0 , 50_000 )), True )
719+
720+ # Define non-standard annex (starts with non-0x00).
721+ non_std_annex = (lambda _ : bytes ([ANNEX_TAG , random .randint (1 , 255 )]) + random .randbytes (random .randint (0 , 500 )), False )
722+
723+ # Run all tests once with the various types of annexes.
724+ for (annex , standard ) in [no_annex , empty_annex , std_unstructured_annex , non_std_annex ]:
716725 # Sighash mutation tests (test all sighash combinations)
717726 for hashtype in VALID_SIGHASHES_TAPROOT :
718- common = {"annex" : annex , "hashtype" : hashtype , "standard" : no_annex }
727+ common = {"annex" : annex , "hashtype" : hashtype , "standard" : standard }
719728
720729 # Pure pubkey
721730 tap = taproot_construct (pubs [0 ])
@@ -729,12 +738,12 @@ def spenders_taproot_active():
729738
730739 # Test SIGHASH_SINGLE behavior in combination with mismatching outputs
731740 if hashtype in VALID_SIGHASHES_TAPROOT_SINGLE :
732- add_spender (spenders , "sighash/keypath_hashtype_mis_%x" % hashtype , tap = tap , key = secs [0 ], annex = annex , standard = no_annex , hashtype_actual = random .choice (VALID_SIGHASHES_TAPROOT_NO_SINGLE ), failure = {"hashtype_actual" : hashtype }, ** ERR_SIG_HASHTYPE , need_vin_vout_mismatch = True )
733- add_spender (spenders , "sighash/scriptpath_hashtype_mis_%x" % hashtype , tap = tap , leaf = "s0" , key = secs [1 ], annex = annex , standard = no_annex , hashtype_actual = random .choice (VALID_SIGHASHES_TAPROOT_NO_SINGLE ), ** SINGLE_SIG , failure = {"hashtype_actual" : hashtype }, ** ERR_SIG_HASHTYPE , need_vin_vout_mismatch = True )
741+ add_spender (spenders , "sighash/keypath_hashtype_mis_%x" % hashtype , tap = tap , key = secs [0 ], annex = annex , standard = standard , hashtype_actual = random .choice (VALID_SIGHASHES_TAPROOT_NO_SINGLE ), failure = {"hashtype_actual" : hashtype }, ** ERR_SIG_HASHTYPE , need_vin_vout_mismatch = True )
742+ add_spender (spenders , "sighash/scriptpath_hashtype_mis_%x" % hashtype , tap = tap , leaf = "s0" , key = secs [1 ], annex = annex , standard = standard , hashtype_actual = random .choice (VALID_SIGHASHES_TAPROOT_NO_SINGLE ), ** SINGLE_SIG , failure = {"hashtype_actual" : hashtype }, ** ERR_SIG_HASHTYPE , need_vin_vout_mismatch = True )
734743
735744 # Test OP_CODESEPARATOR impact on sighashing.
736745 hashtype = lambda _ : random .choice (VALID_SIGHASHES_TAPROOT )
737- common = {"annex" : annex , "hashtype" : hashtype , "standard" : no_annex }
746+ common = {"annex" : annex , "hashtype" : hashtype , "standard" : standard }
738747 scripts = [
739748 ("pk_codesep" , CScript (random_checksig_style (pubs [1 ]) + bytes ([OP_CODESEPARATOR ]))), # codesep after checksig
740749 ("codesep_pk" , CScript (bytes ([OP_CODESEPARATOR ]) + random_checksig_style (pubs [1 ]))), # codesep before checksig
@@ -752,7 +761,7 @@ def spenders_taproot_active():
752761 add_spender (spenders , "sighash/branched_codesep/right" , tap = tap , leaf = "branched_codesep" , key = secs [1 ], codeseppos = 6 , ** common , inputs = [getter ("sign" ), b'' ], ** SIGHASH_BITFLIP , ** ERR_SIG_SCHNORR )
753762
754763 # Reusing the scripts above, test that various features affect the sighash.
755- add_spender (spenders , "sighash/annex" , tap = tap , leaf = "pk_codesep" , key = secs [1 ], hashtype = hashtype , standard = False , ** SINGLE_SIG , annex = bytes ([ANNEX_TAG ]), failure = {"sighash" : override (default_sighash , annex = None )}, ** ERR_SIG_SCHNORR )
764+ add_spender (spenders , "sighash/annex" , tap = tap , leaf = "pk_codesep" , key = secs [1 ], hashtype = hashtype , standard = True , ** SINGLE_SIG , annex = bytes ([ANNEX_TAG ]), failure = {"sighash" : override (default_sighash , annex = None )}, ** ERR_SIG_SCHNORR )
756765 add_spender (spenders , "sighash/script" , tap = tap , leaf = "pk_codesep" , key = secs [1 ], ** common , ** SINGLE_SIG , failure = {"sighash" : override (default_sighash , script_taproot = tap .leaves ["codesep_pk" ].script )}, ** ERR_SIG_SCHNORR )
757766 add_spender (spenders , "sighash/leafver" , tap = tap , leaf = "pk_codesep" , key = secs [1 ], ** common , ** SINGLE_SIG , failure = {"sighash" : override (default_sighash , leafversion = random .choice ([x & 0xFE for x in range (0x100 ) if x & 0xFE != LEAF_VERSION_TAPSCRIPT ]))}, ** ERR_SIG_SCHNORR )
758767 add_spender (spenders , "sighash/scriptpath" , tap = tap , leaf = "pk_codesep" , key = secs [1 ], ** common , ** SINGLE_SIG , failure = {"sighash" : override (default_sighash , leaf = None )}, ** ERR_SIG_SCHNORR )
@@ -1069,7 +1078,7 @@ def big_spend_inputs(ctx):
10691078 # n OP_CHECKSIGADDs and 1 OP_CHECKSIG, but also an OP_CHECKSIGADD with an empty signature.
10701079 lambda n , pk : (CScript ([OP_DROP , OP_0 , OP_10 , pk , OP_CHECKSIGADD , OP_10 , OP_EQUALVERIFY , pk ] + [OP_2DUP , OP_16 , OP_SWAP , OP_CHECKSIGADD , b'\x11 ' , OP_EQUALVERIFY ] * n + [OP_CHECKSIG ]), n + 1 ),
10711080 ]
1072- for annex in [None , bytes ([ANNEX_TAG ]) + random .randbytes (random .randrange (1000 ))]:
1081+ for annex in [None , bytes ([ANNEX_TAG , random . randint ( 1 , 255 ) ]) + random .randbytes (random .randrange (1000 ))]:
10731082 for hashtype in [SIGHASH_DEFAULT , SIGHASH_ALL ]:
10741083 for pubkey in [pubs [1 ], random .randbytes (random .choice ([x for x in range (2 , 81 ) if x != 32 ]))]:
10751084 for fn_num , fn in enumerate (SIGOPS_RATIO_SCRIPTS ):
@@ -1494,15 +1503,26 @@ def test_spenders(self, node, spenders, input_counts):
14941503 # Expected message with each input failure, may be None(which is ignored)
14951504 expected_fail_msg = None if fail_input is None else input_utxos [fail_input ].spender .err_msg
14961505 # Fill inputs/witnesses
1506+ annex_count = 0
14971507 for i in range (len (input_utxos )):
1498- tx .vin [i ].scriptSig = input_data [i ][i != fail_input ][0 ]
1499- tx .wit .vtxinwit [i ].scriptWitness .stack = input_data [i ][i != fail_input ][1 ]
1508+ sat_fn_output = input_data [i ][i != fail_input ]
1509+
1510+ tx .vin [i ].scriptSig = sat_fn_output [0 ]
1511+ tx .wit .vtxinwit [i ].scriptWitness .stack = sat_fn_output [1 ]
1512+
1513+ # Count annex inputs.
1514+ annex = sat_fn_output [2 ]
1515+ if annex is not None :
1516+ annex_count += 1
1517+
15001518 # Submit to mempool to check standardness
15011519 is_standard_tx = (
15021520 fail_input is None # Must be valid to be standard
15031521 and (all (utxo .spender .is_standard for utxo in input_utxos )) # All inputs must be standard
15041522 and tx .version >= 1 # The tx version must be standard
1505- and tx .version <= 2 )
1523+ and tx .version <= 2
1524+ and (annex_count == 0 or annex_count == len (input_utxos )) # Opt-in annexes
1525+ )
15061526 tx .rehash ()
15071527 msg = ',' .join (utxo .spender .comment + ("*" if n == fail_input else "" ) for n , utxo in enumerate (input_utxos ))
15081528 if is_standard_tx :
0 commit comments