diff --git a/lnwallet/chancloser/aux_closer.go b/lnwallet/chancloser/aux_closer.go index 62f475dd4..e810b360c 100644 --- a/lnwallet/chancloser/aux_closer.go +++ b/lnwallet/chancloser/aux_closer.go @@ -1,78 +1,13 @@ package chancloser import ( - "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/fn/v2" "github.com/lightningnetwork/lnd/lnwallet" + "github.com/lightningnetwork/lnd/lnwallet/types" "github.com/lightningnetwork/lnd/lnwire" - "github.com/lightningnetwork/lnd/tlv" ) -// CloseOutput represents an output that should be included in the close -// transaction. -type CloseOutput struct { - // Amt is the amount of the output. - Amt btcutil.Amount - - // DustLimit is the dust limit for the local node. - DustLimit btcutil.Amount - - // PkScript is the script that should be used to pay to the output. - PkScript []byte - - // ShutdownRecords is the set of custom records that may result in - // extra close outputs being added. - ShutdownRecords lnwire.CustomRecords -} - -// AuxShutdownReq is used to request a set of extra custom records to include -// in the shutdown message. -type AuxShutdownReq struct { - // ChanPoint is the channel point of the channel that is being shut - // down. - ChanPoint wire.OutPoint - - // ShortChanID is the short channel ID of the channel that is being - // closed. - ShortChanID lnwire.ShortChannelID - - // Initiator is true if the local node is the initiator of the channel. - Initiator bool - - // InternalKey is the internal key for the shutdown addr. This will - // only be set for taproot shutdown addrs. - InternalKey fn.Option[btcec.PublicKey] - - // CommitBlob is the blob that was included in the last commitment. - CommitBlob fn.Option[tlv.Blob] - - // FundingBlob is the blob that was included in the funding state. - FundingBlob fn.Option[tlv.Blob] -} - -// AuxCloseDesc is used to describe the channel close that is being performed. -type AuxCloseDesc struct { - AuxShutdownReq - - // CloseFee is the closing fee to be paid for this state. - CloseFee btcutil.Amount - - // CommitFee is the fee that was paid for the last commitment. - CommitFee btcutil.Amount - - // LocalCloseOutput is the output that the local node should be paid - // to. This is None if the local party will not have an output on the - // co-op close transaction. - LocalCloseOutput fn.Option[CloseOutput] - - // RemoteCloseOutput is the output that the remote node should be paid - // to. This will be None if the remote party will not have an output on - // the co-op close transaction. - RemoteCloseOutput fn.Option[CloseOutput] -} - // AuxCloseOutputs is used to specify extra outputs that should be used when // constructing the co-op close transaction. type AuxCloseOutputs struct { @@ -91,14 +26,15 @@ type AuxCloseOutputs struct { type AuxChanCloser interface { // ShutdownBlob returns the set of custom records that should be // included in the shutdown message. - ShutdownBlob(req AuxShutdownReq) (fn.Option[lnwire.CustomRecords], + ShutdownBlob(req types.AuxShutdownReq) (fn.Option[lnwire.CustomRecords], error) // AuxCloseOutputs returns the set of custom outputs that should be used // to construct the co-op close transaction. - AuxCloseOutputs(desc AuxCloseDesc) (fn.Option[AuxCloseOutputs], error) + AuxCloseOutputs(desc types.AuxCloseDesc) (fn.Option[AuxCloseOutputs], + error) // FinalizeClose is called after the close transaction has been agreed // upon. - FinalizeClose(desc AuxCloseDesc, closeTx *wire.MsgTx) error + FinalizeClose(desc types.AuxCloseDesc, closeTx *wire.MsgTx) error } diff --git a/lnwallet/chancloser/chancloser.go b/lnwallet/chancloser/chancloser.go index cc6ccffa8..90e91f615 100644 --- a/lnwallet/chancloser/chancloser.go +++ b/lnwallet/chancloser/chancloser.go @@ -19,6 +19,7 @@ import ( "github.com/lightningnetwork/lnd/lnutils" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/chainfee" + "github.com/lightningnetwork/lnd/lnwallet/types" "github.com/lightningnetwork/lnd/lnwire" ) @@ -239,12 +240,12 @@ type ChanCloser struct { // 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] + localCloseOutput fn.Option[types.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] + remoteCloseOutput fn.Option[types.CloseOutput] // auxOutputs are the optional additional outputs that might be added to // the closing transaction. @@ -378,14 +379,17 @@ func (c *ChanCloser) initChanShutdown() (*lnwire.Shutdown, error) { // 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(), - InternalKey: c.localInternalKey, - CommitBlob: c.cfg.Channel.LocalCommitmentBlob(), - FundingBlob: c.cfg.Channel.FundingBlob(), - }) + channel := c.cfg.Channel + shutdownCustomRecords, err := a.ShutdownBlob( + types.AuxShutdownReq{ + ChanPoint: c.chanPoint, + ShortChanID: channel.ShortChanID(), + Initiator: channel.IsInitiator(), + InternalKey: c.localInternalKey, + CommitBlob: channel.LocalCommitmentBlob(), + FundingBlob: channel.FundingBlob(), + }, + ) if err != nil { return err } @@ -442,7 +446,7 @@ func (c *ChanCloser) initChanShutdown() (*lnwire.Shutdown, error) { // it might still carry value in custom channel terms. _, dustAmt := c.cfg.Channel.LocalBalanceDust() localBalance, _ := c.cfg.Channel.CommitBalances() - c.localCloseOutput = fn.Some(CloseOutput{ + c.localCloseOutput = fn.Some(types.CloseOutput{ Amt: localBalance, DustLimit: dustAmt, PkScript: c.localDeliveryScript, @@ -519,12 +523,12 @@ func (c *ChanCloser) NegotiationHeight() uint32 { } // LocalCloseOutput returns the local close output. -func (c *ChanCloser) LocalCloseOutput() fn.Option[CloseOutput] { +func (c *ChanCloser) LocalCloseOutput() fn.Option[types.CloseOutput] { return c.localCloseOutput } // RemoteCloseOutput returns the remote close output. -func (c *ChanCloser) RemoteCloseOutput() fn.Option[CloseOutput] { +func (c *ChanCloser) RemoteCloseOutput() fn.Option[types.CloseOutput] { return c.remoteCloseOutput } @@ -590,7 +594,7 @@ func (c *ChanCloser) ReceiveShutdown(msg lnwire.Shutdown) ( // 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{ + c.remoteCloseOutput = fn.Some(types.CloseOutput{ Amt: remoteBalance, DustLimit: dustAmt, PkScript: msg.Address, @@ -976,7 +980,7 @@ func (c *ChanCloser) ReceiveClosingSigned( //nolint:funlen c.cfg.AuxCloser, func(aux AuxChanCloser) error { channel := c.cfg.Channel //nolint:ll - req := AuxShutdownReq{ + req := types.AuxShutdownReq{ ChanPoint: c.chanPoint, ShortChanID: c.cfg.Channel.ShortChanID(), InternalKey: c.localInternalKey, @@ -984,7 +988,7 @@ func (c *ChanCloser) ReceiveClosingSigned( //nolint:funlen CommitBlob: channel.LocalCommitmentBlob(), FundingBlob: channel.FundingBlob(), } - desc := AuxCloseDesc{ + desc := types.AuxCloseDesc{ AuxShutdownReq: req, LocalCloseOutput: c.localCloseOutput, RemoteCloseOutput: c.remoteCloseOutput, @@ -1053,7 +1057,7 @@ func (c *ChanCloser) auxCloseOutputs( var closeOuts fn.Option[AuxCloseOutputs] err := fn.MapOptionZ(c.cfg.AuxCloser, func(aux AuxChanCloser) error { - req := AuxShutdownReq{ + req := types.AuxShutdownReq{ ChanPoint: c.chanPoint, ShortChanID: c.cfg.Channel.ShortChanID(), InternalKey: c.localInternalKey, @@ -1061,7 +1065,7 @@ func (c *ChanCloser) auxCloseOutputs( CommitBlob: c.cfg.Channel.LocalCommitmentBlob(), FundingBlob: c.cfg.Channel.FundingBlob(), } - outs, err := aux.AuxCloseOutputs(AuxCloseDesc{ + outs, err := aux.AuxCloseOutputs(types.AuxCloseDesc{ AuxShutdownReq: req, CloseFee: closeFee, CommitFee: c.cfg.Channel.CommitFee(), diff --git a/lnwallet/types/close_types.go b/lnwallet/types/close_types.go new file mode 100644 index 000000000..490b08f24 --- /dev/null +++ b/lnwallet/types/close_types.go @@ -0,0 +1,73 @@ +package types + +import ( + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/wire" + "github.com/lightningnetwork/lnd/fn/v2" + "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/tlv" +) + +// CloseOutput represents an output that should be included in the close +// transaction. +type CloseOutput struct { + // Amt is the amount of the output. + Amt btcutil.Amount + + // DustLimit is the dust limit for the local node. + DustLimit btcutil.Amount + + // PkScript is the script that should be used to pay to the output. + PkScript []byte + + // ShutdownRecords is the set of custom records that may result in + // extra close outputs being added. + ShutdownRecords lnwire.CustomRecords +} + +// AuxShutdownReq is used to request a set of extra custom records to include +// in the shutdown message. +type AuxShutdownReq struct { + // ChanPoint is the channel point of the channel that is being shut + // down. + ChanPoint wire.OutPoint + + // ShortChanID is the short channel ID of the channel that is being + // closed. + ShortChanID lnwire.ShortChannelID + + // Initiator is true if the local node is the initiator of the channel. + Initiator bool + + // InternalKey is the internal key for the shutdown addr. This will + // only be set for taproot shutdown addrs. + InternalKey fn.Option[btcec.PublicKey] + + // CommitBlob is the blob that was included in the last commitment. + CommitBlob fn.Option[tlv.Blob] + + // FundingBlob is the blob that was included in the funding state. + FundingBlob fn.Option[tlv.Blob] +} + +// AuxCloseDesc is used to describe the channel close that is being performed. +type AuxCloseDesc struct { + AuxShutdownReq + + // CloseFee is the closing fee to be paid for this state. + CloseFee btcutil.Amount + + // CommitFee is the fee that was paid for the last commitment. + CommitFee btcutil.Amount + + // LocalCloseOutput is the output that the local node should be paid + // to. This is None if the local party will not have an output on the + // co-op close transaction. + LocalCloseOutput fn.Option[CloseOutput] + + // RemoteCloseOutput is the output that the remote node should be paid + // to. This will be None if the remote party will not have an output on + // the co-op close transaction. + RemoteCloseOutput fn.Option[CloseOutput] +} diff --git a/peer/brontide.go b/peer/brontide.go index 8d02ca6e5..d606c09a8 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -44,6 +44,7 @@ import ( "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwallet/chancloser" + "github.com/lightningnetwork/lnd/lnwallet/types" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/msgmux" "github.com/lightningnetwork/lnd/netann" @@ -169,12 +170,12 @@ type ChannelCloseUpdate struct { // LocalCloseOutput is an optional, additional 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[chancloser.CloseOutput] + LocalCloseOutput fn.Option[types.CloseOutput] // RemoteCloseOutput is an optional, additional 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[chancloser.CloseOutput] + RemoteCloseOutput fn.Option[types.CloseOutput] // AuxOutputs is an optional set of additional outputs that might be // included in the closing transaction. These are used for custom diff --git a/rpcserver.go b/rpcserver.go index ee810d1e1..c7d48e9f1 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -69,6 +69,7 @@ import ( "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwallet/chancloser" "github.com/lightningnetwork/lnd/lnwallet/chanfunding" + "github.com/lightningnetwork/lnd/lnwallet/types" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/macaroons" "github.com/lightningnetwork/lnd/onionmessage" @@ -3060,7 +3061,7 @@ func createRPCCloseUpdate( err := fn.MapOptionZ( u.LocalCloseOutput, - func(closeOut chancloser.CloseOutput) error { + func(closeOut types.CloseOutput) error { cr, err := closeOut.ShutdownRecords.Serialize() if err != nil { return fmt.Errorf("error serializing "+ @@ -3085,7 +3086,7 @@ func createRPCCloseUpdate( err = fn.MapOptionZ( u.RemoteCloseOutput, - func(closeOut chancloser.CloseOutput) error { + func(closeOut types.CloseOutput) error { cr, err := closeOut.ShutdownRecords.Serialize() if err != nil { return fmt.Errorf("error serializing "+