-
Notifications
You must be signed in to change notification settings - Fork 378
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
Reliably deliver gossip messages from our ChannelMessageHandler
#3142
Reliably deliver gossip messages from our ChannelMessageHandler
#3142
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3142 +/- ##
==========================================
+ Coverage 89.68% 90.20% +0.52%
==========================================
Files 126 127 +1
Lines 103306 110733 +7427
Branches 103306 110733 +7427
==========================================
+ Hits 92651 99889 +7238
- Misses 7936 8205 +269
+ Partials 2719 2639 -80 ☔ View full report in Codecov by Sentry. |
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 code looks great! Just one quick note about the from_chan_handler
boolean.
While the commit message clarifies that from_chan_handler
suggests it originates from ChannelMessageHandler
and should be forwarded to peers, allowing for a larger buffer, this isn’t immediately clear when reading the code alone.
To enhance clarity, we could either:
- Add a comment in the code to explain this connection.
- Rename
from_chan_handler
toallow_large_buffer
. - Or, rename
allow_large_buffer
tofrom_chan_handler
.
Option 1 makes the purpose clear right away. I also like option 2, as it succinctly reflects that large buffers are permissible for channel events, as shown here:
for event in chan_events {
handle_event(event, true);
}
However, if this new boolean is intended only to be used with chan_events
, then option 3 would be the most fitting solution.
Let me know what you think. Looking forward to your thoughts!
Pushed some additional comments/docs. |
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!
Shall we test to see if this change works as intended?
9b88a14
to
8733e70
Compare
Added a test (and rebased, cause this old branch doesn't even build anymore...thanks MSRV-breakages...). |
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!
8733e70
to
d328d41
Compare
Rebased. |
d328d41
to
4f6a09c
Compare
Rather than building a single `Vec` of `MessageSendEvent`s to handle then iterating over them, we move the body of the loop into a lambda and run the loop twice. In some cases, this may save a single allocation, but more importantly it sets us up for the next commit, which needs to know from which handler the `MessageSendEvent` it is processing came from.
4f6a09c
to
e483e53
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.
Basically LGTM
@@ -1600,7 +1600,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM | |||
} | |||
|
|||
for msg in msgs_to_forward.drain(..) { | |||
self.forward_broadcast_msg(&*peers, &msg, peer_node_id.as_ref().map(|(pk, _)| pk)); | |||
self.forward_broadcast_msg(&*peers, &msg, peer_node_id.as_ref().map(|(pk, _)| pk), false); |
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.
It's not really obvious to me why this is false... seems like it could be a channel message at this point?
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.
These come from handling a message from a peer. It could in theory be for one of our channels, but not from our ChannelMessageHandler
.
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.
given that this conversation won't live on in the code itself, perhaps a comment or a descriptively named variable for the false might help?
e483e53
to
116e369
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.
LGTM after squash
When our `ChannelMessageHandler` creates gossip broadcast `MessageSendEvent`s, we generally want these to be reliably delivered to all our peers, even if there's not much buffer space available. Here we do this by passing an extra flag to `forward_broadcast_msg` which indicates where the message came from, then ignoring the buffer-full criteria when the flag is set.
The `establish_connection` method should work for more than one connection per `PeerManager`, which we fix here.
In testing, its useful to be able to tell the `SocketDescriptor` to pretend the system network buffer is full, which we add here by creating a new `hang_writes` flag. In order to simplify constructing, we also add a new constructor which existing tests are moved to.
This adds a simple test that the gossip message buffer in `PeerManager` is limited, including the new behavior of bypassing the limit when the broadcast comes from the `ChannelMessageHandler`.
Squashed. |
116e369
to
f4b2311
Compare
} | ||
|
||
for (node_id, msg) in self.message_handler.custom_message_handler.get_and_clear_pending_msg() { | ||
if peers_to_disconnect.get(&node_id).is_some() { continue; } | ||
self.enqueue_message(&mut *get_peer_for_forwarding!(&node_id), &msg); | ||
self.enqueue_message(&mut *if let Some(peer) = get_peer_for_forwarding!(&node_id) { peer } else { continue; }, &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.
not really worth voiding the approvals for, but does this have to all be in one line?
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.
rustfmt
will figure it out eventually 🤷♂️
@@ -1600,7 +1600,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM | |||
} | |||
|
|||
for msg in msgs_to_forward.drain(..) { | |||
self.forward_broadcast_msg(&*peers, &msg, peer_node_id.as_ref().map(|(pk, _)| pk)); | |||
self.forward_broadcast_msg(&*peers, &msg, peer_node_id.as_ref().map(|(pk, _)| pk), false); |
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.
given that this conversation won't live on in the code itself, perhaps a comment or a descriptively named variable for the false might help?
|
||
#[allow(unused_imports)] | ||
use crate::prelude::*; | ||
|
||
#[derive(Clone)] | ||
struct FileDescriptor { | ||
fd: u16, | ||
hang_writes: Arc<AtomicBool>, | ||
outbound_data: Arc<Mutex<Vec<u8>>>, |
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 this could use a comment, particularly pointing out its purpose is primarily for testing
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 entire code block is inside #[cfg(test)]
, I think its pretty obvious its only for testing :)
When our
ChannelMessageHandler
creates gossip broadcastMessageSendEvent
s, we generally want these to be reliablydelivered to all our peers, even if there's not much buffer space
available.
Here we do this by passing an extra flag to
forward_broadcast_msg
which indicates where the message came from, then ignoring the
buffer-full criteria when the flag is set.