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.
This commit is contained in:
Daniela Brozzoni
2026-04-02 15:30:57 +02:00
parent 8e789322c5
commit b0735336ee
2 changed files with 12 additions and 2 deletions

View File

@@ -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

View File

@@ -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)