chancloser

package
v0.18.4-beta.rc1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2024 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrChanAlreadyClosing is returned when a channel shutdown is
	// attempted more than once.
	ErrChanAlreadyClosing = fmt.Errorf("channel shutdown already initiated")

	// ErrChanCloseNotFinished is returned when a caller attempts to access
	// a field or function that is contingent on the channel closure
	// negotiation already being completed.
	ErrChanCloseNotFinished = fmt.Errorf("close negotiation not finished")

	// ErrInvalidState is returned when the closing state machine receives a
	// message while it is in an unknown state.
	ErrInvalidState = fmt.Errorf("invalid state")

	// ErrUpfrontShutdownScriptMismatch is returned when a peer or end user
	// provides a cooperative close script which does not match the upfront
	// shutdown script previously set for that party.
	ErrUpfrontShutdownScriptMismatch = fmt.Errorf("shutdown script does not " +
		"match upfront shutdown script")

	// ErrProposalExceedsMaxFee is returned when as the initiator, the
	// latest fee proposal sent by the responder exceed our max fee.
	// responder.
	ErrProposalExceedsMaxFee = fmt.Errorf("latest fee proposal exceeds " +
		"max fee")

	// ErrInvalidShutdownScript is returned when we receive an address from
	// a peer that isn't either a p2wsh or p2tr address.
	ErrInvalidShutdownScript = fmt.Errorf("invalid shutdown script")
)

Functions

func DisableLog

func DisableLog()

DisableLog disables all logging output.

func ParseUpfrontShutdownAddress

func ParseUpfrontShutdownAddress(address string,
	params *chaincfg.Params) (lnwire.DeliveryAddress, error)

ParseUpfrontShutdownAddress attempts to parse an upfront shutdown address. If the address is empty, it returns nil. If it successfully decoded the address, it returns a script that pays out to the address.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info.

Types

type AuxChanCloser

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],
		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)

	// FinalizeClose is called after the close transaction has been agreed
	// upon.
	FinalizeClose(desc AuxCloseDesc, closeTx *wire.MsgTx) error
}

AuxChanCloser is used to allow an external caller to modify the co-op close transaction.

type AuxCloseDesc

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]
}

AuxCloseDesc is used to describe the channel close that is being performed.

type AuxCloseOutputs

type AuxCloseOutputs struct {
	// ExtraCloseOutputs is a set of extra outputs that should be included
	// in the close transaction.
	ExtraCloseOutputs []lnwallet.CloseOutput

	// CustomSort is a custom function that can be used to sort the
	// transaction outputs. If this isn't set, then the default BIP-69
	// sorting is used.
	CustomSort lnwallet.CloseSortFunc
}

AuxCloseOutputs is used to specify extra outputs that should be used when constructing the co-op close transaction.

type AuxShutdownReq

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]
}

AuxShutdownReq is used to request a set of extra custom records to include in the shutdown message.

type ChanCloseCfg

type ChanCloseCfg struct {
	// Channel is the channel that should be closed.
	Channel Channel

	// MusigSession is used to handle generating musig2 nonces, and also
	// creating the proper set of closing options for taproot channels.
	MusigSession MusigSession

	// BroadcastTx broadcasts the passed transaction to the network.
	BroadcastTx func(*wire.MsgTx, string) error

	// DisableChannel disables a channel, resulting in it not being able to
	// forward payments.
	DisableChannel func(wire.OutPoint) error

	// Disconnect will disconnect from the remote peer in this close.
	Disconnect func() error

	// MaxFee, is non-zero represents the highest fee that the initiator is
	// willing to pay to close the channel.
	MaxFee chainfee.SatPerKWeight

	// ChainParams holds the parameters of the chain that we're active on.
	ChainParams *chaincfg.Params

	// Quit is a channel that should be sent upon in the occasion the state
	// machine should cease all progress and shutdown.
	Quit chan struct{}

	// FeeEstimator is used to estimate the absolute starting co-op close
	// fee.
	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]
}

ChanCloseCfg holds all the items that a ChanCloser requires to carry out its duties.

type ChanCloser

type ChanCloser struct {
	// contains filtered or unexported fields
}

ChanCloser is a state machine that handles the cooperative channel closure procedure. This includes shutting down a channel, marking it ineligible for routing HTLC's, negotiating fees with the remote party, and finally broadcasting the fully signed closure transaction to the network.

func NewChanCloser

func NewChanCloser(cfg ChanCloseCfg, deliveryScript DeliveryAddrWithKey,
	idealFeePerKw chainfee.SatPerKWeight, negotiationHeight uint32,
	closeReq *htlcswitch.ChanClose,
	closer lntypes.ChannelParty) *ChanCloser

NewChanCloser creates a new instance of the channel closure given the passed configuration, and delivery+fee preference. The final argument should only be populated iff, we're the initiator of this closing request.

func (*ChanCloser) AuxOutputs

func (c *ChanCloser) AuxOutputs() fn.Option[AuxCloseOutputs]

AuxOutputs returns optional extra outputs.

func (*ChanCloser) BeginNegotiation

func (c *ChanCloser) BeginNegotiation() (fn.Option[lnwire.ClosingSigned],
	error)

BeginNegotiation should be called when we have definitively reached a clean channel state and are ready to cooperatively arrive at a closing transaction. If it is our responsibility to kick off the negotiation, this method will generate a ClosingSigned message. If it is the remote's responsibility, then it will not. In either case it will transition the ChanCloser state machine to the negotiation phase wherein ClosingSigned messages are exchanged until a mutually agreeable result is achieved.

func (*ChanCloser) Channel

func (c *ChanCloser) Channel() *lnwallet.LightningChannel

Channel returns the channel stored in the config as a *lnwallet.LightningChannel.

NOTE: This method will PANIC if the underlying channel implementation isn't the desired type.

func (*ChanCloser) CloseRequest

func (c *ChanCloser) CloseRequest() *htlcswitch.ChanClose

CloseRequest returns the original close request that prompted the creation of the state machine.

NOTE: This will only return a non-nil pointer if we were the initiator of the cooperative closure workflow.

func (*ChanCloser) ClosingTx

func (c *ChanCloser) ClosingTx() (*wire.MsgTx, error)

ClosingTx returns the fully signed, final closing transaction.

NOTE: This transaction is only available if the state machine is in the closeFinished state.

func (*ChanCloser) LocalCloseOutput

func (c *ChanCloser) LocalCloseOutput() fn.Option[CloseOutput]

LocalCloseOutput returns the local close output.

func (*ChanCloser) NegotiationHeight

func (c *ChanCloser) NegotiationHeight() uint32

NegotiationHeight returns the negotiation height.

func (*ChanCloser) ReceiveClosingSigned

func (c *ChanCloser) ReceiveClosingSigned(
	msg lnwire.ClosingSigned) (fn.Option[lnwire.ClosingSigned], error)

ReceiveClosingSigned is a method that should be called whenever we receive a ClosingSigned message from the wire. It may or may not return a ClosingSigned of our own to send back to the remote.

func (*ChanCloser) ReceiveShutdown

func (c *ChanCloser) ReceiveShutdown(msg lnwire.Shutdown) (
	fn.Option[lnwire.Shutdown], error)

ReceiveShutdown takes a raw Shutdown message and uses it to try and advance the ChanCloser state machine, failing if it is coming in at an invalid time. If appropriate, it will also generate a Shutdown message of its own to send out to the peer. It is possible for this method to return None when no error occurred.

func (*ChanCloser) RemoteCloseOutput

func (c *ChanCloser) RemoteCloseOutput() fn.Option[CloseOutput]

RemoteCloseOutput returns the remote close output.

func (*ChanCloser) ShutdownChan

func (c *ChanCloser) ShutdownChan() (*lnwire.Shutdown, error)

ShutdownChan is the first method that's to be called by the initiator of the cooperative channel closure. This message returns the shutdown message to send to the remote party. Upon completion, we enter the closeShutdownInitiated phase as we await a response.

type Channel

type Channel interface {
	// ChannelPoint returns the channel point of the target channel.
	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
	// transaction has been broadcast.
	MarkCoopBroadcasted(*wire.MsgTx, lntypes.ChannelParty) error

	// MarkShutdownSent persists the given ShutdownInfo. The existence of
	// the ShutdownInfo represents the fact that the Shutdown message has
	// been sent by us and so should be re-sent on re-establish.
	MarkShutdownSent(info *channeldb.ShutdownInfo) error

	// IsInitiator returns true we are the initiator of the channel.
	IsInitiator() bool

	// ShortChanID returns the scid of the channel.
	ShortChanID() lnwire.ShortChannelID

	// ChanType returns the channel type of the channel.
	ChanType() channeldb.ChannelType

	// FundingTxOut returns the funding output of the channel.
	FundingTxOut() *wire.TxOut

	// AbsoluteThawHeight returns the absolute thaw height of the channel.
	// If the channel is pending, or an unconfirmed zero conf channel, then
	// an error should be returned.
	AbsoluteThawHeight() (uint32, error)

	// 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 outputs. The dust value for the local
	// party is also returned.
	LocalBalanceDust() (bool, btcutil.Amount)

	// 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 outputs. The dust value the remote party
	// 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
	// the remote party. If the remote party didn't specify such a script,
	// an empty delivery address should be returned.
	RemoteUpfrontShutdownScript() lnwire.DeliveryAddress

	// CreateCloseProposal creates a new co-op close proposal in the form
	// of a valid signature, the chainhash of the final txid, and our final
	// balance in the created state.
	CreateCloseProposal(proposedFee btcutil.Amount,
		localDeliveryScript []byte, remoteDeliveryScript []byte,
		closeOpt ...lnwallet.ChanCloseOpt,
	) (
		input.Signature, *chainhash.Hash, btcutil.Amount, error)

	// CompleteCooperativeClose persistently "completes" the cooperative
	// close by producing a fully signed co-op close transaction.
	CompleteCooperativeClose(localSig, remoteSig input.Signature,
		localDeliveryScript, remoteDeliveryScript []byte,
		proposedFee btcutil.Amount, closeOpt ...lnwallet.ChanCloseOpt,
	) (*wire.MsgTx, btcutil.Amount, error)
}

Channel abstracts away from the core channel state machine by exposing an interface that requires only the methods we need to carry out the channel closing process.

type CloseOutput

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
}

CloseOutput represents an output that should be included in the close transaction.

type CoopFeeEstimator

type CoopFeeEstimator interface {
	// EstimateFee estimates an _absolute_ fee for a co-op close transaction
	// given the local+remote tx outs (for the co-op close transaction),
	// channel type, and ideal fee rate. If a passed TxOut is nil, then
	// that indicates that an output is dust on the co-op close transaction
	// _before_ fees are accounted for.
	EstimateFee(chanType channeldb.ChannelType,
		localTxOut, remoteTxOut *wire.TxOut,
		idealFeeRate chainfee.SatPerKWeight) btcutil.Amount
}

CoopFeeEstimator is used to estimate the fee of a co-op close transaction.

type DeliveryAddrWithKey

type DeliveryAddrWithKey struct {
	// DeliveryAddress is the raw, serialized pkScript of the delivery
	// address.
	lnwire.DeliveryAddress

	// InternalKey is the Taproot internal key of the delivery address, if
	// the address is a P2TR output.
	InternalKey fn.Option[btcec.PublicKey]
}

DeliveryAddrWithKey wraps a normal delivery addr, but also includes the internal key for the delivery addr if known.

type MusigSession

type MusigSession interface {
	// ProposalClosingOpts generates the set of closing options needed to
	// generate a new musig2 proposal signature.
	ProposalClosingOpts() ([]lnwallet.ChanCloseOpt, error)

	// CombineClosingOpts returns the options that should be used when
	// combining the final musig partial signature. The method also maps
	// the lnwire partial signatures into an input.Signature that can be
	// used more generally.
	CombineClosingOpts(localSig, remoteSig lnwire.PartialSig,
	) (input.Signature, input.Signature, []lnwallet.ChanCloseOpt, error)

	// ClosingNonce generates the nonce we'll use to generate the musig2
	// partial signatures for the co-op close transaction.
	ClosingNonce() (*musig2.Nonces, error)

	// InitRemoteNonce saves the remote nonce the party sent during their
	// shutdown message so it can be used later to generate and verify
	// signatures.
	InitRemoteNonce(nonce *musig2.Nonces)
}

MusigSession is an interface that abstracts away the details of the musig2 session details. A session is used to generate the necessary closing options needed to close a channel cooperatively.

type SimpleCoopFeeEstimator

type SimpleCoopFeeEstimator struct {
}

SimpleCoopFeeEstimator is the default co-op close fee estimator. It assumes a normal segwit v0 channel, and that no outputs on the closing transaction are dust.

func (*SimpleCoopFeeEstimator) EstimateFee

func (d *SimpleCoopFeeEstimator) EstimateFee(chanType channeldb.ChannelType,
	localTxOut, remoteTxOut *wire.TxOut,
	idealFeeRate chainfee.SatPerKWeight) btcutil.Amount

EstimateFee estimates an _absolute_ fee for a co-op close transaction given the local+remote tx outs (for the co-op close transaction), channel type, and ideal fee rate.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL