30
30
WALLET_PASSPHRASE = "test"
31
31
WALLET_PASSPHRASE_TIMEOUT = 3600
32
32
33
+ # Fee rates (in BTC per 1000 vbytes)
34
+ INSUFFICIENT = 0.00001000
35
+ ECONOMICAL = 0.00050000
36
+ NORMAL = 0.00100000
37
+ HIGH = 0.00500000
38
+ TOO_HIGH = 1.00000000
39
+
33
40
class BumpFeeTest (BitcoinTestFramework ):
34
41
def set_test_params (self ):
35
42
self .num_nodes = 2
36
43
self .setup_clean_chain = True
37
44
self .extra_args = [[
38
45
"-walletrbf={}" .format (i ),
39
46
"-mintxfee=0.00002" ,
40
- "-deprecatedrpc=totalFee" ,
41
47
"-addresstype=bech32" ,
42
48
] for i in range (self .num_nodes )]
43
49
@@ -75,7 +81,6 @@ def run_test(self):
75
81
test_nonrbf_bumpfee_fails (self , peer_node , dest_address )
76
82
test_notmine_bumpfee_fails (self , rbf_node , peer_node , dest_address )
77
83
test_bumpfee_with_descendant_fails (self , rbf_node , rbf_node_address , dest_address )
78
- test_small_output_fails (self , rbf_node , dest_address )
79
84
test_dust_to_fee (self , rbf_node , dest_address )
80
85
test_settxfee (self , rbf_node , dest_address )
81
86
test_watchonly_psbt (self , peer_node , rbf_node , dest_address )
@@ -93,13 +98,13 @@ def run_test(self):
93
98
94
99
95
100
def test_simple_bumpfee_succeeds (self , mode , rbf_node , peer_node , dest_address ):
96
- self .log .info ('Test simple bumpfee' )
101
+ self .log .info ('Test simple bumpfee: {}' . format ( mode ) )
97
102
rbfid = spend_one_input (rbf_node , dest_address )
98
103
rbftx = rbf_node .gettransaction (rbfid )
99
104
self .sync_mempools ((rbf_node , peer_node ))
100
105
assert rbfid in rbf_node .getrawmempool () and rbfid in peer_node .getrawmempool ()
101
106
if mode == "fee_rate" :
102
- bumped_tx = rbf_node .bumpfee (rbfid , {"fee_rate" :0.0015 })
107
+ bumped_tx = rbf_node .bumpfee (rbfid , {"fee_rate" : NORMAL })
103
108
else :
104
109
bumped_tx = rbf_node .bumpfee (rbfid )
105
110
assert_equal (bumped_tx ["errors" ], [])
@@ -120,7 +125,7 @@ def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address):
120
125
assert_equal (bumpedwtx ["replaces_txid" ], rbfid )
121
126
122
127
def test_feerate_args (self , rbf_node , peer_node , dest_address ):
123
- self .log .info ('Test feerate args' )
128
+ self .log .info ('Test fee_rate args' )
124
129
rbfid = spend_one_input (rbf_node , dest_address )
125
130
self .sync_mempools ((rbf_node , peer_node ))
126
131
assert rbfid in rbf_node .getrawmempool () and rbfid in peer_node .getrawmempool ()
@@ -130,11 +135,11 @@ def test_feerate_args(self, rbf_node, peer_node, dest_address):
130
135
assert_raises_rpc_error (- 8 , "fee_rate can't be set along with totalFee." , rbf_node .bumpfee , rbfid , {"fee_rate" :0.00001 , "totalFee" :0.001 })
131
136
132
137
# Bumping to just above minrelay should fail to increase total fee enough, at least
133
- assert_raises_rpc_error (- 8 , "Insufficient total fee" , rbf_node .bumpfee , rbfid , {"fee_rate" :0.00001000 })
138
+ assert_raises_rpc_error (- 8 , "Insufficient total fee" , rbf_node .bumpfee , rbfid , {"fee_rate" : INSUFFICIENT })
134
139
135
140
assert_raises_rpc_error (- 3 , "Amount out of range" , rbf_node .bumpfee , rbfid , {"fee_rate" :- 1 })
136
141
137
- assert_raises_rpc_error (- 4 , "is too high (cannot be higher than" , rbf_node .bumpfee , rbfid , {"fee_rate" :1 })
142
+ assert_raises_rpc_error (- 4 , "is too high (cannot be higher than" , rbf_node .bumpfee , rbfid , {"fee_rate" : TOO_HIGH })
138
143
139
144
140
145
def test_segwit_bumpfee_succeeds (self , rbf_node , dest_address ):
@@ -204,15 +209,6 @@ def test_bumpfee_with_descendant_fails(self, rbf_node, rbf_node_address, dest_ad
204
209
rbf_node .sendrawtransaction (tx ["hex" ])
205
210
assert_raises_rpc_error (- 8 , "Transaction has descendants in the wallet" , rbf_node .bumpfee , parent_id )
206
211
207
- def test_small_output_fails (self , rbf_node , dest_address ):
208
- self .log .info ('Test totalFee bump with small output fails' )
209
- # cannot bump fee with a too-small output
210
- rbfid = spend_one_input (rbf_node , dest_address )
211
- rbf_node .bumpfee (rbfid , {"totalFee" : 50000 })
212
-
213
- rbfid = spend_one_input (rbf_node , dest_address )
214
- assert_raises_rpc_error (- 4 , "Change output is too small" , rbf_node .bumpfee , rbfid , {"totalFee" : 50001 })
215
-
216
212
def test_small_output_with_feerate_succeeds (self , rbf_node , dest_address ):
217
213
self .log .info ('Testing small output with feerate bump succeeds' )
218
214
@@ -255,15 +251,19 @@ def test_small_output_with_feerate_succeeds(self, rbf_node, dest_address):
255
251
256
252
def test_dust_to_fee (self , rbf_node , dest_address ):
257
253
self .log .info ('Test that bumped output that is dust is dropped to fee' )
258
- # the bumped tx sets fee=49,900, but it converts to 50,000
259
254
rbfid = spend_one_input (rbf_node , dest_address )
260
255
fulltx = rbf_node .getrawtransaction (rbfid , 1 )
261
- # (31-vbyte p2wpkh output size + 67-vbyte p2wpkh spend estimate) * 10k(discard_rate) / 1000 = 980
262
- bumped_tx = rbf_node .bumpfee (rbfid , {"totalFee" : 50000 - 980 })
256
+ # size of transaction (p2wpkh, 1 input, 2 outputs): 141 vbytes
257
+ assert_equal (fulltx ["vsize" ], 141 )
258
+ # bump with fee_rate of 0.00350000 BTC per 1000 vbytes
259
+ # expected bump fee of 141 vbytes * fee_rate 0.00350000 BTC / 1000 vbytes = 0.00049350 BTC
260
+ # but dust is dropped, so actual bump fee is 0.00050000
261
+ bumped_tx = rbf_node .bumpfee (rbfid , {"fee_rate" : 0.0035 })
263
262
full_bumped_tx = rbf_node .getrawtransaction (bumped_tx ["txid" ], 1 )
264
263
assert_equal (bumped_tx ["fee" ], Decimal ("0.00050000" ))
265
264
assert_equal (len (fulltx ["vout" ]), 2 )
266
265
assert_equal (len (full_bumped_tx ["vout" ]), 1 ) # change output is eliminated
266
+ assert_equal (full_bumped_tx ["vout" ][0 ]['value' ], Decimal ("0.00050000" ))
267
267
268
268
269
269
def test_settxfee (self , rbf_node , dest_address ):
@@ -285,7 +285,8 @@ def test_settxfee(self, rbf_node, dest_address):
285
285
def test_maxtxfee_fails (self , rbf_node , dest_address ):
286
286
self .log .info ('Test that bumpfee fails when it hits -matxfee' )
287
287
# size of bumped transaction (p2wpkh, 1 input, 2 outputs): 141 vbytes
288
- # expected bumping feerate of 20 sats/vbyte => 141*20 sats = 0.00002820 btc
288
+ # expected bump fee of 141 vbytes * 0.00200000 BTC / 1000 vbytes = 0.00002820 BTC
289
+ # which exceeds maxtxfee and is expected to raise
289
290
self .restart_node (1 , ['-maxtxfee=0.000025' ] + self .extra_args [1 ])
290
291
rbf_node .walletpassphrase (WALLET_PASSPHRASE , WALLET_PASSPHRASE_TIMEOUT )
291
292
rbfid = spend_one_input (rbf_node , dest_address )
@@ -356,7 +357,7 @@ def test_watchonly_psbt(self, peer_node, rbf_node, dest_address):
356
357
assert_equal (len (watcher .decodepsbt (psbt )["tx" ]["vin" ]), 1 )
357
358
358
359
# Bump fee, obnoxiously high to add additional watchonly input
359
- bumped_psbt = watcher .bumpfee (original_txid , {"fee_rate" :0.005 })
360
+ bumped_psbt = watcher .bumpfee (original_txid , {"fee_rate" : HIGH })
360
361
assert_greater_than (len (watcher .decodepsbt (bumped_psbt ['psbt' ])["tx" ]["vin" ]), 1 )
361
362
assert "txid" not in bumped_psbt
362
363
assert_equal (bumped_psbt ["origfee" ], - watcher .gettransaction (original_txid )["fee" ])
@@ -378,17 +379,17 @@ def test_watchonly_psbt(self, peer_node, rbf_node, dest_address):
378
379
def test_rebumping (self , rbf_node , dest_address ):
379
380
self .log .info ('Test that re-bumping the original tx fails, but bumping successor works' )
380
381
rbfid = spend_one_input (rbf_node , dest_address )
381
- bumped = rbf_node .bumpfee (rbfid , {"totalFee " : 2000 })
382
- assert_raises_rpc_error (- 4 , "already bumped" , rbf_node .bumpfee , rbfid , {"totalFee " : 3000 })
383
- rbf_node .bumpfee (bumped ["txid" ], {"totalFee " : 3000 })
382
+ bumped = rbf_node .bumpfee (rbfid , {"fee_rate " : ECONOMICAL })
383
+ assert_raises_rpc_error (- 4 , "already bumped" , rbf_node .bumpfee , rbfid , {"fee_rate " : NORMAL })
384
+ rbf_node .bumpfee (bumped ["txid" ], {"fee_rate " : NORMAL })
384
385
385
386
386
387
def test_rebumping_not_replaceable (self , rbf_node , dest_address ):
387
388
self .log .info ('Test that re-bumping non-replaceable fails' )
388
389
rbfid = spend_one_input (rbf_node , dest_address )
389
- bumped = rbf_node .bumpfee (rbfid , {"totalFee " : 10000 , "replaceable" : False })
390
+ bumped = rbf_node .bumpfee (rbfid , {"fee_rate " : ECONOMICAL , "replaceable" : False })
390
391
assert_raises_rpc_error (- 4 , "Transaction is not BIP 125 replaceable" , rbf_node .bumpfee , bumped ["txid" ],
391
- {"totalFee " : 20000 })
392
+ {"fee_rate " : NORMAL })
392
393
393
394
394
395
def test_unconfirmed_not_spendable (self , rbf_node , rbf_node_address ):
@@ -450,7 +451,7 @@ def test_locked_wallet_fails(self, rbf_node, dest_address):
450
451
rbf_node .walletpassphrase (WALLET_PASSPHRASE , WALLET_PASSPHRASE_TIMEOUT )
451
452
452
453
def test_change_script_match (self , rbf_node , dest_address ):
453
- self .log .info ('Test that the same change addresses is used for the replacement transaction when possible. ' )
454
+ self .log .info ('Test that the same change addresses is used for the replacement transaction when possible' )
454
455
455
456
def get_change_address (tx ):
456
457
tx_details = rbf_node .getrawtransaction (tx , 1 )
@@ -463,7 +464,7 @@ def get_change_address(tx):
463
464
assert_equal (len (change_addresses ), 1 )
464
465
465
466
# Now find that address in each subsequent tx, and no other change
466
- bumped_total_tx = rbf_node .bumpfee (rbfid , {"totalFee " : 2000 })
467
+ bumped_total_tx = rbf_node .bumpfee (rbfid , {"fee_rate " : ECONOMICAL })
467
468
assert_equal (change_addresses , get_change_address (bumped_total_tx ['txid' ]))
468
469
bumped_rate_tx = rbf_node .bumpfee (bumped_total_tx ["txid" ])
469
470
assert_equal (change_addresses , get_change_address (bumped_rate_tx ['txid' ]))
@@ -503,5 +504,6 @@ def test_no_more_inputs_fails(self, rbf_node, dest_address):
503
504
rbfid = rbf_node .sendtoaddress (rbf_node .getnewaddress (), rbf_node .getbalance (), "" , "" , True )
504
505
assert_raises_rpc_error (- 4 , "Unable to create transaction: Insufficient funds" , rbf_node .bumpfee , rbfid )
505
506
507
+
506
508
if __name__ == "__main__" :
507
509
BumpFeeTest ().main ()
0 commit comments