mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-26 17:52:25 +01:00
In this commit, we fully integrate the new RBF close state machine into the peer. For the restart case after shutdown, we can short circuit the existing logic as the new FSM will handle retransmitting the shutdown message itself, and doesn't need to delegate that duty to the link. Unlike the existing state machine, we're able to restart the flow to sign a coop close with a new higher fee rate. In this case, we can now send multiple updates to the RPC caller, one for each newly singed coop close transaction. To implement the async flush case, we'll launch a new goroutine to wait until the state machine reaches the `ChannelFlushing` state, then we'll register the hook. We don't do this at start up, as otherwise the channel may _already_ be flushed, triggering an invalid state transition.
142 lines
4.5 KiB
Go
142 lines
4.5 KiB
Go
package peer
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/btcsuite/btcd/btcec/v2"
|
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
|
"github.com/btcsuite/btcd/wire"
|
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
"github.com/lightningnetwork/lnd/protofsm"
|
|
)
|
|
|
|
// MessageSender is an interface that represents an object capable of sending
|
|
// p2p messages to a destination.
|
|
type MessageSender interface {
|
|
// SendMessages sends the target set of messages to the target peer.
|
|
//
|
|
// TODO(roasbeef): current impl bound to single peer, need server
|
|
// pointer otherwise
|
|
SendMessages(btcec.PublicKey, []lnwire.Message) error
|
|
}
|
|
|
|
// flexMessageSender is a message sender-like interface that is aware of
|
|
// sync/async semantics, and is bound to a single peer.
|
|
type flexMessageSender interface {
|
|
// SendMessage sends a variadic number of high-priority messages to the
|
|
// remote peer. The first argument denotes if the method should block
|
|
// until the messages have been sent to the remote peer or an error is
|
|
// returned, otherwise it returns immediately after queuing.
|
|
SendMessage(sync bool, msgs ...lnwire.Message) error
|
|
}
|
|
|
|
// peerMsgSender implements the MessageSender interface for a single peer.
|
|
// It'll return an error if the target public isn't equal to public key of the
|
|
// backing peer.
|
|
type peerMsgSender struct {
|
|
sender flexMessageSender
|
|
peerPub btcec.PublicKey
|
|
}
|
|
|
|
// newPeerMsgSender creates a new instance of a peerMsgSender.
|
|
func newPeerMsgSender(peerPub btcec.PublicKey,
|
|
msgSender flexMessageSender) *peerMsgSender {
|
|
|
|
return &peerMsgSender{
|
|
sender: msgSender,
|
|
peerPub: peerPub,
|
|
}
|
|
}
|
|
|
|
// SendMessages sends the target set of messages to the target peer.
|
|
//
|
|
// TODO(roasbeef): current impl bound to single peer, need server pointer
|
|
// otherwise?
|
|
func (p *peerMsgSender) SendMessages(pub btcec.PublicKey,
|
|
msgs []lnwire.Message) error {
|
|
|
|
if !p.peerPub.IsEqual(&pub) {
|
|
return fmt.Errorf("wrong peer pubkey: got %x, can only send "+
|
|
"to %x", pub.SerializeCompressed(),
|
|
p.peerPub.SerializeCompressed())
|
|
}
|
|
|
|
return p.sender.SendMessage(true, msgs...)
|
|
}
|
|
|
|
// TxBroadcaster is an interface that represents an object capable of
|
|
// broadcasting transactions to the network.
|
|
type TxBroadcaster interface {
|
|
// PublishTransaction broadcasts a transaction to the network.
|
|
PublishTransaction(*wire.MsgTx, string) error
|
|
}
|
|
|
|
// LndAdapterCfg is a struct that holds the configuration for the
|
|
// LndDaemonAdapters instance.
|
|
type LndAdapterCfg struct {
|
|
// MsgSender is capable of sending messages to an arbitrary peer.
|
|
MsgSender MessageSender
|
|
|
|
// TxBroadcaster is capable of broadcasting a transaction to the
|
|
// network.
|
|
TxBroadcaster TxBroadcaster
|
|
|
|
// ChainNotifier is capable of receiving notifications for on-chain
|
|
// events.
|
|
ChainNotifier chainntnfs.ChainNotifier
|
|
}
|
|
|
|
// LndDaemonAdapters is a struct that implements the protofsm.DaemonAdapters
|
|
// interface using common lnd abstractions.
|
|
type LndDaemonAdapters struct {
|
|
cfg LndAdapterCfg
|
|
}
|
|
|
|
// NewLndDaemonAdapters creates a new instance of the lndDaemonAdapters struct.
|
|
func NewLndDaemonAdapters(cfg LndAdapterCfg) *LndDaemonAdapters {
|
|
return &LndDaemonAdapters{
|
|
cfg: cfg,
|
|
}
|
|
}
|
|
|
|
// SendMessages sends the target set of messages to the target peer.
|
|
func (l *LndDaemonAdapters) SendMessages(pub btcec.PublicKey,
|
|
msgs []lnwire.Message) error {
|
|
|
|
return l.cfg.MsgSender.SendMessages(pub, msgs)
|
|
}
|
|
|
|
// BroadcastTransaction broadcasts a transaction with the target label.
|
|
func (l *LndDaemonAdapters) BroadcastTransaction(tx *wire.MsgTx,
|
|
label string) error {
|
|
|
|
return l.cfg.TxBroadcaster.PublishTransaction(tx, label)
|
|
}
|
|
|
|
// RegisterConfirmationsNtfn registers an intent to be notified once txid
|
|
// reaches numConfs confirmations.
|
|
func (l *LndDaemonAdapters) RegisterConfirmationsNtfn(txid *chainhash.Hash,
|
|
pkScript []byte, numConfs, heightHint uint32,
|
|
opts ...chainntnfs.NotifierOption,
|
|
) (*chainntnfs.ConfirmationEvent, error) {
|
|
|
|
return l.cfg.ChainNotifier.RegisterConfirmationsNtfn(
|
|
txid, pkScript, numConfs, heightHint, opts...,
|
|
)
|
|
}
|
|
|
|
// RegisterSpendNtfn registers an intent to be notified once the target
|
|
// outpoint is successfully spent within a transaction.
|
|
func (l *LndDaemonAdapters) RegisterSpendNtfn(outpoint *wire.OutPoint,
|
|
pkScript []byte, heightHint uint32) (*chainntnfs.SpendEvent, error) {
|
|
|
|
return l.cfg.ChainNotifier.RegisterSpendNtfn(
|
|
outpoint, pkScript, heightHint,
|
|
)
|
|
}
|
|
|
|
// A compile time check to ensure that lndDaemonAdapters fully implements the
|
|
// DaemonAdapters interface.
|
|
var _ protofsm.DaemonAdapters = (*LndDaemonAdapters)(nil)
|