Skip to content
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

Merged
merged 5 commits into from
Oct 23, 2024

Conversation

TheBlueMatt
Copy link
Collaborator

When our ChannelMessageHandler creates gossip broadcast
MessageSendEvents, 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.

@codecov-commenter
Copy link

codecov-commenter commented Jun 24, 2024

Codecov Report

Attention: Patch coverage is 75.89744% with 47 lines in your changes missing coverage. Please review.

Project coverage is 90.20%. Comparing base (4147de2) to head (116e369).
Report is 40 commits behind head on main.

Files with missing lines Patch % Lines
lightning/src/ln/peer_handler.rs 72.78% 44 Missing and 2 partials ⚠️
lightning/src/util/test_utils.rs 90.00% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

Copy link
Member

@shaavan shaavan left a 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:

  1. Add a comment in the code to explain this connection.
  2. Rename from_chan_handler to allow_large_buffer.
  3. Or, rename allow_large_buffer to from_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!

@TheBlueMatt
Copy link
Collaborator Author

Pushed some additional comments/docs.

Copy link
Member

@shaavan shaavan left a 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?

@TheBlueMatt TheBlueMatt force-pushed the 2024-06-robust-updates branch from 9b88a14 to 8733e70 Compare August 20, 2024 02:30
@TheBlueMatt
Copy link
Collaborator Author

Added a test (and rebased, cause this old branch doesn't even build anymore...thanks MSRV-breakages...).

Copy link
Member

@shaavan shaavan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

lightning/src/ln/peer_handler.rs Outdated Show resolved Hide resolved
@TheBlueMatt TheBlueMatt force-pushed the 2024-06-robust-updates branch from 8733e70 to d328d41 Compare August 20, 2024 14:59
@TheBlueMatt
Copy link
Collaborator Author

Rebased.

@TheBlueMatt TheBlueMatt force-pushed the 2024-06-robust-updates branch from d328d41 to 4f6a09c Compare October 1, 2024 16:48
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.
@TheBlueMatt TheBlueMatt force-pushed the 2024-06-robust-updates branch from 4f6a09c to e483e53 Compare October 1, 2024 16:49
Copy link
Contributor

@valentinewallace valentinewallace left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically LGTM

lightning/src/ln/peer_handler.rs Outdated Show resolved Hide resolved
@@ -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);
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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?

lightning/src/ln/peer_handler.rs Show resolved Hide resolved
@TheBlueMatt TheBlueMatt force-pushed the 2024-06-robust-updates branch from e483e53 to 116e369 Compare October 17, 2024 00:19
Copy link
Contributor

@valentinewallace valentinewallace left a 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`.
@TheBlueMatt
Copy link
Collaborator Author

Squashed.

@TheBlueMatt TheBlueMatt force-pushed the 2024-06-robust-updates branch from 116e369 to f4b2311 Compare October 17, 2024 19:09
}

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);
Copy link
Contributor

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?

Copy link
Collaborator Author

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);
Copy link
Contributor

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>>>,
Copy link
Contributor

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

Copy link
Collaborator Author

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 :)

@TheBlueMatt TheBlueMatt merged commit 3c868dd into lightningdevkit:main Oct 23, 2024
18 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants