-
Notifications
You must be signed in to change notification settings - Fork 385
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
Reintroduce addresses to NodeAnnouncementInfo. #3072
Reintroduce addresses to NodeAnnouncementInfo. #3072
Conversation
5a03472
to
5d9d796
Compare
Codecov ReportAttention: Patch coverage is
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## main #3072 +/- ##
==========================================
+ Coverage 89.81% 91.86% +2.04%
==========================================
Files 116 119 +3
Lines 96467 113993 +17526
Branches 96467 113993 +17526
==========================================
+ Hits 86646 104715 +18069
+ Misses 7276 6941 -335
+ Partials 2545 2337 -208 ☔ View full report in Codecov by Sentry. |
5d9d796
to
cb08eb2
Compare
cb08eb2
to
4bf6a8c
Compare
lightning/src/routing/gossip.rs
Outdated
last_update: last_update.0.unwrap(), | ||
rgb: rgb.0.unwrap(), | ||
alias: alias.0.unwrap(), | ||
addresses: addresses.unwrap_or(Vec::new()), |
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 this be sourced from the announcement message instead? We are introducing the potential for multiple sources of truth, so feedback would be much appreciated.
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.
Yeah, to avoid this I'd prefer one of the enum approaches that you mention in the PR description.
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.
Honestly, same. Any preference on which one? Also, I think @TheBlueMatt should probably weigh in, too
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.
We'd probably need three variants for:
NodeAnnouncement
NodeAnnouncement
that isn't relayed (i.e., whenshould_relay
is false) using a struct containing everything inNodeAnnouncementInfo
butannouncement_message
UnsignedNodeAnnouncement
(maybe withexcess_address_data
andexcess_data
cleared)
In that sense, NodeAnnouncementInfo
would become an enum, though I'm not sure if there's anything that would make the undesirable. We'd also need accessor methods for the fields.
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.
Alternatively, we could just store an UnsignedNodeAnnouncement, and an optional field for the signatures, whose presence would imply should_relay.
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.
That could work, though we'd need to clear excess_address_data
and excess_data
when not relaying, too. It would require that we copy the data to produce a NodeAnnouncement
during relay, though it looks like the RoutingMessageHandler
trait requires us to do that anyway, as currently designed.
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 enum approach seems cleaner over some kind of dummy signatures, especially in that we'll get type checking when trying to access the announcement for relay. IMO we should not be storing UnsignedNodeAnnouncement
s unless we have all the data that goes in them, which in this case we may not, so we should just have one enum variant across unrelayed-announcements and RGS-sourced data.
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 think that pretty much means that NodeAnnouncementInfo
itself would become a two-variant-enum instead, with the variants being either Relayed(NodeAnnouncement), or Unrelayed(features, last_update, rgb, alias, addresses).
However, given that the unrelayed struct is only missing node_id and the two excess fields from UnsignedNodeAnnouncement, is it worth introducing a separate struct for that? My intuition would be yes, but double-checking anyway.
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.
Yea, I think so? Reusing the same struct implies something specific (that this is the node announcement) whereas a separate struct communicates via the type system that this is just info about the node.
a0efc92
to
a8b2aa9
Compare
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.
Design LGTM.
lightning/src/routing/gossip.rs
Outdated
/// Protocol features the node announced support for | ||
pub features: NodeFeatures, | ||
features: NodeFeatures, |
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.
Any reason to not leave these pub?
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.
we have accessors for each of those fields now, so it seemed odd leaving these public
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.
unambiguous usage for developers? But I'll make the fields public
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 is accessing fields ambiguous?
lightning/src/routing/gossip.rs
Outdated
} | ||
|
||
/// When the last known update to the node state was issued. | ||
/// Value is opaque, as set in the 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.
/// Value is opaque, as set in the announcement. | |
/// | |
/// Value may or may not be a timestamp, depending on the policy of the origin node. |
lightning/src/routing/gossip.rs
Outdated
/// May be invalid or malicious (eg control chars), | ||
/// should not be exposed to the user. |
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.
?
/// May be invalid or malicious (eg control chars), | |
/// should not be exposed to the user. | |
/// | |
/// May be invalid or malicious (eg control chars), should not be exposed to the user. |
a8b2aa9
to
baafcdf
Compare
lightning/src/routing/gossip.rs
Outdated
alias: msg.alias, | ||
announcement_message: if should_relay { full_msg.cloned() } else { None }, | ||
}); | ||
node.announcement_info = if let Some(signed_announcement) = full_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.
this looks incredibly awkward to me but rust does't allow combining if let with other booleans, so not sure how to improve this
} | ||
|
||
/// Moniker assigned to the node. | ||
/// May be invalid or malicious (eg control chars), should not be exposed to the user. |
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.
/// May be invalid or malicious (eg control chars), should not be exposed to the user. | |
/// | |
/// May be invalid or malicious (eg control chars), should not be exposed to the user. |
} | ||
|
||
/// An initial announcement of the node | ||
/// Not stored if contains excess data to prevent DoS. |
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.
/// Not stored if contains excess data to prevent DoS. | |
/// | |
/// Not stored if contains excess data to prevent DoS. |
lightning/src/routing/gossip.rs
Outdated
let last_update = self.last_update(); | ||
let rgb = self.rgb(); | ||
let alias = self.alias(); | ||
let addresses = self.addresses().to_vec(); |
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.
If addresses()
returned a vec rather than to_slice
-ing you could avoid the alloc here, which is going to be pretty brutal when we write 10k nodes.
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.
what do you think is the optimal way of avoiding allocations? Returning a &Vec<SocketAddress>
and implementing a new writeable for that type?
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 just need a *
in the write_tlv_fields
call.
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.
thanks! I kept trying to have the right type prior to the macro invocation.
lightning/src/routing/gossip.rs
Outdated
@@ -1182,11 +1271,19 @@ impl Readable for NodeAnnouncementInfo { | |||
(4, rgb, required), | |||
(6, alias, required), | |||
(8, announcement_message, option), | |||
(10, _addresses, optional_vec), // deprecated, not used anymore | |||
(10, addresses, optional_vec), |
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.
Did we ever not write this? Can we make it required?
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.
we should be able 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.
Did you go back and check every release since we made it optional? Also, was it added after the serialization was written or in the original?
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 couldn't find any point in history of us not writing it. And yet, it historically has always been an optional_vec read for some reason.
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.
Something odd happened in this commit: a04bf84, where vec_type instances were converted to required_vec, but this one got converted to optional_vec instead
f8df9fc
to
9770247
Compare
29df13c
to
e9a0c91
Compare
LGTM, feel free to squash. |
e9a0c91
to
3ee0a00
Compare
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.
Sorry one more
.map(|node_announcement| &node_announcement.contents); | ||
.and_then(|announcement_info| { | ||
announcement_info | ||
.announcement_message() |
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.
This should just use anouncement_info.features()
.
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.
but the node addresses are also being used later on, and the features alone don't contain them?
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.
Either way the code here doesn't need to rely on us having stored the full announcement, which it currently does.
3ee0a00
to
06f9510
Compare
Some(node_announcement) if node_announcement.features.supports_onion_messages() => { | ||
let first_node_addresses = Some(node_announcement.addresses.clone()); | ||
match node_details { | ||
Some((features, addresses)) if features.supports_onion_messages() => { |
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.
Oh whoops we should also filter by if we have an address or not.
06f9510
to
bbc291f
Compare
lightning/src/routing/gossip.rs
Outdated
(4, rgb, required), | ||
(6, alias, required), | ||
(8, announcement_message, option), | ||
(10, *addresses, required_vec), // Versions prior to 0.0.115 require this field |
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.
This comment can be removed - we now require the field today too.
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.
any preferences between Versions between 0.0.115 and 0.0.123 did not require this field
and leaving it out altogether?
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 don't have a strong feeling. If we leave a comment it should probably note that those versions wrote empty Vecs, which imo is more relevant than the fact that they would accept no Vec (which we can't take advantage of in the future as we are now going to require it again).
bbc291f
to
db489ba
Compare
Parsing v2 gossip, which will include socket addresses, but no signatures, will require the ability to store addresses on the
NodeAnnouncementInfo
object without a corresponding (signed)NodeAnnouncement
message.This approach is to effectively revert commit 6f5e5e3. Some alternative approaches could be setting an enum for either a signed or unsigned node announcement, or even to have an enum for either a signed node announcement or the addresses field.