-
Notifications
You must be signed in to change notification settings - Fork 421
Handle mon update completion actions even with update(s) is blocked #4236
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
base: main
Are you sure you want to change the base?
Handle mon update completion actions even with update(s) is blocked #4236
Conversation
|
👋 Thanks for assigning @valentinewallace as a reviewer! |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4236 +/- ##
=======================================
Coverage 89.32% 89.33%
=======================================
Files 180 180
Lines 138641 138714 +73
Branches 138641 138714 +73
=======================================
+ Hits 123844 123922 +78
+ Misses 12174 12167 -7
- Partials 2623 2625 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
d28804e to
6700e7c
Compare
If we complete a `ChannelMonitorUpdate` persistence but there are
blocked `ChannelMonitorUpdate`s in the channel, we'll skip all the
post-monitor-update logic entirely. While its correct that we can't
resume the channel (as it expected the monitor updates it generated
to complete, even if they ended up blocked), the post-update
actions are a `channelmanager.rs` concept - they cannot be tied to
blocked updates because `channelmanager.rs` doesn't even see
blocked updates.
This can lead to a channel getting stuck waiting on itself. In a
production environment, an LDK user saw a case where:
(a) an MPP payment was received over several channels, let's call
them A + B.
(b) channel B got into `AwaitingRAA` due to unrelated operations,
(c) the MPP payment was claimed, with async monitor updating,
(d) the `revoke_and_ack` we were waiting on was delivered, but the
resulting `ChannelMonitorUpdate` was blocked due to the
pending claim having inserted an RAA-blocking action,
(e) the preimage `ChannelMonitorUpdate` generated for channel B
completed persistence, which did nothing due to the blocked
`ChannelMonitorUpdate`.
(f) the `Event::PaymentClaimed` event was handled but it, too,
failed to unblock the channel.
Instead, here, we simply process post-update actions when an update
completes, even if there are pending blocked updates. We do not
fully unblock the channel, of course.
6700e7c to
eb5492f
Compare
wpaulino
left a comment
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
| let in_flight_updates = $peer_state.in_flight_monitor_updates.get(&chan_id); | ||
| assert!(in_flight_updates.map(|(_, updates)| updates.is_empty()).unwrap_or(true)); | ||
| assert_eq!($chan.blocked_monitor_updates_pending(), 0); | ||
| assert!($chan.is_awaiting_monitor_update()); |
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 comment above "Requires that $chan.blocked_monitor_updates_pending() == 0" is no longer true
|
👋 The first review has been submitted! Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer. |
valentinewallace
left a comment
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
| let (chan_4_update, _, chan_4_id, ..) = create_announced_chan_between_nodes(&nodes, 2, 3); | ||
| let chan_4_scid = chan_4_update.contents.short_channel_id; | ||
|
|
||
| let (mut route, paymnt_hash_1, preimage_1, payment_secret) = |
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.
nit: s/paymnt_hash_1/payment_hash_1
If we complete a
ChannelMonitorUpdatepersistence but there are blockedChannelMonitorUpdates in the channel, we'll skip all the post-monitor-update logic entirely. While its correct that we can't resume the channel (as it expected the monitor updates it generated to complete, even if they ended up blocked), the post-update actions are achannelmanager.rsconcept - they cannot be tied to blocked updates becausechannelmanager.rsdoesn't even see blocked updates.This can lead to a channel getting stuck waiting on itself. In a production environment, an LDK user saw a case where:
(a) an MPP payment was received over several channels, let's call
them A + B.
(b) channel B got into
AwaitingRAAdue to unrelated operations,(c) the MPP payment was claimed, with async monitor updating,
(d) the
revoke_and_ackwe were waiting on was delivered, but theresulting
ChannelMonitorUpdatewas blocked due to thepending claim having inserted an RAA-blocking action,
(e) the preimage
ChannelMonitorUpdategenerated for channel Bcompleted persistence, which did nothing due to the blocked
ChannelMonitorUpdate.(f) the
Event::PaymentClaimedevent was handled but it, too,failed to unblock the channel.
Instead, here, we simply process post-update actions when an update completes, even if there are pending blocked updates. We do not fully unblock the channel, of course.