5
5
"""Test the rawtransaction RPCs.
6
6
7
7
Test the following RPCs:
8
+ - getrawtransaction
8
9
- createrawtransaction
9
10
- signrawtransactionwithwallet
10
11
- sendrawtransaction
11
12
- decoderawtransaction
12
- - getrawtransaction
13
13
"""
14
14
15
15
from collections import OrderedDict
@@ -85,7 +85,17 @@ def run_test(self):
85
85
self .nodes [0 ].generate (5 )
86
86
self .sync_all ()
87
87
88
- # getrawtransaction tests
88
+ self .getrawtransaction_tests ()
89
+ self .createrawtransaction_tests ()
90
+ self .signrawtransactionwithwallet_tests ()
91
+ self .sendrawtransaction_tests ()
92
+ self .sendrawtransaction_testmempoolaccept_tests ()
93
+ self .decoderawtransaction_tests ()
94
+ self .transaction_version_number_tests ()
95
+ if not self .options .descriptors :
96
+ self .raw_multisig_transaction_legacy_tests ()
97
+
98
+ def getrawtransaction_tests (self ):
89
99
addr = self .nodes [1 ].getnewaddress ()
90
100
txid = self .nodes [0 ].sendtoaddress (addr , 10 )
91
101
self .nodes [0 ].generate (1 )
@@ -168,6 +178,7 @@ def run_test(self):
168
178
block = self .nodes [0 ].getblock (self .nodes [0 ].getblockhash (0 ))
169
179
assert_raises_rpc_error (- 5 , "The genesis block coinbase is not considered an ordinary transaction" , self .nodes [0 ].getrawtransaction , block ['merkleroot' ])
170
180
181
+ def createrawtransaction_tests (self ):
171
182
self .log .info ("Test createrawtransaction" )
172
183
# Test `createrawtransaction` required parameters
173
184
assert_raises_rpc_error (- 1 , "createrawtransaction" , self .nodes [0 ].createrawtransaction )
@@ -247,6 +258,7 @@ def run_test(self):
247
258
self .nodes [2 ].createrawtransaction (inputs = [{'txid' : TXID , 'vout' : 9 }], outputs = [{address : 99 }, {address2 : 99 }, {'data' : '99' }]),
248
259
)
249
260
261
+ def signrawtransactionwithwallet_tests (self ):
250
262
for type in ["bech32" , "p2sh-segwit" , "legacy" ]:
251
263
self .log .info (f"Test signrawtransactionwithwallet with missing prevtx info ({ type } )" )
252
264
addr = self .nodes [0 ].getnewaddress ("" , type )
@@ -259,12 +271,12 @@ def run_test(self):
259
271
prevtx = dict (txid = TXID , scriptPubKey = pubkey , vout = 3 , amount = 1 )
260
272
succ = self .nodes [0 ].signrawtransactionwithwallet (rawtx , [prevtx ])
261
273
assert succ ["complete" ]
274
+
262
275
if type == "legacy" :
263
276
del prevtx ["amount" ]
264
277
succ = self .nodes [0 ].signrawtransactionwithwallet (rawtx , [prevtx ])
265
278
assert succ ["complete" ]
266
-
267
- if type != "legacy" :
279
+ else :
268
280
assert_raises_rpc_error (- 3 , "Missing amount" , self .nodes [0 ].signrawtransactionwithwallet , rawtx , [
269
281
{
270
282
"txid" : TXID ,
@@ -295,13 +307,15 @@ def run_test(self):
295
307
}
296
308
])
297
309
310
+ def sendrawtransaction_tests (self ):
298
311
self .log .info ("Test sendrawtransaction with missing input" )
299
312
inputs = [{'txid' : TXID , 'vout' : 1 }] # won't exist
300
313
outputs = { self .nodes [0 ].getnewaddress () : 4.998 }
301
314
rawtx = self .nodes [2 ].createrawtransaction (inputs , outputs )
302
315
rawtx = self .nodes [2 ].signrawtransactionwithwallet (rawtx )
303
316
assert_raises_rpc_error (- 25 , "bad-txns-inputs-missingorspent" , self .nodes [2 ].sendrawtransaction , rawtx ['hex' ])
304
317
318
+ def sendrawtransaction_testmempoolaccept_tests (self ):
305
319
self .log .info ("Test sendrawtransaction/testmempoolaccept with maxfeerate" )
306
320
# Test a transaction with a small fee.
307
321
txId = self .nodes [0 ].sendtoaddress (self .nodes [2 ].getnewaddress (), 1.0 )
@@ -360,6 +374,7 @@ def run_test(self):
360
374
assert_equal (testres ['reject-reason' ], 'txn-already-known' )
361
375
assert_raises_rpc_error (- 27 , 'Transaction already in block chain' , node .sendrawtransaction , rawTxSigned ['hex' ])
362
376
377
+ def decoderawtransaction_tests (self ):
363
378
self .log .info ("Test decoderawtransaction" )
364
379
# witness transaction
365
380
encrawtx = "010000000001010000000000000072c1a6a246ae63f74f931e8365e15a089c68d61900000000000000000000ffffffff0100e1f50500000000000102616100000000"
@@ -378,6 +393,7 @@ def run_test(self):
378
393
assert_equal (decrawtx , decrawtx_wit ) # the witness interpretation should be chosen
379
394
assert_equal (decrawtx ['vin' ][0 ]['coinbase' ], "03c68708046ff8415c622f4254432e434f4d2ffabe6d6de1965d02c68f928e5b244ab1965115a36f56eb997633c7f690124bbf43644e23080000000ca3d3af6d005a65ff0200fd00000000" )
380
395
396
+ def transaction_version_number_tests (self ):
381
397
self .log .info ("Test transaction version numbers" )
382
398
383
399
# Test the minimum transaction version number that fits in a signed 32-bit integer.
@@ -395,122 +411,122 @@ def run_test(self):
395
411
decrawtx = self .nodes [0 ].decoderawtransaction (rawtx )
396
412
assert_equal (decrawtx ['version' ], 0x7fffffff )
397
413
398
- if not self . options . descriptors :
399
- self .log .info ("Test raw multisig transactions (legacy)" )
400
- # The traditional multisig workflow does not work with descriptor wallets so these are legacy only.
401
- # The multisig workflow with descriptor wallets uses PSBTs and is tested elsewhere, no need to do them here.
402
- # 2of2 test
403
- addr1 = self .nodes [2 ].getnewaddress ()
404
- addr2 = self .nodes [2 ].getnewaddress ()
405
-
406
- addr1Obj = self .nodes [2 ].getaddressinfo (addr1 )
407
- addr2Obj = self .nodes [2 ].getaddressinfo (addr2 )
408
-
409
- # Tests for createmultisig and addmultisigaddress
410
- assert_raises_rpc_error (- 5 , "Invalid public key" , self .nodes [0 ].createmultisig , 1 , ["01020304" ])
411
- self .nodes [0 ].createmultisig (2 , [addr1Obj ['pubkey' ], addr2Obj ['pubkey' ]]) # createmultisig can only take public keys
412
- assert_raises_rpc_error (- 5 , "Invalid public key" , self .nodes [0 ].createmultisig , 2 , [addr1Obj ['pubkey' ], addr1 ]) # addmultisigaddress can take both pubkeys and addresses so long as they are in the wallet, which is tested here.
413
-
414
- mSigObj = self .nodes [2 ].addmultisigaddress (2 , [addr1Obj ['pubkey' ], addr1 ])['address' ]
415
-
416
- #use balance deltas instead of absolute values
417
- bal = self .nodes [2 ].getbalance ()
418
-
419
- # send 1.2 BTC to msig adr
420
- txId = self .nodes [0 ].sendtoaddress (mSigObj , 1.2 )
421
- self .sync_all ()
422
- self .nodes [0 ].generate (1 )
423
- self .sync_all ()
424
- assert_equal (self .nodes [2 ].getbalance (), bal + Decimal ('1.20000000' )) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
425
-
426
-
427
- # 2of3 test from different nodes
428
- bal = self .nodes [2 ].getbalance ()
429
- addr1 = self .nodes [1 ].getnewaddress ()
430
- addr2 = self .nodes [2 ].getnewaddress ()
431
- addr3 = self .nodes [2 ].getnewaddress ()
432
-
433
- addr1Obj = self .nodes [1 ].getaddressinfo (addr1 )
434
- addr2Obj = self .nodes [2 ].getaddressinfo (addr2 )
435
- addr3Obj = self .nodes [2 ].getaddressinfo (addr3 )
436
-
437
- mSigObj = self .nodes [2 ].addmultisigaddress (2 , [addr1Obj ['pubkey' ], addr2Obj ['pubkey' ], addr3Obj ['pubkey' ]])['address' ]
438
-
439
- txId = self .nodes [0 ].sendtoaddress (mSigObj , 2.2 )
440
- decTx = self .nodes [0 ].gettransaction (txId )
441
- rawTx = self .nodes [0 ].decoderawtransaction (decTx ['hex' ])
442
- self .sync_all ()
443
- self .nodes [0 ].generate (1 )
444
- self .sync_all ()
445
-
446
- #THIS IS AN INCOMPLETE FEATURE
447
- #NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION
448
- assert_equal (self .nodes [2 ].getbalance (), bal ) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable
449
-
450
- txDetails = self .nodes [0 ].gettransaction (txId , True )
451
- rawTx = self .nodes [0 ].decoderawtransaction (txDetails ['hex' ])
452
- vout = next (o for o in rawTx ['vout' ] if o ['value' ] == Decimal ('2.20000000' ))
453
-
454
- bal = self .nodes [0 ].getbalance ()
455
- inputs = [{ "txid" : txId , "vout" : vout ['n' ], "scriptPubKey" : vout ['scriptPubKey' ]['hex' ], "amount" : vout ['value' ]}]
456
- outputs = { self .nodes [0 ].getnewaddress () : 2.19 }
457
- rawTx = self .nodes [2 ].createrawtransaction (inputs , outputs )
458
- rawTxPartialSigned = self .nodes [1 ].signrawtransactionwithwallet (rawTx , inputs )
459
- assert_equal (rawTxPartialSigned ['complete' ], False ) #node1 only has one key, can't comp. sign the tx
460
-
461
- rawTxSigned = self .nodes [2 ].signrawtransactionwithwallet (rawTx , inputs )
462
- assert_equal (rawTxSigned ['complete' ], True ) #node2 can sign the tx compl., own two of three keys
463
- self .nodes [2 ].sendrawtransaction (rawTxSigned ['hex' ])
464
- rawTx = self .nodes [0 ].decoderawtransaction (rawTxSigned ['hex' ])
465
- self .sync_all ()
466
- self .nodes [0 ].generate (1 )
467
- self .sync_all ()
468
- assert_equal (self .nodes [0 ].getbalance (), bal + Decimal ('50.00000000' )+ Decimal ('2.19000000' )) #block reward + tx
469
-
470
- # 2of2 test for combining transactions
471
- bal = self .nodes [2 ].getbalance ()
472
- addr1 = self .nodes [1 ].getnewaddress ()
473
- addr2 = self .nodes [2 ].getnewaddress ()
474
-
475
- addr1Obj = self .nodes [1 ].getaddressinfo (addr1 )
476
- addr2Obj = self .nodes [2 ].getaddressinfo (addr2 )
477
-
478
- self .nodes [1 ].addmultisigaddress (2 , [addr1Obj ['pubkey' ], addr2Obj ['pubkey' ]])['address' ]
479
- mSigObj = self .nodes [2 ].addmultisigaddress (2 , [addr1Obj ['pubkey' ], addr2Obj ['pubkey' ]])['address' ]
480
- mSigObjValid = self .nodes [2 ].getaddressinfo (mSigObj )
481
-
482
- txId = self .nodes [0 ].sendtoaddress (mSigObj , 2.2 )
483
- decTx = self .nodes [0 ].gettransaction (txId )
484
- rawTx2 = self .nodes [0 ].decoderawtransaction (decTx ['hex' ])
485
- self .sync_all ()
486
- self .nodes [0 ].generate (1 )
487
- self .sync_all ()
488
-
489
- assert_equal (self .nodes [2 ].getbalance (), bal ) # the funds of a 2of2 multisig tx should not be marked as spendable
490
-
491
- txDetails = self .nodes [0 ].gettransaction (txId , True )
492
- rawTx2 = self .nodes [0 ].decoderawtransaction (txDetails ['hex' ])
493
- vout = next (o for o in rawTx2 ['vout' ] if o ['value' ] == Decimal ('2.20000000' ))
494
-
495
- bal = self .nodes [0 ].getbalance ()
496
- inputs = [{ "txid" : txId , "vout" : vout ['n' ], "scriptPubKey" : vout ['scriptPubKey' ]['hex' ], "redeemScript" : mSigObjValid ['hex' ], "amount" : vout ['value' ]}]
497
- outputs = { self .nodes [0 ].getnewaddress () : 2.19 }
498
- rawTx2 = self .nodes [2 ].createrawtransaction (inputs , outputs )
499
- rawTxPartialSigned1 = self .nodes [1 ].signrawtransactionwithwallet (rawTx2 , inputs )
500
- self .log .debug (rawTxPartialSigned1 )
501
- assert_equal (rawTxPartialSigned1 ['complete' ], False ) #node1 only has one key, can't comp. sign the tx
502
-
503
- rawTxPartialSigned2 = self .nodes [2 ].signrawtransactionwithwallet (rawTx2 , inputs )
504
- self .log .debug (rawTxPartialSigned2 )
505
- assert_equal (rawTxPartialSigned2 ['complete' ], False ) #node2 only has one key, can't comp. sign the tx
506
- rawTxComb = self .nodes [2 ].combinerawtransaction ([rawTxPartialSigned1 ['hex' ], rawTxPartialSigned2 ['hex' ]])
507
- self .log .debug (rawTxComb )
508
- self .nodes [2 ].sendrawtransaction (rawTxComb )
509
- rawTx2 = self .nodes [0 ].decoderawtransaction (rawTxComb )
510
- self .sync_all ()
511
- self .nodes [0 ].generate (1 )
512
- self .sync_all ()
513
- assert_equal (self .nodes [0 ].getbalance (), bal + Decimal ('50.00000000' )+ Decimal ('2.19000000' )) #block reward + tx
414
+ def raw_multisig_transaction_legacy_tests ( self ) :
415
+ self .log .info ("Test raw multisig transactions (legacy)" )
416
+ # The traditional multisig workflow does not work with descriptor wallets so these are legacy only.
417
+ # The multisig workflow with descriptor wallets uses PSBTs and is tested elsewhere, no need to do them here.
418
+ # 2of2 test
419
+ addr1 = self .nodes [2 ].getnewaddress ()
420
+ addr2 = self .nodes [2 ].getnewaddress ()
421
+
422
+ addr1Obj = self .nodes [2 ].getaddressinfo (addr1 )
423
+ addr2Obj = self .nodes [2 ].getaddressinfo (addr2 )
424
+
425
+ # Tests for createmultisig and addmultisigaddress
426
+ assert_raises_rpc_error (- 5 , "Invalid public key" , self .nodes [0 ].createmultisig , 1 , ["01020304" ])
427
+ self .nodes [0 ].createmultisig (2 , [addr1Obj ['pubkey' ], addr2Obj ['pubkey' ]]) # createmultisig can only take public keys
428
+ assert_raises_rpc_error (- 5 , "Invalid public key" , self .nodes [0 ].createmultisig , 2 , [addr1Obj ['pubkey' ], addr1 ]) # addmultisigaddress can take both pubkeys and addresses so long as they are in the wallet, which is tested here.
429
+
430
+ mSigObj = self .nodes [2 ].addmultisigaddress (2 , [addr1Obj ['pubkey' ], addr1 ])['address' ]
431
+
432
+ #use balance deltas instead of absolute values
433
+ bal = self .nodes [2 ].getbalance ()
434
+
435
+ # send 1.2 BTC to msig adr
436
+ txId = self .nodes [0 ].sendtoaddress (mSigObj , 1.2 )
437
+ self .sync_all ()
438
+ self .nodes [0 ].generate (1 )
439
+ self .sync_all ()
440
+ assert_equal (self .nodes [2 ].getbalance (), bal + Decimal ('1.20000000' )) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
441
+
442
+
443
+ # 2of3 test from different nodes
444
+ bal = self .nodes [2 ].getbalance ()
445
+ addr1 = self .nodes [1 ].getnewaddress ()
446
+ addr2 = self .nodes [2 ].getnewaddress ()
447
+ addr3 = self .nodes [2 ].getnewaddress ()
448
+
449
+ addr1Obj = self .nodes [1 ].getaddressinfo (addr1 )
450
+ addr2Obj = self .nodes [2 ].getaddressinfo (addr2 )
451
+ addr3Obj = self .nodes [2 ].getaddressinfo (addr3 )
452
+
453
+ mSigObj = self .nodes [2 ].addmultisigaddress (2 , [addr1Obj ['pubkey' ], addr2Obj ['pubkey' ], addr3Obj ['pubkey' ]])['address' ]
454
+
455
+ txId = self .nodes [0 ].sendtoaddress (mSigObj , 2.2 )
456
+ decTx = self .nodes [0 ].gettransaction (txId )
457
+ rawTx = self .nodes [0 ].decoderawtransaction (decTx ['hex' ])
458
+ self .sync_all ()
459
+ self .nodes [0 ].generate (1 )
460
+ self .sync_all ()
461
+
462
+ #THIS IS AN INCOMPLETE FEATURE
463
+ #NODE2 HAS TWO OF THREE KEY AND THE FUNDS SHOULD BE SPENDABLE AND COUNT AT BALANCE CALCULATION
464
+ assert_equal (self .nodes [2 ].getbalance (), bal ) #for now, assume the funds of a 2of3 multisig tx are not marked as spendable
465
+
466
+ txDetails = self .nodes [0 ].gettransaction (txId , True )
467
+ rawTx = self .nodes [0 ].decoderawtransaction (txDetails ['hex' ])
468
+ vout = next (o for o in rawTx ['vout' ] if o ['value' ] == Decimal ('2.20000000' ))
469
+
470
+ bal = self .nodes [0 ].getbalance ()
471
+ inputs = [{ "txid" : txId , "vout" : vout ['n' ], "scriptPubKey" : vout ['scriptPubKey' ]['hex' ], "amount" : vout ['value' ]}]
472
+ outputs = { self .nodes [0 ].getnewaddress () : 2.19 }
473
+ rawTx = self .nodes [2 ].createrawtransaction (inputs , outputs )
474
+ rawTxPartialSigned = self .nodes [1 ].signrawtransactionwithwallet (rawTx , inputs )
475
+ assert_equal (rawTxPartialSigned ['complete' ], False ) #node1 only has one key, can't comp. sign the tx
476
+
477
+ rawTxSigned = self .nodes [2 ].signrawtransactionwithwallet (rawTx , inputs )
478
+ assert_equal (rawTxSigned ['complete' ], True ) #node2 can sign the tx compl., own two of three keys
479
+ self .nodes [2 ].sendrawtransaction (rawTxSigned ['hex' ])
480
+ rawTx = self .nodes [0 ].decoderawtransaction (rawTxSigned ['hex' ])
481
+ self .sync_all ()
482
+ self .nodes [0 ].generate (1 )
483
+ self .sync_all ()
484
+ assert_equal (self .nodes [0 ].getbalance (), bal + Decimal ('50.00000000' )+ Decimal ('2.19000000' )) #block reward + tx
485
+
486
+ # 2of2 test for combining transactions
487
+ bal = self .nodes [2 ].getbalance ()
488
+ addr1 = self .nodes [1 ].getnewaddress ()
489
+ addr2 = self .nodes [2 ].getnewaddress ()
490
+
491
+ addr1Obj = self .nodes [1 ].getaddressinfo (addr1 )
492
+ addr2Obj = self .nodes [2 ].getaddressinfo (addr2 )
493
+
494
+ self .nodes [1 ].addmultisigaddress (2 , [addr1Obj ['pubkey' ], addr2Obj ['pubkey' ]])['address' ]
495
+ mSigObj = self .nodes [2 ].addmultisigaddress (2 , [addr1Obj ['pubkey' ], addr2Obj ['pubkey' ]])['address' ]
496
+ mSigObjValid = self .nodes [2 ].getaddressinfo (mSigObj )
497
+
498
+ txId = self .nodes [0 ].sendtoaddress (mSigObj , 2.2 )
499
+ decTx = self .nodes [0 ].gettransaction (txId )
500
+ rawTx2 = self .nodes [0 ].decoderawtransaction (decTx ['hex' ])
501
+ self .sync_all ()
502
+ self .nodes [0 ].generate (1 )
503
+ self .sync_all ()
504
+
505
+ assert_equal (self .nodes [2 ].getbalance (), bal ) # the funds of a 2of2 multisig tx should not be marked as spendable
506
+
507
+ txDetails = self .nodes [0 ].gettransaction (txId , True )
508
+ rawTx2 = self .nodes [0 ].decoderawtransaction (txDetails ['hex' ])
509
+ vout = next (o for o in rawTx2 ['vout' ] if o ['value' ] == Decimal ('2.20000000' ))
510
+
511
+ bal = self .nodes [0 ].getbalance ()
512
+ inputs = [{ "txid" : txId , "vout" : vout ['n' ], "scriptPubKey" : vout ['scriptPubKey' ]['hex' ], "redeemScript" : mSigObjValid ['hex' ], "amount" : vout ['value' ]}]
513
+ outputs = { self .nodes [0 ].getnewaddress () : 2.19 }
514
+ rawTx2 = self .nodes [2 ].createrawtransaction (inputs , outputs )
515
+ rawTxPartialSigned1 = self .nodes [1 ].signrawtransactionwithwallet (rawTx2 , inputs )
516
+ self .log .debug (rawTxPartialSigned1 )
517
+ assert_equal (rawTxPartialSigned1 ['complete' ], False ) #node1 only has one key, can't comp. sign the tx
518
+
519
+ rawTxPartialSigned2 = self .nodes [2 ].signrawtransactionwithwallet (rawTx2 , inputs )
520
+ self .log .debug (rawTxPartialSigned2 )
521
+ assert_equal (rawTxPartialSigned2 ['complete' ], False ) #node2 only has one key, can't comp. sign the tx
522
+ rawTxComb = self .nodes [2 ].combinerawtransaction ([rawTxPartialSigned1 ['hex' ], rawTxPartialSigned2 ['hex' ]])
523
+ self .log .debug (rawTxComb )
524
+ self .nodes [2 ].sendrawtransaction (rawTxComb )
525
+ rawTx2 = self .nodes [0 ].decoderawtransaction (rawTxComb )
526
+ self .sync_all ()
527
+ self .nodes [0 ].generate (1 )
528
+ self .sync_all ()
529
+ assert_equal (self .nodes [0 ].getbalance (), bal + Decimal ('50.00000000' )+ Decimal ('2.19000000' )) #block reward + tx
514
530
515
531
516
532
if __name__ == '__main__' :
0 commit comments