Uh oh!
There was an error while loading. Please reload this page.
Move in-flight ChannelMonitorUpdates to ChannelManager - #2362
Conversation
Uh oh!
There was an error while loading. Please reload this page.
486a65e to
f732734CompareCodecov 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. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
32a31af to
3fe91e1Compare
dunxen
left a comment
There was a problem hiding this comment.
LGTM. Can't see anything else glaringly wrong from my knowledge of monitor updates.
| // 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.
Isn't it only correct to call last() if we actually pushed an update above?
There was a problem hiding this comment.
I mean if the vec contains something then it should also be safe?
There was a problem hiding this comment.
Isn't it possible that we've already called update_channel with the last() monitor update, though?
There was a problem hiding this comment.
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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
3fe91e1 to
e721025Compare
alecchendev
left a comment
There was a problem hiding this comment.
Was mostly just absorbing the context here, nothing outstanding to comment on
Uh oh!
There was an error while loading. Please reload this page.
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
2704bf3CompareTheBlueMatt
commented
Jun 21, 2023
Rebased. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| // 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.
Isn't it possible that we've already called update_channel with the last() monitor update, though?
2704bf3 to
653c606CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
653c606 to
d18668bCompare| 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.
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.
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.
Uh oh!
There was an error while loading. Please reload this page.
d18668b to
cd76e97CompareTheBlueMatt
commented
Jun 23, 2023
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(); |
e089a40cd76e97 to
e089a40CompareTheBlueMatt
commented
Jun 23, 2023
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
9c3ad28CompareGrr, intermediate commit had intermediate state, had to shuffle around one line diff, but no total change: $ git diff-tree -U1 e089a404 9c3ad28f
$ |
Because
ChannelMonitorUpdates can be generated for achannel which is already closed, and must still be tracked
through their completion, storing them in a
Channeldoesn'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
ChannelMonitorUpdates to theChannelManager, leavingblocked
ChannelMonitorUpdates in theChannelas 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