fix: reorg behaviour in mempool tests to match real one

This commit is contained in:
yuvicc committed 2025-11-26 13:44:18 +05:30
1 parent 540ed333f6
commit 70d9e8f0a1
6 files changed
+143 -38

No files matched your search

+39 -11
View File
@@ -20,6 +20,9 @@ from test_framework.util import (
from test_framework.wallet import (
MiniWallet,
)
from test_framework.blocktools import (
create_empty_fork
)
class EphemeralDustTest(BitcoinTestFramework):
def set_test_params(self):
@@ -64,6 +67,12 @@ class EphemeralDustTest(BitcoinTestFramework):
return dusty_tx, sweep_tx
def trigger_reorg(self, fork_blocks):
"""Trigger reorg of the fork blocks."""
for block in fork_blocks:
self.nodes[0].submitblock(block.serialize().hex())
assert_equal(self.nodes[0].getbestblockhash(), fork_blocks[-1].hash_hex)
def run_test(self):
node = self.nodes[0]
@@ -323,11 +332,15 @@ class EphemeralDustTest(BitcoinTestFramework):
# Get dusty tx mined, then check that it makes it back into mempool on reorg
# due to bypass_limits allowing 0-fee individually
# Prep for fork with empty blocks
fork_blocks = create_empty_fork(self.nodes[0])
dusty_tx, _ = self.create_ephemeral_dust_package(tx_version=3)
assert_raises_rpc_error(-26, "min relay fee not met", self.nodes[0].sendrawtransaction, dusty_tx["hex"])
block_res = self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_tx["hex"]], sync_fun=self.no_op)
self.nodes[0].invalidateblock(block_res["hash"])
self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_tx["hex"]], sync_fun=self.no_op)
self.trigger_reorg(fork_blocks)
assert_mempool_contents(self, self.nodes[0], expected=[dusty_tx["tx"]], sync=False)
# Create a sweep that has dust of its own and leaves dusty_tx's dust unspent
@@ -335,9 +348,12 @@ class EphemeralDustTest(BitcoinTestFramework):
self.add_output_to_create_multi_result(sweep_tx)
assert_raises_rpc_error(-26, "min relay fee not met", self.nodes[0].sendrawtransaction, sweep_tx["hex"])
# Prep for fork with empty blocks
fork_blocks = create_empty_fork(self.nodes[0])
# Mine the sweep then re-org, the sweep will not make it back in due to spend checks
block_res = self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_tx["hex"], sweep_tx["hex"]], sync_fun=self.no_op)
self.nodes[0].invalidateblock(block_res["hash"])
self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_tx["hex"], sweep_tx["hex"]], sync_fun=self.no_op)
self.trigger_reorg(fork_blocks)
assert_mempool_contents(self, self.nodes[0], expected=[dusty_tx["tx"]], sync=False)
# Should re-enter if dust is swept
@@ -345,27 +361,39 @@ class EphemeralDustTest(BitcoinTestFramework):
self.add_output_to_create_multi_result(sweep_tx_2)
assert_raises_rpc_error(-26, "min relay fee not met", self.nodes[0].sendrawtransaction, sweep_tx_2["hex"])
reconsider_block_res = self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_tx["hex"], sweep_tx_2["hex"]], sync_fun=self.no_op)
self.nodes[0].invalidateblock(reconsider_block_res["hash"])
# Prep for fork with empty blocks
fork_blocks = create_empty_fork(self.nodes[0])
self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_tx["hex"], sweep_tx_2["hex"]], sync_fun=self.no_op)
self.trigger_reorg(fork_blocks)
assert_mempool_contents(self, self.nodes[0], expected=[dusty_tx["tx"], sweep_tx_2["tx"]], sync=False)
# TRUC transactions restriction for ephemeral dust disallows further spends of ancestor chains
child_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=sweep_tx_2["new_utxos"], version=3)
assert_raises_rpc_error(-26, "TRUC-violation", self.nodes[0].sendrawtransaction, child_tx["hex"])
self.nodes[0].reconsiderblock(reconsider_block_res["hash"])
# Clean up the mempool
self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_tx["hex"], sweep_tx_2["hex"]], sync_fun=self.no_op)
assert_equal(self.nodes[0].getrawmempool(), [])
self.log.info("Test that ephemeral dust tx with fees or multi dust don't enter mempool via reorg")
multi_dusty_tx, _ = self.create_ephemeral_dust_package(tx_version=3, num_dust_outputs=2)
block_res = self.generateblock(self.nodes[0], self.wallet.get_address(), [multi_dusty_tx["hex"]], sync_fun=self.no_op)
self.nodes[0].invalidateblock(block_res["hash"])
# Prep for fork with empty blocks
fork_blocks = create_empty_fork(self.nodes[0])
self.generateblock(self.nodes[0], self.wallet.get_address(), [multi_dusty_tx["hex"]], sync_fun=self.no_op)
self.trigger_reorg(fork_blocks)
assert_equal(self.nodes[0].getrawmempool(), [])
# With fee and one dust
dusty_fee_tx, _ = self.create_ephemeral_dust_package(tx_version=3, dust_tx_fee=1)
block_res = self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_fee_tx["hex"]], sync_fun=self.no_op)
self.nodes[0].invalidateblock(block_res["hash"])
# Prep for fork with empty blocks
fork_blocks = create_empty_fork(self.nodes[0])
self.generateblock(self.nodes[0], self.wallet.get_address(), [dusty_fee_tx["hex"]], sync_fun=self.no_op)
self.trigger_reorg(fork_blocks)
assert_equal(self.nodes[0].getrawmempool(), [])
# Re-connect and make sure we have same state still