diff --git a/lnwallet/channel.go b/lnwallet/channel.go index d190acdf5..8e1aed81b 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -8199,6 +8199,8 @@ type chanCloseOpt struct { // transaction outputs. If this isn't set, then the default BIP-69 // sorting is used. customSort CloseSortFunc + + customSequence fn.Option[uint32] } // ChanCloseOpt is a closure type that cen be used to modify the set of default @@ -8232,6 +8234,14 @@ func WithExtraCloseOutputs(extraOutputs []CloseOutput) ChanCloseOpt { func WithCustomCoopSort(sorter CloseSortFunc) ChanCloseOpt { return func(opts *chanCloseOpt) { opts.customSort = sorter + } +} + +// WithCustomSequence can be used to specify a custom sequence number for the +// co-op close process. Otherwise, a default non-final sequence will be used. +func WithCustomSequence(sequence uint32) ChanCloseOpt { + return func(opts *chanCloseOpt) { + opts.customSequence = fn.Some(sequence) } } @@ -8294,6 +8304,12 @@ func (lc *LightningChannel) CreateCloseProposal(proposedFee btcutil.Amount, ) } + opts.customSequence.WhenSome(func(sequence uint32) { + closeTxOpts = append(closeTxOpts, WithCustomTxInSequence( + sequence, + )) + }) + closeTx, err := CreateCooperativeCloseTx( fundingTxIn(lc.channelState), lc.channelState.LocalChanCfg.DustLimit, lc.channelState.RemoteChanCfg.DustLimit, ourBalance, theirBalance, @@ -8395,6 +8411,12 @@ func (lc *LightningChannel) CompleteCooperativeClose( ) } + opts.customSequence.WhenSome(func(sequence uint32) { + closeTxOpts = append(closeTxOpts, WithCustomTxInSequence( + sequence, + )) + }) + // Create the transaction used to return the current settled balance // on this active channel back to both parties. In this current model, // the initiator pays full fees for the cooperative close transaction. @@ -9111,6 +9133,11 @@ type closeTxOpts struct { // transaction outputs. If this isn't set, then the default BIP-69 // sorting is used. customSort CloseSortFunc + + // customSequence is an optional custom sequence to set on the co-op + // close transaction. This gives slightly more control compared to the + // enableRBF option. + customSequence fn.Option[uint32] } // defaultCloseTxOpts returns a closeTxOpts struct with default values. @@ -9144,6 +9171,14 @@ func WithExtraTxCloseOutputs(extraOutputs []CloseOutput) CloseTxOpt { func WithCustomTxSort(sorter CloseSortFunc) CloseTxOpt { return func(opts *closeTxOpts) { opts.customSort = sorter + } +} + +// WithCustomTxInSequence allows a caller to set a custom sequence on the sole +// input of the co-op close tx. +func WithCustomTxInSequence(sequence uint32) CloseTxOpt { + return func(o *closeTxOpts) { + o.customSequence = fn.Some(sequence) } } @@ -9169,6 +9204,11 @@ func CreateCooperativeCloseTx(fundingTxIn wire.TxIn, fundingTxIn.Sequence = mempool.MaxRBFSequence } + // Otherwise, a custom sequence might be specified. + opts.customSequence.WhenSome(func(sequence uint32) { + fundingTxIn.Sequence = sequence + }) + // Construct the transaction to perform a cooperative closure of the // channel. In the event that one side doesn't have any settled funds // within the channel then a refund output for that particular side can @@ -9176,6 +9216,8 @@ func CreateCooperativeCloseTx(fundingTxIn wire.TxIn, closeTx := wire.NewMsgTx(2) closeTx.AddTxIn(&fundingTxIn) + // TODO(roasbeef): needs support for dropping inputs + // Create both cooperative closure outputs, properly respecting the // dust limits of both parties. var localOutputIdx fn.Option[int]