test: add test that EvictTxPeerIfFull only evicts tx-relaying peers
What changed, and why it matters
This commit only adds a new automated test to Bitcoin Core. It checks that when the node is full of block-only peers (peers that do not relay transactions), an incoming connection is rejected rather than incorrectly kicking out a block-only peer. There is no code change to the actual Bitcoin node behavior—only a test is added.
No action required; this is a test-only addition. Reviewers may optionally confirm the test passes and that the behavior it exercises is already present in the production code.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff adds a functional test in test/functional/p2p_connection_limits.py. It creates a VERSION message with nServices=0 and relay=0 to simulate block-relay-only inbound peers, connects 21 such peers, then attempts one more connection and verifies the node logs ‘failed to find a tx-relaying eviction candidate - connection dropped’ and the peer count stays at 21. This validates the existing EvictTxPeerIfFull logic does not evict block-relay peers when no tx-relaying candidates exist.
Changed components
test/functional/p2p_connection_limits.pyInspect captured patch +21 / −0
diff --git a/test/functional/p2p_connection_limits.py b/test/functional/p2p_connection_limits.py
index 44207e01..eee34e8d 100755
--- a/test/functional/p2p_connection_limits.py
+++ b/test/functional/p2p_connection_limits.py
@@ -33,6 +33,15 @@ class P2PConnectionLimits(BitcoinTestFramework):
no_txrelay_version_msg.relay = 0
return no_txrelay_version_msg
+ def create_no_services_blocks_only_version(self):
+ """VERSION with relay=0 and nServices=0 to avoid block-relay eviction protection."""
+ version_msg = msg_version()
+ version_msg.nVersion = P2P_VERSION
+ version_msg.strSubVer = P2P_SUBVERSION
+ version_msg.nServices = 0
+ version_msg.relay = 0
+ return version_msg
+
def test_inbound_limits(self):
node = self.nodes[0]
@@ -81,6 +90,18 @@ class P2PConnectionLimits(BitcoinTestFramework):
node.add_p2p_connection(P2PInterface())
self.wait_until(lambda: len(node.getpeerinfo()) == 2)
+ self.log.info('Test that EvictTxPeerIfFull only evicts tx-relaying peers')
+ NUM_BLOCK_RELAY_PEERS = 21
+ self.restart_node(0, ['-maxconnections=33', '-inboundrelaypercent=0'])
+ for _ in range(NUM_BLOCK_RELAY_PEERS):
+ p = self.nodes[0].add_p2p_connection(P2PInterface(), send_version=False, wait_for_verack=False)
+ p.send_without_ping(self.create_no_services_blocks_only_version())
+ p.wait_for_verack()
+ self.wait_until(lambda: len(node.getpeerinfo()) == NUM_BLOCK_RELAY_PEERS)
+
+ with node.assert_debug_log(['failed to find a tx-relaying eviction candidate - connection dropped'], timeout=5):
+ self.nodes[0].add_p2p_connection(P2PInterface(), expect_success=False, wait_for_verack=False)
+ self.wait_until(lambda: len(node.getpeerinfo()) == NUM_BLOCK_RELAY_PEERS)
if __name__ == '__main__':
P2PConnectionLimits(__file__).main()
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.