-
Notifications
You must be signed in to change notification settings - Fork 418
Splice channel state rework #4061
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Splice channel state rework #4061
Conversation
👋 Thanks for assigning @TheBlueMatt as a reviewer! |
// FIXME: Either we bring back the `OUR_TX_SIGNATURES_READY` flag for this specific | ||
// case, or we somehow access the signing session to check it instead. | ||
ChannelState::FundingNegotiated(flags) => !flags.is_interactive_signing(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation has a potential logic issue. The FIXME comment correctly identifies that is_interactive_signing()
is being used as a replacement for the removed OUR_TX_SIGNATURES_READY
flag, but these represent different states:
is_interactive_signing()
is true during the entire interactive signing processOUR_TX_SIGNATURES_READY
was specifically true only after our signatures were ready to send
This semantic difference could cause funding transactions to be incorrectly marked as non-broadcastable when they should be broadcastable. Consider either:
- Restoring the
OUR_TX_SIGNATURES_READY
flag for this specific use case, or - Accessing the signing session directly to check if holder signatures are ready via something like
signing_session.holder_tx_signatures().is_some()
This would more accurately represent the original intent of the code.
// FIXME: Either we bring back the `OUR_TX_SIGNATURES_READY` flag for this specific | |
// case, or we somehow access the signing session to check it instead. | |
ChannelState::FundingNegotiated(flags) => !flags.is_interactive_signing(), | |
// We need to check if our signatures are ready to send, which means the transaction | |
// is ready to be broadcast. | |
ChannelState::FundingNegotiated(flags) => { | |
if let Some(signing_session) = &self.funding_tx_signing_session { | |
signing_session.holder_tx_signatures().is_none() | |
} else { | |
!flags.is_interactive_signing() | |
} | |
}, |
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
🔔 1st Reminder Hey @valentinewallace! This PR has been waiting for your review. |
9272b39
to
23a1c29
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4061 +/- ##
=======================================
Coverage 88.39% 88.39%
=======================================
Files 177 177
Lines 131314 131355 +41
Branches 131314 131355 +41
=======================================
+ Hits 116069 116113 +44
+ Misses 12596 12594 -2
+ Partials 2649 2648 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
This commit addresses an overlap of state between `InteractiveTxSigningSession` and `ChannelState::FundingNegotiated`. The signing session already tracks whether both holder and counterparty `tx_signatures` have been produced, so tracking the state duplicatively at the `ChannelState` level is unnecessary.
Once a channel open has become locked (i.e., we've entered `ChannelState::ChannelReady`), the channel is intended to remain within this state for the rest of its lifetime until shutdown. Previously, we had assumed a channel being spliced would go through the `ChannelState` lifecycle again starting from `NegotiatingFunding` but skipping `AwaitingChannelReady`. This inconsistency departs from what we strive to achieve with `ChannelState` and also makes the state of a channel harder to reason about. This commit ensures a channel undergoing a splice remains in `ChannelReady`, clearing the quiescent flag once the negotiation is complete. Dual funding is unaffected by this change as the channel is being opened and we want to maintain the same `ChannelState` lifecycle.
23a1c29
to
0cbeb51
Compare
debug_assert!( | ||
false, | ||
"A signing session must always be present while interactive signing" | ||
); | ||
let err = | ||
format!("Channel {} not expecting funding signatures", self.context.channel_id); | ||
return Err(APIError::APIMisuseError { err }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code contains a pattern where a debug assertion claims a signing session must always be present during interactive signing, but then includes error handling for when it's None
. This creates a logical contradiction - either:
- The assertion is correct and the error handling is unnecessary, or
- The error handling is necessary and the assertion is incorrect
This pattern appears multiple times throughout the code. Consider either:
- Removing the error handling if the assertion truly holds
- Adjusting the assertion to reflect the actual conditions where a signing session might be absent
This would make the code's intent clearer and avoid potential confusion about the expected state during interactive signing.
debug_assert!( | |
false, | |
"A signing session must always be present while interactive signing" | |
); | |
let err = | |
format!("Channel {} not expecting funding signatures", self.context.channel_id); | |
return Err(APIError::APIMisuseError { err }); | |
// A signing session should typically be present during interactive signing, | |
// but handle the case where it's not | |
let err = | |
format!("Channel {} not expecting funding signatures", self.context.channel_id); | |
return Err(APIError::APIMisuseError { err }); |
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
This was pulled out of #4054 to ease review. It depends on #4060 to not bother with
cfg(splicing)
anymore.