99from test_framework .messages import (
1010 MAX_BIP125_RBF_SEQUENCE ,
1111 COIN ,
12- SEQUENCE_FINAL ,
1312)
1413from test_framework .test_framework import BitcoinTestFramework
1514from test_framework .util import (
@@ -26,18 +25,15 @@ def add_options(self, parser):
2625
2726 def set_test_params (self ):
2827 self .num_nodes = 2
29- # both nodes disable full-rbf to test BIP125 signaling
3028 self .extra_args = [
3129 [
32- "-mempoolfullrbf=0" ,
3330 "-limitancestorcount=50" ,
3431 "-limitancestorsize=101" ,
3532 "-limitdescendantcount=200" ,
3633 "-limitdescendantsize=101" ,
3734 ],
38- # second node has default mempool parameters, besides mempoolfullrbf being disabled
35+ # second node has default mempool parameters
3936 [
40- "-mempoolfullrbf=0" ,
4137 ],
4238 ]
4339 self .supports_cli = False
@@ -69,18 +65,12 @@ def run_test(self):
6965 self .log .info ("Running test too many replacements using default mempool params..." )
7066 self .test_too_many_replacements_with_default_mempool_params ()
7167
72- self .log .info ("Running test opt-in..." )
73- self .test_opt_in ()
74-
7568 self .log .info ("Running test RPC..." )
7669 self .test_rpc ()
7770
7871 self .log .info ("Running test prioritised transactions..." )
7972 self .test_prioritised_transactions ()
8073
81- self .log .info ("Running test no inherited signaling..." )
82- self .test_no_inherited_signaling ()
83-
8474 self .log .info ("Running test replacement relay fee..." )
8575 self .test_replacement_relay_fee ()
8676
@@ -426,14 +416,12 @@ def test_too_many_replacements_with_default_mempool_params(self):
426416 for graph_num in range (num_tx_graphs ):
427417 root_utxos .append (wallet .get_utxo ())
428418
429- optin_parent_tx = wallet .send_self_transfer_multi (
419+ parent_tx = wallet .send_self_transfer_multi (
430420 from_node = normal_node ,
431- sequence = MAX_BIP125_RBF_SEQUENCE ,
432421 utxos_to_spend = [root_utxos [graph_num ]],
433422 num_outputs = txs_per_graph ,
434423 )
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' ]
437425
438426 for utxo in new_utxos :
439427 # 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):
470458 self .generate (normal_node , 1 )
471459 self .wallet .rescan_utxos ()
472460
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-
548461 def test_prioritised_transactions (self ):
549462 # Ensure that fee deltas used via prioritisetransaction are
550463 # correctly used by replacement logic
@@ -629,69 +542,6 @@ def test_rpc(self):
629542 assert_equal (json0 ["vin" ][0 ]["sequence" ], 4294967293 )
630543 assert_equal (json1 ["vin" ][0 ]["sequence" ], 4294967294 )
631544
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-
695545 def test_replacement_relay_fee (self ):
696546 tx = self .wallet .send_self_transfer (from_node = self .nodes [0 ])['tx' ]
697547
@@ -702,12 +552,12 @@ def test_replacement_relay_fee(self):
702552 assert_raises_rpc_error (- 26 , "insufficient fee" , self .nodes [0 ].sendrawtransaction , tx .serialize ().hex ())
703553
704554 def test_fullrbf (self ):
555+ # BIP125 signaling is not respected
705556
706557 confirmed_utxo = self .make_utxo (self .nodes [0 ], int (2 * COIN ))
707- self .restart_node (0 , extra_args = ["-mempoolfullrbf=1" ])
708558 assert self .nodes [0 ].getmempoolinfo ()["fullrbf" ]
709559
710- # Create an explicitly opt-out transaction
560+ # Create an explicitly opt-out BIP125 transaction, which will be ignored
711561 optout_tx = self .wallet .send_self_transfer (
712562 from_node = self .nodes [0 ],
713563 utxo_to_spend = confirmed_utxo ,
@@ -718,7 +568,6 @@ def test_fullrbf(self):
718568
719569 conflicting_tx = self .wallet .create_self_transfer (
720570 utxo_to_spend = confirmed_utxo ,
721- sequence = SEQUENCE_FINAL ,
722571 fee_rate = Decimal ('0.02' ),
723572 )
724573
0 commit comments