Add functional test exercising tx downloadman recently confirmed filter
What changed, and why it matters
This commit only adds a new automated test to Bitcoin Core. It does not change any production code. The test documents that transactions confirmed during initial block download (IBD) are remembered and not re-requested from peers once IBD finishes. There is no security fix or vulnerability here.
No action required; this is a test-only change. Reviewers may optionally confirm the test passes in CI.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff extends test/functional/p2p_ibd_txrelay.py with a scenario that mines a block while the node is in IBD, records the coinbase wtxid, then after leaving IBD sends an INV for that wtxid and asserts no getdata is requested. This verifies the txdownload manager’s recently-confirmed bloom filter works across the IBD-to-post-IBD transition. No C++ or consensus code is modified.
Changed components
test/functional/p2p_ibd_txrelay.pyInspect captured patch +16 / −0
diff --git a/test/functional/p2p_ibd_txrelay.py b/test/functional/p2p_ibd_txrelay.py
index 423c2a07..a622554a 100755
--- a/test/functional/p2p_ibd_txrelay.py
+++ b/test/functional/p2p_ibd_txrelay.py
@@ -11,6 +11,7 @@
from decimal import Decimal
import time
+from test_framework.blocktools import create_block, create_coinbase
from test_framework.messages import (
CInv,
COIN,
@@ -48,6 +49,12 @@ class P2PIBDTxRelayTest(BitcoinTestFramework):
self.wait_until(lambda: all(peer['minfeefilter'] == MAX_FEE_FILTER for peer in node.getpeerinfo()))
self.nodes[0].setmocktime(int(time.time()))
+ self.log.info("Mine one old block so we stay in IBD, then remember its coinbase wtxid")
+ block = create_block(int(self.nodes[0].getbestblockhash(), 16), create_coinbase(1), int(time.time()) - 2 * 24 * 60 * 60)
+ block.solve()
+ self.nodes[0].submitblock(block.serialize().hex())
+ assert self.nodes[0].getblockchaininfo()['initialblockdownload']
+ ibd_wtxid = int(self.nodes[0].getblock(f"{block.hash_int:064x}", 2)["tx"][0]["hash"], 16)
self.log.info("Check that nodes don't send getdatas for transactions while still in IBD")
peer_inver = self.nodes[0].add_p2p_connection(P2PDataStore())
@@ -82,6 +89,15 @@ class P2PIBDTxRelayTest(BitcoinTestFramework):
assert not node.getblockchaininfo()['initialblockdownload']
self.wait_until(lambda: all(peer['minfeefilter'] == NORMAL_FEE_FILTER for peer in node.getpeerinfo()))
+ self.log.info("Check that txs confirmed during IBD are in the recently-confirmed filter once out of ibd")
+ peer_inver = self.nodes[0].add_p2p_connection(P2PDataStore())
+ peer_inver.send_and_ping(msg_inv([CInv(t=MSG_WTX, h=ibd_wtxid)]))
+ self.nodes[0].bumpmocktime(NONPREF_PEER_TX_DELAY)
+ peer_inver.sync_with_ping()
+ with p2p_lock:
+ assert ibd_wtxid not in peer_inver.getdata_requests
+ self.nodes[0].disconnect_p2ps()
+
self.log.info("Check that nodes process the same transaction, even when unsolicited, when no longer in IBD")
peer_txer = self.nodes[0].add_p2p_connection(P2PInterface())
with self.nodes[0].assert_debug_log(expected_msgs=["was not accepted"]):
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.