9
9
from test_framework .messages import (
10
10
MAX_BIP125_RBF_SEQUENCE ,
11
11
COIN ,
12
- SEQUENCE_FINAL ,
13
12
)
14
13
from test_framework .test_framework import BitcoinTestFramework
15
14
from test_framework .util import (
@@ -26,18 +25,15 @@ def add_options(self, parser):
26
25
27
26
def set_test_params (self ):
28
27
self .num_nodes = 2
29
- # both nodes disable full-rbf to test BIP125 signaling
30
28
self .extra_args = [
31
29
[
32
- "-mempoolfullrbf=0" ,
33
30
"-limitancestorcount=50" ,
34
31
"-limitancestorsize=101" ,
35
32
"-limitdescendantcount=200" ,
36
33
"-limitdescendantsize=101" ,
37
34
],
38
- # second node has default mempool parameters, besides mempoolfullrbf being disabled
35
+ # second node has default mempool parameters
39
36
[
40
- "-mempoolfullrbf=0" ,
41
37
],
42
38
]
43
39
self .supports_cli = False
@@ -69,18 +65,12 @@ def run_test(self):
69
65
self .log .info ("Running test too many replacements using default mempool params..." )
70
66
self .test_too_many_replacements_with_default_mempool_params ()
71
67
72
- self .log .info ("Running test opt-in..." )
73
- self .test_opt_in ()
74
-
75
68
self .log .info ("Running test RPC..." )
76
69
self .test_rpc ()
77
70
78
71
self .log .info ("Running test prioritised transactions..." )
79
72
self .test_prioritised_transactions ()
80
73
81
- self .log .info ("Running test no inherited signaling..." )
82
- self .test_no_inherited_signaling ()
83
-
84
74
self .log .info ("Running test replacement relay fee..." )
85
75
self .test_replacement_relay_fee ()
86
76
@@ -426,14 +416,12 @@ def test_too_many_replacements_with_default_mempool_params(self):
426
416
for graph_num in range (num_tx_graphs ):
427
417
root_utxos .append (wallet .get_utxo ())
428
418
429
- optin_parent_tx = wallet .send_self_transfer_multi (
419
+ parent_tx = wallet .send_self_transfer_multi (
430
420
from_node = normal_node ,
431
- sequence = MAX_BIP125_RBF_SEQUENCE ,
432
421
utxos_to_spend = [root_utxos [graph_num ]],
433
422
num_outputs = txs_per_graph ,
434
423
)
435
- assert_equal (True , normal_node .getmempoolentry (optin_parent_tx ['txid' ])['bip125-replaceable' ])
436
- new_utxos = optin_parent_tx ['new_utxos' ]
424
+ new_utxos = parent_tx ['new_utxos' ]
437
425
438
426
for utxo in new_utxos :
439
427
# Create spends for each output from the "root" of this graph.
@@ -470,81 +458,6 @@ def test_too_many_replacements_with_default_mempool_params(self):
470
458
self .generate (normal_node , 1 )
471
459
self .wallet .rescan_utxos ()
472
460
473
- def test_opt_in (self ):
474
- """Replacing should only work if orig tx opted in"""
475
- tx0_outpoint = self .make_utxo (self .nodes [0 ], int (1.1 * COIN ))
476
-
477
- # Create a non-opting in transaction
478
- tx1a_utxo = self .wallet .send_self_transfer (
479
- from_node = self .nodes [0 ],
480
- utxo_to_spend = tx0_outpoint ,
481
- sequence = SEQUENCE_FINAL ,
482
- fee = Decimal ("0.1" ),
483
- )["new_utxo" ]
484
-
485
- # This transaction isn't shown as replaceable
486
- assert_equal (self .nodes [0 ].getmempoolentry (tx1a_utxo ["txid" ])['bip125-replaceable' ], False )
487
-
488
- # Shouldn't be able to double-spend
489
- tx1b_hex = self .wallet .create_self_transfer (
490
- utxo_to_spend = tx0_outpoint ,
491
- sequence = 0 ,
492
- fee = Decimal ("0.2" ),
493
- )["hex" ]
494
-
495
- # This will raise an exception
496
- assert_raises_rpc_error (- 26 , "txn-mempool-conflict" , self .nodes [0 ].sendrawtransaction , tx1b_hex , 0 )
497
-
498
- tx1_outpoint = self .make_utxo (self .nodes [0 ], int (1.1 * COIN ))
499
-
500
- # Create a different non-opting in transaction
501
- tx2a_utxo = self .wallet .send_self_transfer (
502
- from_node = self .nodes [0 ],
503
- utxo_to_spend = tx1_outpoint ,
504
- sequence = 0xfffffffe ,
505
- fee = Decimal ("0.1" ),
506
- )["new_utxo" ]
507
-
508
- # Still shouldn't be able to double-spend
509
- tx2b_hex = self .wallet .create_self_transfer (
510
- utxo_to_spend = tx1_outpoint ,
511
- sequence = 0 ,
512
- fee = Decimal ("0.2" ),
513
- )["hex" ]
514
-
515
- # This will raise an exception
516
- assert_raises_rpc_error (- 26 , "txn-mempool-conflict" , self .nodes [0 ].sendrawtransaction , tx2b_hex , 0 )
517
-
518
- # Now create a new transaction that spends from tx1a and tx2a
519
- # opt-in on one of the inputs
520
- # Transaction should be replaceable on either input
521
-
522
- tx3a_txid = self .wallet .send_self_transfer_multi (
523
- from_node = self .nodes [0 ],
524
- utxos_to_spend = [tx1a_utxo , tx2a_utxo ],
525
- sequence = [SEQUENCE_FINAL , 0xfffffffd ],
526
- fee_per_output = int (0.1 * COIN ),
527
- )["txid" ]
528
-
529
- # This transaction is shown as replaceable
530
- assert_equal (self .nodes [0 ].getmempoolentry (tx3a_txid )['bip125-replaceable' ], True )
531
-
532
- self .wallet .send_self_transfer (
533
- from_node = self .nodes [0 ],
534
- utxo_to_spend = tx1a_utxo ,
535
- sequence = 0 ,
536
- fee = Decimal ("0.4" ),
537
- )
538
-
539
- # If tx3b was accepted, tx3c won't look like a replacement,
540
- # but make sure it is accepted anyway
541
- self .wallet .send_self_transfer (
542
- from_node = self .nodes [0 ],
543
- utxo_to_spend = tx2a_utxo ,
544
- sequence = 0 ,
545
- fee = Decimal ("0.4" ),
546
- )
547
-
548
461
def test_prioritised_transactions (self ):
549
462
# Ensure that fee deltas used via prioritisetransaction are
550
463
# correctly used by replacement logic
@@ -629,69 +542,6 @@ def test_rpc(self):
629
542
assert_equal (json0 ["vin" ][0 ]["sequence" ], 4294967293 )
630
543
assert_equal (json1 ["vin" ][0 ]["sequence" ], 4294967294 )
631
544
632
- def test_no_inherited_signaling (self ):
633
- confirmed_utxo = self .wallet .get_utxo ()
634
-
635
- # Create an explicitly opt-in parent transaction
636
- optin_parent_tx = self .wallet .send_self_transfer (
637
- from_node = self .nodes [0 ],
638
- utxo_to_spend = confirmed_utxo ,
639
- sequence = MAX_BIP125_RBF_SEQUENCE ,
640
- fee_rate = Decimal ('0.01' ),
641
- )
642
- assert_equal (True , self .nodes [0 ].getmempoolentry (optin_parent_tx ['txid' ])['bip125-replaceable' ])
643
-
644
- replacement_parent_tx = self .wallet .create_self_transfer (
645
- utxo_to_spend = confirmed_utxo ,
646
- sequence = MAX_BIP125_RBF_SEQUENCE ,
647
- fee_rate = Decimal ('0.02' ),
648
- )
649
-
650
- # Test if parent tx can be replaced.
651
- res = self .nodes [0 ].testmempoolaccept (rawtxs = [replacement_parent_tx ['hex' ]])[0 ]
652
-
653
- # Parent can be replaced.
654
- assert_equal (res ['allowed' ], True )
655
-
656
- # Create an opt-out child tx spending the opt-in parent
657
- parent_utxo = self .wallet .get_utxo (txid = optin_parent_tx ['txid' ])
658
- optout_child_tx = self .wallet .send_self_transfer (
659
- from_node = self .nodes [0 ],
660
- utxo_to_spend = parent_utxo ,
661
- sequence = SEQUENCE_FINAL ,
662
- fee_rate = Decimal ('0.01' ),
663
- )
664
-
665
- # Reports true due to inheritance
666
- assert_equal (True , self .nodes [0 ].getmempoolentry (optout_child_tx ['txid' ])['bip125-replaceable' ])
667
-
668
- replacement_child_tx = self .wallet .create_self_transfer (
669
- utxo_to_spend = parent_utxo ,
670
- sequence = SEQUENCE_FINAL ,
671
- fee_rate = Decimal ('0.02' ),
672
- )
673
-
674
- # Broadcast replacement child tx
675
- # BIP 125 :
676
- # 1. The original transactions signal replaceability explicitly or through inheritance as described in the above
677
- # Summary section.
678
- # The original transaction (`optout_child_tx`) doesn't signal RBF but its parent (`optin_parent_tx`) does.
679
- # The replacement transaction (`replacement_child_tx`) should be able to replace the original transaction.
680
- # See CVE-2021-31876 for further explanations.
681
- assert_equal (True , self .nodes [0 ].getmempoolentry (optin_parent_tx ['txid' ])['bip125-replaceable' ])
682
- assert_raises_rpc_error (- 26 , 'txn-mempool-conflict' , self .nodes [0 ].sendrawtransaction , replacement_child_tx ["hex" ], 0 )
683
-
684
- self .log .info ('Check that the child tx can still be replaced (via a tx that also replaces the parent)' )
685
- replacement_parent_tx = self .wallet .send_self_transfer (
686
- from_node = self .nodes [0 ],
687
- utxo_to_spend = confirmed_utxo ,
688
- sequence = SEQUENCE_FINAL ,
689
- fee_rate = Decimal ('0.03' ),
690
- )
691
- # Check that child is removed and update wallet utxo state
692
- assert_raises_rpc_error (- 5 , 'Transaction not in mempool' , self .nodes [0 ].getmempoolentry , optout_child_tx ['txid' ])
693
- self .wallet .get_utxo (txid = optout_child_tx ['txid' ])
694
-
695
545
def test_replacement_relay_fee (self ):
696
546
tx = self .wallet .send_self_transfer (from_node = self .nodes [0 ])['tx' ]
697
547
@@ -702,12 +552,12 @@ def test_replacement_relay_fee(self):
702
552
assert_raises_rpc_error (- 26 , "insufficient fee" , self .nodes [0 ].sendrawtransaction , tx .serialize ().hex ())
703
553
704
554
def test_fullrbf (self ):
555
+ # BIP125 signaling is not respected
705
556
706
557
confirmed_utxo = self .make_utxo (self .nodes [0 ], int (2 * COIN ))
707
- self .restart_node (0 , extra_args = ["-mempoolfullrbf=1" ])
708
558
assert self .nodes [0 ].getmempoolinfo ()["fullrbf" ]
709
559
710
- # Create an explicitly opt-out transaction
560
+ # Create an explicitly opt-out BIP125 transaction, which will be ignored
711
561
optout_tx = self .wallet .send_self_transfer (
712
562
from_node = self .nodes [0 ],
713
563
utxo_to_spend = confirmed_utxo ,
@@ -718,7 +568,6 @@ def test_fullrbf(self):
718
568
719
569
conflicting_tx = self .wallet .create_self_transfer (
720
570
utxo_to_spend = confirmed_utxo ,
721
- sequence = SEQUENCE_FINAL ,
722
571
fee_rate = Decimal ('0.02' ),
723
572
)
724
573
0 commit comments