-
Notifications
You must be signed in to change notification settings - Fork 367
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
Gossip filtration fix #3390
base: main
Are you sure you want to change the base?
Gossip filtration fix #3390
Conversation
lightning/src/ln/peer_handler.rs
Outdated
(f.first_timestamp, f.first_timestamp.saturating_add(f.timestamp_range)) | ||
}); | ||
|
||
if msg.contents.timestamp >= min && msg.contents.timestamp <= max { |
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.
You'll need to apply the same in NodesSyncing
handling below.
lightning/src/ln/peer_handler.rs
Outdated
}); | ||
|
||
if msg.contents.timestamp >= min && msg.contents.timestamp <= max { | ||
self.enqueue_message(peer, &msg); |
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.
Hmm, this now results in us sending node_announcement
s for nodes for which we didn't send the requisite channel_announcement
s :/. Maybe its fine, but I'm kinda inclined to just skip all historical state for a peer that sends us a time more recent than now - an hour and otherwise give them a full dump.
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.
the delivery order notwithstanding, don't you think the update timestamps are typically more likely to be higher than their corresponding node announcements' timestamps, meaning that it would be less likely to see a node announcement without a channel announcement than vice versa?
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.
I'm also a bit reluctant to continue bombarding peers with gossip when they're explicitly requesting not to
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.
don't you think the update timestamps are typically more likely to be higher than their corresponding node announcements' timestamps, meaning that it would be less likely to see a node announcement without a channel announcement than vice versa?
Not particularly? Both are generally on a timer, they may be independent timers.
I'm also a bit reluctant to continue bombarding peers with gossip when they're explicitly requesting not to
I don't think I suggested that. Rather, I suggested just skipping historical state sync entirely if we're gonna filter a material number of channels.
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.
Per this suggestion, I replaced all changes with one additional check upon receipt of the timestamp filter message, determining if the requested range started more than an hour ago. Based on that, it flips between either a full sync or new gossip relay only.
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.
Just resurfacing this in case it went under @TheBlueMatt. All other comments should be obsolete if we simply go with the modified behavior of checking whether the requested filter's timestamp was more than an hour ago.
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.
Based on that, it flips between either a full sync or new gossip relay only.
Reading the following comment to try to understand how gossip_timestamp_filter
works.
rust-lightning/lightning/src/routing/gossip.rs
Lines 650 to 663 in 0c31021
// Once you opt into "gossip queries" the only way to receive any gossip updates that a | |
// peer receives after you connect, you must send a `gossip_timestamp_filter` message. This | |
// message, as the name implies, tells the peer to not forward any gossip messages with a | |
// timestamp older than a given value (not the time the peer received the filter, but the | |
// timestamp in the update message, which is often hours behind when the peer received the | |
// message). | |
// | |
// Obnoxiously, `gossip_timestamp_filter` isn't *just* a filter, but its also a request for | |
// your peer to send you the full routing graph (subject to the filter). Thus, in order to | |
// tell a peer to send you any updates as it sees them, you have to also ask for the full | |
// routing graph to be synced. If you set a timestamp filter near the current time, peers | |
// will simply not forward any new updates they see to you which were generated some time | |
// ago (which is not uncommon). If you instead set a timestamp filter near 0 (or two weeks | |
// ago), you will always get the full routing graph from all your peers. |
IIUC, it seems with this PR we either send the full dump or not based on the timestamp. And if the newly added check doesn't pass, we won't send any gossip. It doesn't seem to be the case that we'd even relay new gossip. This is because should_forward_channel_announcement
and should_forward_node_announcement
will return false
when sent_gossip_timestamp_filter
is false
.
lightning/src/ln/peer_handler.rs
Outdated
if let Some(update_a) = update_a_option { | ||
self.enqueue_message(peer, &update_a); | ||
if update_a.contents.timestamp >= min && update_a.contents.timestamp <= max { | ||
if !has_enqueued_announcement { |
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.
Won't this always evaluate to true?
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.
why?
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.
Because has_enqueued_announcement
is initialized to false
and never modified before reaching this line. The variable is actually only used to prevent enqueuing the announcement more than once. The reason given in the comment above is really covered by the let if let Some(update_a|b)
checks.
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.
ah, I thought you were referring to the timestamp range. Yes, good point
lightning/src/ln/peer_handler.rs
Outdated
if let Some(update_a) = update_a_option { | ||
self.enqueue_message(peer, &update_a); | ||
if update_a.contents.timestamp >= min && update_a.contents.timestamp <= max { |
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.
Should be < max
according to BOLT7. Likewise below.
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #3390 +/- ##
==========================================
+ Coverage 89.61% 90.45% +0.84%
==========================================
Files 129 130 +1
Lines 105506 113427 +7921
Branches 105506 113427 +7921
==========================================
+ Hits 94544 102596 +8052
+ Misses 8208 8110 -98
+ Partials 2754 2721 -33 ☔ View full report in Codecov by Sentry. 🚨 Try these New Features:
|
268ecea
to
3854be0
Compare
lightning/src/ln/peer_handler.rs
Outdated
}); | ||
|
||
if msg.contents.timestamp >= min && msg.contents.timestamp <= max { | ||
self.enqueue_message(peer, &msg); |
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.
Based on that, it flips between either a full sync or new gossip relay only.
Reading the following comment to try to understand how gossip_timestamp_filter
works.
rust-lightning/lightning/src/routing/gossip.rs
Lines 650 to 663 in 0c31021
// Once you opt into "gossip queries" the only way to receive any gossip updates that a | |
// peer receives after you connect, you must send a `gossip_timestamp_filter` message. This | |
// message, as the name implies, tells the peer to not forward any gossip messages with a | |
// timestamp older than a given value (not the time the peer received the filter, but the | |
// timestamp in the update message, which is often hours behind when the peer received the | |
// message). | |
// | |
// Obnoxiously, `gossip_timestamp_filter` isn't *just* a filter, but its also a request for | |
// your peer to send you the full routing graph (subject to the filter). Thus, in order to | |
// tell a peer to send you any updates as it sees them, you have to also ask for the full | |
// routing graph to be synced. If you set a timestamp filter near the current time, peers | |
// will simply not forward any new updates they see to you which were generated some time | |
// ago (which is not uncommon). If you instead set a timestamp filter near 0 (or two weeks | |
// ago), you will always get the full routing graph from all your peers. |
IIUC, it seems with this PR we either send the full dump or not based on the timestamp. And if the newly added check doesn't pass, we won't send any gossip. It doesn't seem to be the case that we'd even relay new gossip. This is because should_forward_channel_announcement
and should_forward_node_announcement
will return false
when sent_gossip_timestamp_filter
is false
.
47f4228
to
e5f9a11
Compare
I have split the check in two to address that, @jkczyz. |
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.
LGTM. May want to add a test as mentioned offline. Also, would be good to document InitSyncTracker
as otherwise you need to read the code to figure out the behavior.
Previously, upon receipt of a
GossipTimestampFilter
message, we would immediately start unloading the entire network graph on our unsuspecting peer.This PR modifies our behavior to only do so if the timestamp of the filter message is at least an hour old. Otherwise, we only send updated sync data as it comes in.