-
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
Move in-flight ChannelMonitorUpdates to ChannelManager #2362
Move in-flight ChannelMonitorUpdates to ChannelManager #2362
Conversation
486a65e
to
f732734
Compare
Codecov ReportPatch coverage:
❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more. Additional details and impacted files@@ Coverage Diff @@
## main #2362 +/- ##
==========================================
- Coverage 90.30% 90.29% -0.02%
==========================================
Files 106 106
Lines 54747 54920 +173
Branches 54747 54920 +173
==========================================
+ Hits 49441 49591 +150
- Misses 5306 5329 +23
☔ 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.
Concept ACK. Just reviewing f52ed23 a bit more in-depth.
32a31af
to
3fe91e1
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. Can't see anything else glaringly wrong from my knowledge of monitor updates.
lightning/src/ln/channelmanager.rs
Outdated
// filter for uniqueness here. | ||
in_flight_updates.push($update); | ||
} | ||
let update_res = $self.chain_monitor.update_channel($funding_txo, in_flight_updates.last().unwrap()); |
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.
Isn't it only correct to call last()
if we actually pushed an update above?
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 mean if the vec contains something then it should also be safe?
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.
Isn't it possible that we've already called update_channel
with the last()
monitor update, though?
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.
Hmmmm, yea, maybe, I updated the code to handle it. We shouldn't be double-calling, but indeed I think there's maybe a case where we have two background updates to apply and we just apply the last()
twice.
3fe91e1
to
e721025
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.
Was mostly just absorbing the context here, nothing outstanding to comment on
In the coming commits we'll move to storing in-flight `ChannelMonitorUpdate`s in the `ChannelManager` rather in the `Channel` (which will then only retain `ChannelMonitorUpdate`s which have not yet been released/are blocked. This will simplify handling of pending `ChannelMonitorUpdate` after a channel has closed by not having to move them into the `ChannelManager`.
Most of the calls to the `handle_new_monitor_update` macro had the exact same pattern - calling `update_monitor` followed by the macro. Given that common pattern will grow to first pushing the new monitor onto an in-flight set and then calling `update_monitor` unifying the pattern into a single macro now avoids more code churn in the coming commits.
By giving up on a tiny bit of parallelism and tweaking the return types, we can make the `handle_new_monitor_update` macro a bit clearer - now the only cases where its called after a monitor was updated was when the monitor was initially committed.
e721025
to
2704bf3
Compare
Rebased. |
lightning/src/ln/channelmanager.rs
Outdated
// filter for uniqueness here. | ||
in_flight_updates.push($update); | ||
} | ||
let update_res = $self.chain_monitor.update_channel($funding_txo, in_flight_updates.last().unwrap()); |
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.
Isn't it possible that we've already called update_channel
with the last()
monitor update, though?
2704bf3
to
653c606
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 this.
653c606
to
d18668b
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.
Feel free to squash.
highest_applied_update_id, channel.get().context.get_latest_monitor_update_id()); | ||
let remaining_in_flight = | ||
if let Some(pending) = peer_state.in_flight_monitor_updates.get_mut(funding_txo) { | ||
pending.retain(|upd| upd.update_id > highest_applied_update_id); |
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 there are multiple updates in flight, would you call channel_monitor_updated
once after they're all done, or after each one is done? If the latter, and they complete out of order, it seems this doesn't work?
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.
Only after they're all done, this is implemented in ChainMonitor
. We should probably move to doing it per-update, but we previously didn't track the updates in-flight so couldn't.
d18668b
to
cd76e97
Compare
Fixed spelling and squashed: $ git diff-tree -U1 d18668b4 cd76e97c
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index 942998840..cff623caa 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -8399,3 +8399,3 @@ where
//
- // Because tha actual handling of the in-flight updates is the same, its macro'ized here:
+ // Because the actual handling of the in-flight updates is the same, it's macro'ized here:
let mut pending_background_events = Vec::new(); |
e089a40
cd76e97
to
e089a40
Compare
Oops, fixed one more bug @wpaulino pointed out that got introduced in one of the fixups: $ git diff-tree -U1 cd76e97c e089a404
diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index 36260f1d2..69a69e7a1 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -865,3 +865,3 @@ pub(super) struct ChannelContext<Signer: ChannelSigner> {
/// If we can't release a [`ChannelMonitorUpdate`] until some external action completes, we
- /// store it here and only release it to [`ChannelManager`] once it asks for it.
+ /// store it here and only release it to the `ChannelManager` once it asks for it.
blocked_monitor_updates: Vec<PendingChannelMonitorUpdate>,
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index cff623caa..f38c6c13d 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -1923,3 +1923,3 @@ macro_rules! handle_new_monitor_update {
{
- in_flight_updates.pop();
+ let _ = in_flight_updates.remove(idx);
if in_flight_updates.is_empty() && $chan.blocked_monitor_updates_pending() == 0 { |
Because `ChannelMonitorUpdate`s can be generated for a channel which is already closed, and must still be tracked through their completion, storing them in a `Channel` doesn't make sense - we'd have to have a redundant place to put them post-closure and handle both storage locations equivalently. Instead, here, we move to storing in-flight `ChannelMonitorUpdate`s to the `ChannelManager`, leaving blocked `ChannelMonitorUpdate`s in the `Channel` as they were.
Now that all `ChannelMonitorUpdate`s stored in `Channel` are blocked we don't need a bool to track it.
`Channel::get_latest_complete_monitor_update_id` no longer refers to complete updates, but rather ones which were passed to the `ChannelManager` and which the `CHannel` no longer knows about. Thus, we rename it `get_latest_unblocked_monitor_update_id`.
To differentiate between in-flight pending completion and blocked updates.
e089a40
to
9c3ad28
Compare
Grr, intermediate commit had intermediate state, had to shuffle around one line diff, but no total change: $ git diff-tree -U1 e089a404 9c3ad28f
$ |
Because
ChannelMonitorUpdate
s can be generated for achannel which is already closed, and must still be tracked
through their completion, storing them in a
Channel
doesn't make sense - we'd have to have a redundant place to
put them post-closure and handle both storage locations
equivalently.
Instead, here, we move to storing in-flight
ChannelMonitorUpdate
s to theChannelManager
, leavingblocked
ChannelMonitorUpdate
s in theChannel
as theywere.
This is the first (and largest) step towards #2168, and after this we're at least clear of the serialization-breaking parts, so could in theory cut a test version even without fully fixing 2168 (which needs fixing for 116 though).
Most of the work for #2317