From b0735336eed9d79d1b1148eff16533cb2d862c01 Mon Sep 17 00:00:00 2001 From: Daniela Brozzoni Date: Thu, 2 Apr 2026 15:30:57 +0200 Subject: [PATCH] p2p: Don't participate in addr relay with feeler connections Feeler connections are short-lived connections made to check that a node is alive, useful for test-before-evict from addrman, and for moving addresses from the new to the tried table. We currently send a GETADDR message to feelers, but then disconnect before being able to receive a response. This wastes some bandwidth, so we can avoid sending the GETADDR altogether. Not sending the initial GETADDR will effectively disable addr relay: we initialize addr relay for the peer when we send GETADDR, and the peer initializes addr relay to us when they receive it. So the peer will not relay any announcement to us, and we will not relay any to them either. This is ok, since the use of feelers is to test if there is a bitcoin node behind an address, not exchange addresses with them. --- src/net_processing.cpp | 7 ++++++- test/functional/p2p_addr_relay.py | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 28d7d2c13ab..12fc506613e 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3748,7 +3748,7 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string // Attempt to initialize address relay for outbound peers and use result // to decide whether to send GETADDR, so that we don't send it to - // inbound or outbound block-relay-only peers. + // inbound, feelers, or outbound block-relay-only peers. bool send_getaddr{false}; if (!pfrom.IsInboundConn()) { send_getaddr = SetupAddressRelay(pfrom, peer); @@ -5612,6 +5612,11 @@ bool PeerManagerImpl::SetupAddressRelay(const CNode& node, Peer& peer) // information of addr traffic to infer the link. if (node.IsBlockOnlyConn()) return false; + // We don't participate in addr relay with feeler connections because + // they are disconnected shortly after the handshake completes, + // before the node will receive the addr response. + if (node.IsFeelerConn()) return false; + if (!peer.m_addr_relay_enabled.exchange(true)) { // During version message processing (non-block-relay-only outbound peers) // or on first addr-related message we have received (inbound peers), initialize diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py index 65b21c0d505..1464e23c467 100755 --- a/test/functional/p2p_addr_relay.py +++ b/test/functional/p2p_addr_relay.py @@ -280,12 +280,17 @@ class AddrTest(BitcoinTestFramework): tip_header = from_hex(CBlockHeader(), self.nodes[0].getblockheader(self.nodes[0].getbestblockhash(), False)) full_outbound_peer.send_and_ping(msg_headers([tip_header])) - self.log.info('Check that we do not send a getaddr message to a block-relay-only or inbound peer') + self.log.info('Check that we do not send a getaddr message to a block-relay-only, feeler or inbound peer') block_relay_peer = self.nodes[0].add_outbound_p2p_connection(AddrReceiver(), p2p_idx=1, connection_type="block-relay-only") block_relay_peer.sync_with_ping() assert_equal(block_relay_peer.getaddr_received(), False) block_relay_peer.send_and_ping(msg_headers([tip_header])) + feeler_peer = self.nodes[0].add_outbound_p2p_connection(AddrReceiver(), p2p_idx=2, connection_type="feeler") + # bitcoind closes feeler connections as soon as it receives a version message + assert_equal(feeler_peer.is_connected, False) + assert_equal(feeler_peer.getaddr_received(), False) + inbound_peer = self.nodes[0].add_p2p_connection(AddrReceiver(send_getaddr=False)) inbound_peer.sync_with_ping() assert_equal(inbound_peer.getaddr_received(), False)