20
20
assert_raises_rpc_error ,
21
21
)
22
22
from test_framework .wallet import (
23
+ COIN ,
23
24
DEFAULT_FEE ,
24
25
MiniWallet ,
25
26
)
@@ -239,11 +240,13 @@ def test_rbf(self):
239
240
coin = self .wallet .get_utxo ()
240
241
fee = Decimal ("0.00125000" )
241
242
replaceable_tx = self .wallet .create_self_transfer (utxo_to_spend = coin , sequence = MAX_BIP125_RBF_SEQUENCE , fee = fee )
242
- testres_replaceable = node .testmempoolaccept ([replaceable_tx ["hex" ]])
243
- assert_equal (testres_replaceable , [
244
- {"txid" : replaceable_tx ["txid" ], "wtxid" : replaceable_tx ["wtxid" ],
245
- "allowed" : True , "vsize" : replaceable_tx ["tx" ].get_vsize (), "fees" : { "base" : fee }}
246
- ])
243
+ testres_replaceable = node .testmempoolaccept ([replaceable_tx ["hex" ]])[0 ]
244
+ assert_equal (testres_replaceable ["txid" ], replaceable_tx ["txid" ])
245
+ assert_equal (testres_replaceable ["wtxid" ], replaceable_tx ["wtxid" ])
246
+ assert testres_replaceable ["allowed" ]
247
+ assert_equal (testres_replaceable ["vsize" ], replaceable_tx ["tx" ].get_vsize ())
248
+ assert_equal (testres_replaceable ["fees" ]["base" ], fee )
249
+ assert_fee_amount (fee , replaceable_tx ["tx" ].get_vsize (), testres_replaceable ["fees" ]["effective-feerate" ])
247
250
248
251
# Replacement transaction is identical except has double the fee
249
252
replacement_tx = self .wallet .create_self_transfer (utxo_to_spend = coin , sequence = MAX_BIP125_RBF_SEQUENCE , fee = 2 * fee )
@@ -287,11 +290,13 @@ def test_submit_child_with_parents(self, num_parents, partial_submit):
287
290
peer = node .add_p2p_connection (P2PTxInvStore ())
288
291
289
292
package_txns = []
293
+ presubmitted_wtxids = set ()
290
294
for _ in range (num_parents ):
291
295
parent_tx = self .wallet .create_self_transfer (fee = DEFAULT_FEE )
292
296
package_txns .append (parent_tx )
293
297
if partial_submit and random .choice ([True , False ]):
294
298
node .sendrawtransaction (parent_tx ["hex" ])
299
+ presubmitted_wtxids .add (parent_tx ["wtxid" ])
295
300
child_tx = self .wallet .create_self_transfer_multi (utxos_to_spend = [tx ["new_utxo" ] for tx in package_txns ], fee_per_output = 10000 ) #DEFAULT_FEE
296
301
package_txns .append (child_tx )
297
302
@@ -302,14 +307,14 @@ def test_submit_child_with_parents(self, num_parents, partial_submit):
302
307
for package_txn in package_txns :
303
308
tx = package_txn ["tx" ]
304
309
assert tx .getwtxid () in submitpackage_result ["tx-results" ]
305
- tx_result = submitpackage_result [ "tx-results" ][ tx .getwtxid ()]
306
- assert_equal ( tx_result , {
307
- "txid" : package_txn [ "txid" ],
308
- "vsize" : tx .get_vsize (),
309
- "fees" : {
310
- " base": DEFAULT_FEE ,
311
- }
312
- } )
310
+ wtxid = tx .getwtxid ()
311
+ assert wtxid in submitpackage_result [ "tx-results" ]
312
+ tx_result = submitpackage_result [ "tx-results" ][ wtxid ]
313
+ assert_equal ( tx_result [ "txid" ], tx .rehash ())
314
+ assert_equal ( tx_result [ "vsize" ], tx . get_vsize ())
315
+ assert_equal ( tx_result [ "fees" ][ " base"], DEFAULT_FEE )
316
+ if wtxid not in presubmitted_wtxids :
317
+ assert_fee_amount ( DEFAULT_FEE , tx . get_vsize (), tx_result [ "fees" ][ "effective-feerate" ] )
313
318
314
319
# submitpackage result should be consistent with testmempoolaccept and getmempoolentry
315
320
self .assert_equal_package_results (node , testmempoolaccept_result , submitpackage_result )
@@ -328,8 +333,11 @@ def test_submit_cpfp(self):
328
333
node = self .nodes [0 ]
329
334
peer = node .add_p2p_connection (P2PTxInvStore ())
330
335
336
+ # Package with 2 parents and 1 child. One parent pays for itself using modified fees, and
337
+ # another has 0 fees but is bumped by child.
331
338
tx_poor = self .wallet .create_self_transfer (fee = 0 , fee_rate = 0 )
332
- tx_rich = self .wallet .create_self_transfer (fee = DEFAULT_FEE )
339
+ tx_rich = self .wallet .create_self_transfer (fee = 0 , fee_rate = 0 )
340
+ node .prioritisetransaction (tx_rich ["txid" ], 0 , int (DEFAULT_FEE * COIN ))
333
341
package_txns = [tx_rich , tx_poor ]
334
342
coins = [tx ["new_utxo" ] for tx in package_txns ]
335
343
tx_child = self .wallet .create_self_transfer_multi (utxos_to_spend = coins , fee_per_output = 10000 ) #DEFAULT_FEE
@@ -340,9 +348,16 @@ def test_submit_cpfp(self):
340
348
rich_parent_result = submitpackage_result ["tx-results" ][tx_rich ["wtxid" ]]
341
349
poor_parent_result = submitpackage_result ["tx-results" ][tx_poor ["wtxid" ]]
342
350
child_result = submitpackage_result ["tx-results" ][tx_child ["tx" ].getwtxid ()]
343
- assert_equal (rich_parent_result ["fees" ]["base" ], DEFAULT_FEE )
351
+ assert_equal (rich_parent_result ["fees" ]["base" ], 0 )
344
352
assert_equal (poor_parent_result ["fees" ]["base" ], 0 )
345
353
assert_equal (child_result ["fees" ]["base" ], DEFAULT_FEE )
354
+ # The "rich" parent does not require CPFP so its effective feerate.
355
+ assert_fee_amount (DEFAULT_FEE , tx_rich ["tx" ].get_vsize (), rich_parent_result ["fees" ]["effective-feerate" ])
356
+ # The "poor" parent and child's effective feerates are the same, composed of the child's fee
357
+ # divided by their combined vsize.
358
+ assert_fee_amount (DEFAULT_FEE , tx_poor ["tx" ].get_vsize () + tx_child ["tx" ].get_vsize (), poor_parent_result ["fees" ]["effective-feerate" ])
359
+ assert_fee_amount (DEFAULT_FEE , tx_poor ["tx" ].get_vsize () + tx_child ["tx" ].get_vsize (), child_result ["fees" ]["effective-feerate" ])
360
+
346
361
# Package feerate is calculated for the remaining transactions after deduplication and
347
362
# individual submission. Since this package had a 0-fee parent, package feerate must have
348
363
# been used and returned.
0 commit comments