24
24
from test_framework .util import (
25
25
assert_equal ,
26
26
assert_raises_rpc_error ,
27
- find_vout_for_address ,
27
+ )
28
+ from test_framework .wallet import (
29
+ getnewdestination ,
30
+ MiniWallet ,
28
31
)
29
32
30
33
@@ -52,78 +55,67 @@ def items(self):
52
55
class RawTransactionsTest (BitcoinTestFramework ):
53
56
def set_test_params (self ):
54
57
self .setup_clean_chain = True
55
- self .num_nodes = 4
58
+ self .num_nodes = 3
56
59
self .extra_args = [
57
- ["-txindex" ],
58
60
["-txindex" ],
59
61
["-txindex" ],
60
62
[],
61
63
]
62
64
# whitelist all peers to speed up tx relay / mempool sync
63
65
for args in self .extra_args :
64
66
67
+ self .requires_wallet = self .is_specified_wallet_compiled ()
65
68
66
69
self .supports_cli = False
67
70
68
- def skip_test_if_missing_module (self ):
69
- self .skip_if_no_wallet ()
70
-
71
71
def setup_network (self ):
72
72
super ().setup_network ()
73
73
self .connect_nodes (0 , 2 )
74
74
75
75
def run_test (self ):
76
+ self .wallet = MiniWallet (self .nodes [0 ])
76
77
self .log .info ("Prepare some coins for multiple *rawtransaction commands" )
77
- self .generate (self .nodes [ 2 ], 1 )
78
+ self .generate (self .wallet , 10 )
78
79
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 )
83
80
84
81
self .getrawtransaction_tests ()
85
82
self .createrawtransaction_tests ()
86
83
self .sendrawtransaction_tests ()
87
84
self .sendrawtransaction_testmempoolaccept_tests ()
88
85
self .decoderawtransaction_tests ()
89
86
self .transaction_version_number_tests ()
90
- if not self .options .descriptors :
87
+ if self . requires_wallet and not self .options .descriptors :
91
88
self .raw_multisig_transaction_legacy_tests ()
92
89
93
90
def getrawtransaction_tests (self ):
94
- addr = self .nodes [1 ].getnewaddress ()
95
- txid = self .nodes [0 ].sendtoaddress (addr , 10 )
91
+ tx = self .wallet .send_self_transfer (from_node = self .nodes [0 ])
96
92
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' ]])
93
+ txId = tx ['txid' ]
102
94
err_msg = (
103
95
"No such mempool transaction. Use -txindex or provide a block hash to enable"
104
96
" blockchain transaction queries. Use gettransaction for wallet transactions."
105
97
)
106
98
107
- for n in [0 , 3 ]:
99
+ for n in [0 , 2 ]:
108
100
self .log .info (f"Test getrawtransaction { 'with' if n == 0 else 'without' } -txindex" )
109
101
110
102
if n == 0 :
111
103
# With -txindex.
112
104
# 1. valid parameters - only supply txid
113
- assert_equal (self .nodes [n ].getrawtransaction (txId ), rawTxSigned ['hex' ])
105
+ assert_equal (self .nodes [n ].getrawtransaction (txId ), tx ['hex' ])
114
106
115
107
# 2. valid parameters - supply txid and 0 for non-verbose
116
- assert_equal (self .nodes [n ].getrawtransaction (txId , 0 ), rawTxSigned ['hex' ])
108
+ assert_equal (self .nodes [n ].getrawtransaction (txId , 0 ), tx ['hex' ])
117
109
118
110
# 3. valid parameters - supply txid and False for non-verbose
119
- assert_equal (self .nodes [n ].getrawtransaction (txId , False ), rawTxSigned ['hex' ])
111
+ assert_equal (self .nodes [n ].getrawtransaction (txId , False ), tx ['hex' ])
120
112
121
113
# 4. valid parameters - supply txid and 1 for verbose.
122
114
# We only check the "hex" field of the output so we don't need to update this test every time the output format changes.
123
- assert_equal (self .nodes [n ].getrawtransaction (txId , 1 )["hex" ], rawTxSigned ['hex' ])
115
+ assert_equal (self .nodes [n ].getrawtransaction (txId , 1 )["hex" ], tx ['hex' ])
124
116
125
117
# 5. valid parameters - supply txid and True for non-verbose
126
- assert_equal (self .nodes [n ].getrawtransaction (txId , True )["hex" ], rawTxSigned ['hex' ])
118
+ assert_equal (self .nodes [n ].getrawtransaction (txId , True )["hex" ], tx ['hex' ])
127
119
else :
128
120
# Without -txindex, expect to raise.
129
121
for verbose in [None , 0 , False , 1 , True ]:
@@ -140,9 +132,9 @@ def getrawtransaction_tests(self):
140
132
assert_raises_rpc_error (- 1 , "not a boolean" , self .nodes [n ].getrawtransaction , txId , {})
141
133
142
134
# Make a tx by sending, then generate 2 blocks; block1 has the tx in it
143
- tx = self .nodes [ 2 ]. sendtoaddress ( self .nodes [1 ]. getnewaddress (), 1 )
135
+ tx = self .wallet . send_self_transfer ( from_node = self .nodes [2 ])[ 'txid' ]
144
136
block1 , block2 = self .generate (self .nodes [2 ], 2 )
145
- for n in [0 , 3 ]:
137
+ for n in [0 , 2 ]:
146
138
self .log .info (f"Test getrawtransaction { 'with' if n == 0 else 'without' } -txindex, with blockhash" )
147
139
# We should be able to get the raw transaction by providing the correct block
148
140
gottx = self .nodes [n ].getrawtransaction (txid = tx , verbose = True , blockhash = block1 )
@@ -199,20 +191,21 @@ def createrawtransaction_tests(self):
199
191
# sequence number out of range
200
192
for invalid_seq in [- 1 , 4294967296 ]:
201
193
inputs = [{'txid' : TXID , 'vout' : 1 , 'sequence' : invalid_seq }]
202
- outputs = {self .nodes [0 ].getnewaddress (): 1 }
194
+ address = getnewdestination ()[2 ]
195
+ outputs = {address : 1 }
203
196
assert_raises_rpc_error (- 8 , 'Invalid parameter, sequence number is out of range' ,
204
197
self .nodes [0 ].createrawtransaction , inputs , outputs )
205
198
# with valid sequence number
206
199
for valid_seq in [1000 , 4294967294 ]:
207
200
inputs = [{'txid' : TXID , 'vout' : 1 , 'sequence' : valid_seq }]
208
- outputs = {self .nodes [0 ].getnewaddress (): 1 }
201
+ address = getnewdestination ()[2 ]
202
+ outputs = {address : 1 }
209
203
rawtx = self .nodes [0 ].createrawtransaction (inputs , outputs )
210
204
decrawtx = self .nodes [0 ].decoderawtransaction (rawtx )
211
205
assert_equal (decrawtx ['vin' ][0 ]['sequence' ], valid_seq )
212
206
213
207
# Test `createrawtransaction` invalid `outputs`
214
- address = self .nodes [0 ].getnewaddress ()
215
- address2 = self .nodes [0 ].getnewaddress ()
208
+ address = getnewdestination ()[2 ]
216
209
assert_raises_rpc_error (- 1 , "JSON value is not an array as expected" , self .nodes [0 ].createrawtransaction , [], 'foo' )
217
210
self .nodes [0 ].createrawtransaction (inputs = [], outputs = {}) # Should not throw for backwards compatibility
218
211
self .nodes [0 ].createrawtransaction (inputs = [], outputs = [])
@@ -244,6 +237,7 @@ def createrawtransaction_tests(self):
244
237
self .nodes [2 ].createrawtransaction (inputs = [{'txid' : TXID , 'vout' : 9 }], outputs = [{address : 99 }]),
245
238
)
246
239
# Two outputs
240
+ address2 = getnewdestination ()[2 ]
247
241
tx = tx_from_hex (self .nodes [2 ].createrawtransaction (inputs = [{'txid' : TXID , 'vout' : 9 }], outputs = OrderedDict ([(address , 99 ), (address2 , 99 )])))
248
242
assert_equal (len (tx .vout ), 2 )
249
243
assert_equal (
@@ -261,70 +255,50 @@ def createrawtransaction_tests(self):
261
255
def sendrawtransaction_tests (self ):
262
256
self .log .info ("Test sendrawtransaction with missing input" )
263
257
inputs = [{'txid' : TXID , 'vout' : 1 }] # won't exist
264
- outputs = {self .nodes [0 ].getnewaddress (): 4.998 }
258
+ address = getnewdestination ()[2 ]
259
+ outputs = {address : 4.998 }
265
260
rawtx = self .nodes [2 ].createrawtransaction (inputs , outputs )
266
- rawtx = self .nodes [2 ].signrawtransactionwithwallet (rawtx )
267
- assert_raises_rpc_error (- 25 , "bad-txns-inputs-missingorspent" , self .nodes [2 ].sendrawtransaction , rawtx ['hex' ])
261
+ assert_raises_rpc_error (- 25 , "bad-txns-inputs-missingorspent" , self .nodes [2 ].sendrawtransaction , rawtx )
268
262
269
263
def sendrawtransaction_testmempoolaccept_tests (self ):
270
264
self .log .info ("Test sendrawtransaction/testmempoolaccept with maxfeerate" )
271
265
fee_exceeds_max = "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"
272
266
273
267
# Test a transaction with a small fee.
274
- txId = self .nodes [0 ].sendtoaddress (self .nodes [2 ].getnewaddress (), 1.0 )
275
- rawTx = self .nodes [0 ].getrawtransaction (txId , True )
276
- vout = next (o for o in rawTx ['vout' ] if o ['value' ] == Decimal ('1.00000000' ))
277
-
278
- self .sync_all ()
279
- inputs = [{"txid" : txId , "vout" : vout ['n' ]}]
280
- # Fee 10,000 satoshis, (1 - (10000 sat * 0.00000001 BTC/sat)) = 0.9999
281
- outputs = {self .nodes [0 ].getnewaddress (): Decimal ("0.99990000" )}
282
- rawTx = self .nodes [2 ].createrawtransaction (inputs , outputs )
283
- rawTxSigned = self .nodes [2 ].signrawtransactionwithwallet (rawTx )
284
- assert_equal (rawTxSigned ['complete' ], True )
285
- # Fee 10,000 satoshis, ~100 b transaction, fee rate should land around 100 sat/byte = 0.00100000 BTC/kB
268
+ # Fee rate is 0.00100000 BTC/kvB
269
+ tx = self .wallet .create_self_transfer (fee_rate = Decimal ('0.00100000' ))
286
270
# Thus, testmempoolaccept should reject
287
- testres = self .nodes [2 ].testmempoolaccept ([rawTxSigned ['hex' ]], 0.00001000 )[0 ]
271
+ testres = self .nodes [2 ].testmempoolaccept ([tx ['hex' ]], 0.00001000 )[0 ]
288
272
assert_equal (testres ['allowed' ], False )
289
273
assert_equal (testres ['reject-reason' ], 'max-fee-exceeded' )
290
274
# and sendrawtransaction should throw
291
- assert_raises_rpc_error (- 25 , fee_exceeds_max , self .nodes [2 ].sendrawtransaction , rawTxSigned ['hex' ], 0.00001000 )
275
+ assert_raises_rpc_error (- 25 , fee_exceeds_max , self .nodes [2 ].sendrawtransaction , tx ['hex' ], 0.00001000 )
292
276
# and the following calls should both succeed
293
- testres = self .nodes [2 ].testmempoolaccept (rawtxs = [rawTxSigned ['hex' ]])[0 ]
277
+ testres = self .nodes [2 ].testmempoolaccept (rawtxs = [tx ['hex' ]])[0 ]
294
278
assert_equal (testres ['allowed' ], True )
295
- self .nodes [2 ].sendrawtransaction (hexstring = rawTxSigned ['hex' ])
279
+ self .nodes [2 ].sendrawtransaction (hexstring = tx ['hex' ])
296
280
297
281
# Test a transaction with a large fee.
298
- txId = self .nodes [0 ].sendtoaddress (self .nodes [2 ].getnewaddress (), 1.0 )
299
- rawTx = self .nodes [0 ].getrawtransaction (txId , True )
300
- vout = next (o for o in rawTx ['vout' ] if o ['value' ] == Decimal ('1.00000000' ))
301
-
302
- self .sync_all ()
303
- inputs = [{"txid" : txId , "vout" : vout ['n' ]}]
304
- # Fee 2,000,000 satoshis, (1 - (2000000 sat * 0.00000001 BTC/sat)) = 0.98
305
- outputs = {self .nodes [0 ].getnewaddress () : Decimal ("0.98000000" )}
306
- rawTx = self .nodes [2 ].createrawtransaction (inputs , outputs )
307
- rawTxSigned = self .nodes [2 ].signrawtransactionwithwallet (rawTx )
308
- assert_equal (rawTxSigned ['complete' ], True )
309
- # Fee 2,000,000 satoshis, ~100 b transaction, fee rate should land around 20,000 sat/byte = 0.20000000 BTC/kB
282
+ # Fee rate is 0.20000000 BTC/kvB
283
+ tx = self .wallet .create_self_transfer (mempool_valid = False , from_node = self .nodes [0 ], fee_rate = Decimal ('0.20000000' ))
310
284
# Thus, testmempoolaccept should reject
311
- testres = self .nodes [2 ].testmempoolaccept ([rawTxSigned ['hex' ]])[0 ]
285
+ testres = self .nodes [2 ].testmempoolaccept ([tx ['hex' ]])[0 ]
312
286
assert_equal (testres ['allowed' ], False )
313
287
assert_equal (testres ['reject-reason' ], 'max-fee-exceeded' )
314
288
# and sendrawtransaction should throw
315
- assert_raises_rpc_error (- 25 , fee_exceeds_max , self .nodes [2 ].sendrawtransaction , rawTxSigned ['hex' ])
289
+ assert_raises_rpc_error (- 25 , fee_exceeds_max , self .nodes [2 ].sendrawtransaction , tx ['hex' ])
316
290
# and the following calls should both succeed
317
- testres = self .nodes [2 ].testmempoolaccept (rawtxs = [rawTxSigned ['hex' ]], maxfeerate = '0.20000000' )[0 ]
291
+ testres = self .nodes [2 ].testmempoolaccept (rawtxs = [tx ['hex' ]], maxfeerate = '0.20000000' )[0 ]
318
292
assert_equal (testres ['allowed' ], True )
319
- self .nodes [2 ].sendrawtransaction (hexstring = rawTxSigned ['hex' ], maxfeerate = '0.20000000' )
293
+ self .nodes [2 ].sendrawtransaction (hexstring = tx ['hex' ], maxfeerate = '0.20000000' )
320
294
321
295
self .log .info ("Test sendrawtransaction/testmempoolaccept with tx already in the chain" )
322
296
self .generate (self .nodes [2 ], 1 )
323
297
for node in self .nodes :
324
- testres = node .testmempoolaccept ([rawTxSigned ['hex' ]])[0 ]
298
+ testres = node .testmempoolaccept ([tx ['hex' ]])[0 ]
325
299
assert_equal (testres ['allowed' ], False )
326
300
assert_equal (testres ['reject-reason' ], 'txn-already-known' )
327
- assert_raises_rpc_error (- 27 , 'Transaction already in block chain' , node .sendrawtransaction , rawTxSigned ['hex' ])
301
+ assert_raises_rpc_error (- 27 , 'Transaction already in block chain' , node .sendrawtransaction , tx ['hex' ])
328
302
329
303
def decoderawtransaction_tests (self ):
330
304
self .log .info ("Test decoderawtransaction" )
0 commit comments