Skip to content

Follow-ups #3741: Exchange splice_locked messages - #3873

Merged
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes
Jun 20, 2025
Merged

Follow-ups #3741: Exchange splice_locked messages#3873
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Addresses remaining feedback from #3741.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 17, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattJune 17, 2025 22:42
Comment threadlightning/src/ln/channel.rs Outdated
let pending_splice = self.pending_splice.as_ref().unwrap();
let funding = self.pending_funding.get(confirmed_funding_index).unwrap();
if let Some(splice_locked) = self.check_get_splice_locked(pending_splice, funding, height) {
let pending_splice = self.pending_splice.as_mut().unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just DRY this up and do this in check_get_splice_locked so that we don't forget to do it at its callsites?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... a few reasons:

  • it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready
  • we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed
  • it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)

I made the change in a fixup to see what it looks like. However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope). Elsewhere, we get around this by passing confirmed_funding_index to maybe_promote_splice_funding. We'd likely need to do something similar, which is kinda meh. What do you think?

@TheBlueMattTheBlueMattJun 18, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready

Indeed, this is what we've done elsewhere, really the "get" part of the thing...Maybe a new name would make it clearer

we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed

Sure, but we can't be sure we ever send a message. Generally our message generators are treated as "this message has now been generated, it will be sent to our peer as the next message and if it doesn't make it we'll figure it out later and retransmit", so I think its still in line with what we do otherwise.

it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)
However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope).

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Yup, that's what the fixup does...

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

... though now we need to pass &ChannelContext. The future refactor will need to remove &FundingScope in favor of confirmed_funding_index because of the issue mentioned above.

Comment threadlightning/src/ln/channel.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 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.

@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from e0386ba to 8ea5689CompareJune 18, 2025 14:44
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 8ea5689 to e08c2ffCompareJune 18, 2025 16:50
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch 2 times, most recently from 1c0d324 to 061a02aCompareJune 18, 2025 17:08

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feel free to squash, looks fine to me.

jkczyz added 5 commits June 18, 2025 18:23
When sending splice_locked, set PendingSplice::sent_funding_txid prior
to calling FundedChannel::maybe_promote_splice_funding. This makes the
latter idempotent when the splice is not promoted. Otherwise, successive
calls could override the previously set sent_funding_txid.
This will help make the code more compact when using rustfmt.
Use of a macro as a function parameter prevented this method from being
formatted by rustfmt. Extract out a variable such is now can be.
When sending or receiving splice_locked results in promoting a
FundingScope, return the new funding_txo to ChannelManager. This is used
to determine if Event::ChannelReady should be emitted. This is deemed
safer than checking the channel if there are any pending splices after
it handles splice_locked or after checking funding confirmations.
The spec is being changed to keep around a channel_announcement when the
funding_txo is spent. This allows spliced channels more time to exchange
splice_locked messages before the channel is dropped from the network
graph. While LDK does not drop such channels, it uses this constant to
allow forwarding HTLCs over the channel using SCIDs from previous
funding transactions. Here, the increase from 12 to 144 reflects double
the spec change of 72 blocks.
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 061a02a to db69ec7CompareJune 18, 2025 23:23
@jkczyz
jkczyz requested a review from TheBlueMattJune 18, 2025 23:23
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.

4 participants

@jkczyz@ldk-reviews-bot@TheBlueMatt@wpaulino
, '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" + '
Follow-ups #3741: Exchange `splice_locked` messages by jkczyz · Pull Request #3873 · lightningdevkit/rust-lightning · GitHub
Skip to content

Follow-ups #3741: Exchange splice_locked messages - #3873

Merged
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes
Jun 20, 2025
Merged

Follow-ups #3741: Exchange splice_locked messages#3873
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Addresses remaining feedback from #3741.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 17, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattJune 17, 2025 22:42
Comment threadlightning/src/ln/channel.rs Outdated
let pending_splice = self.pending_splice.as_ref().unwrap();
let funding = self.pending_funding.get(confirmed_funding_index).unwrap();
if let Some(splice_locked) = self.check_get_splice_locked(pending_splice, funding, height) {
let pending_splice = self.pending_splice.as_mut().unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just DRY this up and do this in check_get_splice_locked so that we don't forget to do it at its callsites?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... a few reasons:

  • it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready
  • we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed
  • it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)

I made the change in a fixup to see what it looks like. However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope). Elsewhere, we get around this by passing confirmed_funding_index to maybe_promote_splice_funding. We'd likely need to do something similar, which is kinda meh. What do you think?

@TheBlueMattTheBlueMattJun 18, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready

Indeed, this is what we've done elsewhere, really the "get" part of the thing...Maybe a new name would make it clearer

we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed

Sure, but we can't be sure we ever send a message. Generally our message generators are treated as "this message has now been generated, it will be sent to our peer as the next message and if it doesn't make it we'll figure it out later and retransmit", so I think its still in line with what we do otherwise.

it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)
However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope).

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Yup, that's what the fixup does...

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

... though now we need to pass &ChannelContext. The future refactor will need to remove &FundingScope in favor of confirmed_funding_index because of the issue mentioned above.

Comment threadlightning/src/ln/channel.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 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.

@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from e0386ba to 8ea5689CompareJune 18, 2025 14:44
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 8ea5689 to e08c2ffCompareJune 18, 2025 16:50
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch 2 times, most recently from 1c0d324 to 061a02aCompareJune 18, 2025 17:08

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feel free to squash, looks fine to me.

jkczyz added 5 commits June 18, 2025 18:23
When sending splice_locked, set PendingSplice::sent_funding_txid prior
to calling FundedChannel::maybe_promote_splice_funding. This makes the
latter idempotent when the splice is not promoted. Otherwise, successive
calls could override the previously set sent_funding_txid.
This will help make the code more compact when using rustfmt.
Use of a macro as a function parameter prevented this method from being
formatted by rustfmt. Extract out a variable such is now can be.
When sending or receiving splice_locked results in promoting a
FundingScope, return the new funding_txo to ChannelManager. This is used
to determine if Event::ChannelReady should be emitted. This is deemed
safer than checking the channel if there are any pending splices after
it handles splice_locked or after checking funding confirmations.
The spec is being changed to keep around a channel_announcement when the
funding_txo is spent. This allows spliced channels more time to exchange
splice_locked messages before the channel is dropped from the network
graph. While LDK does not drop such channels, it uses this constant to
allow forwarding HTLCs over the channel using SCIDs from previous
funding transactions. Here, the increase from 12 to 144 reflects double
the spec change of 72 blocks.
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 061a02a to db69ec7CompareJune 18, 2025 23:23
@jkczyz
jkczyz requested a review from TheBlueMattJune 18, 2025 23:23
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.

4 participants

@jkczyz@ldk-reviews-bot@TheBlueMatt@wpaulino
, '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('^' + ".*" + ' Follow-ups #3741: Exchange `splice_locked` messages by jkczyz · Pull Request #3873 · lightningdevkit/rust-lightning · GitHub
Skip to content

Follow-ups #3741: Exchange splice_locked messages - #3873

Merged
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes
Jun 20, 2025
Merged

Follow-ups #3741: Exchange splice_locked messages#3873
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Addresses remaining feedback from #3741.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 17, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattJune 17, 2025 22:42
Comment threadlightning/src/ln/channel.rs Outdated
let pending_splice = self.pending_splice.as_ref().unwrap();
let funding = self.pending_funding.get(confirmed_funding_index).unwrap();
if let Some(splice_locked) = self.check_get_splice_locked(pending_splice, funding, height) {
let pending_splice = self.pending_splice.as_mut().unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just DRY this up and do this in check_get_splice_locked so that we don't forget to do it at its callsites?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... a few reasons:

  • it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready
  • we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed
  • it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)

I made the change in a fixup to see what it looks like. However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope). Elsewhere, we get around this by passing confirmed_funding_index to maybe_promote_splice_funding. We'd likely need to do something similar, which is kinda meh. What do you think?

@TheBlueMattTheBlueMattJun 18, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready

Indeed, this is what we've done elsewhere, really the "get" part of the thing...Maybe a new name would make it clearer

we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed

Sure, but we can't be sure we ever send a message. Generally our message generators are treated as "this message has now been generated, it will be sent to our peer as the next message and if it doesn't make it we'll figure it out later and retransmit", so I think its still in line with what we do otherwise.

it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)
However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope).

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Yup, that's what the fixup does...

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

... though now we need to pass &ChannelContext. The future refactor will need to remove &FundingScope in favor of confirmed_funding_index because of the issue mentioned above.

Comment threadlightning/src/ln/channel.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 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.

@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from e0386ba to 8ea5689CompareJune 18, 2025 14:44
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 8ea5689 to e08c2ffCompareJune 18, 2025 16:50
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch 2 times, most recently from 1c0d324 to 061a02aCompareJune 18, 2025 17:08

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feel free to squash, looks fine to me.

jkczyz added 5 commits June 18, 2025 18:23
When sending splice_locked, set PendingSplice::sent_funding_txid prior
to calling FundedChannel::maybe_promote_splice_funding. This makes the
latter idempotent when the splice is not promoted. Otherwise, successive
calls could override the previously set sent_funding_txid.
This will help make the code more compact when using rustfmt.
Use of a macro as a function parameter prevented this method from being
formatted by rustfmt. Extract out a variable such is now can be.
When sending or receiving splice_locked results in promoting a
FundingScope, return the new funding_txo to ChannelManager. This is used
to determine if Event::ChannelReady should be emitted. This is deemed
safer than checking the channel if there are any pending splices after
it handles splice_locked or after checking funding confirmations.
The spec is being changed to keep around a channel_announcement when the
funding_txo is spent. This allows spliced channels more time to exchange
splice_locked messages before the channel is dropped from the network
graph. While LDK does not drop such channels, it uses this constant to
allow forwarding HTLCs over the channel using SCIDs from previous
funding transactions. Here, the increase from 12 to 144 reflects double
the spec change of 72 blocks.
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 061a02a to db69ec7CompareJune 18, 2025 23:23
@jkczyz
jkczyz requested a review from TheBlueMattJune 18, 2025 23:23
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.

4 participants

@jkczyz@ldk-reviews-bot@TheBlueMatt@wpaulino
, '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('^' + ".*" + ' Follow-ups #3741: Exchange `splice_locked` messages by jkczyz · Pull Request #3873 · lightningdevkit/rust-lightning · GitHub
Skip to content

Follow-ups #3741: Exchange splice_locked messages - #3873

Merged
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes
Jun 20, 2025
Merged

Follow-ups #3741: Exchange splice_locked messages#3873
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Addresses remaining feedback from #3741.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 17, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattJune 17, 2025 22:42
Comment threadlightning/src/ln/channel.rs Outdated
let pending_splice = self.pending_splice.as_ref().unwrap();
let funding = self.pending_funding.get(confirmed_funding_index).unwrap();
if let Some(splice_locked) = self.check_get_splice_locked(pending_splice, funding, height) {
let pending_splice = self.pending_splice.as_mut().unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just DRY this up and do this in check_get_splice_locked so that we don't forget to do it at its callsites?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... a few reasons:

  • it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready
  • we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed
  • it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)

I made the change in a fixup to see what it looks like. However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope). Elsewhere, we get around this by passing confirmed_funding_index to maybe_promote_splice_funding. We'd likely need to do something similar, which is kinda meh. What do you think?

@TheBlueMattTheBlueMattJun 18, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready

Indeed, this is what we've done elsewhere, really the "get" part of the thing...Maybe a new name would make it clearer

we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed

Sure, but we can't be sure we ever send a message. Generally our message generators are treated as "this message has now been generated, it will be sent to our peer as the next message and if it doesn't make it we'll figure it out later and retransmit", so I think its still in line with what we do otherwise.

it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)
However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope).

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Yup, that's what the fixup does...

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

... though now we need to pass &ChannelContext. The future refactor will need to remove &FundingScope in favor of confirmed_funding_index because of the issue mentioned above.

Comment threadlightning/src/ln/channel.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 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.

@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from e0386ba to 8ea5689CompareJune 18, 2025 14:44
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 8ea5689 to e08c2ffCompareJune 18, 2025 16:50
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch 2 times, most recently from 1c0d324 to 061a02aCompareJune 18, 2025 17:08

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feel free to squash, looks fine to me.

jkczyz added 5 commits June 18, 2025 18:23
When sending splice_locked, set PendingSplice::sent_funding_txid prior
to calling FundedChannel::maybe_promote_splice_funding. This makes the
latter idempotent when the splice is not promoted. Otherwise, successive
calls could override the previously set sent_funding_txid.
This will help make the code more compact when using rustfmt.
Use of a macro as a function parameter prevented this method from being
formatted by rustfmt. Extract out a variable such is now can be.
When sending or receiving splice_locked results in promoting a
FundingScope, return the new funding_txo to ChannelManager. This is used
to determine if Event::ChannelReady should be emitted. This is deemed
safer than checking the channel if there are any pending splices after
it handles splice_locked or after checking funding confirmations.
The spec is being changed to keep around a channel_announcement when the
funding_txo is spent. This allows spliced channels more time to exchange
splice_locked messages before the channel is dropped from the network
graph. While LDK does not drop such channels, it uses this constant to
allow forwarding HTLCs over the channel using SCIDs from previous
funding transactions. Here, the increase from 12 to 144 reflects double
the spec change of 72 blocks.
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 061a02a to db69ec7CompareJune 18, 2025 23:23
@jkczyz
jkczyz requested a review from TheBlueMattJune 18, 2025 23:23
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.

4 participants

@jkczyz@ldk-reviews-bot@TheBlueMatt@wpaulino
, '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" + ' Follow-ups #3741: Exchange `splice_locked` messages by jkczyz · Pull Request #3873 · lightningdevkit/rust-lightning · GitHub
Skip to content

Follow-ups #3741: Exchange splice_locked messages - #3873

Merged
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes
Jun 20, 2025
Merged

Follow-ups #3741: Exchange splice_locked messages#3873
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Addresses remaining feedback from #3741.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 17, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattJune 17, 2025 22:42
Comment threadlightning/src/ln/channel.rs Outdated
let pending_splice = self.pending_splice.as_ref().unwrap();
let funding = self.pending_funding.get(confirmed_funding_index).unwrap();
if let Some(splice_locked) = self.check_get_splice_locked(pending_splice, funding, height) {
let pending_splice = self.pending_splice.as_mut().unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just DRY this up and do this in check_get_splice_locked so that we don't forget to do it at its callsites?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... a few reasons:

  • it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready
  • we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed
  • it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)

I made the change in a fixup to see what it looks like. However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope). Elsewhere, we get around this by passing confirmed_funding_index to maybe_promote_splice_funding. We'd likely need to do something similar, which is kinda meh. What do you think?

@TheBlueMattTheBlueMattJun 18, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready

Indeed, this is what we've done elsewhere, really the "get" part of the thing...Maybe a new name would make it clearer

we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed

Sure, but we can't be sure we ever send a message. Generally our message generators are treated as "this message has now been generated, it will be sent to our peer as the next message and if it doesn't make it we'll figure it out later and retransmit", so I think its still in line with what we do otherwise.

it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)
However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope).

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Yup, that's what the fixup does...

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

... though now we need to pass &ChannelContext. The future refactor will need to remove &FundingScope in favor of confirmed_funding_index because of the issue mentioned above.

Comment threadlightning/src/ln/channel.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 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.

@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from e0386ba to 8ea5689CompareJune 18, 2025 14:44
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 8ea5689 to e08c2ffCompareJune 18, 2025 16:50
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch 2 times, most recently from 1c0d324 to 061a02aCompareJune 18, 2025 17:08

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feel free to squash, looks fine to me.

jkczyz added 5 commits June 18, 2025 18:23
When sending splice_locked, set PendingSplice::sent_funding_txid prior
to calling FundedChannel::maybe_promote_splice_funding. This makes the
latter idempotent when the splice is not promoted. Otherwise, successive
calls could override the previously set sent_funding_txid.
This will help make the code more compact when using rustfmt.
Use of a macro as a function parameter prevented this method from being
formatted by rustfmt. Extract out a variable such is now can be.
When sending or receiving splice_locked results in promoting a
FundingScope, return the new funding_txo to ChannelManager. This is used
to determine if Event::ChannelReady should be emitted. This is deemed
safer than checking the channel if there are any pending splices after
it handles splice_locked or after checking funding confirmations.
The spec is being changed to keep around a channel_announcement when the
funding_txo is spent. This allows spliced channels more time to exchange
splice_locked messages before the channel is dropped from the network
graph. While LDK does not drop such channels, it uses this constant to
allow forwarding HTLCs over the channel using SCIDs from previous
funding transactions. Here, the increase from 12 to 144 reflects double
the spec change of 72 blocks.
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 061a02a to db69ec7CompareJune 18, 2025 23:23
@jkczyz
jkczyz requested a review from TheBlueMattJune 18, 2025 23:23
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.

4 participants

@jkczyz@ldk-reviews-bot@TheBlueMatt@wpaulino
, '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('^' + ".*" + ' Follow-ups #3741: Exchange `splice_locked` messages by jkczyz · Pull Request #3873 · lightningdevkit/rust-lightning · GitHub
Skip to content

Follow-ups #3741: Exchange splice_locked messages - #3873

Merged
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes
Jun 20, 2025
Merged

Follow-ups #3741: Exchange splice_locked messages#3873
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Addresses remaining feedback from #3741.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 17, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattJune 17, 2025 22:42
Comment threadlightning/src/ln/channel.rs Outdated
let pending_splice = self.pending_splice.as_ref().unwrap();
let funding = self.pending_funding.get(confirmed_funding_index).unwrap();
if let Some(splice_locked) = self.check_get_splice_locked(pending_splice, funding, height) {
let pending_splice = self.pending_splice.as_mut().unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just DRY this up and do this in check_get_splice_locked so that we don't forget to do it at its callsites?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... a few reasons:

  • it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready
  • we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed
  • it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)

I made the change in a fixup to see what it looks like. However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope). Elsewhere, we get around this by passing confirmed_funding_index to maybe_promote_splice_funding. We'd likely need to do something similar, which is kinda meh. What do you think?

@TheBlueMattTheBlueMattJun 18, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready

Indeed, this is what we've done elsewhere, really the "get" part of the thing...Maybe a new name would make it clearer

we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed

Sure, but we can't be sure we ever send a message. Generally our message generators are treated as "this message has now been generated, it will be sent to our peer as the next message and if it doesn't make it we'll figure it out later and retransmit", so I think its still in line with what we do otherwise.

it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)
However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope).

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Yup, that's what the fixup does...

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

... though now we need to pass &ChannelContext. The future refactor will need to remove &FundingScope in favor of confirmed_funding_index because of the issue mentioned above.

Comment threadlightning/src/ln/channel.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 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.

@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from e0386ba to 8ea5689CompareJune 18, 2025 14:44
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 8ea5689 to e08c2ffCompareJune 18, 2025 16:50
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch 2 times, most recently from 1c0d324 to 061a02aCompareJune 18, 2025 17:08

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feel free to squash, looks fine to me.

jkczyz added 5 commits June 18, 2025 18:23
When sending splice_locked, set PendingSplice::sent_funding_txid prior
to calling FundedChannel::maybe_promote_splice_funding. This makes the
latter idempotent when the splice is not promoted. Otherwise, successive
calls could override the previously set sent_funding_txid.
This will help make the code more compact when using rustfmt.
Use of a macro as a function parameter prevented this method from being
formatted by rustfmt. Extract out a variable such is now can be.
When sending or receiving splice_locked results in promoting a
FundingScope, return the new funding_txo to ChannelManager. This is used
to determine if Event::ChannelReady should be emitted. This is deemed
safer than checking the channel if there are any pending splices after
it handles splice_locked or after checking funding confirmations.
The spec is being changed to keep around a channel_announcement when the
funding_txo is spent. This allows spliced channels more time to exchange
splice_locked messages before the channel is dropped from the network
graph. While LDK does not drop such channels, it uses this constant to
allow forwarding HTLCs over the channel using SCIDs from previous
funding transactions. Here, the increase from 12 to 144 reflects double
the spec change of 72 blocks.
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 061a02a to db69ec7CompareJune 18, 2025 23:23
@jkczyz
jkczyz requested a review from TheBlueMattJune 18, 2025 23:23
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.

4 participants

@jkczyz@ldk-reviews-bot@TheBlueMatt@wpaulino
, '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('^' + ".*" + ' Follow-ups #3741: Exchange `splice_locked` messages by jkczyz · Pull Request #3873 · lightningdevkit/rust-lightning · GitHub
Skip to content

Follow-ups #3741: Exchange splice_locked messages - #3873

Merged
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes
Jun 20, 2025
Merged

Follow-ups #3741: Exchange splice_locked messages#3873
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Addresses remaining feedback from #3741.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 17, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattJune 17, 2025 22:42
Comment threadlightning/src/ln/channel.rs Outdated
let pending_splice = self.pending_splice.as_ref().unwrap();
let funding = self.pending_funding.get(confirmed_funding_index).unwrap();
if let Some(splice_locked) = self.check_get_splice_locked(pending_splice, funding, height) {
let pending_splice = self.pending_splice.as_mut().unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just DRY this up and do this in check_get_splice_locked so that we don't forget to do it at its callsites?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... a few reasons:

  • it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready
  • we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed
  • it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)

I made the change in a fixup to see what it looks like. However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope). Elsewhere, we get around this by passing confirmed_funding_index to maybe_promote_splice_funding. We'd likely need to do something similar, which is kinda meh. What do you think?

@TheBlueMattTheBlueMattJun 18, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready

Indeed, this is what we've done elsewhere, really the "get" part of the thing...Maybe a new name would make it clearer

we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed

Sure, but we can't be sure we ever send a message. Generally our message generators are treated as "this message has now been generated, it will be sent to our peer as the next message and if it doesn't make it we'll figure it out later and retransmit", so I think its still in line with what we do otherwise.

it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)
However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope).

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Yup, that's what the fixup does...

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

... though now we need to pass &ChannelContext. The future refactor will need to remove &FundingScope in favor of confirmed_funding_index because of the issue mentioned above.

Comment threadlightning/src/ln/channel.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 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.

@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from e0386ba to 8ea5689CompareJune 18, 2025 14:44
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 8ea5689 to e08c2ffCompareJune 18, 2025 16:50
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch 2 times, most recently from 1c0d324 to 061a02aCompareJune 18, 2025 17:08

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feel free to squash, looks fine to me.

jkczyz added 5 commits June 18, 2025 18:23
When sending splice_locked, set PendingSplice::sent_funding_txid prior
to calling FundedChannel::maybe_promote_splice_funding. This makes the
latter idempotent when the splice is not promoted. Otherwise, successive
calls could override the previously set sent_funding_txid.
This will help make the code more compact when using rustfmt.
Use of a macro as a function parameter prevented this method from being
formatted by rustfmt. Extract out a variable such is now can be.
When sending or receiving splice_locked results in promoting a
FundingScope, return the new funding_txo to ChannelManager. This is used
to determine if Event::ChannelReady should be emitted. This is deemed
safer than checking the channel if there are any pending splices after
it handles splice_locked or after checking funding confirmations.
The spec is being changed to keep around a channel_announcement when the
funding_txo is spent. This allows spliced channels more time to exchange
splice_locked messages before the channel is dropped from the network
graph. While LDK does not drop such channels, it uses this constant to
allow forwarding HTLCs over the channel using SCIDs from previous
funding transactions. Here, the increase from 12 to 144 reflects double
the spec change of 72 blocks.
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 061a02a to db69ec7CompareJune 18, 2025 23:23
@jkczyz
jkczyz requested a review from TheBlueMattJune 18, 2025 23:23
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.

4 participants

@jkczyz@ldk-reviews-bot@TheBlueMatt@wpaulino
, '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); } })(); })(); Follow-ups #3741: Exchange `splice_locked` messages by jkczyz · Pull Request #3873 · lightningdevkit/rust-lightning · GitHub
Skip to content

Follow-ups #3741: Exchange splice_locked messages - #3873

Merged
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes
Jun 20, 2025
Merged

Follow-ups #3741: Exchange splice_locked messages#3873
wpaulino merged 5 commits into
lightningdevkit:mainfrom
jkczyz:2025-06-splice-locked-fixes

Conversation

@jkczyz

Copy link
Copy Markdown
Contributor

Addresses remaining feedback from #3741.

@ldk-reviews-bot

ldk-reviews-bot commented Jun 17, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @TheBlueMatt as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@jkczyz
jkczyz requested a review from TheBlueMattJune 17, 2025 22:42
Comment threadlightning/src/ln/channel.rs Outdated
let pending_splice = self.pending_splice.as_ref().unwrap();
let funding = self.pending_funding.get(confirmed_funding_index).unwrap();
if let Some(splice_locked) = self.check_get_splice_locked(pending_splice, funding, height) {
let pending_splice = self.pending_splice.as_mut().unwrap();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why not just DRY this up and do this in check_get_splice_locked so that we don't forget to do it at its callsites?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Hmmm... a few reasons:

  • it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready
  • we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed
  • it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)

I made the change in a fixup to see what it looks like. However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope). Elsewhere, we get around this by passing confirmed_funding_index to maybe_promote_splice_funding. We'd likely need to do something similar, which is kinda meh. What do you think?

@TheBlueMattTheBlueMattJun 18, 2025

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

it introduces a side effect into a "check" function, though it seems we already do that for check_get_channel_ready

Indeed, this is what we've done elsewhere, really the "get" part of the thing...Maybe a new name would make it clearer

we would update state before knowing if we actually will send splice_locked for the call in transactions_confirmed

Sure, but we can't be sure we ever send a message. Generally our message generators are treated as "this message has now been generated, it will be sent to our peer as the next message and if it doesn't make it we'll figure it out later and retransmit", so I think its still in line with what we do otherwise.

it requires a bit of refactoring to placate the borrow checker, which may be a problem later (see below)
However, I think we'll have a problem once we move ChannelFunded::pending_funding into PendingSplice because we'll need a mutable reference to PendingSplice and an immutable reference to one of its parts (FundingScope).

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Shouldn't that simply imply that the method can move to be a method on PendingSplice at that point, where we wouldn't have that issue because it just takes a &mut self?

Yup, that's what the fixup does...

Put another way, this feels like an indication that our data model is wrong - we shouldn't need to be passing two references to different parts of a struct to a method, the method should be on that struct.

... though now we need to pass &ChannelContext. The future refactor will need to remove &FundingScope in favor of confirmed_funding_index because of the issue mentioned above.

Comment threadlightning/src/ln/channel.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 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.

@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from e0386ba to 8ea5689CompareJune 18, 2025 14:44
Comment threadlightning/src/ln/channel.rs
Comment threadlightning/src/ln/channel.rs Outdated
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 8ea5689 to e08c2ffCompareJune 18, 2025 16:50
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch 2 times, most recently from 1c0d324 to 061a02aCompareJune 18, 2025 17:08

@TheBlueMattTheBlueMatt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Feel free to squash, looks fine to me.

jkczyz added 5 commits June 18, 2025 18:23
When sending splice_locked, set PendingSplice::sent_funding_txid prior
to calling FundedChannel::maybe_promote_splice_funding. This makes the
latter idempotent when the splice is not promoted. Otherwise, successive
calls could override the previously set sent_funding_txid.
This will help make the code more compact when using rustfmt.
Use of a macro as a function parameter prevented this method from being
formatted by rustfmt. Extract out a variable such is now can be.
When sending or receiving splice_locked results in promoting a
FundingScope, return the new funding_txo to ChannelManager. This is used
to determine if Event::ChannelReady should be emitted. This is deemed
safer than checking the channel if there are any pending splices after
it handles splice_locked or after checking funding confirmations.
The spec is being changed to keep around a channel_announcement when the
funding_txo is spent. This allows spliced channels more time to exchange
splice_locked messages before the channel is dropped from the network
graph. While LDK does not drop such channels, it uses this constant to
allow forwarding HTLCs over the channel using SCIDs from previous
funding transactions. Here, the increase from 12 to 144 reflects double
the spec change of 72 blocks.
@jkczyz
jkczyzforce-pushed the 2025-06-splice-locked-fixes branch from 061a02a to db69ec7CompareJune 18, 2025 23:23
@jkczyz
jkczyz requested a review from TheBlueMattJune 18, 2025 23:23
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.

4 participants

@jkczyz@ldk-reviews-bot@TheBlueMatt@wpaulino