Skip to content

Commit 6b161cb

Browse files
glozowismaelsadeeq
andcommitted
[test] second child of a v3 tx can be replaced individually
Co-authored-by: ismaelsadeeq <[email protected]>
1 parent 5c998a6 commit 6b161cb

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

test/functional/mempool_accept_v3.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Copyright (c) 2024 The Bitcoin Core developers
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
from decimal import Decimal
56

67
from test_framework.messages import (
78
MAX_BIP125_RBF_SEQUENCE,
@@ -397,6 +398,37 @@ def test_v3_in_testmempoolaccept(self):
397398
test_accept_2children_with_in_mempool_parent = node.testmempoolaccept([tx_v3_child_1["hex"], tx_v3_child_2["hex"]])
398399
assert all([result["package-error"] == expected_error_extra for result in test_accept_2children_with_in_mempool_parent])
399400

401+
@cleanup(extra_args=["-acceptnonstdtxn=1"])
402+
def test_reorg_2child_rbf(self):
403+
node = self.nodes[0]
404+
self.log.info("Test that children of a v3 transaction can be replaced individually, even if there are multiple due to reorg")
405+
406+
ancestor_tx = self.wallet.send_self_transfer_multi(from_node=node, num_outputs=2, version=3)
407+
self.check_mempool([ancestor_tx["txid"]])
408+
409+
block = self.generate(node, 1)[0]
410+
self.check_mempool([])
411+
412+
child_1 = self.wallet.send_self_transfer(from_node=node, version=3, utxo_to_spend=ancestor_tx["new_utxos"][0])
413+
child_2 = self.wallet.send_self_transfer(from_node=node, version=3, utxo_to_spend=ancestor_tx["new_utxos"][1])
414+
self.check_mempool([child_1["txid"], child_2["txid"]])
415+
416+
self.generate(node, 1)
417+
self.check_mempool([])
418+
419+
# Create a reorg, causing ancestor_tx to exceed the 1-child limit
420+
node.invalidateblock(block)
421+
self.check_mempool([ancestor_tx["txid"], child_1["txid"], child_2["txid"]])
422+
assert_equal(node.getmempoolentry(ancestor_tx["txid"])["descendantcount"], 3)
423+
424+
# Create a replacement of child_1. It does not conflict with child_2.
425+
child_1_conflict = self.wallet.send_self_transfer(from_node=node, version=3, utxo_to_spend=ancestor_tx["new_utxos"][0], fee_rate=Decimal("0.01"))
426+
427+
# Ensure child_1 and child_1_conflict are different transactions
428+
assert (child_1_conflict["txid"] != child_1["txid"])
429+
self.check_mempool([ancestor_tx["txid"], child_1_conflict["txid"], child_2["txid"]])
430+
assert_equal(node.getmempoolentry(ancestor_tx["txid"])["descendantcount"], 3)
431+
400432
def run_test(self):
401433
self.log.info("Generate blocks to create UTXOs")
402434
node = self.nodes[0]
@@ -412,6 +444,7 @@ def run_test(self):
412444
self.test_mempool_sibling()
413445
self.test_v3_package_inheritance()
414446
self.test_v3_in_testmempoolaccept()
447+
self.test_reorg_2child_rbf()
415448

416449

417450
if __name__ == "__main__":

0 commit comments

Comments
 (0)