bitcoin: Finding peers to connect to after -onlynet changes may be problematic

Expected behavior

Bitcoin Core, ideally, should always have peers to try to connect to just like when started for the very first time (empty peers.dat). It should not be more difficult to find possible peers if it was ran before with a different -onlynet= setting.

Actual behavior

If addrman has some entries, even to only unreachable networks, due to previous runs and changes in -onlynet, then the fixed seeds will not be used.

To reproduce

Run with -onlynet=ipv4, change to -onlynet=i2p.

To fix

This problem is two-fold:

  1. Fixed seeds should be used if we have 0 reachable peers in addrman. I guess this condition should be relaxed, like discussed in https://github.com/bitcoin/bitcoin/pull/25678#issuecomment-1238542029

https://github.com/bitcoin/bitcoin/blob/fc44d1796e4df5824423d7d13de3082fe204db7d/src/net.cpp#L1628

  1. Even if there are a few reachable peers in addrman, e.g. 0.1% it will take a long time before they are tried. The address selection logic can be improved. It is, simplified, like this (see lines 1797 and 1810):
select random address
if not reachable then try another random address

Can be improved to “select random address, but only from reachable networks”.

This problem is amplified by the fact that we do not save non-reachable addresses in addrman during p2p gossip (and also see https://github.com/bitcoin/bitcoin/pull/25678). Maybe we should reconsider that as a 3rd fixup, in addition to the above 2 - save even unreachable addresses in addrman during p2p gossip and fixed seeds loadup? What is the worst that can happen? We will have some wasted space in addrman if onlynet is never altered?

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 16 (14 by maintainers)

Commits related to this issue

Most upvoted comments

A very interesting long-term solution (not just for this problem, it would have several other benefits) would be to have a separate addrman for each network instead of one shared addrman.

Trying to maintain at least 1 outbound connection to each reachable network sounds good idea to me. Not only because of this but also because of redundancy (imagine node configured as Tor and I2P only and Tor network is under heavy attack and not working normally at some moment, then you will have at least one I2P connection all the time and will continue to receive new blocks).

@CocolinoFan what you describe is problem 2 from the OP. A fix for it is at https://github.com/bitcoin/bitcoin/pull/27213. It would be nice if you can test and/or review that.

What is the reasoning behind 1.2? Would it not benefit the network to have better gossiped addresses, especially for networks like I2P and CJDNS?

The general idea that addresses are more strongly gossiped among those nodes that actually can make use of them makes sense to me. Having all the clearnet-only nodes constantly exchanging I2P or onion addresses on the same scale as IPv4 seems a bit wasteful.

A possible improvement very much related to this: try to maintain at least 1 outbound connection to each reachable network.

Currently the chance of selecting a peer from network X to connect to depends on how many such peers are in addrman, compared to all addrman entries. It is dominated by IPv4 peers.