Fix async release before HTLC decode#4548
Fix async release before HTLC decode#4548valentinewallace wants to merge 1 commit intolightningdevkit:mainfrom
Conversation
|
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
|
After thoroughly reviewing every file and hunk in this PR, including tracing all race condition windows, lock ordering, and state machine transitions: Review SummaryNo new issues found beyond those already flagged in prior reviews. Prior comment status update
Architecture assessmentThe three-stage release in
The |
tnull
left a comment
There was a problem hiding this comment.
Mostly looks good, CI is just failing due to some broken doc links AFAICT.
Also validated this still works in conjunction with #4463 / for lightningdevkit/ldk-node#817.
| state: InboundHTLCState, | ||
| } | ||
|
|
||
| /// Result of [`FundedChannel::release_pending_inbound_held_htlc`]. |
There was a problem hiding this comment.
Might be worth adding some more rationale why this is even necessary? I.e. describing the race this fixes?
There was a problem hiding this comment.
Updated most of the docs, lmk your thoughts.
lightning/src/ln/channelmanager.rs
Outdated
| LocalHTLCFailureReason::TemporaryNodeFailure | ||
| ); | ||
| }, | ||
| // Check whether a ReleaseHeldHtlc arrived while the HTLC was in transit from channel |
There was a problem hiding this comment.
Also might be worth adding some more context here.
ae776b9 to
bd632fb
Compare
|
Addressed feedback with diff (plus an extra push for a whitespace fix). |
| pub(super) enum HeldHtlcReleaseResult { | ||
| /// `hold_htlc` was cleared. The release of the HTLC is fully handled. | ||
| Released, | ||
| /// The ChannelManager has already pulled a copy of this HTLC out of the Channel for processing, |
There was a problem hiding this comment.
nit:
| /// The ChannelManager has already pulled a copy of this HTLC out of the Channel for processing, | |
| /// The `ChannelManager` has already pulled a copy of this HTLC out of the `Channel` for processing, |
| Released, | ||
| /// The ChannelManager has already pulled a copy of this HTLC out of the Channel for processing, | ||
| /// but may not yet be persisting the HTLC in its internal state. This variant indicates that | ||
| /// we've cleared the `hold_htlc` flag in the Channel's cached version of the HTLC, which the |
There was a problem hiding this comment.
| /// we've cleared the `hold_htlc` flag in the Channel's cached version of the HTLC, which the | |
| /// we've cleared the `hold_htlc` flag in the `Channel`'s cached version of the HTLC, which the |
| /// The ChannelManager has already pulled a copy of this HTLC out of the Channel for processing, | ||
| /// but may not yet be persisting the HTLC in its internal state. This variant indicates that | ||
| /// we've cleared the `hold_htlc` flag in the Channel's cached version of the HTLC, which the | ||
| /// manager will re-check when it goes to actually forward in process_pending_htlc_forwards. |
There was a problem hiding this comment.
| /// manager will re-check when it goes to actually forward in process_pending_htlc_forwards. | |
| /// manager will re-check when it goes to actually forward in `process_pending_htlc_forwards`. |
| HeldHtlcReleaseResult::NotFound | ||
| } | ||
|
|
||
| /// Returns whether an inbound HTlC has the `hold_htlc` flag set. Useful if the Channel's copy of |
There was a problem hiding this comment.
| /// Returns whether an inbound HTlC has the `hold_htlc` flag set. Useful if the Channel's copy of | |
| /// Returns whether an inbound HTLC has the `hold_htlc` flag set. Useful if the `Channel`'s copy of |
| } | ||
|
|
||
| /// Returns whether an inbound HTlC has the `hold_htlc` flag set. Useful if the Channel's copy of | ||
| /// an HTLC was updated to be released but the ChannelManager's copy of the HTLC wasn't. |
There was a problem hiding this comment.
| /// an HTLC was updated to be released but the ChannelManager's copy of the HTLC wasn't. | |
| /// an HTLC was updated to be released but the `ChannelManager`'s copy of the HTLC wasn't. |
Handle `ReleaseHeldHtlc` messages that arrive before the sender-side LSP has even queued the held HTLC for onion decoding. Unlike lightningdevkit#4106, which covers releases arriving after the HTLC is in `decode_update_add_htlcs` but before it reaches `pending_intercepted_htlcs`, this preserves releases that arrive one step earlier and would otherwise be dropped as HTLC not found. Co-Authored-By: HAL 9000 Co-Authored-By: Elias Rohrer <dev@tnull.de>
bd632fb to
f764872
Compare
| HeldHtlcReleaseResult::NotFound | ||
| } | ||
|
|
||
| /// Returns whether an inbound HTlC has the `hold_htlc` flag set. Useful if the Channel's copy of |
There was a problem hiding this comment.
Nit: "HTlC" → "HTLC" (lowercase 'l').
| /// Returns whether an inbound HTlC has the `hold_htlc` flag set. Useful if the Channel's copy of | |
| /// Returns whether an inbound HTLC has the `hold_htlc` flag set. Useful if the Channel's copy of |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4548 +/- ##
=======================================
Coverage 86.99% 87.00%
=======================================
Files 163 163
Lines 108635 108720 +85
Branches 108635 108720 +85
=======================================
+ Hits 94511 94587 +76
- Misses 11647 11650 +3
- Partials 2477 2483 +6
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:
|
| ); | ||
| if pending_add.forward_info.routing.should_hold_htlc() { | ||
| let hold_htlc = if pending_add.forward_info.routing.should_hold_htlc() { | ||
| // Check whether a ReleaseHeldHtlc arrived after the manager pulled a copy of this |
There was a problem hiding this comment.
This feel like it should be fixed by taking an additional lock in handle_release_held_htlc rather than checking for it here?
There was a problem hiding this comment.
I don't believe so -- did you see this race condition? #4542 (comment) Maybe we don't support that kind of multithreaded usage anyway?
There was a problem hiding this comment.
Btw, if we try to acquire the decode_update_add_htlcs lock prior to taking the channel lock, which I think would fix a different race you may be pointing out here, it currently results in a lock order violation.
Handle
ReleaseHeldHtlcmessages that arrive before the sender-side LSP has even queued the held HTLC for onion decoding. Unlike #4106, which covers releases arriving after the HTLC is indecode_update_add_htlcsbut before it reachespending_intercepted_htlcs, this preserves releases that arrive one step earlier and would otherwise be dropped as HTLC not found.Supersedes #4542