@@ -1230,6 +1230,41 @@ def spenders_taproot_nonstandard():
12301230
12311231 return spenders
12321232
1233+ def sample_spenders ():
1234+
1235+ # Create key(s) for output creation, as well as key and script-spends
1236+ secs = [generate_privkey () for _ in range (2 )]
1237+ pubs = [compute_xonly_pubkey (sec )[0 ] for sec in secs ]
1238+
1239+ # Create a list of scripts which will be built into a taptree
1240+ scripts = [
1241+ # leaf label, followed by CScript
1242+ ("encodeable_pushdata1" , CScript ([OP_DROP , OP_PUSHDATA1 , b'aa' * 75 ])),
1243+ ("nonstd_encodeable_pushdata1" , CScript ([OP_PUSHDATA1 , b'aa' ])),
1244+ ("dummyleaf" , CScript ([])),
1245+ ]
1246+
1247+ # Build TaprootInfo using scripts and appropriate pubkey for output creation
1248+ tap = taproot_construct (pubs [0 ], scripts )
1249+
1250+ # Finally, add spender(s).
1251+ # Each spender embodies a test with an optional failure condition.
1252+ # These failure conditions allow for fine-grained success/failure
1253+ # conditions that are tested randomly.
1254+ spenders = []
1255+
1256+ # Named comment, using first leaf from scripts, with empty string as witness data, no optional fail condition
1257+ add_spender (spenders , comment = "tutorial/pushdata1" , tap = tap , leaf = "encodeable_pushdata1" , inputs = [b'\x00 ' ], no_fail = True )
1258+
1259+ # Spender with alternative failure tapscript via over-riding "failure" dictionary, along with the failure's expected err_msg / ERR_*
1260+ add_spender (spenders , comment = "tutorial/pushdata1redux" , tap = tap , leaf = "encodeable_pushdata1" , inputs = [b'\x00 ' ], failure = {"leaf" : "dummyleaf" }, ** ERR_NO_SUCCESS )
1261+
1262+ # Spender that is non-standard but otherwise valid, with extraneous signature data from inner key for optional failure condition
1263+ add_spender (spenders , comment = "tutorial/nonminpushdata1" , tap = tap , leaf = "nonstd_encodeable_pushdata1" , key = secs [0 ], standard = False , failure = {"inputs" : [getter ("sign" )]}, ** ERR_CLEANSTACK )
1264+
1265+ # New scripts=[] can be defined, and rinse-repeated as necessary until the spenders list is returned for execution
1266+ return spenders
1267+
12331268# Consensus validation flags to use in dumps for tests with "legacy/" or "inactive/" prefix.
12341269LEGACY_FLAGS = "P2SH,DERSIG,CHECKLOCKTIMEVERIFY,CHECKSEQUENCEVERIFY,WITNESS,NULLDUMMY"
12351270# Consensus validation flags to use in dumps for all other tests.
@@ -1756,12 +1791,20 @@ def run_test(self):
17561791 self .gen_test_vectors ()
17571792
17581793 self .log .info ("Post-activation tests..." )
1759- self .test_spenders (self .nodes [0 ], spenders_taproot_active (), input_counts = [1 , 2 , 2 , 2 , 2 , 3 ])
1794+
1795+ # New sub-tests not checking standardness can be added to consensus_spenders
1796+ # to allow for increased coverage across input types.
1797+ # See sample_spenders for a minimal example
1798+ consensus_spenders = sample_spenders ()
1799+ consensus_spenders += spenders_taproot_active ()
1800+ self .test_spenders (self .nodes [0 ], consensus_spenders , input_counts = [1 , 2 , 2 , 2 , 2 , 3 ])
1801+
17601802 # Run each test twice; once in isolation, and once combined with others. Testing in isolation
17611803 # means that the standardness is verified in every test (as combined transactions are only standard
17621804 # when all their inputs are standard).
1763- self .test_spenders (self .nodes [0 ], spenders_taproot_nonstandard (), input_counts = [1 ])
1764- self .test_spenders (self .nodes [0 ], spenders_taproot_nonstandard (), input_counts = [2 , 3 ])
1805+ nonstd_spenders = spenders_taproot_nonstandard ()
1806+ self .test_spenders (self .nodes [0 ], nonstd_spenders , input_counts = [1 ])
1807+ self .test_spenders (self .nodes [0 ], nonstd_spenders , input_counts = [2 , 3 ])
17651808
17661809
17671810if __name__ == '__main__' :
0 commit comments