-
Notifications
You must be signed in to change notification settings - Fork 418
[Splicing] Tx negotiation during splicing #3736
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?
Conversation
👋 I see @wpaulino was un-assigned. |
7f6dfbd
to
c3778bc
Compare
1 similar comment
1 similar comment
1 similar comment
1 similar comment
1 similar comment
1 similar comment
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.
Sorry about the late review. We were traveling to an off site last week. Just a high-level pass on the first four commits. Will need to take a closer look at the last one.
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3736 +/- ##
==========================================
+ Coverage 88.92% 88.95% +0.03%
==========================================
Files 174 174
Lines 123869 124165 +296
Branches 123869 124165 +296
==========================================
+ Hits 110152 110456 +304
+ Misses 11256 11228 -28
- Partials 2461 2481 +20
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:
|
88d2e83
to
866368d
Compare
Ready for a new round of review. I have addressed the comments, applied most of them. There is still one to-do (update channel reserve values), that I will do, but the rest is ready for review. |
Ready for a new round of review. All pending and newly raised comments addressed. |
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.
Squashed all the fixups and created some standalone commits where possible. Will need to update some of the commit authorship. Hopefully, this will be a little easier to review now.
let post_value_to_self_msat = AddSigned::checked_add_signed( | ||
prev_funding.value_to_self_msat, | ||
our_funding_contribution_sats * 1000, | ||
); | ||
debug_assert!(post_value_to_self_msat.is_some()); | ||
let post_value_to_self_msat = post_value_to_self_msat.unwrap(); |
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 debug_assert!(post_value_to_self_msat.is_some())
assumes that adding our_funding_contribution_sats * 1000
to prev_funding.value_to_self_msat
will never overflow. However, this isn't guaranteed, especially with large values.
If the addition overflows, post_value_to_self_msat
will be None
, and the subsequent unwrap()
will panic. Consider handling the overflow case explicitly, perhaps by capping the value at u64::MAX
or returning an error if the addition would overflow. This would make the code more robust against edge cases.
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
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.
This shouldn't be possible so long as our_funding_contribution_sats
doesn't exceed the total bitcoin supply. I will add more checks in the splice-out follow-up PR.
This is a simple rename, DualFundingContext to FundingNegotiationContext, to suggest that this is use not only in dual-funded channel open. Also rename the field dual_funding_context to funding_negotiation_context.
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.
Couple comments still left to address
9766f21
to
cdc393c
Compare
lightning/src/ln/interactivetxs.rs
Outdated
@@ -1270,6 +1270,10 @@ impl SharedOwnedInput { | |||
Self { input, prev_output, local_owned } | |||
} | |||
|
|||
pub fn local_owned(&self) -> u64 { |
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.
Nit: doesn't look like this belongs in commit 526bf62
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.
Yeah, doesn't look like it is used at all actually.
chan.holder_commitment_point.transaction_number(), | ||
&&logger, | ||
) | ||
// Don't close a funded channel if splicing fails |
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.
I think if we always return a tx_abort
from funding_tx_constructed
then it should handle both dual funded and splicing cases appropriately.
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.
As in for the Err
type instead of ChannelError
? Don't we want to close the channel for the dual funding case?
lightning/src/ln/channel.rs
Outdated
@@ -10515,50 +10691,191 @@ where | |||
// MUST send a warning and close the connection or send an error | |||
// and fail the channel. | |||
if !self.context.is_live() { | |||
return Err(ChannelError::Warn(format!("Splicing requested on a channel that is not live"))); | |||
return Err(ChannelError::Warn(format!( |
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.
We should WarnAndDisconnect
instead whenever we come across an error on a counterparty message, otherwise we'll be stuck in quiescence until the timeout. Though it's short, might as well do it immediately.
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.
Done. Though used Ignore
in a couple places that seemed more appropriate.
PendingSplice holds a FundingScope being negotiated. However, when implementing funding negotiation, other states are possible depending on which party initiated the splice. Using an enum prevents needing various Option fields which may result in invalid states. When the user initiates the splice, the FundingNegotiationContext must be held until the counterparty responds with splice_ack. At that point enough information becomes available to create a new FundingScope and an InteractiveTxConstructor. When the counterparty initiates the splice, both a new FundingScope and an InteractiveTxConstructor can be created immediately when responding with splice_ack. After the transaction is constructed, those are no longer needed. At that point an InteractiveTxSigningSession is tracked until signatures are exchanged.
FundingNegotiationContext and PendingSplice both hold the user's contribution to a splice, which doesn't need to be duplicated. Instead, only store this in FundingNegotiationContext, which then can be used to create an InteractiveTxConstructor when transitioning to FundingNegotiation:::ConstructingTransaction. This commit updates that code to properly compute change outputs using the FundingNegotiationContext by not considering the shared input since it is accounted for in the shared output. Co-authored-by: Wilmer Paulino <[email protected]> Co-authored-by: Jeffrey Czyz <[email protected]>
Instead of passing the shared funding input as another parameter to FundingNegotiationContext::into_interactive_tx_constructor, make it a member of FundingNegotiationContext.
InteractiveTxConstructor was only used in PendingV2Channel methods, but for splicing those methods are needed for FundedChannel, too. Refactor the code such that each type has a method for accessing its InteractiveTxConstructor such that it can be called in either use, refactoring code out of PendingV2Channel as needed. Co-authored-by: Wilmer Paulino <[email protected]> Co-authored-by: Jeffrey Czyz <[email protected]>
Update splice_channel, split_init, and splice_ack to implement transitioning from splice initialization to funding transaction negotiation. Co-authored-by: optout <[email protected]> Co-authored-by: Jeffrey Czyz <[email protected]>
Instead of passing the optional change script as another parameter to FundingNegotiationContext::into_interactive_tx_constructor, make it a member of FundingNegotiationContext. Also, allow it to be passed to ChannelManager::splice_channel.
If splicing fails, the previous funding is still usable. Convert any ChannelError::Close to ChannelClose::Warn when this is the case to avoid closing a usable channel.
Once splice has been promoted, the interactive_tx_signing_session is no longer needed. Clear it at this time to prevent being in an inconsistent state.
Implementation of transaction negotiation during splicing.
Builds on 3407 and 3443.
No new phase,Funded(FundedChannel)
is used throughout splicingFundedChannel
andPendingV2Channel
can act as a transaction constructorPendingV2Channel
logic is put behind a trait --FundingTxConstructorV2
RenegotiatingScope
is used to store extra state during splicingFundingChannel
can act as aFundingTxConstructorV2
, using the state fromRenegotiatingScope
(if present)Since bothFundedChannel
andFundingTxConstructor
has context(), context accessors are extracted into a common base trait,ChannelContextProvider
(it is also shared byInitialRemoteCommitmentReceiver
).(Also relevant: #3444)