mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-19 05:45:21 +01:00
lnwallet/chancloser: add aux chan closer, use in coop flow
This commit is contained in:
parent
7ff251ca44
commit
8d651b9370
@ -140,6 +140,10 @@ type ChanCloseCfg struct {
|
|||||||
// FeeEstimator is used to estimate the absolute starting co-op close
|
// FeeEstimator is used to estimate the absolute starting co-op close
|
||||||
// fee.
|
// fee.
|
||||||
FeeEstimator CoopFeeEstimator
|
FeeEstimator CoopFeeEstimator
|
||||||
|
|
||||||
|
// AuxCloser is an optional interface that can be used to modify the
|
||||||
|
// way the co-op close process proceeds.
|
||||||
|
AuxCloser fn.Option[AuxChanCloser]
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChanCloser is a state machine that handles the cooperative channel closure
|
// ChanCloser is a state machine that handles the cooperative channel closure
|
||||||
@ -215,6 +219,20 @@ type ChanCloser struct {
|
|||||||
// we use to handle a specific race condition caused by the independent
|
// we use to handle a specific race condition caused by the independent
|
||||||
// message processing queues.
|
// message processing queues.
|
||||||
cachedClosingSigned fn.Option[lnwire.ClosingSigned]
|
cachedClosingSigned fn.Option[lnwire.ClosingSigned]
|
||||||
|
|
||||||
|
// localCloseOutput is the local output on the closing transaction that
|
||||||
|
// the local party should be paid to. This will only be populated if the
|
||||||
|
// local balance isn't dust.
|
||||||
|
localCloseOutput fn.Option[CloseOutput]
|
||||||
|
|
||||||
|
// remoteCloseOutput is the remote output on the closing transaction
|
||||||
|
// that the remote party should be paid to. This will only be populated
|
||||||
|
// if the remote balance isn't dust.
|
||||||
|
remoteCloseOutput fn.Option[CloseOutput]
|
||||||
|
|
||||||
|
// auxOutputs are the optional additional outputs that might be added to
|
||||||
|
// the closing transaction.
|
||||||
|
auxOutputs fn.Option[AuxCloseOutputs]
|
||||||
}
|
}
|
||||||
|
|
||||||
// calcCoopCloseFee computes an "ideal" absolute co-op close fee given the
|
// calcCoopCloseFee computes an "ideal" absolute co-op close fee given the
|
||||||
@ -295,13 +313,13 @@ func (c *ChanCloser) initFeeBaseline() {
|
|||||||
// Depending on if a balance ends up being dust or not, we'll pass a
|
// Depending on if a balance ends up being dust or not, we'll pass a
|
||||||
// nil TxOut into the EstimateFee call which can handle it.
|
// nil TxOut into the EstimateFee call which can handle it.
|
||||||
var localTxOut, remoteTxOut *wire.TxOut
|
var localTxOut, remoteTxOut *wire.TxOut
|
||||||
if !c.cfg.Channel.LocalBalanceDust() {
|
if isDust, _ := c.cfg.Channel.LocalBalanceDust(); !isDust {
|
||||||
localTxOut = &wire.TxOut{
|
localTxOut = &wire.TxOut{
|
||||||
PkScript: c.localDeliveryScript,
|
PkScript: c.localDeliveryScript,
|
||||||
Value: 0,
|
Value: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !c.cfg.Channel.RemoteBalanceDust() {
|
if isDust, _ := c.cfg.Channel.RemoteBalanceDust(); !isDust {
|
||||||
remoteTxOut = &wire.TxOut{
|
remoteTxOut = &wire.TxOut{
|
||||||
PkScript: c.remoteDeliveryScript,
|
PkScript: c.remoteDeliveryScript,
|
||||||
Value: 0,
|
Value: 0,
|
||||||
@ -337,6 +355,30 @@ func (c *ChanCloser) initChanShutdown() (*lnwire.Shutdown, error) {
|
|||||||
// desired closing script.
|
// desired closing script.
|
||||||
shutdown := lnwire.NewShutdown(c.cid, c.localDeliveryScript)
|
shutdown := lnwire.NewShutdown(c.cid, c.localDeliveryScript)
|
||||||
|
|
||||||
|
// At this point, we'll check to see if we have any custom records to
|
||||||
|
// add to the shutdown message.
|
||||||
|
err := fn.MapOptionZ(c.cfg.AuxCloser, func(a AuxChanCloser) error {
|
||||||
|
shutdownCustomRecords, err := a.ShutdownBlob(AuxShutdownReq{
|
||||||
|
ChanPoint: c.chanPoint,
|
||||||
|
ShortChanID: c.cfg.Channel.ShortChanID(),
|
||||||
|
Initiator: c.cfg.Channel.IsInitiator(),
|
||||||
|
CommitBlob: c.cfg.Channel.LocalCommitmentBlob(),
|
||||||
|
FundingBlob: c.cfg.Channel.FundingBlob(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
shutdownCustomRecords.WhenSome(func(cr lnwire.CustomRecords) {
|
||||||
|
shutdown.CustomRecords = cr
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// If this is a taproot channel, then we'll need to also generate a
|
// If this is a taproot channel, then we'll need to also generate a
|
||||||
// nonce that'll be used sign the co-op close transaction offer.
|
// nonce that'll be used sign the co-op close transaction offer.
|
||||||
if c.cfg.Channel.ChanType().IsTaproot() {
|
if c.cfg.Channel.ChanType().IsTaproot() {
|
||||||
@ -370,11 +412,22 @@ func (c *ChanCloser) initChanShutdown() (*lnwire.Shutdown, error) {
|
|||||||
shutdownInfo := channeldb.NewShutdownInfo(
|
shutdownInfo := channeldb.NewShutdownInfo(
|
||||||
c.localDeliveryScript, c.closer.IsLocal(),
|
c.localDeliveryScript, c.closer.IsLocal(),
|
||||||
)
|
)
|
||||||
err := c.cfg.Channel.MarkShutdownSent(shutdownInfo)
|
err = c.cfg.Channel.MarkShutdownSent(shutdownInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll track our local close output, even if it's dust in BTC terms,
|
||||||
|
// it might still carry value in custom channel terms.
|
||||||
|
_, dustAmt := c.cfg.Channel.LocalBalanceDust()
|
||||||
|
localBalance, _ := c.cfg.Channel.CommitBalances()
|
||||||
|
c.localCloseOutput = fn.Some(CloseOutput{
|
||||||
|
Amt: localBalance,
|
||||||
|
DustLimit: dustAmt,
|
||||||
|
PkScript: c.localDeliveryScript,
|
||||||
|
ShutdownRecords: shutdown.CustomRecords,
|
||||||
|
})
|
||||||
|
|
||||||
return shutdown, nil
|
return shutdown, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,6 +497,21 @@ func (c *ChanCloser) NegotiationHeight() uint32 {
|
|||||||
return c.negotiationHeight
|
return c.negotiationHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LocalCloseOutput returns the local close output.
|
||||||
|
func (c *ChanCloser) LocalCloseOutput() fn.Option[CloseOutput] {
|
||||||
|
return c.localCloseOutput
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoteCloseOutput returns the remote close output.
|
||||||
|
func (c *ChanCloser) RemoteCloseOutput() fn.Option[CloseOutput] {
|
||||||
|
return c.remoteCloseOutput
|
||||||
|
}
|
||||||
|
|
||||||
|
// AuxOutputs returns optional extra outputs.
|
||||||
|
func (c *ChanCloser) AuxOutputs() fn.Option[AuxCloseOutputs] {
|
||||||
|
return c.auxOutputs
|
||||||
|
}
|
||||||
|
|
||||||
// validateShutdownScript attempts to match and validate the script provided in
|
// validateShutdownScript attempts to match and validate the script provided in
|
||||||
// our peer's shutdown message with the upfront shutdown script we have on
|
// our peer's shutdown message with the upfront shutdown script we have on
|
||||||
// record. For any script specified, we also make sure it matches our
|
// record. For any script specified, we also make sure it matches our
|
||||||
@ -503,6 +571,17 @@ func (c *ChanCloser) ReceiveShutdown(msg lnwire.Shutdown) (
|
|||||||
|
|
||||||
noShutdown := fn.None[lnwire.Shutdown]()
|
noShutdown := fn.None[lnwire.Shutdown]()
|
||||||
|
|
||||||
|
// We'll track their remote close output, even if it's dust in BTC
|
||||||
|
// terms, it might still carry value in custom channel terms.
|
||||||
|
_, dustAmt := c.cfg.Channel.RemoteBalanceDust()
|
||||||
|
_, remoteBalance := c.cfg.Channel.CommitBalances()
|
||||||
|
c.remoteCloseOutput = fn.Some(CloseOutput{
|
||||||
|
Amt: remoteBalance,
|
||||||
|
DustLimit: dustAmt,
|
||||||
|
PkScript: msg.Address,
|
||||||
|
ShutdownRecords: msg.CustomRecords,
|
||||||
|
})
|
||||||
|
|
||||||
switch c.state {
|
switch c.state {
|
||||||
// If we're in the close idle state, and we're receiving a channel
|
// If we're in the close idle state, and we're receiving a channel
|
||||||
// closure related message, then this indicates that we're on the
|
// closure related message, then this indicates that we're on the
|
||||||
@ -850,6 +929,25 @@ func (c *ChanCloser) ReceiveClosingSigned( //nolint:funlen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before we complete the cooperative close, we'll see if we
|
||||||
|
// have any extra aux options.
|
||||||
|
c.auxOutputs, err = c.auxCloseOutputs(remoteProposedFee)
|
||||||
|
if err != nil {
|
||||||
|
return noClosing, err
|
||||||
|
}
|
||||||
|
c.auxOutputs.WhenSome(func(outs AuxCloseOutputs) {
|
||||||
|
closeOpts = append(
|
||||||
|
closeOpts, lnwallet.WithExtraCloseOutputs(
|
||||||
|
outs.ExtraCloseOutputs,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
closeOpts = append(
|
||||||
|
closeOpts, lnwallet.WithCustomCoopSort(
|
||||||
|
outs.CustomSort,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
closeTx, _, err := c.cfg.Channel.CompleteCooperativeClose(
|
closeTx, _, err := c.cfg.Channel.CompleteCooperativeClose(
|
||||||
localSig, remoteSig, c.localDeliveryScript,
|
localSig, remoteSig, c.localDeliveryScript,
|
||||||
c.remoteDeliveryScript, remoteProposedFee, closeOpts...,
|
c.remoteDeliveryScript, remoteProposedFee, closeOpts...,
|
||||||
@ -859,6 +957,32 @@ func (c *ChanCloser) ReceiveClosingSigned( //nolint:funlen
|
|||||||
}
|
}
|
||||||
c.closingTx = closeTx
|
c.closingTx = closeTx
|
||||||
|
|
||||||
|
// If there's an aux chan closer, then we'll finalize with it
|
||||||
|
// before we write to disk.
|
||||||
|
err = fn.MapOptionZ(
|
||||||
|
c.cfg.AuxCloser, func(aux AuxChanCloser) error {
|
||||||
|
channel := c.cfg.Channel
|
||||||
|
//nolint:lll
|
||||||
|
req := AuxShutdownReq{
|
||||||
|
ChanPoint: c.chanPoint,
|
||||||
|
ShortChanID: c.cfg.Channel.ShortChanID(),
|
||||||
|
Initiator: channel.IsInitiator(),
|
||||||
|
CommitBlob: channel.LocalCommitmentBlob(),
|
||||||
|
FundingBlob: channel.FundingBlob(),
|
||||||
|
}
|
||||||
|
desc := AuxCloseDesc{
|
||||||
|
AuxShutdownReq: req,
|
||||||
|
LocalCloseOutput: c.localCloseOutput,
|
||||||
|
RemoteCloseOutput: c.remoteCloseOutput,
|
||||||
|
}
|
||||||
|
|
||||||
|
return aux.FinalizeClose(desc, closeTx)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return noClosing, err
|
||||||
|
}
|
||||||
|
|
||||||
// Before publishing the closing tx, we persist it to the
|
// Before publishing the closing tx, we persist it to the
|
||||||
// database, such that it can be republished if something goes
|
// database, such that it can be republished if something goes
|
||||||
// wrong.
|
// wrong.
|
||||||
@ -908,9 +1032,45 @@ func (c *ChanCloser) ReceiveClosingSigned( //nolint:funlen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// auxCloseOutputs returns any additional outputs that should be used when
|
||||||
|
// closing the channel.
|
||||||
|
func (c *ChanCloser) auxCloseOutputs(
|
||||||
|
closeFee btcutil.Amount) (fn.Option[AuxCloseOutputs], error) {
|
||||||
|
|
||||||
|
var closeOuts fn.Option[AuxCloseOutputs]
|
||||||
|
err := fn.MapOptionZ(c.cfg.AuxCloser, func(aux AuxChanCloser) error {
|
||||||
|
req := AuxShutdownReq{
|
||||||
|
ChanPoint: c.chanPoint,
|
||||||
|
ShortChanID: c.cfg.Channel.ShortChanID(),
|
||||||
|
Initiator: c.cfg.Channel.IsInitiator(),
|
||||||
|
CommitBlob: c.cfg.Channel.LocalCommitmentBlob(),
|
||||||
|
FundingBlob: c.cfg.Channel.FundingBlob(),
|
||||||
|
}
|
||||||
|
outs, err := aux.AuxCloseOutputs(AuxCloseDesc{
|
||||||
|
AuxShutdownReq: req,
|
||||||
|
CloseFee: closeFee,
|
||||||
|
CommitFee: c.cfg.Channel.CommitFee(),
|
||||||
|
LocalCloseOutput: c.localCloseOutput,
|
||||||
|
RemoteCloseOutput: c.remoteCloseOutput,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
closeOuts = outs
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return closeOuts, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return closeOuts, nil
|
||||||
|
}
|
||||||
|
|
||||||
// proposeCloseSigned attempts to propose a new signature for the closing
|
// proposeCloseSigned attempts to propose a new signature for the closing
|
||||||
// transaction for a channel based on the prior fee negotiations and our current
|
// transaction for a channel based on the prior fee negotiations and our
|
||||||
// compromise fee.
|
// current compromise fee.
|
||||||
func (c *ChanCloser) proposeCloseSigned(fee btcutil.Amount) (
|
func (c *ChanCloser) proposeCloseSigned(fee btcutil.Amount) (
|
||||||
*lnwire.ClosingSigned, error) {
|
*lnwire.ClosingSigned, error) {
|
||||||
|
|
||||||
@ -928,6 +1088,26 @@ func (c *ChanCloser) proposeCloseSigned(fee btcutil.Amount) (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll also now see if the aux chan closer has any additional options
|
||||||
|
// for the closing purpose.
|
||||||
|
c.auxOutputs, err = c.auxCloseOutputs(fee)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c.auxOutputs.WhenSome(func(outs AuxCloseOutputs) {
|
||||||
|
closeOpts = append(
|
||||||
|
closeOpts, lnwallet.WithExtraCloseOutputs(
|
||||||
|
outs.ExtraCloseOutputs,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
closeOpts = append(
|
||||||
|
closeOpts, lnwallet.WithCustomCoopSort(
|
||||||
|
outs.CustomSort,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// With all our options added, we'll attempt to co-op close now.
|
||||||
rawSig, _, _, err := c.cfg.Channel.CreateCloseProposal(
|
rawSig, _, _, err := c.cfg.Channel.CreateCloseProposal(
|
||||||
fee, c.localDeliveryScript, c.remoteDeliveryScript,
|
fee, c.localDeliveryScript, c.remoteDeliveryScript,
|
||||||
closeOpts...,
|
closeOpts...,
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -152,6 +153,14 @@ func (m *mockChannel) ChannelPoint() wire.OutPoint {
|
|||||||
return m.chanPoint
|
return m.chanPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *mockChannel) LocalCommitmentBlob() fn.Option[tlv.Blob] {
|
||||||
|
return fn.None[tlv.Blob]()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockChannel) FundingBlob() fn.Option[tlv.Blob] {
|
||||||
|
return fn.None[tlv.Blob]()
|
||||||
|
}
|
||||||
|
|
||||||
func (m *mockChannel) MarkCoopBroadcasted(*wire.MsgTx,
|
func (m *mockChannel) MarkCoopBroadcasted(*wire.MsgTx,
|
||||||
lntypes.ChannelParty) error {
|
lntypes.ChannelParty) error {
|
||||||
|
|
||||||
@ -205,12 +214,20 @@ func (m *mockChannel) CompleteCooperativeClose(localSig,
|
|||||||
return &wire.MsgTx{}, 0, nil
|
return &wire.MsgTx{}, 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockChannel) LocalBalanceDust() bool {
|
func (m *mockChannel) LocalBalanceDust() (bool, btcutil.Amount) {
|
||||||
return false
|
return false, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockChannel) RemoteBalanceDust() bool {
|
func (m *mockChannel) RemoteBalanceDust() (bool, btcutil.Amount) {
|
||||||
return false
|
return false, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockChannel) CommitBalances() (btcutil.Amount, btcutil.Amount) {
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockChannel) CommitFee() btcutil.Amount {
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *mockChannel) ChanType() channeldb.ChannelType {
|
func (m *mockChannel) ChanType() channeldb.ChannelType {
|
||||||
|
@ -6,11 +6,13 @@ import (
|
|||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
|
"github.com/lightningnetwork/lnd/fn"
|
||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/lntypes"
|
"github.com/lightningnetwork/lnd/lntypes"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
"github.com/lightningnetwork/lnd/tlv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CoopFeeEstimator is used to estimate the fee of a co-op close transaction.
|
// CoopFeeEstimator is used to estimate the fee of a co-op close transaction.
|
||||||
@ -32,6 +34,14 @@ type Channel interface { //nolint:interfacebloat
|
|||||||
// ChannelPoint returns the channel point of the target channel.
|
// ChannelPoint returns the channel point of the target channel.
|
||||||
ChannelPoint() wire.OutPoint
|
ChannelPoint() wire.OutPoint
|
||||||
|
|
||||||
|
// LocalCommitmentBlob may return the auxiliary data storage blob for
|
||||||
|
// the local commitment transaction.
|
||||||
|
LocalCommitmentBlob() fn.Option[tlv.Blob]
|
||||||
|
|
||||||
|
// FundingBlob may return the auxiliary data storage blob related to
|
||||||
|
// funding details for the channel.
|
||||||
|
FundingBlob() fn.Option[tlv.Blob]
|
||||||
|
|
||||||
// MarkCoopBroadcasted persistently marks that the channel close
|
// MarkCoopBroadcasted persistently marks that the channel close
|
||||||
// transaction has been broadcast.
|
// transaction has been broadcast.
|
||||||
MarkCoopBroadcasted(*wire.MsgTx, lntypes.ChannelParty) error
|
MarkCoopBroadcasted(*wire.MsgTx, lntypes.ChannelParty) error
|
||||||
@ -60,13 +70,23 @@ type Channel interface { //nolint:interfacebloat
|
|||||||
|
|
||||||
// LocalBalanceDust returns true if when creating a co-op close
|
// LocalBalanceDust returns true if when creating a co-op close
|
||||||
// transaction, the balance of the local party will be dust after
|
// transaction, the balance of the local party will be dust after
|
||||||
// accounting for any anchor outputs.
|
// accounting for any anchor outputs. The dust value for the local
|
||||||
LocalBalanceDust() bool
|
// party is also returned.
|
||||||
|
LocalBalanceDust() (bool, btcutil.Amount)
|
||||||
|
|
||||||
// RemoteBalanceDust returns true if when creating a co-op close
|
// RemoteBalanceDust returns true if when creating a co-op close
|
||||||
// transaction, the balance of the remote party will be dust after
|
// transaction, the balance of the remote party will be dust after
|
||||||
// accounting for any anchor outputs.
|
// accounting for any anchor outputs. The dust value the remote party
|
||||||
RemoteBalanceDust() bool
|
// is also returned.
|
||||||
|
RemoteBalanceDust() (bool, btcutil.Amount)
|
||||||
|
|
||||||
|
// CommitBalances returns the local and remote balances in the current
|
||||||
|
// commitment state.
|
||||||
|
CommitBalances() (btcutil.Amount, btcutil.Amount)
|
||||||
|
|
||||||
|
// CommitFee returns the commitment fee for the current commitment
|
||||||
|
// state.
|
||||||
|
CommitFee() btcutil.Amount
|
||||||
|
|
||||||
// RemoteUpfrontShutdownScript returns the upfront shutdown script of
|
// RemoteUpfrontShutdownScript returns the upfront shutdown script of
|
||||||
// the remote party. If the remote party didn't specify such a script,
|
// the remote party. If the remote party didn't specify such a script,
|
||||||
|
@ -8814,7 +8814,7 @@ func CreateCooperativeCloseTx(fundingTxIn wire.TxIn,
|
|||||||
// LocalBalanceDust returns true if when creating a co-op close transaction,
|
// LocalBalanceDust returns true if when creating a co-op close transaction,
|
||||||
// the balance of the local party will be dust after accounting for any anchor
|
// the balance of the local party will be dust after accounting for any anchor
|
||||||
// outputs.
|
// outputs.
|
||||||
func (lc *LightningChannel) LocalBalanceDust() bool {
|
func (lc *LightningChannel) LocalBalanceDust() (bool, btcutil.Amount) {
|
||||||
lc.RLock()
|
lc.RLock()
|
||||||
defer lc.RUnlock()
|
defer lc.RUnlock()
|
||||||
|
|
||||||
@ -8828,13 +8828,15 @@ func (lc *LightningChannel) LocalBalanceDust() bool {
|
|||||||
localBalance += 2 * AnchorSize
|
localBalance += 2 * AnchorSize
|
||||||
}
|
}
|
||||||
|
|
||||||
return localBalance <= chanState.LocalChanCfg.DustLimit
|
localDust := chanState.LocalChanCfg.DustLimit
|
||||||
|
|
||||||
|
return localBalance <= localDust, localDust
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteBalanceDust returns true if when creating a co-op close transaction,
|
// RemoteBalanceDust returns true if when creating a co-op close transaction,
|
||||||
// the balance of the remote party will be dust after accounting for any anchor
|
// the balance of the remote party will be dust after accounting for any anchor
|
||||||
// outputs.
|
// outputs.
|
||||||
func (lc *LightningChannel) RemoteBalanceDust() bool {
|
func (lc *LightningChannel) RemoteBalanceDust() (bool, btcutil.Amount) {
|
||||||
lc.RLock()
|
lc.RLock()
|
||||||
defer lc.RUnlock()
|
defer lc.RUnlock()
|
||||||
|
|
||||||
@ -8848,7 +8850,40 @@ func (lc *LightningChannel) RemoteBalanceDust() bool {
|
|||||||
remoteBalance += 2 * AnchorSize
|
remoteBalance += 2 * AnchorSize
|
||||||
}
|
}
|
||||||
|
|
||||||
return remoteBalance <= chanState.RemoteChanCfg.DustLimit
|
remoteDust := chanState.RemoteChanCfg.DustLimit
|
||||||
|
|
||||||
|
return remoteBalance <= remoteDust, remoteDust
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitBalances returns the local and remote balances in the current
|
||||||
|
// commitment state.
|
||||||
|
func (lc *LightningChannel) CommitBalances() (btcutil.Amount, btcutil.Amount) {
|
||||||
|
lc.RLock()
|
||||||
|
defer lc.RUnlock()
|
||||||
|
|
||||||
|
chanState := lc.channelState
|
||||||
|
localCommit := lc.channelState.LocalCommitment
|
||||||
|
|
||||||
|
localBalance := localCommit.LocalBalance.ToSatoshis()
|
||||||
|
remoteBalance := localCommit.RemoteBalance.ToSatoshis()
|
||||||
|
|
||||||
|
if chanState.ChanType.HasAnchors() {
|
||||||
|
if chanState.IsInitiator {
|
||||||
|
localBalance += 2 * AnchorSize
|
||||||
|
} else {
|
||||||
|
remoteBalance += 2 * AnchorSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return localBalance, remoteBalance
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommitFee returns the commitment fee for the current commitment state.
|
||||||
|
func (lc *LightningChannel) CommitFee() btcutil.Amount {
|
||||||
|
lc.RLock()
|
||||||
|
defer lc.RUnlock()
|
||||||
|
|
||||||
|
return lc.channelState.LocalCommitment.CommitFee
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalcFee returns the commitment fee to use for the given fee rate
|
// CalcFee returns the commitment fee to use for the given fee rate
|
||||||
|
Loading…
Reference in New Issue
Block a user