-
Notifications
You must be signed in to change notification settings - Fork 417
[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
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.02%
==========================================
Files 174 174
Lines 123869 124200 +331
Branches 123869 124200 +331
==========================================
+ Hits 110152 110476 +324
+ Misses 11256 11247 -9
- Partials 2461 2477 +16
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. |
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
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. Send a tx_abort message if the channel was already successfully funded, thus aborting the negotiation. Otherwise, close the channel as this means the failure occurred during v2 channel establishment.
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.
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.
Ok((commitment_signed, event)) => (commitment_signed, event), | ||
Err(tx_abort) => { | ||
if chan_entry.get().is_funded() { | ||
peer_state.pending_msg_events.push(MessageSendEvent::SendTxAbort { |
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 don't think it applies here since the negotiated completed and we consumed the constructor, but generally when we send this we want to make sure we're no longer tracking one, and also probably assert that tx_signatures
have not been exchanged.
We'll also want to follow-up with sending tx_abort
in most other error cases until the tx_signatures
exchange.
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)