2424from test_framework .util import (
2525 assert_equal ,
2626 assert_raises_rpc_error ,
27- find_vout_for_address ,
27+ )
28+ from test_framework .wallet import (
29+ getnewdestination ,
30+ MiniWallet ,
2831)
2932
3033
@@ -52,82 +55,70 @@ def items(self):
5255class RawTransactionsTest (BitcoinTestFramework ):
5356 def set_test_params (self ):
5457 self .setup_clean_chain = True
55- self .num_nodes = 4
58+ self .num_nodes = 3
5659 self .extra_args = [
57- [], # by default Tx Index is enabled
5860 ["-txindex" ],
5961 ["-txindex" ],
6062 ["-notxindex" ],
6163 ]
6264 # whitelist all peers to speed up tx relay / mempool sync
6365 for args in self .extra_args :
6466 args .append ("-whitelist=noban@127.0.0.1" )
67+ self .requires_wallet = self .is_specified_wallet_compiled ()
6568
6669 self .supports_cli = False
6770
68- def skip_test_if_missing_module (self ):
69- self .skip_if_no_wallet ()
70-
7171 def setup_network (self ):
7272 super ().setup_network ()
7373 self .connect_nodes (0 , 2 )
7474
7575 def run_test (self ):
76+ self .wallet = MiniWallet (self .nodes [0 ])
7677 self .log .info ("Prepare some coins for multiple *rawtransaction commands" )
77- self .generate (self .nodes [ 2 ], 1 )
78+ self .generate (self .wallet , 10 )
7879 self .generate (self .nodes [0 ], COINBASE_MATURITY + 1 )
79- for amount in [1.5 , 1.0 , 5.0 ]:
80- self .nodes [0 ].sendtoaddress (self .nodes [2 ].getnewaddress (), amount )
81- self .sync_all ()
82- self .generate (self .nodes [0 ], 5 )
8380
8481 self .getrawtransaction_tests ()
8582 self .createrawtransaction_tests ()
86- self .signrawtransactionwithwallet_tests ()
8783 self .sendrawtransaction_tests ()
8884 self .sendrawtransaction_testmempoolaccept_tests ()
8985 self .transaction_version_number_tests ()
90- if not self .options .descriptors :
86+ if self . requires_wallet and not self .options .descriptors :
9187 self .raw_multisig_transaction_legacy_tests ()
9288
9389 def getrawtransaction_tests (self ):
94- addr = self .nodes [1 ].getnewaddress ()
95- txid = self .nodes [0 ].sendtoaddress (addr , 10 )
90+ tx = self .wallet .send_self_transfer (from_node = self .nodes [0 ])
9691 self .generate (self .nodes [0 ], 1 )
97- vout = find_vout_for_address (self .nodes [1 ], txid , addr )
98- rawTx = self .nodes [1 ].createrawtransaction ([{'txid' : txid , 'vout' : vout }], {self .nodes [1 ].getnewaddress (): 9.999 })
99- rawTxSigned = self .nodes [1 ].signrawtransactionwithwallet (rawTx )
100- txId = self .nodes [1 ].sendrawtransaction (rawTxSigned ['hex' ])
101- self .generateblock (self .nodes [0 ], output = self .nodes [0 ].getnewaddress (), transactions = [rawTxSigned ['hex' ]])
92+ txId = tx ['txid' ]
10293 err_msg = (
10394 "No such mempool transaction. Use -txindex or provide a block hash to enable"
10495 " blockchain transaction queries. Use gettransaction for wallet transactions."
10596 )
10697
107- for n in [0 , 3 ]:
98+ for n in [0 , 2 ]:
10899 self .log .info (f"Test getrawtransaction { 'with' if n == 0 else 'without' } -txindex" )
109100 if n == 0 :
110101 # With -txindex.
111102 # 1. valid parameters - only supply txid
112- assert_equal (self .nodes [n ].getrawtransaction (txId ), rawTxSigned ['hex' ])
113- assert_equal (self .nodes [n ].getrawtransactionmulti ({"0" :[txId ]})[txId ], rawTxSigned ['hex' ])
103+ assert_equal (self .nodes [n ].getrawtransaction (txId ), tx ['hex' ])
104+ assert_equal (self .nodes [n ].getrawtransactionmulti ({"0" :[txId ]})[txId ], tx ['hex' ])
114105
115106 # 2. valid parameters - supply txid and 0 for non-verbose
116- assert_equal (self .nodes [n ].getrawtransaction (txId , 0 ), rawTxSigned ['hex' ])
117- assert_equal (self .nodes [n ].getrawtransactionmulti ({"0" :[txId ]}, 0 )[txId ], rawTxSigned ['hex' ])
107+ assert_equal (self .nodes [n ].getrawtransaction (txId , 0 ), tx ['hex' ])
108+ assert_equal (self .nodes [n ].getrawtransactionmulti ({"0" :[txId ]}, 0 )[txId ], tx ['hex' ])
118109
119110 # 3. valid parameters - supply txid and False for non-verbose
120- assert_equal (self .nodes [n ].getrawtransaction (txId , False ), rawTxSigned ['hex' ])
121- assert_equal (self .nodes [n ].getrawtransactionmulti ({"0" :[txId ]}, False )[txId ], rawTxSigned ['hex' ])
111+ assert_equal (self .nodes [n ].getrawtransaction (txId , False ), tx ['hex' ])
112+ assert_equal (self .nodes [n ].getrawtransactionmulti ({"0" :[txId ]}, False )[txId ], tx ['hex' ])
122113
123114 # 4. valid parameters - supply txid and 1 for verbose.
124115 # We only check the "hex" field of the output so we don't need to update this test every time the output format changes.
125- assert_equal (self .nodes [n ].getrawtransaction (txId , 1 )["hex" ], rawTxSigned ['hex' ])
126- assert_equal (self .nodes [n ].getrawtransactionmulti ({"0" :[txId ]}, 1 )[txId ]['hex' ], rawTxSigned ['hex' ])
116+ assert_equal (self .nodes [n ].getrawtransaction (txId , 1 )["hex" ], tx ['hex' ])
117+ assert_equal (self .nodes [n ].getrawtransactionmulti ({"0" :[txId ]}, 1 )[txId ]['hex' ], tx ['hex' ])
127118
128119 # 5. valid parameters - supply txid and True for non-verbose
129- assert_equal (self .nodes [n ].getrawtransaction (txId , True )["hex" ], rawTxSigned ['hex' ])
130- assert_equal (self .nodes [n ].getrawtransactionmulti (verbose = True , transactions = {"0" :[txId ]})[txId ]['hex' ], rawTxSigned ['hex' ])
120+ assert_equal (self .nodes [n ].getrawtransaction (txId , True )["hex" ], tx ['hex' ])
121+ assert_equal (self .nodes [n ].getrawtransactionmulti (verbose = True , transactions = {"0" :[txId ]})[txId ]['hex' ], tx ['hex' ])
131122 else :
132123 # Without -txindex, expect to raise.
133124 for verbose in [None , 0 , False , 1 , True ]:
@@ -147,9 +138,9 @@ def getrawtransaction_tests(self):
147138 assert_raises_rpc_error (- 1 , "not a boolean" , self .nodes [n ].getrawtransaction , txId , {})
148139
149140 # Make a tx by sending, then generate 2 blocks; block1 has the tx in it
150- tx = self .nodes [ 2 ]. sendtoaddress ( self .nodes [1 ]. getnewaddress (), 1 )
141+ tx = self .wallet . send_self_transfer ( from_node = self .nodes [2 ])[ 'txid' ]
151142 block1 , block2 = self .generate (self .nodes [2 ], 2 )
152- for n in [0 , 3 ]:
143+ for n in [0 , 2 ]:
153144 self .log .info (f"Test getrawtransaction { 'with' if n == 0 else 'without' } -txindex, with blockhash" )
154145 # We should be able to get the raw transaction by providing the correct block
155146 gottx = self .nodes [n ].getrawtransaction (txid = tx , verbose = True , blockhash = block1 )
@@ -207,20 +198,21 @@ def createrawtransaction_tests(self):
207198 # sequence number out of range
208199 for invalid_seq in [- 1 , 4294967296 ]:
209200 inputs = [{'txid' : TXID , 'vout' : 1 , 'sequence' : invalid_seq }]
210- outputs = {self .nodes [0 ].getnewaddress (): 1 }
201+ address = getnewdestination ()[2 ]
202+ outputs = {address : 1 }
211203 assert_raises_rpc_error (- 8 , 'Invalid parameter, sequence number is out of range' ,
212204 self .nodes [0 ].createrawtransaction , inputs , outputs )
213205 # with valid sequence number
214206 for valid_seq in [1000 , 4294967294 ]:
215207 inputs = [{'txid' : TXID , 'vout' : 1 , 'sequence' : valid_seq }]
216- outputs = {self .nodes [0 ].getnewaddress (): 1 }
208+ address = getnewdestination ()[2 ]
209+ outputs = {address : 1 }
217210 rawtx = self .nodes [0 ].createrawtransaction (inputs , outputs )
218211 decrawtx = self .nodes [0 ].decoderawtransaction (rawtx )
219212 assert_equal (decrawtx ['vin' ][0 ]['sequence' ], valid_seq )
220213
221214 # Test `createrawtransaction` invalid `outputs`
222- address = self .nodes [0 ].getnewaddress ()
223- address2 = self .nodes [0 ].getnewaddress ()
215+ address = getnewdestination ()[2 ]
224216 assert_raises_rpc_error (- 1 , "JSON value is not an array as expected" , self .nodes [0 ].createrawtransaction , [], 'foo' )
225217 self .nodes [0 ].createrawtransaction (inputs = [], outputs = {}) # Should not throw for backwards compatibility
226218 self .nodes [0 ].createrawtransaction (inputs = [], outputs = [])
@@ -249,6 +241,7 @@ def createrawtransaction_tests(self):
249241 self .nodes [2 ].createrawtransaction (inputs = [{'txid' : TXID , 'vout' : 9 }], outputs = [{address : 99 }]),
250242 )
251243 # Two outputs
244+ address2 = getnewdestination ()[2 ]
252245 tx = tx_from_hex (self .nodes [2 ].createrawtransaction (inputs = [{'txid' : TXID , 'vout' : 9 }], outputs = OrderedDict ([(address , 99 ), (address2 , 99 )])))
253246 assert_equal (len (tx .vout ), 2 )
254247 assert_equal (
@@ -263,122 +256,53 @@ def createrawtransaction_tests(self):
263256 self .nodes [2 ].createrawtransaction (inputs = [{'txid' : TXID , 'vout' : 9 }], outputs = [{address : 99 }, {address2 : 99 }, {'data' : '99' }]),
264257 )
265258
266- def signrawtransactionwithwallet_tests (self ):
267- for type in ["legacy" ]:
268- self .log .info (f"Test signrawtransactionwithwallet with missing prevtx info ({ type } )" )
269- addr = self .nodes [0 ].getnewaddress ("" )
270- addrinfo = self .nodes [0 ].getaddressinfo (addr )
271- pubkey = addrinfo ["scriptPubKey" ]
272- inputs = [{'txid' : TXID , 'vout' : 3 , 'sequence' : 1000 }]
273- outputs = {self .nodes [0 ].getnewaddress (): 1 }
274- rawtx = self .nodes [0 ].createrawtransaction (inputs , outputs )
275-
276- prevtx = dict (txid = TXID , scriptPubKey = pubkey , vout = 3 , amount = 1 )
277- succ = self .nodes [0 ].signrawtransactionwithwallet (rawtx , [prevtx ])
278- assert succ ["complete" ]
279-
280- if type == "legacy" :
281- del prevtx ["amount" ]
282- succ = self .nodes [0 ].signrawtransactionwithwallet (rawtx , [prevtx ])
283- assert succ ["complete" ]
284- else :
285- assert_raises_rpc_error (- 3 , "Missing amount" , self .nodes [0 ].signrawtransactionwithwallet , rawtx , [
286- {
287- "txid" : TXID ,
288- "scriptPubKey" : pubkey ,
289- "vout" : 3 ,
290- }
291- ])
292-
293- assert_raises_rpc_error (- 3 , "Missing vout" , self .nodes [0 ].signrawtransactionwithwallet , rawtx , [
294- {
295- "txid" : TXID ,
296- "scriptPubKey" : pubkey ,
297- "amount" : 1 ,
298- }
299- ])
300- assert_raises_rpc_error (- 3 , "Missing txid" , self .nodes [0 ].signrawtransactionwithwallet , rawtx , [
301- {
302- "scriptPubKey" : pubkey ,
303- "vout" : 3 ,
304- "amount" : 1 ,
305- }
306- ])
307- assert_raises_rpc_error (- 3 , "Missing scriptPubKey" , self .nodes [0 ].signrawtransactionwithwallet , rawtx , [
308- {
309- "txid" : TXID ,
310- "vout" : 3 ,
311- "amount" : 1
312- }
313- ])
314-
315259 def sendrawtransaction_tests (self ):
316260 self .log .info ("Test sendrawtransaction with missing input" )
317261 inputs = [{'txid' : TXID , 'vout' : 1 }] # won't exist
318- outputs = {self .nodes [0 ].getnewaddress (): 4.998 }
262+ address = getnewdestination ()[2 ]
263+ outputs = {address : 4.998 }
319264 rawtx = self .nodes [2 ].createrawtransaction (inputs , outputs )
320- rawtx = self .nodes [2 ].signrawtransactionwithwallet (rawtx )
321- assert_raises_rpc_error (- 25 , "bad-txns-inputs-missingorspent" , self .nodes [2 ].sendrawtransaction , rawtx ['hex' ])
265+ assert_raises_rpc_error (- 25 , "bad-txns-inputs-missingorspent" , self .nodes [2 ].sendrawtransaction , rawtx )
322266
323267 def sendrawtransaction_testmempoolaccept_tests (self ):
324268 self .log .info ("Test sendrawtransaction/testmempoolaccept with maxfeerate" )
325269 fee_exceeds_max = "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"
326270
327271 # Test a transaction with a small fee.
328- txId = self .nodes [0 ].sendtoaddress (self .nodes [2 ].getnewaddress (), 1.0 )
329- rawTx = self .nodes [0 ].getrawtransaction (txId , True )
330- vout = next (o for o in rawTx ['vout' ] if o ['value' ] == Decimal ('1.00000000' ))
331-
332- self .sync_all ()
333- inputs = [{"txid" : txId , "vout" : vout ['n' ]}]
334- # Fee 10,000 satoshis, (1 - (10000 sat * 0.00000001 BTC/sat)) = 0.9999
335- outputs = {self .nodes [0 ].getnewaddress (): Decimal ("0.99990000" )}
336- rawTx = self .nodes [2 ].createrawtransaction (inputs , outputs )
337- rawTxSigned = self .nodes [2 ].signrawtransactionwithwallet (rawTx )
338- assert_equal (rawTxSigned ['complete' ], True )
339- # Fee 10,000 satoshis, ~200 b transaction, fee rate should land around 50 sat/byte = 0.00500000 BTC/kB
272+ # Fee rate is 0.00500000 BTC/kvB
273+ tx = self .wallet .create_self_transfer (fee_rate = Decimal ('0.00500000' ))
340274 # Thus, testmempoolaccept should reject
341- testres = self .nodes [2 ].testmempoolaccept ([rawTxSigned ['hex' ]], 0.00001000 )[0 ]
275+ testres = self .nodes [2 ].testmempoolaccept ([tx ['hex' ]], 0.00001000 )[0 ]
342276 assert_equal (testres ['allowed' ], False )
343277 assert_equal (testres ['reject-reason' ], 'max-fee-exceeded' )
344278 # and sendrawtransaction should throw
345- assert_raises_rpc_error (- 25 , fee_exceeds_max , self .nodes [2 ].sendrawtransaction , rawTxSigned ['hex' ], 0.00001000 )
279+ assert_raises_rpc_error (- 25 , fee_exceeds_max , self .nodes [2 ].sendrawtransaction , tx ['hex' ], 0.00001000 )
346280 # and the following calls should both succeed
347- testres = self .nodes [2 ].testmempoolaccept (rawtxs = [rawTxSigned ['hex' ]])[0 ]
281+ testres = self .nodes [2 ].testmempoolaccept (rawtxs = [tx ['hex' ]])[0 ]
348282 assert_equal (testres ['allowed' ], True )
349- self .nodes [2 ].sendrawtransaction (hexstring = rawTxSigned ['hex' ])
283+ self .nodes [2 ].sendrawtransaction (hexstring = tx ['hex' ])
350284
351285 # Test a transaction with a large fee.
352- txId = self .nodes [0 ].sendtoaddress (self .nodes [2 ].getnewaddress (), 1.0 )
353- rawTx = self .nodes [0 ].getrawtransaction (txId , True )
354- vout = next (o for o in rawTx ['vout' ] if o ['value' ] == Decimal ('1.00000000' ))
355-
356- self .sync_all ()
357- inputs = [{"txid" : txId , "vout" : vout ['n' ]}]
358- # Fee 2,000,000 satoshis, (1 - (2000000 sat * 0.00000001 BTC/sat)) = 0.98
359- outputs = {self .nodes [0 ].getnewaddress () : Decimal ("0.98000000" )}
360- rawTx = self .nodes [2 ].createrawtransaction (inputs , outputs )
361- rawTxSigned = self .nodes [2 ].signrawtransactionwithwallet (rawTx )
362- assert_equal (rawTxSigned ['complete' ], True )
363- # Fee 2,000,000 satoshis, ~100 b transaction, fee rate should land around 20,000 sat/byte = 0.20000000 BTC/kB
286+ # Fee rate is 0.20000000 BTC/kvB
287+ tx = self .wallet .create_self_transfer (fee_rate = Decimal ('0.20000000' ))
364288 # Thus, testmempoolaccept should reject
365- testres = self .nodes [2 ].testmempoolaccept ([rawTxSigned ['hex' ]])[0 ]
289+ testres = self .nodes [2 ].testmempoolaccept ([tx ['hex' ]])[0 ]
366290 assert_equal (testres ['allowed' ], False )
367291 assert_equal (testres ['reject-reason' ], 'max-fee-exceeded' )
368292 # and sendrawtransaction should throw
369- assert_raises_rpc_error (- 25 , fee_exceeds_max , self .nodes [2 ].sendrawtransaction , rawTxSigned ['hex' ])
293+ assert_raises_rpc_error (- 25 , fee_exceeds_max , self .nodes [2 ].sendrawtransaction , tx ['hex' ])
370294 # and the following calls should both succeed
371- testres = self .nodes [2 ].testmempoolaccept (rawtxs = [rawTxSigned ['hex' ]], maxfeerate = '0.20000000' )[0 ]
295+ testres = self .nodes [2 ].testmempoolaccept (rawtxs = [tx ['hex' ]], maxfeerate = '0.20000000' )[0 ]
372296 assert_equal (testres ['allowed' ], True )
373- self .nodes [2 ].sendrawtransaction (hexstring = rawTxSigned ['hex' ], maxfeerate = '0.20000000' )
297+ self .nodes [2 ].sendrawtransaction (hexstring = tx ['hex' ], maxfeerate = '0.20000000' )
374298
375299 self .log .info ("Test sendrawtransaction/testmempoolaccept with tx already in the chain" )
376300 self .generate (self .nodes [2 ], 1 )
377301 for node in self .nodes :
378- testres = node .testmempoolaccept ([rawTxSigned ['hex' ]])[0 ]
302+ testres = node .testmempoolaccept ([tx ['hex' ]])[0 ]
379303 assert_equal (testres ['allowed' ], False )
380304 assert_equal (testres ['reject-reason' ], 'txn-already-known' )
381- assert_raises_rpc_error (- 27 , 'Transaction already in block chain' , node .sendrawtransaction , rawTxSigned ['hex' ])
305+ assert_raises_rpc_error (- 27 , 'Transaction already in block chain' , node .sendrawtransaction , tx ['hex' ])
382306
383307 def transaction_version_number_tests (self ):
384308 self .log .info ("Test transaction version numbers" )
0 commit comments