-
Notifications
You must be signed in to change notification settings - Fork 418
Detect and fail-back monitor-blocked un-forwarded HTLCs at close #3989
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
Detect and fail-back monitor-blocked un-forwarded HTLCs at close #3989
Conversation
I've assigned @tankyleo as a reviewer! |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3989 +/- ##
==========================================
+ Coverage 88.97% 88.98% +0.01%
==========================================
Files 174 174
Lines 124161 124394 +233
Branches 124161 124394 +233
==========================================
+ Hits 110470 110693 +223
- Misses 11216 11219 +3
- Partials 2475 2482 +7
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:
|
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.
Quick first pass
👋 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. |
54fff98
to
34abcf6
Compare
If we have pending HTLCs which we intended to forward, but which were waiting on a `ChannelMonitorUpdate` to be forwarded when we closed, they will neither be in the `ChannelMonitor` nor in the `Channel` in a state which indicates they need to be failed (i.e. in the holding cell). As a result, we previously did not fail such HTLCs back immediately. Note that we cannot rely on the catch-all fail-back-before-channel-closure logic either as it is done by the `ChannelMonitor` that is unaware of these HTLCs. Here we fix this by detecting the specific case - HTLCs which are in `LocalSent` (i.e. the counterparty has not provided an RAA yet) and we have a blocked `ChannelMonitorUpdate` containing a remote commitment transaction update (which will always contain the HTLC). In such a case, we can be confident the counterparty does not have a commitment transaction containing the HTLC, and can fail it back immediately.
34abcf6
to
7c39480
Compare
Fixed handling the missing monitor update type: $ git diff-tree -U2 34abcf6603^1 7c394804b0
diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index 5a95295f8f..115b917649 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -5351,25 +5351,33 @@ where
for update in self.blocked_monitor_updates.iter() {
for update in update.update.updates.iter() {
- match update {
- ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo {
- htlc_outputs,
+ let have_htlc = match update {
+ ChannelMonitorUpdateStep::LatestCounterpartyCommitment {
+ htlc_data,
..
} => {
- let have_htlc = htlc_outputs.iter().any(|(_, source)| {
- source.as_ref().map(|s| &**s) == Some(&htlc.source)
- });
- debug_assert!(have_htlc);
- if have_htlc {
- dropped_outbound_htlcs.push((
- htlc.source.clone(),
- htlc.payment_hash,
- counterparty_node_id,
- self.channel_id,
- ));
- }
- continue 'htlc_iter;
+ let dust =
+ htlc_data.dust_htlcs.iter().map(|(_, source)| source.as_ref());
+ let nondust =
+ htlc_data.nondust_htlc_sources.iter().map(|s| Some(s));
+ dust.chain(nondust).any(|source| source == Some(&htlc.source))
},
- _ => {},
+ ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo {
+ htlc_outputs,
+ ..
+ } => htlc_outputs.iter().any(|(_, source)| {
+ source.as_ref().map(|s| &**s) == Some(&htlc.source)
+ }),
+ _ => continue,
+ };
+ debug_assert!(have_htlc);
+ if have_htlc {
+ dropped_outbound_htlcs.push((
+ htlc.source.clone(),
+ htlc.payment_hash,
+ counterparty_node_id,
+ self.channel_id,
+ ));
}
+ continue 'htlc_iter;
}
} |
If we have pending HTLCs which we intended to forward, but which were waiting on a
ChannelMonitorUpdate
to be forwarded when we closed, they will neither be in theChannelMonitor
nor in theChannel
in a state which indicates they need to be failed (i.e. in the holding cell). As a result, we previously did not fail such HTLCs back. Note that the catch-allfail-back-before-channel-closure logic is run by the ChannelMonitor so is also unaware of these HTLCs.
Here we fix this by detecting the specific case - HTLCs which are in
LocalSent
(i.e. the counterparty has not provided an RAA yet) and we have a blockedChannelMonitorUpdate
containing a remote commitment transaction update (which will always contain the HTLC).In such a case, we can be confident the counterparty does not have a commitment transaction containing the HTLC, and can fail it back immediately.