Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 39: [PATCH 39/68] test: qualify configured RBF policy with TRUC replacement

test/functional/mempool_rbf_policy.py

Before: test/functional/mempool_rbf_policy.py · After: test/functional/mempool_rbf_policy.py

File metadata
index 55a1d04a6089cfe5760575164f3531e3f6eec3c1..7e149a3a03dbe531ec41da30ce3ab84d03fe3bc9 100755

Download original patch · Release notes

Diff rows 1–66 of 66. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

test/functional/mempool_rbf_policy.py CHANGED
@@ -5,9 +5,9 @@
5
  """Test that getmempoolinfo reports the configured replacement policy.
6
 
7
  -mempoolreplacement and -mempoolfullrbf select whether conflicting
8
- transactions are never replaced, replaced only when the original signals
9
- BIP125 replaceability, or always replaced by fee. The "fullrbf" field must
10
- match the policy the node enforces.
11
  """
12
 
13
  from decimal import Decimal
@@ -23,13 +23,15 @@ from test_framework.util import (
23
  )
24
  from test_framework.wallet import MiniWallet
25
 
26
- # (extra_args, fullrbf, non-signaling original replaceable, signaling original replaceable)
 
27
  POLICIES = [
28
- ([], True, True, True),
29
- (["-mempoolreplacement=fee,-optin"], True, True, True),
30
- (["-mempoolreplacement=fee,optin"], False, False, True),
31
- (["-mempoolfullrbf=0"], False, False, True),
32
- (["-mempoolreplacement=0"], False, False, False),
 
33
  ]
34
 
35
 
@@ -40,19 +42,20 @@ class MempoolRBFPolicyTest(BitcoinTestFramework):
40
  def run_test(self):
41
  self.wallet = MiniWallet(self.nodes[0])
42
 
43
- for extra_args, fullrbf, nonsignaling_replaceable, signaling_replaceable in POLICIES:
44
  self.log.info(f"Check replacement policy with {extra_args or 'default options'}")
45
  self.restart_node(0, extra_args=extra_args)
46
  assert_equal(self.nodes[0].getmempoolinfo()["fullrbf"], fullrbf)
47
- self.check_replacement(sequence=SEQUENCE_FINAL, replaceable=nonsignaling_replaceable)
48
- self.check_replacement(sequence=MAX_BIP125_RBF_SEQUENCE, replaceable=signaling_replaceable)
 
49
  self.generate(self.nodes[0], 1)
50
 
51
- def check_replacement(self, *, sequence, replaceable):
52
  node = self.nodes[0]
53
  utxo = self.wallet.get_utxo()
54
- original = self.wallet.create_self_transfer(utxo_to_spend=utxo, sequence=sequence)
55
- replacement = self.wallet.create_self_transfer(utxo_to_spend=utxo, sequence=sequence, fee_rate=Decimal("0.01"))
56
  node.sendrawtransaction(original["hex"])
57
  if replaceable:
58
  node.sendrawtransaction(replacement["hex"])
@@ -62,6 +65,7 @@ class MempoolRBFPolicyTest(BitcoinTestFramework):
62
  else:
63
  assert_raises_rpc_error(-26, "txn-mempool-conflict", node.sendrawtransaction, replacement["hex"])
64
  assert original["txid"] in node.getrawmempool()
 
65
 
66
 
67
  if __name__ == '__main__':
 
5
  """Test that getmempoolinfo reports the configured replacement policy.
6
 
7
  -mempoolreplacement and -mempoolfullrbf select whether conflicting
8
+ transactions are never replaced, replaced when the original signals BIP125
9
+ replaceability or is TRUC/v3, or always replaced by fee. The "fullrbf" field
10
+ reports Always, even though OptIn also permits non-signaling TRUC conflicts.
11
  """
12
 
13
  from decimal import Decimal
 
23
  )
24
  from test_framework.wallet import MiniWallet
25
 
26
+ # (extra_args, fullrbf, non-signaling v2 replaceable, signaling original replaceable,
27
+ # non-signaling TRUC/v3 replaceable)
28
  POLICIES = [
29
+ ([], True, True, True, True),
30
+ (["-mempoolreplacement=fee,-optin"], True, True, True, True),
31
+ (["-mempoolreplacement=fee,optin"], False, False, True, True),
32
+ (["-mempoolfullrbf=0"], False, False, True, True),
33
+ (["-mempoolfullrbf=1"], True, True, True, True),
34
+ (["-mempoolreplacement=0"], False, False, False, False),
35
  ]
36
 
37
 
 
42
  def run_test(self):
43
  self.wallet = MiniWallet(self.nodes[0])
44
 
45
+ for extra_args, fullrbf, nonsignaling_replaceable, signaling_replaceable, truc_replaceable in POLICIES:
46
  self.log.info(f"Check replacement policy with {extra_args or 'default options'}")
47
  self.restart_node(0, extra_args=extra_args)
48
  assert_equal(self.nodes[0].getmempoolinfo()["fullrbf"], fullrbf)
49
+ for version, nonsignaling in ((2, nonsignaling_replaceable), (3, truc_replaceable)):
50
+ self.check_replacement(version=version, sequence=SEQUENCE_FINAL, replaceable=nonsignaling)
51
+ self.check_replacement(version=version, sequence=MAX_BIP125_RBF_SEQUENCE, replaceable=signaling_replaceable)
52
  self.generate(self.nodes[0], 1)
53
 
54
+ def check_replacement(self, *, version, sequence, replaceable):
55
  node = self.nodes[0]
56
  utxo = self.wallet.get_utxo()
57
+ original = self.wallet.create_self_transfer(utxo_to_spend=utxo, version=version, sequence=sequence)
58
+ replacement = self.wallet.create_self_transfer(utxo_to_spend=utxo, version=version, sequence=sequence, fee_rate=Decimal("0.01"))
59
  node.sendrawtransaction(original["hex"])
60
  if replaceable:
61
  node.sendrawtransaction(replacement["hex"])
 
65
  else:
66
  assert_raises_rpc_error(-26, "txn-mempool-conflict", node.sendrawtransaction, replacement["hex"])
67
  assert original["txid"] in node.getrawmempool()
68
+ assert replacement["txid"] not in node.getrawmempool()
69
 
70
 
71
  if __name__ == '__main__':