I ran mutation testing for this PR and noticed that the following mutant isn’t killed by any test. See:
0diff --git a/src/net.cpp b/src/net.cpp
1index 499312fbbd..88afc05216 100644
2--- a/src/net.cpp
3+++ b/src/net.cpp
4@@ -2504,7 +2504,7 @@ bool CConnman::EvictTxPeerIfFull(std::optional<NodeId> protect_peer)
5 }
6 }
7 if (tx_inbound_peers > m_max_inbound_full_relay) {
8- return AttemptToEvictConnection(/*evict_tx_relay_peer=*/true, protect_peer);
9+ return AttemptToEvictConnection(/*evict_tx_relay_peer=*/false, protect_peer);
10 }
11:
When evict_tx_relay_peer is true, it means that whether the node is over its tx-relay inbound limit, it must evict an existing tx-relay peer, not a block-relay-only peer. So, a test case to address it would be great. Suggestion (did not fully tested it):
0diff --git a/test/functional/p2p_connection_limits.py b/test/functional/p2p_connection_limits.py
1index 64dab1089e..56c1d81980 100755
2--- a/test/functional/p2p_connection_limits.py
3+++ b/test/functional/p2p_connection_limits.py
4@@ -33,6 +33,22 @@ class P2PConnectionLimits(BitcoinTestFramework):
5 no_txrelay_version_msg.relay = 0
6 return no_txrelay_version_msg
7
8+ def create_no_services_blocks_only_version(self):
9+ """VERSION with relay=0 and nServices=0.
10+ version_msg = msg_version()
11+ version_msg.nVersion = P2P_VERSION
12+ version_msg.strSubVer = P2P_SUBVERSION
13+ version_msg.nServices = 0
14+ version_msg.relay = 0
15+ return version_msg
16+
17 def test_inbound_limits(self):
18 node = self.nodes[0]
19
20@@ -81,6 +97,18 @@ class P2PConnectionLimits(BitcoinTestFramework):
21 node.add_p2p_connection(P2PInterface())
22 self.wait_until(lambda: len(node.getpeerinfo()) == 2)
23
24+ self.log.info('Test that EvictTxPeerIfFull only evicts tx-relaying peers')
25+ NUM_BLOCK_RELAY_PEERS = 21
26+ self.restart_node(0, ['-maxconnections=33', '-inboundrelaypercent=0'])
27+ for _ in range(NUM_BLOCK_RELAY_PEERS):
28+ p = self.nodes[0].add_p2p_connection(P2PInterface(), send_version=False, wait_for_verack=False)
29+ p.send_without_ping(self.create_no_services_blocks_only_version())
30+ self.wait_until(lambda: len(node.getpeerinfo()) == NUM_BLOCK_RELAY_PEERS)
31+
32+ with node.assert_debug_log(['failed to find a tx-relaying eviction candidate - connection dropped'], timeout=5):
33+ self.nodes[0].add_p2p_connection(P2PInterface(), expect_success=False, wait_for_verack=False)
34+ self.wait_until(lambda: len(node.getpeerinfo()) == NUM_BLOCK_RELAY_PEERS)
35+
36
37 if __name__ == '__main__':
38 P2PConnectionLimits(__file__).main()