Skip to content

Conversation

wpaulino
Copy link
Contributor

An interactive funding construction can be considered failed upon a disconnect or a tx_abort message. So far, we've consumed the InteractiveTxConstructor in the latter case, but not the former. Additionally, we may have splice-specific state that needs to be consumed as well to allow us to negotiate another splice later on.

This commit ensures that we properly consume all splice and interactive funding state whenever possible upon a disconnect or tx_abort.

The interactive funding state is safe to consume as long as we have either yet to reach AwaitingSignatures, or we have but tx_signatures has not been sent/received.

The splice state is safe to consume as long as we don't have a pending FundingNegotiation::AwaitingSignatures with a tx_signatures sent/received and we don't have any negotiated candidates. Note that until splice RBF is supported, it is not currently possible to have any negotiated candidates with a pending interactive funding transaction.

@wpaulino wpaulino added this to the 0.2 milestone Sep 24, 2025
@wpaulino wpaulino requested a review from jkczyz September 24, 2025 19:40
@wpaulino wpaulino self-assigned this Sep 24, 2025
@ldk-reviews-bot
Copy link

ldk-reviews-bot commented Sep 24, 2025

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

Copy link

codecov bot commented Sep 24, 2025

Codecov Report

❌ Patch coverage is 88.14815% with 32 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.68%. Comparing base (3e21ba3) to head (6d2b110).
⚠️ Report is 82 commits behind head on main.

Files with missing lines Patch % Lines
lightning/src/ln/channel.rs 60.00% 30 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4120      +/-   ##
==========================================
- Coverage   88.72%   88.68%   -0.04%     
==========================================
  Files         177      180       +3     
  Lines      133404   135148    +1744     
  Branches   133404   135148    +1744     
==========================================
+ Hits       118365   119860    +1495     
- Misses      12325    12523     +198     
- Partials     2714     2765      +51     
Flag Coverage Δ
fuzzing 21.79% <33.75%> (+0.05%) ⬆️
tests 88.52% <88.14%> (-0.04%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines 6766 to 6781
signing_session.holder_tx_signatures().is_some()
|| signing_session.has_received_tx_signatures()
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it matter if we received their signatures if we haven't sent ours? Or is it because if they sent theirs then they would not have reset their state?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're supposed to remember the channel as soon as one side has sent tx_signatures, because you can't be sure the other side didn't just sign and broadcast without sending their own.

@ldk-reviews-bot
Copy link

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

.pending_splice
.as_mut()
.and_then(|pending_splice| pending_splice.funding_negotiation.take());
if funded_channel.should_reset_pending_splice_funding_negotiation() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like we aren't calling fail_interactive_tx_negotiation when failing to handle a splice_ack. #4077 updates fail_interactive_tx_negotiation to take a NegotiationError, which it uses to construct a SpliceFundingFailed struct.

For FundingNegotiation::ConstructingTransaction, the NegotiationError is formed by copying the inputs from the InteractiveTxConstructor. For FundingNegotiation::AwaitingAck when handling splice_ack, we'd need to do something similar?

Either way we are cloning the inputs just to later take the FundingNegotiation here. Maybe that is ok for now? Any thoughts on a better way of doing this?

Copy link
Contributor

@jkczyz jkczyz Sep 25, 2025

Choose a reason for hiding this comment

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

Hmmm... so we are also already take'ing the FundingNegotiation in one place in splice_ack handling (when FundingNegotiation::into_interactive_tx_constructor fails), but not earlier when validating the splice_ack message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We shouldn't need to call fail_interactive_tx_negotiation whenever we fail handling a message by sending a warning and disconnecting.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, so failing to process a splice_ack would just disconnect, and the peer could re-send it after reconnecting. Do we eventually timeout quiescence somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Quiescence is also implicitly terminated upon disconnection, but we do have a timeout enforced at should_disconnect_peer_awaiting_response.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, so we'd need to produce a SpliceFailed event in some other way? I'm thinking when we are in FundingNegotiation::AwaitingAck and fail processing the splice_ack.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah sounds like that logic might need to live in the disconnection handler, since we'll need to emit an event anyway if a peer disconnects mid-splice negotiation for whatever reason.

jkczyz
jkczyz previously approved these changes Sep 26, 2025
TheBlueMatt
TheBlueMatt previously approved these changes Sep 26, 2025
An interactive funding construction can be considered failed upon a
disconnect or a `tx_abort` message. So far, we've consumed the
`InteractiveTxConstructor` in the latter case, but not the former.
Additionally, we may have splice-specific state that needs to be
consumed as well to allow us to negotiate another splice later on.

This commit ensures that we properly consume all splice and interactive
funding state whenever possible upon a disconnect or `tx_abort`.

The interactive funding state is safe to consume as long as we have
either yet to reach `AwaitingSignatures`, or we have but `tx_signatures`
has not been sent/received. In all of these cases, we also make sure to
clear the quiescent state flag such that we're able to resume processing
updates on the channel.

The splice state is safe to consume as long as we don't have a pending
`FundingNegotiation::AwaitingSignatures` with a `tx_signatures`
sent/received and we don't have any negotiated candidates. Note that
until splice RBF is supported, it is not currently possible to have any
negotiated candidates with a pending interactive funding transaction.
@jkczyz jkczyz requested a review from TheBlueMatt September 30, 2025 15:21
@jkczyz jkczyz merged commit cfe2a1e into lightningdevkit:main Oct 1, 2025
25 checks passed
@wpaulino wpaulino deleted the reset-splice-state branch October 1, 2025 07:57
Sign up for free to 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