Skip to content

Commit cd8adcf

Browse files
committed
test: Add a test for removetxfrommempool RPC method
1 parent f13dd0f commit cd8adcf

1 file changed

Lines changed: 113 additions & 0 deletions

File tree

test/functional/rpc_mempool_info.py

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,117 @@ class RPCMempoolInfoTest(BitcoinTestFramework):
1616
def set_test_params(self):
1717
self.num_nodes = 1
1818

19+
def test_removetxfrommempool(self):
20+
"""Test for removetxfrommempool RPC functionality"""
21+
self.log.info("Starting removetxfrommempool tests")
22+
node = self.nodes[0]
23+
initial_mempool_size = len(node.getrawmempool())
24+
25+
# Basic transaction removal
26+
tx1 = self.wallet.send_self_transfer(from_node=node)
27+
txid1 = tx1["txid"]
28+
assert txid1 in node.getrawmempool()
29+
assert_equal(len(node.getrawmempool()), initial_mempool_size + 1)
30+
result = node.removetxfrommempool(txid1)
31+
assert_equal(result["removed"], True)
32+
33+
# Verify transaction is no longer in mempool
34+
assert txid1 not in node.getrawmempool()
35+
assert_equal(len(node.getrawmempool()), initial_mempool_size)
36+
37+
# Removing non-existent transaction
38+
fake_txid = "0" * 64
39+
result = node.removetxfrommempool(fake_txid)
40+
assert_equal(result["removed"], False)
41+
42+
# Recursive removal (parent-child transactions)
43+
# Create parent transaction
44+
parent_tx = self.wallet.send_self_transfer(from_node=node)
45+
parent_txid = parent_tx["txid"]
46+
47+
# Create child transaction spending from parent
48+
child_tx = self.wallet.send_self_transfer(
49+
from_node=node,
50+
utxo_to_spend=parent_tx["new_utxo"]
51+
)
52+
child_txid = child_tx["txid"]
53+
mempool = node.getrawmempool()
54+
assert parent_txid in mempool
55+
assert child_txid in mempool
56+
assert_equal(len(mempool), initial_mempool_size + 2)
57+
58+
# Remove parent transaction
59+
result = node.removetxfrommempool(parent_txid)
60+
assert_equal(result["removed"], True)
61+
62+
# Verify both parent and child are removed
63+
mempool = node.getrawmempool()
64+
assert parent_txid not in mempool
65+
assert child_txid not in mempool
66+
assert_equal(len(mempool), initial_mempool_size)
67+
68+
# Transaction chain removal
69+
# Create a chain of 3 transactions: tx1 -> tx2 -> tx3
70+
chain_tx1 = self.wallet.send_self_transfer(from_node=node)
71+
chain_tx2 = self.wallet.send_self_transfer(
72+
from_node=node,
73+
utxo_to_spend=chain_tx1["new_utxo"]
74+
)
75+
chain_tx3 = self.wallet.send_self_transfer(
76+
from_node=node,
77+
utxo_to_spend=chain_tx2["new_utxo"]
78+
)
79+
80+
# Verify all transactions are in mempool
81+
mempool = node.getrawmempool()
82+
assert_equal(len(mempool), initial_mempool_size + 3)
83+
for tx in [chain_tx1, chain_tx2, chain_tx3]:
84+
assert tx["txid"] in mempool
85+
86+
# Remove the middle transaction (chain_tx2)
87+
result = node.removetxfrommempool(chain_tx2["txid"])
88+
assert_equal(result["removed"], True)
89+
90+
# chain_tx2 and chain_tx3 should be removed, chain_tx1 should remain
91+
mempool = node.getrawmempool()
92+
assert chain_tx1["txid"] in mempool
93+
assert chain_tx2["txid"] not in mempool
94+
assert chain_tx3["txid"] not in mempool
95+
assert_equal(len(mempool), initial_mempool_size + 1)
96+
97+
# Test with invalid txid format
98+
assert_raises_rpc_error(-8, "txid must be of length 64", node.removetxfrommempool, "invalid")
99+
100+
# Test with wrong length hex (too short)
101+
assert_raises_rpc_error(-8, "txid must be of length 64", node.removetxfrommempool, "a" * 63)
102+
103+
# Test with wrong length hex (too long)
104+
assert_raises_rpc_error(-8, "txid must be of length 64", node.removetxfrommempool, "a" * 65)
105+
106+
# Test with no parameters
107+
assert_raises_rpc_error(-1, "", node.removetxfrommempool)
108+
109+
# Test with valid hex but non-existent txid
110+
valid_but_fake_txid = "a" * 64
111+
result = node.removetxfrommempool(valid_but_fake_txid)
112+
assert_equal(result["removed"], False)
113+
114+
# Test removing the same transaction twice
115+
double_remove_tx = self.wallet.send_self_transfer(from_node=node)
116+
double_remove_txid = double_remove_tx["txid"]
117+
result1 = node.removetxfrommempool(double_remove_txid)
118+
assert_equal(result1["removed"], True)
119+
result2 = node.removetxfrommempool(double_remove_txid)
120+
assert_equal(result2["removed"], False)
121+
122+
# Clean up remaining transactions
123+
node.removetxfrommempool(chain_tx1["txid"])
124+
125+
# Verify mempool is clean
126+
assert_equal(len(node.getrawmempool()), initial_mempool_size)
127+
128+
self.log.info("All removetxfrommempool tests completed successfully")
129+
19130
def run_test(self):
20131
self.wallet = MiniWallet(self.nodes[0])
21132
confirmed_utxo = self.wallet.get_utxo()
@@ -94,6 +205,8 @@ def create_tx(**kwargs):
94205
self.log.info("Missing txid")
95206
assert_raises_rpc_error(-3, "Missing txid", self.nodes[0].gettxspendingprevout, [{'vout' : 3}])
96207

208+
self.log.info("Test removetxfrommempool RPC")
209+
self.test_removetxfrommempool()
97210

98211
if __name__ == '__main__':
99212
RPCMempoolInfoTest(__file__).main()

0 commit comments

Comments
 (0)