-
Notifications
You must be signed in to change notification settings - Fork 38.6k
p2p: Remove fGetAddr flag #19794
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
p2p: Remove fGetAddr flag #19794
Conversation
|
concept ACK |
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
jnewbery
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Just two minor style comments inline.
You should update the commit log to include your excellent description of why it's ok to remove this.
32bd4cb to
ef98555
Compare
|
Thanks for the review! I pushed an update, implementing both style suggestions and copying the PR description into the commit message. |
|
ACK ef9855580098654cdfc5844f8922518e6602878f. It's good to get rid of the useless code. Even though it's only a couple lines, the burden of this variable is massive: I spent 10 minutes figuring what does it do, even after reading the PR description. I tried to make sure we don't miss any corner cases, and I think this PR works correctly. Regarding your commit message:
I'm not sure it's a bug in master. I always thought of As a side note, is this possible?
This PR doesn't address this issue as a whole, but it removes one out of two mechanisms making this possible I believe :) |
I just wanted to note that it is a small change in behaviour, not sure if it is a bug. In any case, I don't think that this will occur often, because with Regarding your scenario: |
|
Though I had an idea what it was for, I don't think I've ever thoroughly understood this flag. Thanks for the explanation and ACK on removing it. |
|
ACK the code changes in ef9855580098654cdfc5844f8922518e6602878f If you touch this again, could you line-wrap the body of your commit log at 80 chars? (also no need to credit me in the commit log - this is your work!) |
|
strong concept ACK! thank you! that variable is a distraction. |
ef98555 to
d3eaaf4
Compare
|
Rebased and reformatted the commit message as suggested by @jnewbery . |
|
ACK d3eaaf4 Another behavior change, or rather an elaboration over "If the response to GETADDR is small (<=10 addresses), it will be relayed to peers just as any other ADDR message of that size."
I think this order of events is unlikely (need much luck for (3) to happen before (5)) but possible. In that case,
I think this is actually an improvement. I don't see any reason to withhold an initial announcement of the peer instead of forwarding it to other nodes. Even if this had any privacy benefits as a side-effect (e.g., somehow less revealing of new connections), it had a very low chance of working. Maybe this should be a real feature tho. |
|
ACK d3eaaf4 |
|
ACK d3eaaf4 CI failures look unrelated. |
If I'm understanding you correctly, you're saying that we can't get more than one ADDR message in response because our own software wouldn't do it. But what about other software on the network? At any rate, I think the reason we have this variable is to track whether an ADDR message is likely in response to a getaddr message we send, in which case we don't want to relay the learned addresses to other peers, or if an addr message is an unsolicited relay from our peer, in which case we also want to try to relay. (The reason to not relay messages with more than 10 entries is to rate limit the addr relay, so that a spammer can't use up all the network's bandwidth by blasting out addr messages.) I think one downside to relaying getaddr responses is a privacy leak - if you started up with a small addrman, and learned only a small set of nodes to connect to from one peer (and relayed that whole thing to another peer), that other peer might have a pretty good idea of who you're going to be connecting to. Anyway I'd be hesitant to remove this bool without talking through how we view this scenario, as it seems odd to me to relay addresses that are in response to a getaddr message, since we expect those to be of a very different nature than unsolicited addresses being relayed to us, which you expect to be originating with some peer announcing itself. (I wish the response to a getaddr was a different message type than an unsolicited address being relayed to us!) |
|
@sdaftuar hmm interesting, I'm trying to evaluate this concern, do I have the scenario right:
and then your concern is at this point, that Node C is able to deduce private information? the connection between Node A and Node B? or more generally what Node A's options for connections are? |
|
I just realized that The problem is that the first ADDR we receive in the lifetime of a typical connection is the initial self-announcement of our peer! After receiving this ADDR message of size 1, Therefore, what this flag currently seems to do is prevent initial self-announcements of outbound peers from being relayed to other peers. I'll update the PR description with above info later this weekend and will also address @sdaftuar's comment - marking the PR as Draft until then. |
Wow, good observation. So, this flag doesn't even do what it was introduced for. Strong ACK on improving the comments/logic here, but I also still think removing it entirely is fine. Our "don't relay getaddr responses" logic is enforced by the |
|
To elaborate on my last comment: The typical behavior seems to be that in the first So I think that there are now two separate issues: 2.) Even though I think it might be more problematic for privacy sending GETADDR responses < 1000, because we communicate the size of our addrman (via 23% factor) and signal that we might be susceptive to an eclipse attack if our addrman is small. I'll update the commit message and the PR description (will leave the originally assumed changes in behavior in for now, because they were quoted in this discussion). |
`fGetAddr` is an old flag that indicates an ongoing GETADDR/ADDR interaction. Introduced in dd51920, it prevents further relay of received ADDR answers to other peers via the `RelayAddress()` gossip mechanism while set - probably to prevent ADDR traffic from being dominated by large GETADDR answers. It also used to be possible to receive a large GETADDR answer spread over multiple ADDR messages (each bounded to max 1000 addresses), so the condition `if (vAddr.size() < 1000) pfrom.fGetAddr = false;` was meant to ensure that `fGetAddr` would only get cleared once the last ADDR of the package was received (typically with < 1000 addresses). However, `fGetAddr` currently does not work as originally intended and is no longer useful: - typically, the first ADDR we receive from a peer after sending the GETADDR is not the GETADDR response but the self-announcement of our peer. If this is the case, `fGetAddr` acts on it (preventing its relay) and is already inactivated once the GETADDR response is received. - 5cbf753 introduced the condition `vAddr.size() <= 10`, so messages with more than 10 elements won't be relayed further regardless. - since bitcoin#5419, we do not get more than one ADDR message in response to GETADDR because `vAddrToSend` cannot have more than 1000 elements. Removing the flag will cause initial self-announcements from outbound peers to be gossip-relayed.
d3eaaf4 to
628812a
Compare
|
ACK 628812a |
|
So there are 2 issues pointed out by sdaftuar, I'd consider them separately:
I'm leaning towards reACK, but before that I'd rather us make some efforts to make sure (2) is not a concern (maybe an ML post is sufficient). |
|
Actually, |
|
@naumenkogs , I don't understand this:
Why would fGetAddr stay as true? I think it's flipped to false in this scenario. |
|
@jnewbery this was a mistake (see I updated it), but the example remains valid. |
|
Rather than remove the |
I'm not 100% persuaded that |
It seems like it should be a reasonably good guess that if you send someone a Fixing that race condition (usually) for our own software is pretty easy; and that then reduces the question posed by this PR to "is it important to keep track of when an addr message is in response to a getaddr, or not?" And I tend to think that the answer is probably yes; although addr relay is not something specified in any BIPs, it makes sense to me that responses to a As for what other software might exist: in addition to other full-node implementations out there, I think the dns seednodes can be used as addr-fetch peers by Bitcoin Core, in some situations? I haven't tried to exercise it carefully, but my understanding is that the seednodes are custom software, which potentially differ from each other and from Bitcoin Core. |
In this case, I think that we should change the I think of |
Yes, I agree that makes sense and better matches what we typically are seeing on the network. |
|
Ok - I will open a PR in the next days for that. Will close this one and link it from the new one, because it would become a bit confusing with another change in the PR description and discussion referring to old versions. |
|
There is some more discussion here, BTW: bitcoin/bips#907 |
fGetAddris an old flag that indicates an ongoing GETADDR/ADDR interaction. Introduced in dd51920, it prevents further relay of received ADDR answers to other peers via theRelayAddress()gossip mechanism while set - probably to prevent ADDR traffic from being dominated by large GETADDR answers.It also used to be possible to receive a large GETADDR answer spread over multiple ADDR messages (each bounded to max 1000 addresses), so the condition
if (vAddr.size() < 1000) pfrom.fGetAddr = false;was meant to ensure thatfGetAddrwould only get cleared once the last ADDR of the package was received (typically with < 1000 addresses).However,
fGetAddrcurrently does not work as originally intended and is no longer useful:fGetAddracts on it (preventing its relay) and is already inactivated once the GETADDR response is received.vAddr.size() <= 10, so messages with more than 10 elements won't be relayed further regardless.vAddrToSendcannot have more than 1000 elements.Removing the flag will cause initial self-announcement from outbound peers to be gossip-relayed.
Thanks to jnewbery for help with reconstructing the history of
fGetAddr![Outdated, but left in for context]
Removing the flag will change behaviour in two special cases:
1.) If the GETADDR response is exactly of size 1000,
fGetAddrwill not not be cleared on current master, so that the next "regular" ADDR message by this peer won't be relayed - this does not seem intentional, changing it arguably fixes a bug.2.) If the response to GETADDR is small (<=10 addresses), it will be relayed to peers just as any other ADDR message of that size.