Skip to content

Re-claim forwarded HTLCs on startup - #2364

Merged
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay
Jul 10, 2023
Merged

Re-claim forwarded HTLCs on startup#2364
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay

Conversation

@TheBlueMatt

@TheBlueMattTheBlueMatt commented Jun 20, 2023

Copy link
Copy Markdown
Collaborator

Because ChannelMonitorUpdates can complete asynchronously and
out-of-order now, a commitment_signedChannelMonitorUpdate from
a downstream channel could complete prior to the preimage
ChannelMonitorUpdate on the upstream channel. In that case, we may
not get a update_fulfill_htlc replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.

Here we do this during the existing walk of the ChannelMonitor
preimages for closed channels.

This was originally a part of #2167 but got dropped as it was buggy. Its now been fixed. This should ideally go in 116 so that async users of 117 can safely downgrade, but if it doesn't make it that's somewhat okay.

Based on #2362.

@codecov-commenter

codecov-commenter commented Jun 20, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 79.22% and project coverage change: +0.11 🎉

Comparison is base (0f2c4c0) 90.32% compared to head (192c5d2) 90.43%.

❗ Current head 192c5d2 differs from pull request most recent head 9ce7e8e. Consider uploading reports for the commit 9ce7e8e to get more accurate results

❗ 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 #2364 +/- ##
==========================================
+ Coverage 90.32% 90.43% +0.11% 
==========================================
Files 106 106 Lines 54948 58208 +3260 Branches 54948 58208 +3260 ==========================================
+ Hits 49633 52642 +3009 - Misses 5315 5566 +251 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.42% <ø> (ø)
lightning/src/ln/channelmanager.rs89.70% <79.22%> (+3.44%)⬆️

... and 10 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

A few nits that came up in review to make the docs clearer, but not
anything super critical.
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 5259cd5 to 568e3f1CompareJune 27, 2023 14:36
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Rebased.

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks pretty good to me, just one comment

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +4766 to +4772
// Note that while its safe to use `ClosingMonitorUpdateRegeneratedOnStartup` here (the
// channel is already closed) we need to ultimately handle the monitor update
// completion action only after we've completed the monitor update. This is the only
// way to guarantee this update *will* be regenerated on startup (otherwise if this was
// from a forwarded HTLC the downstream preimage may be deleted before we claim
// upstream). Thus, we need to transition to some new `BackgroundEvent` type which will
// complete the monitor update completion action from `completion_action`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused with this comment - I'm confused why only handling the completion_action after completing the monitor update is the only way to guarantee regenerating this update on startup? I'm thinking the completion_action that's used for claiming a forwarded HTLC upstream is just emitting a PaymentForwarded event right (I'm just looking at where this is used in claim_funds_internal), why would doing that before waiting for the monitor update to complete possibly mean the downstream preimage may be deleted before claiming upstream?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an HTLC which is forwarded is claimed, first we receive the preimage from the outbound edge, and we store the preimage in that channel's monitor. Then, we go and store the preimage in the inbound edge's monitor as well when we go to claim upstream. In the rare case that the outbound edge not only completes the initial monitor update but also one further monitor update, we will remove the preimage from that monitor and call it a day. By that point, we must make sure that the inbound edge's monitor has been safely updated and the preimage is durably in the previous channel, that is what the completion action does - unblocks the downstream channel monitor so that it can be updated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay, that part makes sense, thanks.

Just checking, we only unblock the downstream channel monitor when handling a MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel where downstream_counterparty_and_funding_outpoint = Some(..) right?

I'm wondering, is this then talking about the case where we generate this BackgroundEvent::ClosingMonitorUpdateRegeneratedOnStartup on startup, but then because we immediately handle the completion_action (instead of having a different kind of BackgroundEvent that does the completion_action after the monitor update completed like the comment suggests), in the situation that claim_funds_from_hop is called with a completion_action that returns a monitor update completion action that would unblock the outbound channel monitor, we'd risk the outbound channel completing a further monitor update and deleting the preimage? But in its current state this is safe because right now we only hit this path with a completion_action that returns a monitor completion action that doesn't free up an outbound channel (downstream_counterparty_and_funding_outpoint = None)?

I think my main confusion is around which parts of the comment are talking about this specific code path versus generally within claim_funds_from_hop?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in its current state this is safe..

No, in the current state it is not safe. We need to fix this on both this (the during-startup) case and on the not-during-startup case, but in either case its possible we remove the preimage before its durably on the inbound edge.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace

Copy link
Copy Markdown
Contributor

CI sad, otherwise LGTM.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 192c5d2 to aabd35eCompareJuly 7, 2023 21:14
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Oops, background_events_processed_since_startup was test-only, I made it always-on.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from aabd35e to d3811cdCompareJuly 7, 2023 21:34
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes:

$ git diff-tree -U1 aabd35e7 d3811cd7
$ 

wpaulino
wpaulino previously approved these changes Jul 7, 2023
valentinewallace
valentinewallace previously approved these changes Jul 7, 2023
Because `ChannelMonitorUpdate`s can complete asynchronously and
out-of-order now, a `commitment_signed` `ChannelMonitorUpdate` from
a downstream channel could complete prior to the preimage
`ChannelMonitorUpdate` on the upstream channel. In that case, we may
not get a `update_fulfill_htlc` replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.
Here we do this during the existing walk of the `ChannelMonitor`
preimages for closed channels.
Now that we also use the "Closing" `BackgroundEvent` for
already-closed channels we need to rename it and tweak the docs.
@TheBlueMatt
TheBlueMatt dismissed stale reviews from valentinewallace and wpaulino via 9ce7e8eJuly 8, 2023 02:16
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from d3811cd to 9ce7e8eCompareJuly 8, 2023 02:16
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Grrr, I missed one cfg:

$ git diff-tree -U1 d3811cd7 9ce7e8e6
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index faed19407..398975c65 100644
--- a/lightning/src/ln/channelmanager.rs+++ b/lightning/src/ln/channelmanager.rs@@ -8888,3 +8888,2 @@ where
total_consistency_lock: RwLock::new(()),
- #[cfg(debug_assertions)]
background_events_processed_since_startup: AtomicBool::new(false),

@wpaulino
wpaulino merged commit dba3e8f into lightningdevkit:mainJul 10, 2023
Sharmalm added a commit to Sharmalm/rust-lightning that referenced this pull request Sep 23, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@TheBlueMatt@codecov-commenter@valentinewallace@dunxen@wpaulino@alecchendev
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Re-claim forwarded HTLCs on startup by TheBlueMatt · Pull Request #2364 · lightningdevkit/rust-lightning · GitHub
Skip to content

Re-claim forwarded HTLCs on startup - #2364

Merged
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay
Jul 10, 2023
Merged

Re-claim forwarded HTLCs on startup#2364
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay

Conversation

@TheBlueMatt

@TheBlueMattTheBlueMatt commented Jun 20, 2023

Copy link
Copy Markdown
Collaborator

Because ChannelMonitorUpdates can complete asynchronously and
out-of-order now, a commitment_signedChannelMonitorUpdate from
a downstream channel could complete prior to the preimage
ChannelMonitorUpdate on the upstream channel. In that case, we may
not get a update_fulfill_htlc replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.

Here we do this during the existing walk of the ChannelMonitor
preimages for closed channels.

This was originally a part of #2167 but got dropped as it was buggy. Its now been fixed. This should ideally go in 116 so that async users of 117 can safely downgrade, but if it doesn't make it that's somewhat okay.

Based on #2362.

@codecov-commenter

codecov-commenter commented Jun 20, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 79.22% and project coverage change: +0.11 🎉

Comparison is base (0f2c4c0) 90.32% compared to head (192c5d2) 90.43%.

❗ Current head 192c5d2 differs from pull request most recent head 9ce7e8e. Consider uploading reports for the commit 9ce7e8e to get more accurate results

❗ 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 #2364 +/- ##
==========================================
+ Coverage 90.32% 90.43% +0.11% 
==========================================
Files 106 106 Lines 54948 58208 +3260 Branches 54948 58208 +3260 ==========================================
+ Hits 49633 52642 +3009 - Misses 5315 5566 +251 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.42% <ø> (ø)
lightning/src/ln/channelmanager.rs89.70% <79.22%> (+3.44%)⬆️

... and 10 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

A few nits that came up in review to make the docs clearer, but not
anything super critical.
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 5259cd5 to 568e3f1CompareJune 27, 2023 14:36
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Rebased.

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks pretty good to me, just one comment

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +4766 to +4772
// Note that while its safe to use `ClosingMonitorUpdateRegeneratedOnStartup` here (the
// channel is already closed) we need to ultimately handle the monitor update
// completion action only after we've completed the monitor update. This is the only
// way to guarantee this update *will* be regenerated on startup (otherwise if this was
// from a forwarded HTLC the downstream preimage may be deleted before we claim
// upstream). Thus, we need to transition to some new `BackgroundEvent` type which will
// complete the monitor update completion action from `completion_action`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused with this comment - I'm confused why only handling the completion_action after completing the monitor update is the only way to guarantee regenerating this update on startup? I'm thinking the completion_action that's used for claiming a forwarded HTLC upstream is just emitting a PaymentForwarded event right (I'm just looking at where this is used in claim_funds_internal), why would doing that before waiting for the monitor update to complete possibly mean the downstream preimage may be deleted before claiming upstream?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an HTLC which is forwarded is claimed, first we receive the preimage from the outbound edge, and we store the preimage in that channel's monitor. Then, we go and store the preimage in the inbound edge's monitor as well when we go to claim upstream. In the rare case that the outbound edge not only completes the initial monitor update but also one further monitor update, we will remove the preimage from that monitor and call it a day. By that point, we must make sure that the inbound edge's monitor has been safely updated and the preimage is durably in the previous channel, that is what the completion action does - unblocks the downstream channel monitor so that it can be updated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay, that part makes sense, thanks.

Just checking, we only unblock the downstream channel monitor when handling a MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel where downstream_counterparty_and_funding_outpoint = Some(..) right?

I'm wondering, is this then talking about the case where we generate this BackgroundEvent::ClosingMonitorUpdateRegeneratedOnStartup on startup, but then because we immediately handle the completion_action (instead of having a different kind of BackgroundEvent that does the completion_action after the monitor update completed like the comment suggests), in the situation that claim_funds_from_hop is called with a completion_action that returns a monitor update completion action that would unblock the outbound channel monitor, we'd risk the outbound channel completing a further monitor update and deleting the preimage? But in its current state this is safe because right now we only hit this path with a completion_action that returns a monitor completion action that doesn't free up an outbound channel (downstream_counterparty_and_funding_outpoint = None)?

I think my main confusion is around which parts of the comment are talking about this specific code path versus generally within claim_funds_from_hop?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in its current state this is safe..

No, in the current state it is not safe. We need to fix this on both this (the during-startup) case and on the not-during-startup case, but in either case its possible we remove the preimage before its durably on the inbound edge.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace

Copy link
Copy Markdown
Contributor

CI sad, otherwise LGTM.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 192c5d2 to aabd35eCompareJuly 7, 2023 21:14
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Oops, background_events_processed_since_startup was test-only, I made it always-on.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from aabd35e to d3811cdCompareJuly 7, 2023 21:34
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes:

$ git diff-tree -U1 aabd35e7 d3811cd7
$ 

wpaulino
wpaulino previously approved these changes Jul 7, 2023
valentinewallace
valentinewallace previously approved these changes Jul 7, 2023
Because `ChannelMonitorUpdate`s can complete asynchronously and
out-of-order now, a `commitment_signed` `ChannelMonitorUpdate` from
a downstream channel could complete prior to the preimage
`ChannelMonitorUpdate` on the upstream channel. In that case, we may
not get a `update_fulfill_htlc` replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.
Here we do this during the existing walk of the `ChannelMonitor`
preimages for closed channels.
Now that we also use the "Closing" `BackgroundEvent` for
already-closed channels we need to rename it and tweak the docs.
@TheBlueMatt
TheBlueMatt dismissed stale reviews from valentinewallace and wpaulino via 9ce7e8eJuly 8, 2023 02:16
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from d3811cd to 9ce7e8eCompareJuly 8, 2023 02:16
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Grrr, I missed one cfg:

$ git diff-tree -U1 d3811cd7 9ce7e8e6
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index faed19407..398975c65 100644
--- a/lightning/src/ln/channelmanager.rs+++ b/lightning/src/ln/channelmanager.rs@@ -8888,3 +8888,2 @@ where
total_consistency_lock: RwLock::new(()),
- #[cfg(debug_assertions)]
background_events_processed_since_startup: AtomicBool::new(false),

@wpaulino
wpaulino merged commit dba3e8f into lightningdevkit:mainJul 10, 2023
Sharmalm added a commit to Sharmalm/rust-lightning that referenced this pull request Sep 23, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@TheBlueMatt@codecov-commenter@valentinewallace@dunxen@wpaulino@alecchendev
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Re-claim forwarded HTLCs on startup by TheBlueMatt · Pull Request #2364 · lightningdevkit/rust-lightning · GitHub
Skip to content

Re-claim forwarded HTLCs on startup - #2364

Merged
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay
Jul 10, 2023
Merged

Re-claim forwarded HTLCs on startup#2364
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay

Conversation

@TheBlueMatt

@TheBlueMattTheBlueMatt commented Jun 20, 2023

Copy link
Copy Markdown
Collaborator

Because ChannelMonitorUpdates can complete asynchronously and
out-of-order now, a commitment_signedChannelMonitorUpdate from
a downstream channel could complete prior to the preimage
ChannelMonitorUpdate on the upstream channel. In that case, we may
not get a update_fulfill_htlc replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.

Here we do this during the existing walk of the ChannelMonitor
preimages for closed channels.

This was originally a part of #2167 but got dropped as it was buggy. Its now been fixed. This should ideally go in 116 so that async users of 117 can safely downgrade, but if it doesn't make it that's somewhat okay.

Based on #2362.

@codecov-commenter

codecov-commenter commented Jun 20, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 79.22% and project coverage change: +0.11 🎉

Comparison is base (0f2c4c0) 90.32% compared to head (192c5d2) 90.43%.

❗ Current head 192c5d2 differs from pull request most recent head 9ce7e8e. Consider uploading reports for the commit 9ce7e8e to get more accurate results

❗ 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 #2364 +/- ##
==========================================
+ Coverage 90.32% 90.43% +0.11% 
==========================================
Files 106 106 Lines 54948 58208 +3260 Branches 54948 58208 +3260 ==========================================
+ Hits 49633 52642 +3009 - Misses 5315 5566 +251 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.42% <ø> (ø)
lightning/src/ln/channelmanager.rs89.70% <79.22%> (+3.44%)⬆️

... and 10 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

A few nits that came up in review to make the docs clearer, but not
anything super critical.
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 5259cd5 to 568e3f1CompareJune 27, 2023 14:36
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Rebased.

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks pretty good to me, just one comment

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +4766 to +4772
// Note that while its safe to use `ClosingMonitorUpdateRegeneratedOnStartup` here (the
// channel is already closed) we need to ultimately handle the monitor update
// completion action only after we've completed the monitor update. This is the only
// way to guarantee this update *will* be regenerated on startup (otherwise if this was
// from a forwarded HTLC the downstream preimage may be deleted before we claim
// upstream). Thus, we need to transition to some new `BackgroundEvent` type which will
// complete the monitor update completion action from `completion_action`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused with this comment - I'm confused why only handling the completion_action after completing the monitor update is the only way to guarantee regenerating this update on startup? I'm thinking the completion_action that's used for claiming a forwarded HTLC upstream is just emitting a PaymentForwarded event right (I'm just looking at where this is used in claim_funds_internal), why would doing that before waiting for the monitor update to complete possibly mean the downstream preimage may be deleted before claiming upstream?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an HTLC which is forwarded is claimed, first we receive the preimage from the outbound edge, and we store the preimage in that channel's monitor. Then, we go and store the preimage in the inbound edge's monitor as well when we go to claim upstream. In the rare case that the outbound edge not only completes the initial monitor update but also one further monitor update, we will remove the preimage from that monitor and call it a day. By that point, we must make sure that the inbound edge's monitor has been safely updated and the preimage is durably in the previous channel, that is what the completion action does - unblocks the downstream channel monitor so that it can be updated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay, that part makes sense, thanks.

Just checking, we only unblock the downstream channel monitor when handling a MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel where downstream_counterparty_and_funding_outpoint = Some(..) right?

I'm wondering, is this then talking about the case where we generate this BackgroundEvent::ClosingMonitorUpdateRegeneratedOnStartup on startup, but then because we immediately handle the completion_action (instead of having a different kind of BackgroundEvent that does the completion_action after the monitor update completed like the comment suggests), in the situation that claim_funds_from_hop is called with a completion_action that returns a monitor update completion action that would unblock the outbound channel monitor, we'd risk the outbound channel completing a further monitor update and deleting the preimage? But in its current state this is safe because right now we only hit this path with a completion_action that returns a monitor completion action that doesn't free up an outbound channel (downstream_counterparty_and_funding_outpoint = None)?

I think my main confusion is around which parts of the comment are talking about this specific code path versus generally within claim_funds_from_hop?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in its current state this is safe..

No, in the current state it is not safe. We need to fix this on both this (the during-startup) case and on the not-during-startup case, but in either case its possible we remove the preimage before its durably on the inbound edge.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace

Copy link
Copy Markdown
Contributor

CI sad, otherwise LGTM.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 192c5d2 to aabd35eCompareJuly 7, 2023 21:14
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Oops, background_events_processed_since_startup was test-only, I made it always-on.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from aabd35e to d3811cdCompareJuly 7, 2023 21:34
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes:

$ git diff-tree -U1 aabd35e7 d3811cd7
$ 

wpaulino
wpaulino previously approved these changes Jul 7, 2023
valentinewallace
valentinewallace previously approved these changes Jul 7, 2023
Because `ChannelMonitorUpdate`s can complete asynchronously and
out-of-order now, a `commitment_signed` `ChannelMonitorUpdate` from
a downstream channel could complete prior to the preimage
`ChannelMonitorUpdate` on the upstream channel. In that case, we may
not get a `update_fulfill_htlc` replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.
Here we do this during the existing walk of the `ChannelMonitor`
preimages for closed channels.
Now that we also use the "Closing" `BackgroundEvent` for
already-closed channels we need to rename it and tweak the docs.
@TheBlueMatt
TheBlueMatt dismissed stale reviews from valentinewallace and wpaulino via 9ce7e8eJuly 8, 2023 02:16
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from d3811cd to 9ce7e8eCompareJuly 8, 2023 02:16
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Grrr, I missed one cfg:

$ git diff-tree -U1 d3811cd7 9ce7e8e6
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index faed19407..398975c65 100644
--- a/lightning/src/ln/channelmanager.rs+++ b/lightning/src/ln/channelmanager.rs@@ -8888,3 +8888,2 @@ where
total_consistency_lock: RwLock::new(()),
- #[cfg(debug_assertions)]
background_events_processed_since_startup: AtomicBool::new(false),

@wpaulino
wpaulino merged commit dba3e8f into lightningdevkit:mainJul 10, 2023
Sharmalm added a commit to Sharmalm/rust-lightning that referenced this pull request Sep 23, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@TheBlueMatt@codecov-commenter@valentinewallace@dunxen@wpaulino@alecchendev
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Re-claim forwarded HTLCs on startup by TheBlueMatt · Pull Request #2364 · lightningdevkit/rust-lightning · GitHub
Skip to content

Re-claim forwarded HTLCs on startup - #2364

Merged
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay
Jul 10, 2023
Merged

Re-claim forwarded HTLCs on startup#2364
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay

Conversation

@TheBlueMatt

@TheBlueMattTheBlueMatt commented Jun 20, 2023

Copy link
Copy Markdown
Collaborator

Because ChannelMonitorUpdates can complete asynchronously and
out-of-order now, a commitment_signedChannelMonitorUpdate from
a downstream channel could complete prior to the preimage
ChannelMonitorUpdate on the upstream channel. In that case, we may
not get a update_fulfill_htlc replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.

Here we do this during the existing walk of the ChannelMonitor
preimages for closed channels.

This was originally a part of #2167 but got dropped as it was buggy. Its now been fixed. This should ideally go in 116 so that async users of 117 can safely downgrade, but if it doesn't make it that's somewhat okay.

Based on #2362.

@codecov-commenter

codecov-commenter commented Jun 20, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 79.22% and project coverage change: +0.11 🎉

Comparison is base (0f2c4c0) 90.32% compared to head (192c5d2) 90.43%.

❗ Current head 192c5d2 differs from pull request most recent head 9ce7e8e. Consider uploading reports for the commit 9ce7e8e to get more accurate results

❗ 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 #2364 +/- ##
==========================================
+ Coverage 90.32% 90.43% +0.11% 
==========================================
Files 106 106 Lines 54948 58208 +3260 Branches 54948 58208 +3260 ==========================================
+ Hits 49633 52642 +3009 - Misses 5315 5566 +251 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.42% <ø> (ø)
lightning/src/ln/channelmanager.rs89.70% <79.22%> (+3.44%)⬆️

... and 10 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

A few nits that came up in review to make the docs clearer, but not
anything super critical.
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 5259cd5 to 568e3f1CompareJune 27, 2023 14:36
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Rebased.

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks pretty good to me, just one comment

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +4766 to +4772
// Note that while its safe to use `ClosingMonitorUpdateRegeneratedOnStartup` here (the
// channel is already closed) we need to ultimately handle the monitor update
// completion action only after we've completed the monitor update. This is the only
// way to guarantee this update *will* be regenerated on startup (otherwise if this was
// from a forwarded HTLC the downstream preimage may be deleted before we claim
// upstream). Thus, we need to transition to some new `BackgroundEvent` type which will
// complete the monitor update completion action from `completion_action`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused with this comment - I'm confused why only handling the completion_action after completing the monitor update is the only way to guarantee regenerating this update on startup? I'm thinking the completion_action that's used for claiming a forwarded HTLC upstream is just emitting a PaymentForwarded event right (I'm just looking at where this is used in claim_funds_internal), why would doing that before waiting for the monitor update to complete possibly mean the downstream preimage may be deleted before claiming upstream?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an HTLC which is forwarded is claimed, first we receive the preimage from the outbound edge, and we store the preimage in that channel's monitor. Then, we go and store the preimage in the inbound edge's monitor as well when we go to claim upstream. In the rare case that the outbound edge not only completes the initial monitor update but also one further monitor update, we will remove the preimage from that monitor and call it a day. By that point, we must make sure that the inbound edge's monitor has been safely updated and the preimage is durably in the previous channel, that is what the completion action does - unblocks the downstream channel monitor so that it can be updated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay, that part makes sense, thanks.

Just checking, we only unblock the downstream channel monitor when handling a MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel where downstream_counterparty_and_funding_outpoint = Some(..) right?

I'm wondering, is this then talking about the case where we generate this BackgroundEvent::ClosingMonitorUpdateRegeneratedOnStartup on startup, but then because we immediately handle the completion_action (instead of having a different kind of BackgroundEvent that does the completion_action after the monitor update completed like the comment suggests), in the situation that claim_funds_from_hop is called with a completion_action that returns a monitor update completion action that would unblock the outbound channel monitor, we'd risk the outbound channel completing a further monitor update and deleting the preimage? But in its current state this is safe because right now we only hit this path with a completion_action that returns a monitor completion action that doesn't free up an outbound channel (downstream_counterparty_and_funding_outpoint = None)?

I think my main confusion is around which parts of the comment are talking about this specific code path versus generally within claim_funds_from_hop?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in its current state this is safe..

No, in the current state it is not safe. We need to fix this on both this (the during-startup) case and on the not-during-startup case, but in either case its possible we remove the preimage before its durably on the inbound edge.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace

Copy link
Copy Markdown
Contributor

CI sad, otherwise LGTM.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 192c5d2 to aabd35eCompareJuly 7, 2023 21:14
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Oops, background_events_processed_since_startup was test-only, I made it always-on.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from aabd35e to d3811cdCompareJuly 7, 2023 21:34
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes:

$ git diff-tree -U1 aabd35e7 d3811cd7
$ 

wpaulino
wpaulino previously approved these changes Jul 7, 2023
valentinewallace
valentinewallace previously approved these changes Jul 7, 2023
Because `ChannelMonitorUpdate`s can complete asynchronously and
out-of-order now, a `commitment_signed` `ChannelMonitorUpdate` from
a downstream channel could complete prior to the preimage
`ChannelMonitorUpdate` on the upstream channel. In that case, we may
not get a `update_fulfill_htlc` replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.
Here we do this during the existing walk of the `ChannelMonitor`
preimages for closed channels.
Now that we also use the "Closing" `BackgroundEvent` for
already-closed channels we need to rename it and tweak the docs.
@TheBlueMatt
TheBlueMatt dismissed stale reviews from valentinewallace and wpaulino via 9ce7e8eJuly 8, 2023 02:16
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from d3811cd to 9ce7e8eCompareJuly 8, 2023 02:16
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Grrr, I missed one cfg:

$ git diff-tree -U1 d3811cd7 9ce7e8e6
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index faed19407..398975c65 100644
--- a/lightning/src/ln/channelmanager.rs+++ b/lightning/src/ln/channelmanager.rs@@ -8888,3 +8888,2 @@ where
total_consistency_lock: RwLock::new(()),
- #[cfg(debug_assertions)]
background_events_processed_since_startup: AtomicBool::new(false),

@wpaulino
wpaulino merged commit dba3e8f into lightningdevkit:mainJul 10, 2023
Sharmalm added a commit to Sharmalm/rust-lightning that referenced this pull request Sep 23, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@TheBlueMatt@codecov-commenter@valentinewallace@dunxen@wpaulino@alecchendev
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Re-claim forwarded HTLCs on startup by TheBlueMatt · Pull Request #2364 · lightningdevkit/rust-lightning · GitHub
Skip to content

Re-claim forwarded HTLCs on startup - #2364

Merged
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay
Jul 10, 2023
Merged

Re-claim forwarded HTLCs on startup#2364
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay

Conversation

@TheBlueMatt

@TheBlueMattTheBlueMatt commented Jun 20, 2023

Copy link
Copy Markdown
Collaborator

Because ChannelMonitorUpdates can complete asynchronously and
out-of-order now, a commitment_signedChannelMonitorUpdate from
a downstream channel could complete prior to the preimage
ChannelMonitorUpdate on the upstream channel. In that case, we may
not get a update_fulfill_htlc replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.

Here we do this during the existing walk of the ChannelMonitor
preimages for closed channels.

This was originally a part of #2167 but got dropped as it was buggy. Its now been fixed. This should ideally go in 116 so that async users of 117 can safely downgrade, but if it doesn't make it that's somewhat okay.

Based on #2362.

@codecov-commenter

codecov-commenter commented Jun 20, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 79.22% and project coverage change: +0.11 🎉

Comparison is base (0f2c4c0) 90.32% compared to head (192c5d2) 90.43%.

❗ Current head 192c5d2 differs from pull request most recent head 9ce7e8e. Consider uploading reports for the commit 9ce7e8e to get more accurate results

❗ 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 #2364 +/- ##
==========================================
+ Coverage 90.32% 90.43% +0.11% 
==========================================
Files 106 106 Lines 54948 58208 +3260 Branches 54948 58208 +3260 ==========================================
+ Hits 49633 52642 +3009 - Misses 5315 5566 +251 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.42% <ø> (ø)
lightning/src/ln/channelmanager.rs89.70% <79.22%> (+3.44%)⬆️

... and 10 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

A few nits that came up in review to make the docs clearer, but not
anything super critical.
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 5259cd5 to 568e3f1CompareJune 27, 2023 14:36
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Rebased.

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks pretty good to me, just one comment

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +4766 to +4772
// Note that while its safe to use `ClosingMonitorUpdateRegeneratedOnStartup` here (the
// channel is already closed) we need to ultimately handle the monitor update
// completion action only after we've completed the monitor update. This is the only
// way to guarantee this update *will* be regenerated on startup (otherwise if this was
// from a forwarded HTLC the downstream preimage may be deleted before we claim
// upstream). Thus, we need to transition to some new `BackgroundEvent` type which will
// complete the monitor update completion action from `completion_action`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused with this comment - I'm confused why only handling the completion_action after completing the monitor update is the only way to guarantee regenerating this update on startup? I'm thinking the completion_action that's used for claiming a forwarded HTLC upstream is just emitting a PaymentForwarded event right (I'm just looking at where this is used in claim_funds_internal), why would doing that before waiting for the monitor update to complete possibly mean the downstream preimage may be deleted before claiming upstream?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an HTLC which is forwarded is claimed, first we receive the preimage from the outbound edge, and we store the preimage in that channel's monitor. Then, we go and store the preimage in the inbound edge's monitor as well when we go to claim upstream. In the rare case that the outbound edge not only completes the initial monitor update but also one further monitor update, we will remove the preimage from that monitor and call it a day. By that point, we must make sure that the inbound edge's monitor has been safely updated and the preimage is durably in the previous channel, that is what the completion action does - unblocks the downstream channel monitor so that it can be updated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay, that part makes sense, thanks.

Just checking, we only unblock the downstream channel monitor when handling a MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel where downstream_counterparty_and_funding_outpoint = Some(..) right?

I'm wondering, is this then talking about the case where we generate this BackgroundEvent::ClosingMonitorUpdateRegeneratedOnStartup on startup, but then because we immediately handle the completion_action (instead of having a different kind of BackgroundEvent that does the completion_action after the monitor update completed like the comment suggests), in the situation that claim_funds_from_hop is called with a completion_action that returns a monitor update completion action that would unblock the outbound channel monitor, we'd risk the outbound channel completing a further monitor update and deleting the preimage? But in its current state this is safe because right now we only hit this path with a completion_action that returns a monitor completion action that doesn't free up an outbound channel (downstream_counterparty_and_funding_outpoint = None)?

I think my main confusion is around which parts of the comment are talking about this specific code path versus generally within claim_funds_from_hop?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in its current state this is safe..

No, in the current state it is not safe. We need to fix this on both this (the during-startup) case and on the not-during-startup case, but in either case its possible we remove the preimage before its durably on the inbound edge.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace

Copy link
Copy Markdown
Contributor

CI sad, otherwise LGTM.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 192c5d2 to aabd35eCompareJuly 7, 2023 21:14
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Oops, background_events_processed_since_startup was test-only, I made it always-on.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from aabd35e to d3811cdCompareJuly 7, 2023 21:34
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes:

$ git diff-tree -U1 aabd35e7 d3811cd7
$ 

wpaulino
wpaulino previously approved these changes Jul 7, 2023
valentinewallace
valentinewallace previously approved these changes Jul 7, 2023
Because `ChannelMonitorUpdate`s can complete asynchronously and
out-of-order now, a `commitment_signed` `ChannelMonitorUpdate` from
a downstream channel could complete prior to the preimage
`ChannelMonitorUpdate` on the upstream channel. In that case, we may
not get a `update_fulfill_htlc` replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.
Here we do this during the existing walk of the `ChannelMonitor`
preimages for closed channels.
Now that we also use the "Closing" `BackgroundEvent` for
already-closed channels we need to rename it and tweak the docs.
@TheBlueMatt
TheBlueMatt dismissed stale reviews from valentinewallace and wpaulino via 9ce7e8eJuly 8, 2023 02:16
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from d3811cd to 9ce7e8eCompareJuly 8, 2023 02:16
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Grrr, I missed one cfg:

$ git diff-tree -U1 d3811cd7 9ce7e8e6
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index faed19407..398975c65 100644
--- a/lightning/src/ln/channelmanager.rs+++ b/lightning/src/ln/channelmanager.rs@@ -8888,3 +8888,2 @@ where
total_consistency_lock: RwLock::new(()),
- #[cfg(debug_assertions)]
background_events_processed_since_startup: AtomicBool::new(false),

@wpaulino
wpaulino merged commit dba3e8f into lightningdevkit:mainJul 10, 2023
Sharmalm added a commit to Sharmalm/rust-lightning that referenced this pull request Sep 23, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@TheBlueMatt@codecov-commenter@valentinewallace@dunxen@wpaulino@alecchendev
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Re-claim forwarded HTLCs on startup by TheBlueMatt · Pull Request #2364 · lightningdevkit/rust-lightning · GitHub
Skip to content

Re-claim forwarded HTLCs on startup - #2364

Merged
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay
Jul 10, 2023
Merged

Re-claim forwarded HTLCs on startup#2364
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay

Conversation

@TheBlueMatt

@TheBlueMattTheBlueMatt commented Jun 20, 2023

Copy link
Copy Markdown
Collaborator

Because ChannelMonitorUpdates can complete asynchronously and
out-of-order now, a commitment_signedChannelMonitorUpdate from
a downstream channel could complete prior to the preimage
ChannelMonitorUpdate on the upstream channel. In that case, we may
not get a update_fulfill_htlc replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.

Here we do this during the existing walk of the ChannelMonitor
preimages for closed channels.

This was originally a part of #2167 but got dropped as it was buggy. Its now been fixed. This should ideally go in 116 so that async users of 117 can safely downgrade, but if it doesn't make it that's somewhat okay.

Based on #2362.

@codecov-commenter

codecov-commenter commented Jun 20, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 79.22% and project coverage change: +0.11 🎉

Comparison is base (0f2c4c0) 90.32% compared to head (192c5d2) 90.43%.

❗ Current head 192c5d2 differs from pull request most recent head 9ce7e8e. Consider uploading reports for the commit 9ce7e8e to get more accurate results

❗ 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 #2364 +/- ##
==========================================
+ Coverage 90.32% 90.43% +0.11% 
==========================================
Files 106 106 Lines 54948 58208 +3260 Branches 54948 58208 +3260 ==========================================
+ Hits 49633 52642 +3009 - Misses 5315 5566 +251 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.42% <ø> (ø)
lightning/src/ln/channelmanager.rs89.70% <79.22%> (+3.44%)⬆️

... and 10 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

A few nits that came up in review to make the docs clearer, but not
anything super critical.
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 5259cd5 to 568e3f1CompareJune 27, 2023 14:36
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Rebased.

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks pretty good to me, just one comment

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +4766 to +4772
// Note that while its safe to use `ClosingMonitorUpdateRegeneratedOnStartup` here (the
// channel is already closed) we need to ultimately handle the monitor update
// completion action only after we've completed the monitor update. This is the only
// way to guarantee this update *will* be regenerated on startup (otherwise if this was
// from a forwarded HTLC the downstream preimage may be deleted before we claim
// upstream). Thus, we need to transition to some new `BackgroundEvent` type which will
// complete the monitor update completion action from `completion_action`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused with this comment - I'm confused why only handling the completion_action after completing the monitor update is the only way to guarantee regenerating this update on startup? I'm thinking the completion_action that's used for claiming a forwarded HTLC upstream is just emitting a PaymentForwarded event right (I'm just looking at where this is used in claim_funds_internal), why would doing that before waiting for the monitor update to complete possibly mean the downstream preimage may be deleted before claiming upstream?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an HTLC which is forwarded is claimed, first we receive the preimage from the outbound edge, and we store the preimage in that channel's monitor. Then, we go and store the preimage in the inbound edge's monitor as well when we go to claim upstream. In the rare case that the outbound edge not only completes the initial monitor update but also one further monitor update, we will remove the preimage from that monitor and call it a day. By that point, we must make sure that the inbound edge's monitor has been safely updated and the preimage is durably in the previous channel, that is what the completion action does - unblocks the downstream channel monitor so that it can be updated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay, that part makes sense, thanks.

Just checking, we only unblock the downstream channel monitor when handling a MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel where downstream_counterparty_and_funding_outpoint = Some(..) right?

I'm wondering, is this then talking about the case where we generate this BackgroundEvent::ClosingMonitorUpdateRegeneratedOnStartup on startup, but then because we immediately handle the completion_action (instead of having a different kind of BackgroundEvent that does the completion_action after the monitor update completed like the comment suggests), in the situation that claim_funds_from_hop is called with a completion_action that returns a monitor update completion action that would unblock the outbound channel monitor, we'd risk the outbound channel completing a further monitor update and deleting the preimage? But in its current state this is safe because right now we only hit this path with a completion_action that returns a monitor completion action that doesn't free up an outbound channel (downstream_counterparty_and_funding_outpoint = None)?

I think my main confusion is around which parts of the comment are talking about this specific code path versus generally within claim_funds_from_hop?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in its current state this is safe..

No, in the current state it is not safe. We need to fix this on both this (the during-startup) case and on the not-during-startup case, but in either case its possible we remove the preimage before its durably on the inbound edge.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace

Copy link
Copy Markdown
Contributor

CI sad, otherwise LGTM.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 192c5d2 to aabd35eCompareJuly 7, 2023 21:14
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Oops, background_events_processed_since_startup was test-only, I made it always-on.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from aabd35e to d3811cdCompareJuly 7, 2023 21:34
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes:

$ git diff-tree -U1 aabd35e7 d3811cd7
$ 

wpaulino
wpaulino previously approved these changes Jul 7, 2023
valentinewallace
valentinewallace previously approved these changes Jul 7, 2023
Because `ChannelMonitorUpdate`s can complete asynchronously and
out-of-order now, a `commitment_signed` `ChannelMonitorUpdate` from
a downstream channel could complete prior to the preimage
`ChannelMonitorUpdate` on the upstream channel. In that case, we may
not get a `update_fulfill_htlc` replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.
Here we do this during the existing walk of the `ChannelMonitor`
preimages for closed channels.
Now that we also use the "Closing" `BackgroundEvent` for
already-closed channels we need to rename it and tweak the docs.
@TheBlueMatt
TheBlueMatt dismissed stale reviews from valentinewallace and wpaulino via 9ce7e8eJuly 8, 2023 02:16
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from d3811cd to 9ce7e8eCompareJuly 8, 2023 02:16
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Grrr, I missed one cfg:

$ git diff-tree -U1 d3811cd7 9ce7e8e6
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index faed19407..398975c65 100644
--- a/lightning/src/ln/channelmanager.rs+++ b/lightning/src/ln/channelmanager.rs@@ -8888,3 +8888,2 @@ where
total_consistency_lock: RwLock::new(()),
- #[cfg(debug_assertions)]
background_events_processed_since_startup: AtomicBool::new(false),

@wpaulino
wpaulino merged commit dba3e8f into lightningdevkit:mainJul 10, 2023
Sharmalm added a commit to Sharmalm/rust-lightning that referenced this pull request Sep 23, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@TheBlueMatt@codecov-commenter@valentinewallace@dunxen@wpaulino@alecchendev
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Re-claim forwarded HTLCs on startup by TheBlueMatt · Pull Request #2364 · lightningdevkit/rust-lightning · GitHub
Skip to content

Re-claim forwarded HTLCs on startup - #2364

Merged
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay
Jul 10, 2023
Merged

Re-claim forwarded HTLCs on startup#2364
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay

Conversation

@TheBlueMatt

@TheBlueMattTheBlueMatt commented Jun 20, 2023

Copy link
Copy Markdown
Collaborator

Because ChannelMonitorUpdates can complete asynchronously and
out-of-order now, a commitment_signedChannelMonitorUpdate from
a downstream channel could complete prior to the preimage
ChannelMonitorUpdate on the upstream channel. In that case, we may
not get a update_fulfill_htlc replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.

Here we do this during the existing walk of the ChannelMonitor
preimages for closed channels.

This was originally a part of #2167 but got dropped as it was buggy. Its now been fixed. This should ideally go in 116 so that async users of 117 can safely downgrade, but if it doesn't make it that's somewhat okay.

Based on #2362.

@codecov-commenter

codecov-commenter commented Jun 20, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 79.22% and project coverage change: +0.11 🎉

Comparison is base (0f2c4c0) 90.32% compared to head (192c5d2) 90.43%.

❗ Current head 192c5d2 differs from pull request most recent head 9ce7e8e. Consider uploading reports for the commit 9ce7e8e to get more accurate results

❗ 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 #2364 +/- ##
==========================================
+ Coverage 90.32% 90.43% +0.11% 
==========================================
Files 106 106 Lines 54948 58208 +3260 Branches 54948 58208 +3260 ==========================================
+ Hits 49633 52642 +3009 - Misses 5315 5566 +251 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.42% <ø> (ø)
lightning/src/ln/channelmanager.rs89.70% <79.22%> (+3.44%)⬆️

... and 10 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

A few nits that came up in review to make the docs clearer, but not
anything super critical.
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 5259cd5 to 568e3f1CompareJune 27, 2023 14:36
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Rebased.

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks pretty good to me, just one comment

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +4766 to +4772
// Note that while its safe to use `ClosingMonitorUpdateRegeneratedOnStartup` here (the
// channel is already closed) we need to ultimately handle the monitor update
// completion action only after we've completed the monitor update. This is the only
// way to guarantee this update *will* be regenerated on startup (otherwise if this was
// from a forwarded HTLC the downstream preimage may be deleted before we claim
// upstream). Thus, we need to transition to some new `BackgroundEvent` type which will
// complete the monitor update completion action from `completion_action`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused with this comment - I'm confused why only handling the completion_action after completing the monitor update is the only way to guarantee regenerating this update on startup? I'm thinking the completion_action that's used for claiming a forwarded HTLC upstream is just emitting a PaymentForwarded event right (I'm just looking at where this is used in claim_funds_internal), why would doing that before waiting for the monitor update to complete possibly mean the downstream preimage may be deleted before claiming upstream?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an HTLC which is forwarded is claimed, first we receive the preimage from the outbound edge, and we store the preimage in that channel's monitor. Then, we go and store the preimage in the inbound edge's monitor as well when we go to claim upstream. In the rare case that the outbound edge not only completes the initial monitor update but also one further monitor update, we will remove the preimage from that monitor and call it a day. By that point, we must make sure that the inbound edge's monitor has been safely updated and the preimage is durably in the previous channel, that is what the completion action does - unblocks the downstream channel monitor so that it can be updated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay, that part makes sense, thanks.

Just checking, we only unblock the downstream channel monitor when handling a MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel where downstream_counterparty_and_funding_outpoint = Some(..) right?

I'm wondering, is this then talking about the case where we generate this BackgroundEvent::ClosingMonitorUpdateRegeneratedOnStartup on startup, but then because we immediately handle the completion_action (instead of having a different kind of BackgroundEvent that does the completion_action after the monitor update completed like the comment suggests), in the situation that claim_funds_from_hop is called with a completion_action that returns a monitor update completion action that would unblock the outbound channel monitor, we'd risk the outbound channel completing a further monitor update and deleting the preimage? But in its current state this is safe because right now we only hit this path with a completion_action that returns a monitor completion action that doesn't free up an outbound channel (downstream_counterparty_and_funding_outpoint = None)?

I think my main confusion is around which parts of the comment are talking about this specific code path versus generally within claim_funds_from_hop?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in its current state this is safe..

No, in the current state it is not safe. We need to fix this on both this (the during-startup) case and on the not-during-startup case, but in either case its possible we remove the preimage before its durably on the inbound edge.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace

Copy link
Copy Markdown
Contributor

CI sad, otherwise LGTM.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 192c5d2 to aabd35eCompareJuly 7, 2023 21:14
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Oops, background_events_processed_since_startup was test-only, I made it always-on.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from aabd35e to d3811cdCompareJuly 7, 2023 21:34
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes:

$ git diff-tree -U1 aabd35e7 d3811cd7
$ 

wpaulino
wpaulino previously approved these changes Jul 7, 2023
valentinewallace
valentinewallace previously approved these changes Jul 7, 2023
Because `ChannelMonitorUpdate`s can complete asynchronously and
out-of-order now, a `commitment_signed` `ChannelMonitorUpdate` from
a downstream channel could complete prior to the preimage
`ChannelMonitorUpdate` on the upstream channel. In that case, we may
not get a `update_fulfill_htlc` replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.
Here we do this during the existing walk of the `ChannelMonitor`
preimages for closed channels.
Now that we also use the "Closing" `BackgroundEvent` for
already-closed channels we need to rename it and tweak the docs.
@TheBlueMatt
TheBlueMatt dismissed stale reviews from valentinewallace and wpaulino via 9ce7e8eJuly 8, 2023 02:16
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from d3811cd to 9ce7e8eCompareJuly 8, 2023 02:16
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Grrr, I missed one cfg:

$ git diff-tree -U1 d3811cd7 9ce7e8e6
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index faed19407..398975c65 100644
--- a/lightning/src/ln/channelmanager.rs+++ b/lightning/src/ln/channelmanager.rs@@ -8888,3 +8888,2 @@ where
total_consistency_lock: RwLock::new(()),
- #[cfg(debug_assertions)]
background_events_processed_since_startup: AtomicBool::new(false),

@wpaulino
wpaulino merged commit dba3e8f into lightningdevkit:mainJul 10, 2023
Sharmalm added a commit to Sharmalm/rust-lightning that referenced this pull request Sep 23, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@TheBlueMatt@codecov-commenter@valentinewallace@dunxen@wpaulino@alecchendev
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Re-claim forwarded HTLCs on startup by TheBlueMatt · Pull Request #2364 · lightningdevkit/rust-lightning · GitHub
Skip to content

Re-claim forwarded HTLCs on startup - #2364

Merged
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay
Jul 10, 2023
Merged

Re-claim forwarded HTLCs on startup#2364
wpaulino merged 3 commits into
lightningdevkit:mainfrom
TheBlueMatt:2023-06-htlc-preimage-replay

Conversation

@TheBlueMatt

@TheBlueMattTheBlueMatt commented Jun 20, 2023

Copy link
Copy Markdown
Collaborator

Because ChannelMonitorUpdates can complete asynchronously and
out-of-order now, a commitment_signedChannelMonitorUpdate from
a downstream channel could complete prior to the preimage
ChannelMonitorUpdate on the upstream channel. In that case, we may
not get a update_fulfill_htlc replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.

Here we do this during the existing walk of the ChannelMonitor
preimages for closed channels.

This was originally a part of #2167 but got dropped as it was buggy. Its now been fixed. This should ideally go in 116 so that async users of 117 can safely downgrade, but if it doesn't make it that's somewhat okay.

Based on #2362.

@codecov-commenter

codecov-commenter commented Jun 20, 2023

Copy link
Copy Markdown

Codecov Report

Patch coverage: 79.22% and project coverage change: +0.11 🎉

Comparison is base (0f2c4c0) 90.32% compared to head (192c5d2) 90.43%.

❗ Current head 192c5d2 differs from pull request most recent head 9ce7e8e. Consider uploading reports for the commit 9ce7e8e to get more accurate results

❗ 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 #2364 +/- ##
==========================================
+ Coverage 90.32% 90.43% +0.11% 
==========================================
Files 106 106 Lines 54948 58208 +3260 Branches 54948 58208 +3260 ==========================================
+ Hits 49633 52642 +3009 - Misses 5315 5566 +251 
Impacted FilesCoverage Δ
lightning/src/ln/channel.rs89.42% <ø> (ø)
lightning/src/ln/channelmanager.rs89.70% <79.22%> (+3.44%)⬆️

... and 10 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

A few nits that came up in review to make the docs clearer, but not
anything super critical.
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 5259cd5 to 568e3f1CompareJune 27, 2023 14:36
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Rebased.

@alecchendevalecchendev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This generally looks pretty good to me, just one comment

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment on lines +4766 to +4772
// Note that while its safe to use `ClosingMonitorUpdateRegeneratedOnStartup` here (the
// channel is already closed) we need to ultimately handle the monitor update
// completion action only after we've completed the monitor update. This is the only
// way to guarantee this update *will* be regenerated on startup (otherwise if this was
// from a forwarded HTLC the downstream preimage may be deleted before we claim
// upstream). Thus, we need to transition to some new `BackgroundEvent` type which will
// complete the monitor update completion action from `completion_action`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused with this comment - I'm confused why only handling the completion_action after completing the monitor update is the only way to guarantee regenerating this update on startup? I'm thinking the completion_action that's used for claiming a forwarded HTLC upstream is just emitting a PaymentForwarded event right (I'm just looking at where this is used in claim_funds_internal), why would doing that before waiting for the monitor update to complete possibly mean the downstream preimage may be deleted before claiming upstream?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When an HTLC which is forwarded is claimed, first we receive the preimage from the outbound edge, and we store the preimage in that channel's monitor. Then, we go and store the preimage in the inbound edge's monitor as well when we go to claim upstream. In the rare case that the outbound edge not only completes the initial monitor update but also one further monitor update, we will remove the preimage from that monitor and call it a day. By that point, we must make sure that the inbound edge's monitor has been safely updated and the preimage is durably in the previous channel, that is what the completion action does - unblocks the downstream channel monitor so that it can be updated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay, that part makes sense, thanks.

Just checking, we only unblock the downstream channel monitor when handling a MonitorUpdateCompletionAction::EmitEventAndFreeOtherChannel where downstream_counterparty_and_funding_outpoint = Some(..) right?

I'm wondering, is this then talking about the case where we generate this BackgroundEvent::ClosingMonitorUpdateRegeneratedOnStartup on startup, but then because we immediately handle the completion_action (instead of having a different kind of BackgroundEvent that does the completion_action after the monitor update completed like the comment suggests), in the situation that claim_funds_from_hop is called with a completion_action that returns a monitor update completion action that would unblock the outbound channel monitor, we'd risk the outbound channel completing a further monitor update and deleting the preimage? But in its current state this is safe because right now we only hit this path with a completion_action that returns a monitor completion action that doesn't free up an outbound channel (downstream_counterparty_and_funding_outpoint = None)?

I think my main confusion is around which parts of the comment are talking about this specific code path versus generally within claim_funds_from_hop?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But in its current state this is safe..

No, in the current state it is not safe. We need to fix this on both this (the during-startup) case and on the not-during-startup case, but in either case its possible we remove the preimage before its durably on the inbound edge.

Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs
Comment threadlightning/src/ln/channelmanager.rs Outdated
@valentinewallace

Copy link
Copy Markdown
Contributor

CI sad, otherwise LGTM.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from 192c5d2 to aabd35eCompareJuly 7, 2023 21:14
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Oops, background_events_processed_since_startup was test-only, I made it always-on.

@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from aabd35e to d3811cdCompareJuly 7, 2023 21:34
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Squashed without further changes:

$ git diff-tree -U1 aabd35e7 d3811cd7
$ 

wpaulino
wpaulino previously approved these changes Jul 7, 2023
valentinewallace
valentinewallace previously approved these changes Jul 7, 2023
Because `ChannelMonitorUpdate`s can complete asynchronously and
out-of-order now, a `commitment_signed` `ChannelMonitorUpdate` from
a downstream channel could complete prior to the preimage
`ChannelMonitorUpdate` on the upstream channel. In that case, we may
not get a `update_fulfill_htlc` replay on startup. Thus, we have to
ensure any payment preimages contained in that downstream update are
re-claimed on startup.
Here we do this during the existing walk of the `ChannelMonitor`
preimages for closed channels.
Now that we also use the "Closing" `BackgroundEvent` for
already-closed channels we need to rename it and tweak the docs.
@TheBlueMatt
TheBlueMatt dismissed stale reviews from valentinewallace and wpaulino via 9ce7e8eJuly 8, 2023 02:16
@TheBlueMatt
TheBlueMattforce-pushed the 2023-06-htlc-preimage-replay branch from d3811cd to 9ce7e8eCompareJuly 8, 2023 02:16
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Grrr, I missed one cfg:

$ git diff-tree -U1 d3811cd7 9ce7e8e6
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index faed19407..398975c65 100644
--- a/lightning/src/ln/channelmanager.rs+++ b/lightning/src/ln/channelmanager.rs@@ -8888,3 +8888,2 @@ where
total_consistency_lock: RwLock::new(()),
- #[cfg(debug_assertions)]
background_events_processed_since_startup: AtomicBool::new(false),

@wpaulino
wpaulino merged commit dba3e8f into lightningdevkit:mainJul 10, 2023
Sharmalm added a commit to Sharmalm/rust-lightning that referenced this pull request Sep 23, 2023
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@TheBlueMatt@codecov-commenter@valentinewallace@dunxen@wpaulino@alecchendev