lnd/protofsm/daemon_events.go
Olaoluwa Osuntokun 424ae09631
protofsm: add ability for state machine to consume wire msgs
In this commit, we add the ability for the state machine to consume wire
messages. This'll allow the creation of a new generic message router
that takes the place of the current peer `readHandler` in an upcoming
commit.
2024-11-18 20:48:59 -08:00

119 lines
3.9 KiB
Go

package protofsm
import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/lnwire"
)
// DaemonEvent is a special event that can be emitted by a state transition
// function. A state machine can use this to perform side effects, such as
// sending a message to a peer, or broadcasting a transaction.
type DaemonEvent interface {
daemonSealed()
}
// DaemonEventSet is a set of daemon events that can be emitted by a state
// transition.
type DaemonEventSet []DaemonEvent
// DaemonEvents is a special type constraint that enumerates all the possible
// types of daemon events.
type DaemonEvents interface {
SendMsgEvent[any] | BroadcastTxn | RegisterSpend[any] |
RegisterConf[any]
}
// SendPredicate is a function that returns true if the target message should
// sent.
type SendPredicate = func() bool
// SendMsgEvent is a special event that can be emitted by a state transition
// that instructs the daemon to send the contained message to the target peer.
type SendMsgEvent[Event any] struct {
// TargetPeer is the peer to send the message to.
TargetPeer btcec.PublicKey
// Msgs is the set of messages to send to the target peer.
Msgs []lnwire.Message
// SendWhen implements a system for a conditional send once a special
// send predicate has been met.
//
// TODO(roasbeef): contrast with usage of OnCommitFlush, etc
SendWhen fn.Option[SendPredicate]
// PostSendEvent is an optional event that is to be emitted after the
// message has been sent. If a SendWhen is specified, then this will
// only be executed after that returns true to unblock the send.
PostSendEvent fn.Option[Event]
}
// daemonSealed indicates that this struct is a DaemonEvent instance.
func (s *SendMsgEvent[E]) daemonSealed() {}
// BroadcastTxn indicates the target transaction should be broadcast to the
// network.
type BroadcastTxn struct {
// Tx is the transaction to broadcast.
Tx *wire.MsgTx
// Label is an optional label to attach to the transaction.
Label string
}
// daemonSealed indicates that this struct is a DaemonEvent instance.
func (b *BroadcastTxn) daemonSealed() {}
// RegisterSpend is used to request that a certain event is sent into the state
// machien once the specified outpoint has been spent.
type RegisterSpend[Event any] struct {
// OutPoint is the outpoint on chain to watch.
OutPoint wire.OutPoint
// PkScript is the script that we expect to be spent along with the
// outpoint.
PkScript []byte
// HeightHint is a value used to give the chain scanner a hint on how
// far back it needs to start its search.
HeightHint uint32
// PostSpendEvent is an event that's sent back to the requester once a
// transaction spending the outpoint has been confirmed in the main
// chain.
PostSpendEvent fn.Option[Event]
}
// daemonSealed indicates that this struct is a DaemonEvent instance.
func (r *RegisterSpend[E]) daemonSealed() {}
// RegisterConf is used to request that a certain event is sent into the state
// machien once the specified outpoint has been spent.
type RegisterConf[Event any] struct {
// Txid is the txid of the txn we want to watch the chain for.
Txid chainhash.Hash
// PkScript is the script that we expect to be created along with the
// outpoint.
PkScript []byte
// HeightHint is a value used to give the chain scanner a hint on how
// far back it needs to start its search.
HeightHint uint32
// NumConfs is the number of confirmations that the spending
// transaction needs to dispatch an event.
NumConfs fn.Option[uint32]
// PostConfEvent is an event that's sent back to the requester once the
// transaction specified above has confirmed in the chain with
// sufficient depth.
PostConfEvent fn.Option[Event]
}
// daemonSealed indicates that this struct is a DaemonEvent instance.
func (r *RegisterConf[E]) daemonSealed() {}