-
Notifications
You must be signed in to change notification settings - Fork 418
Add splice-out support #3979
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?
Add splice-out support #3979
Conversation
👋 Thanks for assigning @wpaulino as a reviewer! |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3979 +/- ##
==========================================
+ Coverage 88.74% 88.83% +0.09%
==========================================
Files 173 175 +2
Lines 124899 127732 +2833
Branches 124899 127732 +2833
==========================================
+ Hits 110841 113477 +2636
- Misses 11631 11686 +55
- Partials 2427 2569 +142
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:
|
2d39059
to
381fba6
Compare
🔔 1st Reminder Hey @wpaulino! This PR has been waiting for your review. |
lightning/src/ln/channel.rs
Outdated
@@ -6079,7 +6081,7 @@ pub enum FundingTxContributions { | |||
InputsOnly { | |||
/// The inputs used to meet the contributed amount. Any excess amount will be sent to a | |||
/// change output. | |||
inputs: Vec<(TxIn, Transaction)>, | |||
inputs: Vec<(TxIn, Transaction, Weight)>, |
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.
Let's make this a struct now so we can properly document each field. The weight here should be the witness_weight
for the input to be spent. We may even be able to reuse bump_transaction::Utxo
.
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 may even be able to reuse
bump_transaction::Utxo
.
Hmm... that doesn't have a TxIn
. We also need the full previous transaction in InteractiveTxConstructor
to use as prevtx
in tx_add_input
.
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 would just need to track TxIn::sequence
and prevtx
separately if we choose to go with it
lightning/src/ln/channel.rs
Outdated
our_funding_contribution_satoshis, | ||
); | ||
// FIXME: Should we check value_to_self instead? Do HTLCs need to be accounted for? | ||
// FIXME: Check that we can pay for the outputs from the channel value? |
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 probably don't even need our_funding_contribution
for a splice out, we can just assume it from adding all the output values
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.
Ah, good point. For paying for the outputs, seems we should actually use check_v2_funding_inputs_sufficient
for both splice-in and splice-out and account for outputs?
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.
Ah, actually that only looks at the input from the previous funding transaction for weight, not amount.
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.
Re-wrote this to ensure fees for the funding outputs are accounted for. One thing of note is that our_funding_contribution
for a splice-out needs to be adjusted by the fees to be paid (i.e., fees need to be subtracted from the negative our_funding_contribution
to increase the amount being removed from the channel).
Also, a bit of an oversight, but we don't yet support accepting a splice-out. Technically, it could contain both inputs and outputs even if the net amount is negative. But I think we shouldn't care as long as we check everything is sane upon exchanging tx_complete
.
👋 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. |
396948e
to
59fbd7e
Compare
🔔 1st Reminder Hey @wpaulino! This PR has been waiting for your review. |
Splice contributions should never exceed the total bitcoin supply. This check prevents a potential overflow when converting the contribution from sats to msats. The commit additionally begins to store the contribution using SignedAmount.
fde2f61
to
f12c993
Compare
Rebased to resolve merge conflicts. |
f12c993
to
806220e
Compare
Squashed as requested. |
@@ -10724,21 +10735,38 @@ where | |||
))); | |||
} | |||
|
|||
if their_funding_contribution_satoshis.saturating_add(our_funding_contribution_satoshis) < 0 | |||
{ | |||
if our_funding_contribution > SignedAmount::MAX_MONEY { |
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: this check doesn't really belong here, ideally it's done when the user tells us they're interested in contributing to an incoming splice
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.
Right, I suppose we'd never pass in our_funding_contribution
when handling splice_ack
. Rather, we'd surface an event to allow users to contribute.
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.
Added a TODO to move the check once user-provided contributions are supported for counterparty-initiated splices.
/// An input to contribute to a channel's funding transaction either when using the v2 channel | ||
/// establishment protocol or when splicing. | ||
#[derive(Clone)] | ||
pub struct FundingTxInput { |
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 still think reusing Utxo
internally would be a good fit here if we can make it happen.
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 could then have helpers like FundingTxInput::new_p2wpkh(tx, vout, sequence)
and others to make it simpler for the user.
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 still think reusing
Utxo
internally would be a good fit here if we can make it happen.
Are you saying something like the following?
pub struct FundingTxInput {
utxo: Utxo,
sequence: Sequence,
prevtx: Transaction,
}
We could then have helpers like
FundingTxInput::new_p2wpkh(tx, vout, sequence)
and others to make it simpler for the user.
If this re-used Utxo::new_p2wpkh
, won't the weight in FundingTxInput::utxo
be wrong? It includes the weight of TxIn::script_sig
, not just the witness.
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.
Hmm... maybe estimate_v2_funding_transaction_fee
isn't correct. It isn't including the script_sig
in the calculation, AFAICT.
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.
Oh, nevermind. Forgot that script_sig
is empty in segwit transactions.
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 discussed offline, added FundingTxInput
with dedicated constructors where some requiring a witness script.
lightning/src/ln/channelmanager.rs
Outdated
#[derive(Clone)] | ||
pub struct FundingTxInput { | ||
/// An input for the funding transaction used to cover the channel contributions. | ||
pub txin: TxIn, |
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 really just need the previous_output
and sequence
, not the full TxIn
. Would also be nice to track the TxOut
separately so that we can just check it once during initialization and never have to worry about it again.
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.
Ah, so the TxOut
created in Utxo
would be checked against the provided prevtx
on initialization?
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
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.
Ended up having the FundingTxInput
constructors create Utxo
inline rather than relying on its constructors in order to properly set satisfaction_weight
.
funding_feerate.to_sat_per_kwu() as u32, | ||
)); | ||
|
||
if channel_balance > contribution_amount.unsigned_abs() + estimated_fee { |
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 isn't enough, we need to make sure the balance is still above the reserve and has enough to pay for fees on the commitment transaction if they're the channel initiator
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.
Right, the reserve check will be at the call site as a separate check. I hadn't considered the fees for the commitment transaction. For the splice-in case, is it assumed it is sufficient because it was sufficient with the previous funding contributions?
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.
For the splice-in case, is it assumed it is sufficient because it was sufficient with the previous funding contributions?
Most likely yeah, but it's better to be safe than sorry. We already need to always check it for the counterparty and for our splice-outs, so might as well always do it for splice-ins.
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.
Leaving this for @tankyleo.
…text Once the counterparty supplies their funding contribution, there is no longer a need to store it in FundingNegotiationContext as it will have already been used to create a FundingScope.
TransactionU16LenLimited was used to limit Transaction serialization size to u16::MAX. This was because messages can not be longer than u16::MAX bytes when serialized for the transport layer. However, this limit doesn't take into account other fields in a message containing a Transaction, including the length of the transaction itself. Remove TransactionU16LenLimited and instead check any user supplied transactions in the context of the enclosing message (e.g. TxAddInput).
ChannelManager::splice_channel takes witness weights with the funding inputs. Storing these in FundingNegotiationContext allows us to use them when calculating the change output and include them in a common struct used for initiating a splice-in. In preparation for having ChannelManager::splice_channel take FundingTxContributions, add a weight to the FundingTxContributions::InputsOnly, which supports the splice-in use case.
The funding inputs used for splicing and v2 channel establishment are passed as a tuple of txin, prevtx, and witness weight. Add a struct so that the items included can be better documented.
ChannelManager::splice_channel takes individual parameters to support splice-in. Change these to an enum such that it can be used for splice-out as well.
Update SpliceContribution with a variant used to support splice-out (i.e., removing funds from a channel). The TxOut values must not exceed the users channel balance after accounting for fees and the reserve requirement.
When a counterparty sends splice_init with a negative contribution, they are requesting to remove funds from a channel. Remove conditions guarding against this and check that they have enough channel balance to cover the removed funds.
806220e
to
9c2f266
Compare
Splice-in support was added in #3736. This PR expands
ChannelManager::splice_channel
to support splice-out (i.e., removing funds from a channel). This is accomplished by adding aFundingTxContributions
enum to cover both use cases.Depends on #3736.