diff --git a/peer/daemon_adapters.go b/peer/daemon_adapters.go new file mode 100644 index 000000000..606f88b25 --- /dev/null +++ b/peer/daemon_adapters.go @@ -0,0 +1,149 @@ +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. +// +//nolint:unused +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. +// +//nolint:unused +type peerMsgSender struct { + sender flexMessageSender + peerPub btcec.PublicKey +} + +// newPeerMsgSender creates a new instance of a peerMsgSender. +// +//nolint:unused +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? +// +//nolint:unused +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)