@@ -1230,6 +1230,41 @@ def spenders_taproot_nonstandard():
1230
1230
1231
1231
return spenders
1232
1232
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
+
1233
1268
# Consensus validation flags to use in dumps for tests with "legacy/" or "inactive/" prefix.
1234
1269
LEGACY_FLAGS = "P2SH,DERSIG,CHECKLOCKTIMEVERIFY,CHECKSEQUENCEVERIFY,WITNESS,NULLDUMMY"
1235
1270
# Consensus validation flags to use in dumps for all other tests.
@@ -1756,12 +1791,20 @@ def run_test(self):
1756
1791
self .gen_test_vectors ()
1757
1792
1758
1793
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
+
1760
1802
# Run each test twice; once in isolation, and once combined with others. Testing in isolation
1761
1803
# means that the standardness is verified in every test (as combined transactions are only standard
1762
1804
# 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 ])
1765
1808
1766
1809
1767
1810
if __name__ == '__main__' :
0 commit comments