Skip to content

Commit f0da26c

Browse files
committed
Merge #34997: p2p: Don't participate in addr relay with feelers
b073533 p2p: Don't participate in addr relay with feeler connections (Daniela Brozzoni) Pull request description: Feeler connections are short-lived connection made to check that a node is alive, useful for test-before-evict, 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 GETADDR is not useful and can be removed. I couldn't find any previous discussion about this, but I found PR #22777, that similarly made sure that we don't ask for tx relay to feelers. --- I noticed this behavior on my peer-observer instance: I would see the number of sent GETADDR messages increase over time, but the number of ADDR messages with >100 addresses received (which are likely GETADDR responses and not self announcements relays) wouldn't increase as much. I later realized that it was my node opening feeler connections, sending a GETADDR, and closing the connection. You can see the same behavior using this command - the node is making feeler connections, sending getaddr to them, closing before receiving the addr response: ``` ~ ₿ tail -f ~/.bitcoin/debug.log | grep -E "(Making feeler connection|Added connection to|sending getaddr|feeler connection completed|Received addr: [0-9]{2,} addresses)" 2026-04-02T13:25:50Z [net] Making feeler connection to xyz.onion:8333 2026-04-02T13:26:06Z [net] Added connection to xyz.onion:8333 peer=27 2026-04-02T13:26:08Z [net] sending getaddr (0 bytes) peer=27 2026-04-02T13:26:08Z [net] feeler connection completed, disconnecting peer=27, peeraddr=xyz.onion:8333 ``` On a node that accepts inbounds connections, this command can be used to see in the logs all the nodes that connected, sent a getaddr, and disconnected before receiving a reply. It is possible that these nodes connected to us as a feeler: ``` ~ ₿ cat .bitcoin/debug.log | awk ' /received: getaddr/ { split($0, a, "peer=") got_getaddr[a[2]] = $0 } /sending addr/ { split($0, a, "peer=") sent_addr[a[2]] = 1 } /socket closed/ { split($0, a, "peer=") id = a[2] if (id in got_getaddr && !(id in sent_addr)) { print "possible feeler: " got_getaddr[id] print " " $0 } delete got_getaddr[id] delete sent_addr[id] } ' possible feeler: 2026-04-01T21:45:13Z [net] received: getaddr (0 bytes) peer=2311974 2026-04-01T21:45:13Z [net] socket closed, disconnecting peer=2311974 possible feeler: 2026-04-02T00:18:58Z [net] received: getaddr (0 bytes) peer=2426389 2026-04-02T00:18:58Z [net] socket closed, disconnecting peer=2426389 ... ``` Then, you can manually inspect one of them: ``` ~ ₿ cat .bitcoin/debug.log | grep -E "peer=2311974" 2026-04-01T21:45:13Z [net] Added connection peer=2311974 2026-04-01T21:45:13Z [net] received: version (102 bytes) peer=2311974 2026-04-01T21:45:13Z [net] sending version (102 bytes) peer=2311974 2026-04-01T21:45:13Z [net] send version message: version 70016, blocks=943279, txrelay=0, peer=2311974 2026-04-01T21:45:13Z [net] sending wtxidrelay (0 bytes) peer=2311974 2026-04-01T21:45:13Z [net] sending sendaddrv2 (0 bytes) peer=2311974 2026-04-01T21:45:13Z [net] sending verack (0 bytes) peer=2311974 2026-04-01T21:45:13Z [net] receive version message: /Satoshi:27.0.0/: version 70016, blocks=943279, us=x.x.x.x:8333, txrelay=0, peer=2311974 2026-04-01T21:45:13Z [net] received: wtxidrelay (0 bytes) peer=2311974 2026-04-01T21:45:13Z [net] received: sendaddrv2 (0 bytes) peer=2311974 2026-04-01T21:45:13Z [net] received: verack (0 bytes) peer=2311974 2026-04-01T21:45:13Z New inbound v1 peer connected: version: 70016, blocks=943279, peer=2311974 2026-04-01T21:45:13Z [net] sending sendcmpct (9 bytes) peer=2311974 2026-04-01T21:45:13Z [net] sending ping (8 bytes) peer=2311974 2026-04-01T21:45:13Z [net] sending getheaders (1029 bytes) peer=2311974 2026-04-01T21:45:13Z [net] initial getheaders (943278) to peer=2311974 (startheight:943279) 2026-04-01T21:45:13Z [net] received: getaddr (0 bytes) peer=2311974 2026-04-01T21:45:13Z [net] Advertising address x.x.x.x:8333 to peer=2311974 2026-04-01T21:45:13Z [net] socket closed, disconnecting peer=2311974 2026-04-01T21:45:13Z [net] Resetting socket for peer=2311974 2026-04-01T21:45:13Z [net] sending addrv2 (24665 bytes) peer=2311974 2026-04-01T21:45:13Z [net] Cleared nodestate for peer=2311974 ``` ACKs for top commit: 0xB10C: ACK b073533 achow101: ACK b073533 andrewtoth: ACK b073533 stratospher: ACK b073533. didn't see any addr message from feelers in my node's last 24 hours/it would disconnect before addr message is received. so consistent with today's behaviour. Tree-SHA512: 1ac220dfd8361c4687399546a0d968d268e447446053fb8b90ba6b987482cc038e2ad94e670f33181d08d6d0c576882328bb5d0a8b8b1175a5e2ec31ff051833
2 parents 32941e1 + b073533 commit f0da26c

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

src/net_processing.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3792,7 +3792,7 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string
37923792

37933793
// Attempt to initialize address relay for outbound peers and use result
37943794
// to decide whether to send GETADDR, so that we don't send it to
3795-
// inbound or outbound block-relay-only peers.
3795+
// inbound, feelers, or outbound block-relay-only peers.
37963796
bool send_getaddr{false};
37973797
if (!pfrom.IsInboundConn()) {
37983798
send_getaddr = SetupAddressRelay(pfrom, peer);
@@ -5724,6 +5724,11 @@ bool PeerManagerImpl::SetupAddressRelay(const CNode& node, Peer& peer)
57245724
// information of addr traffic to infer the link.
57255725
if (node.IsBlockOnlyConn()) return false;
57265726

5727+
// We don't participate in addr relay with feeler connections because
5728+
// they are disconnected shortly after the handshake completes,
5729+
// before the node will receive the addr response.
5730+
if (node.IsFeelerConn()) return false;
5731+
57275732
if (!peer.m_addr_relay_enabled.exchange(true)) {
57285733
// During version message processing (non-block-relay-only outbound peers)
57295734
// or on first addr-related message we have received (inbound peers), initialize

test/functional/p2p_addr_relay.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,17 @@ def getaddr_tests(self):
280280
tip_header = from_hex(CBlockHeader(), self.nodes[0].getblockheader(self.nodes[0].getbestblockhash(), False))
281281
full_outbound_peer.send_and_ping(msg_headers([tip_header]))
282282

283-
self.log.info('Check that we do not send a getaddr message to a block-relay-only or inbound peer')
283+
self.log.info('Check that we do not send a getaddr message to a block-relay-only, feeler or inbound peer')
284284
block_relay_peer = self.nodes[0].add_outbound_p2p_connection(AddrReceiver(), p2p_idx=1, connection_type="block-relay-only")
285285
block_relay_peer.sync_with_ping()
286286
assert_equal(block_relay_peer.getaddr_received(), False)
287287
block_relay_peer.send_and_ping(msg_headers([tip_header]))
288288

289+
feeler_peer = self.nodes[0].add_outbound_p2p_connection(AddrReceiver(), p2p_idx=2, connection_type="feeler")
290+
# bitcoind closes feeler connections as soon as it receives a version message
291+
assert_equal(feeler_peer.is_connected, False)
292+
assert_equal(feeler_peer.getaddr_received(), False)
293+
289294
inbound_peer = self.nodes[0].add_p2p_connection(AddrReceiver(send_getaddr=False))
290295
inbound_peer.sync_with_ping()
291296
assert_equal(inbound_peer.getaddr_received(), False)

0 commit comments

Comments
 (0)