lnwallet/chancloser: create a MsgMapper for the protofsm rbf close

This'll allow us to treat the state machine as a MsgEndpoint, and have
the readHandler in the peer automatically send new messages to it.
This commit is contained in:
Olaoluwa Osuntokun 2024-01-31 19:24:08 -08:00
parent 17af859cdc
commit c8ce507192

View File

@ -0,0 +1,77 @@
package chancloser
import (
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/lnwire"
)
// RbfMsgMapper is a struct that implements the MsgMapper interface for the
// rbf-coop close state machine. This enables the state machine to be used with
// protofsm.
type RbfMsgMapper struct {
// blockHeight is the height of the block when the co-op close request
// was initiated. This is used to validate conditions related to the
// thaw height.
blockHeight uint32
// chanID is the channel ID of the channel being closed.
chanID lnwire.ChannelID
}
// NewRbfMsgMapper creates a new RbfMsgMapper instance given the current block
// height when the co-op close request was initiated.
func NewRbfMsgMapper(blockHeight uint32,
chanID lnwire.ChannelID) *RbfMsgMapper {
return &RbfMsgMapper{
blockHeight: blockHeight,
chanID: chanID,
}
}
// someEvent returns the target type as a protocol event option.
func someEvent[T ProtocolEvent](m T) fn.Option[ProtocolEvent] {
return fn.Some(ProtocolEvent(m))
}
// isExpectedChanID returns true if the channel ID of the message matches the
// bound instance.
func (r *RbfMsgMapper) isExpectedChanID(chanID lnwire.ChannelID) bool {
return r.chanID == chanID
}
// MapMsg maps a wire message into a FSM event. If the message is not mappable,
// then an error is returned.
func (r *RbfMsgMapper) MapMsg(wireMsg lnwire.Message) fn.Option[ProtocolEvent] {
switch msg := wireMsg.(type) {
case *lnwire.Shutdown:
if !r.isExpectedChanID(msg.ChannelID) {
return fn.None[ProtocolEvent]()
}
return someEvent(&ShutdownReceived{
BlockHeight: r.blockHeight,
ShutdownScript: msg.Address,
})
case *lnwire.ClosingComplete:
if !r.isExpectedChanID(msg.ChannelID) {
return fn.None[ProtocolEvent]()
}
return someEvent(&OfferReceivedEvent{
SigMsg: *msg,
})
case *lnwire.ClosingSig:
if !r.isExpectedChanID(msg.ChannelID) {
return fn.None[ProtocolEvent]()
}
return someEvent(&LocalSigReceived{
SigMsg: *msg,
})
}
return fn.None[ProtocolEvent]()
}