The PR branch HEAD was 7e95f8f6bb at the time of this review club meeting.
Notes
Nodes connect to peers based on a set of addresses they know about, stored in their
AddrMan,
but a brand new node starts out with an empty AddrMan. In order to participate in the network, the
node needs to find addresses of peers to connect to.
Care is taken to not create a bias in the source of addresses. For example, it would be
inappropriate to have all new nodes connect to a list of 10 hard-coded addresses. That list of
nodes would become outdated very quickly, have an enormous burden of serving blocks to new nodes,
and be an eclipse vulnerability.
If the node’s addrman is empty, it queries
DNS seeds
run by community members.
If addrman is still empty, the node attempts connections to a set of fixed seeds,
hard-coded and updated once per release. You can read more about how the fixed seeds are
generated here.
The node doesn’t store addresses for
unreachable
networks. For example, if the node is only running on Tor, it won’t add a clearnet address
to its AddrMan.
Prior to PR #26114, fixed seeds are added to
AddrMan. This means the node’s first outbound connections are likely all taken from the fixed seeds.
An
AddrFetch
connection is a temporary outbound connection, used specifically for soliciting addresses.
The networking logic is multi-threaded (see list of threads and descriptions
here).
The ThreadOpenConnections() thread processes and sends messages to this node’s peers.
The ThreadDNSAddressSeed thread makes connections to DNS seeds.
This PR also moves handling of fixed seeds from ThreadOpenConnections to
ThreadDNSAddressSeed, and renames the latter to ThreadAddressSeed. Note this is
more involved than refactoring some code from one function to another. For example, moving
logic from one thread to another could mean that operations are no longer guaranteed to
execute in the same order, or that data structures previously accessed by one thread are now shared
between multiple.
Under what circumstances do we connect to the fixed seeds?
What observable behavior change does this PR introduce? What kinds of addresses do we add to
AddrMan, and under what circumstances?
What is an AddrFetch connection and what is a full outbound connection? Why might we want to make
an AddrFetch connection instead of full outbound connection to fixed seeds? Why might the node
operator behind a fixed seed prefer this as well?
The DNS seeds are expected to be responsive and serve up-to-date addresses of Bitcoin nodes. Why
doesn’t this help a -onlynet=tor node?
What does the ThreadOpenConnections do? What does ThreadDNSAddressSeed do? Which thread should
handle connecting to fixed seeds, and why?
Why wait 2
minutes
before adding the fixed seeds to AddrMan?
<glozow> LarryRuane: the peer only knows that you initiated the connection. it can make a guess, but no you don't tell them anything about the type of connection
<glozow> the DNS seeds should be serving you live data, i.e. updated quite regularly with the addresses of nodes they've been able to connect to. the fixed seeds are hardcoded and thus only updated once per release. should be intuitive which source you'd prefer to use
<glozow> Can anyone tell us: What observable behavior change does this PR introduce? What kinds of addresses do we add to AddrMan, and under what circumstances?
<LarryRuane> Our (starting from scratch) node won't be as likely to connect to only fixed-seed nodes; we'll be more likely to connect to nodes they know about (and tell us about)
<yashraj> move fixed seeds to addrfetch from addrman so they're only used if they have to be which reduces bandwidth for them and protects against eclipse attacks?
<glozow> and yes, this reduces the load on those fixed seeds. if a bunch of new nodes connect to them first thing, they're probably serving up a lot of blocks
<lightlike> It's pretty much a normal connection, with the special property that we disconnect once we receive an answer to our getaddr message. It's not like we disable block relay or tx relay, we may even get a block from them before they get disconnected.
<brunoerg> ThreadDNSAddressSeed because we will use the fixed seeds after trying to get some addrs from DNS seeds (in case we wasn't able to get anything)?
<glozow> brunoerg: yeah that's pretty much what I'm getting at. they're very similar in nature; you're trying to solicit addrs because your addrman is empty
<stickies-v> sounds mostly like a fallback for unforeseen/unexpected circumstances? if the network gets bloated with unresponsive peers and all we get is junk, then at least the fixed seeds can still bootstrap?
<glozow> Don't forget this is multi-threaded, so other things are still happening while this thread is seeding addresses. i.e., we are also making full outbound connections to catch up our chainstate at the same time
<lightlike> stickies-v: yes, if we just try 10 of them and they are all offline, it makes sense to add the other ones to the addrman after a while (so that we can hopefully make a connection to them).