p2p: Don’t participate in addr relay with feelers #34997

pull danielabrozzoni wants to merge 1 commits into bitcoin:master from danielabrozzoni:getaddr_feeler changing 2 files +9 −1
  1. danielabrozzoni commented at 4:16 pm on April 3, 2026: member

    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. It seems to me that the GETADDR is not useful and can be removed.

    More broadly, addr relay with feelers isn’t useful: we are receiving plenty of address information already through getaddr to outbounds, and the addresses from feelers are likely low quality, given that they come from addresses we’re not even sure are running a Bitcoin node.

    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:

    0~ ₿ tail -f ~/.bitcoin/debug.log | grep -E "(Making feeler connection|Added connection to|sending getaddr|feeler connection completed|Received addr: [0-9]{2,} addresses)"
    1
    22026-04-02T13:25:50Z [net] Making feeler connection to xyz.onion:8333
    32026-04-02T13:26:06Z [net] Added connection to xyz.onion:8333 peer=27
    42026-04-02T13:26:08Z [net] sending getaddr (0 bytes) peer=27
    52026-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:

     0~ ₿ cat .bitcoin/debug.log | awk '
     1
     2  /received: getaddr/ {
     3      split($0, a, "peer=")
     4      got_getaddr[a[2]] = $0
     5  }
     6
     7  /sending addr/ {
     8      split($0, a, "peer=")
     9      sent_addr[a[2]] = 1
    10  }
    11
    12  /socket closed/ {
    13      split($0, a, "peer=")
    14      id = a[2]
    15
    16      if (id in got_getaddr && !(id in sent_addr)) {
    17          print "possible feeler: " got_getaddr[id]
    18          print "                 " $0
    19      }
    20
    21      delete got_getaddr[id]
    22      delete sent_addr[id]
    23  }
    24'
    25
    26possible feeler: 2026-04-01T21:45:13Z [net] received: getaddr (0 bytes) peer=2311974
    27                 2026-04-01T21:45:13Z [net] socket closed, disconnecting peer=2311974
    28possible feeler: 2026-04-02T00:18:58Z [net] received: getaddr (0 bytes) peer=2426389
    29                 2026-04-02T00:18:58Z [net] socket closed, disconnecting peer=2426389
    30...
    

    Then, you can manually inspect one of them:

     0~ ₿ cat .bitcoin/debug.log | grep -E "peer=2311974"
     12026-04-01T21:45:13Z [net] Added connection peer=2311974
     22026-04-01T21:45:13Z [net] received: version (102 bytes) peer=2311974
     32026-04-01T21:45:13Z [net] sending version (102 bytes) peer=2311974
     42026-04-01T21:45:13Z [net] send version message: version 70016, blocks=943279, txrelay=0, peer=2311974
     52026-04-01T21:45:13Z [net] sending wtxidrelay (0 bytes) peer=2311974
     62026-04-01T21:45:13Z [net] sending sendaddrv2 (0 bytes) peer=2311974
     72026-04-01T21:45:13Z [net] sending verack (0 bytes) peer=2311974
     82026-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
     92026-04-01T21:45:13Z [net] received: wtxidrelay (0 bytes) peer=2311974
    102026-04-01T21:45:13Z [net] received: sendaddrv2 (0 bytes) peer=2311974
    112026-04-01T21:45:13Z [net] received: verack (0 bytes) peer=2311974
    122026-04-01T21:45:13Z New inbound v1 peer connected: version: 70016, blocks=943279, peer=2311974
    132026-04-01T21:45:13Z [net] sending sendcmpct (9 bytes) peer=2311974
    142026-04-01T21:45:13Z [net] sending ping (8 bytes) peer=2311974
    152026-04-01T21:45:13Z [net] sending getheaders (1029 bytes) peer=2311974
    162026-04-01T21:45:13Z [net] initial getheaders (943278) to peer=2311974 (startheight:943279)
    172026-04-01T21:45:13Z [net] received: getaddr (0 bytes) peer=2311974
    182026-04-01T21:45:13Z [net] Advertising address x.x.x.x:8333 to peer=2311974
    192026-04-01T21:45:13Z [net] socket closed, disconnecting peer=2311974
    202026-04-01T21:45:13Z [net] Resetting socket for peer=2311974
    212026-04-01T21:45:13Z [net] sending addrv2 (24665 bytes) peer=2311974
    222026-04-01T21:45:13Z [net] Cleared nodestate for peer=2311974
    
  2. DrahtBot added the label P2P on Apr 3, 2026
  3. DrahtBot commented at 4:16 pm on April 3, 2026: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept ACK taki-abedesselam, ajtowns, mzumsande

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

  4. taki-abedesselam commented at 1:59 pm on April 4, 2026: none

    Concept ACK, I suggest adding this conndition at https://github.com/bitcoin/bitcoin/blob/a7c30da1f6fc2eebd7514dd032fbb54940d467de/src/net_processing.cpp#L4823 So the bitcoin client will not respond to any GETADDR message from a feeler connection or outbound connections

    0if (!pfrom.IsInboundConn() || pfrom.IsFeelerConn()) {
    1            LogDebug(BCLog::NET, "Ignoring \"getaddr\" from %s connection. peer=%d\n", pfrom.ConnectionTypeAsString(), pfrom.GetId());
    2            return;
    3}
    
  5. danielabrozzoni commented at 9:15 am on April 6, 2026: member

    Thanks @taki-abedesselam!

    I suggest adding this conndition at

    https://github.com/bitcoin/bitcoin/blob/a7c30da1f6fc2eebd7514dd032fbb54940d467de/src/net_processing.cpp#L4823

    So the bitcoin client will not respond to any GETADDR message from a feeler connection or outbound connections

    I don’t think this is going to work:

    • for outbound connections (us connecting to a feeler), if the feeler node sends us a getaddr we are already going to ignore the message, because of !pfrom.IsInboundConn()
    • for inbound connections (some other node treating us as a feeler), we don’t know that the other node is using us as a feeler, we simply see “someone connected to us and quickly disconnected”, we have no way of selectively ignoring their getaddr.
  6. ajtowns commented at 10:27 am on April 6, 2026: contributor

    I guess if we have 8 outbounds sustained (and are not already eclipsed), then we likely get fairly good addr information constantly, and if we don’t have 8 outbounds, we’ll keep making new outbound connections, send a GETADDR to them, and get back 1000 new addressed, so one way or the other will get good coverage. So I guess we don’t need to put in any extra effort to get better address coverage, in the same way that we put in extra-effort via extra-block-relay-only peers to ensure we don’t miss out on any higher-PoW blocks.

    Getting addresses from feeler connections is probably low-quality: those are the addresses we think might not even be running a bitcoin node. So this seems fine from that perspective too.

    I find addrfetch connections confusing every time I think about them; I wish they were called addrseed or something instead. In any event, they’re only really meaningful for initially populating your addrman when your node is either fresh or has been down for a while. If we were wanting to do something better, doing that via additional addrfetch connections would probably be more reasonable than doing it via feeler connections.

    Concept ACK.

  7. in src/net_processing.cpp:3754 in 04718e1d98 outdated
    3747@@ -3748,9 +3748,9 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string
    3748 
    3749         // Attempt to initialize address relay for outbound peers and use result
    3750         // to decide whether to send GETADDR, so that we don't send it to
    3751-        // inbound or outbound block-relay-only peers.
    3752+        // inbound, feelers, or outbound block-relay-only peers.
    3753         bool send_getaddr{false};
    3754-        if (!pfrom.IsInboundConn()) {
    3755+        if (!pfrom.IsInboundConn() && !pfrom.IsFeelerConn()) {
    3756             send_getaddr = SetupAddressRelay(pfrom, peer);
    


    ajtowns commented at 10:28 am on April 6, 2026:
    We drop out of SetupAddressRelay for blocks-only nodes rather than gating calls to it. Maybe we should do feelers there too?
  8. yancyribbens commented at 1:52 pm on April 6, 2026: contributor
    I’m not very familiar with “feelers”, although, wouldn’t the quality of the data returned by feelers be better if we waited for the results of the GETADDR message instead of the current behavior of disconnecting before receiving the result?
  9. mzumsande commented at 12:50 pm on April 9, 2026: contributor

    Concept ACK

    This saves a little bit of bandwidth (not just our GETADDR message, but also their ADDR answer that the peer might prepare before they recognize they are being disconnected) but shouldn’t change anything else.

    I’m not very familiar with “feelers”, although, wouldn’t the quality of the data returned by feelers be better if we waited for the results of the GETADDR message

    They wouldn’t really be feeler anymore then. The current scope of feelers is just to know if there is a bitcoin node behind an address, not to get data from them. We could extend the scope in various ways (it has already been suggested in the past to exchange headers/compare the tip with them before disconnecting), but this should follow some sort of need. I agree with @ajtowns that currently there doesn’t really seem to be a need for more addresses - if we extend the scope I think that the tip sync may be more important).

  10. danielabrozzoni force-pushed on Apr 9, 2026
  11. danielabrozzoni commented at 2:18 pm on April 9, 2026: member

    Thanks for the reviews!

    I spent some time thinking about https://github.com/bitcoin/bitcoin/pull/34997/changes#r3039010154, and I realized that it makes more sense to disable address relay altogether, instead of simply not sending the getaddr. I was initially thinking along the lines of “we might still want to receive and relay the peer self announcement, or send our self announcement”. However:

    • From logs, it seems to me that we disconnect quickly enough that this doesn’t happen. What I saw on my machines was simply nodes sending a GETADDR to feelers, and disconnecting right away.
    • Even assuming that there is time for this message exchange, if we drop the initial GETADDR, we won’t send any self announcement to the peer, because addr relay won’t be initialized: https://github.com/bitcoin/bitcoin/blob/d2844c6a4ffa39ec365009777cd87caf1fbab867/src/net_processing.cpp#L5443-L5446 Similarly, the peer won’t send any self announcement to us, because they never receive an ADDR/GETADDR that initializes address relay.

    So, since not sending a GETADDR already disables address relay altogether, I might as well be a bit more clear and do so in SetupAddressRelay.


    In my last push (04718e1d984d7722c8e74e41156aa93ec18be83d -> d263660b9ba516e9145da9cbadff262fe26fc2b5):

    • Disable address relay for feelers in SetupAddressRelay, instead of simply not sending the GETADDR to feelers
    • Update commit title / message to reflect that we are disabling all address relay to feelers
  12. danielabrozzoni force-pushed on Apr 9, 2026
  13. danielabrozzoni force-pushed on Apr 9, 2026
  14. DrahtBot added the label CI failed on Apr 9, 2026
  15. danielabrozzoni renamed this:
    p2p: Don't send a GETADDR to feelers
    p2p: Don't participate in addr relay with feelers
    on Apr 9, 2026
  16. 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, 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.
    
    More broadly, addr relay with feelers isn't useful: we are receiving
    plenty of address information already through getaddr to outbounds,
    and the addresses from feelers are likely
    low quality, given that they come from addresses we're not even sure are
    running a Bitcoin node.
    3934d95408
  17. danielabrozzoni force-pushed on Apr 9, 2026
  18. DrahtBot removed the label CI failed on Apr 9, 2026
  19. danielabrozzoni commented at 8:56 pm on April 9, 2026: member

    Sorry, had to push again to retrigger CI, I hit #34849

    Last push (d263660 -> 3934d95): no changes, commit amend to retrigger CI


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-12 09:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me