mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-08-27 06:01:48 +02:00
peer: add new composite chanCloserFsm type
In this commit, we add a new composite chanCloserFsm type. This'll allow us to store a single value that might be a negotiator or and rbf-er. In a follow up commit, we'll use this to conditionally create the new rbf closer.
This commit is contained in:
@@ -445,6 +445,18 @@ type Config struct {
|
|||||||
Quit chan struct{}
|
Quit chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// chanCloserFsm is a union-like type that can hold the two versions of co-op
|
||||||
|
// close we support: negotiation, and RBF based.
|
||||||
|
//
|
||||||
|
// TODO(roasbeef): rename to chancloser.Negotiator and chancloser.RBF?
|
||||||
|
type chanCloserFsm = fn.Either[*chancloser.ChanCloser, *chancloser.RbfChanCloser] //nolint:ll
|
||||||
|
|
||||||
|
func makeNegotiateCloser(chanCloser *chancloser.ChanCloser) chanCloserFsm {
|
||||||
|
return fn.NewLeft[*chancloser.ChanCloser, *chancloser.RbfChanCloser](
|
||||||
|
chanCloser,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// Brontide is an active peer on the Lightning Network. This struct is responsible
|
// Brontide is an active peer on the Lightning Network. This struct is responsible
|
||||||
// for managing any channel state related to this peer. To do so, it has
|
// for managing any channel state related to this peer. To do so, it has
|
||||||
// several helper goroutines to handle events such as HTLC timeouts, new
|
// several helper goroutines to handle events such as HTLC timeouts, new
|
||||||
@@ -543,7 +555,7 @@ type Brontide struct {
|
|||||||
// cooperative channel closures. Any channel closing messages are directed
|
// cooperative channel closures. Any channel closing messages are directed
|
||||||
// to one of these active state machines. Once the channel has been closed,
|
// to one of these active state machines. Once the channel has been closed,
|
||||||
// the state machine will be deleted from the map.
|
// the state machine will be deleted from the map.
|
||||||
activeChanCloses map[lnwire.ChannelID]*chancloser.ChanCloser
|
activeChanCloses map[lnwire.ChannelID]chanCloserFsm
|
||||||
|
|
||||||
// localCloseChanReqs is a channel in which any local requests to close
|
// localCloseChanReqs is a channel in which any local requests to close
|
||||||
// a particular channel are sent over.
|
// a particular channel are sent over.
|
||||||
@@ -629,7 +641,7 @@ func NewBrontide(cfg Config) *Brontide {
|
|||||||
removePendingChannel: make(chan *newChannelMsg),
|
removePendingChannel: make(chan *newChannelMsg),
|
||||||
|
|
||||||
activeMsgStreams: make(map[lnwire.ChannelID]*msgStream),
|
activeMsgStreams: make(map[lnwire.ChannelID]*msgStream),
|
||||||
activeChanCloses: make(map[lnwire.ChannelID]*chancloser.ChanCloser),
|
activeChanCloses: make(map[lnwire.ChannelID]chanCloserFsm),
|
||||||
localCloseChanReqs: make(chan *htlcswitch.ChanClose),
|
localCloseChanReqs: make(chan *htlcswitch.ChanClose),
|
||||||
linkFailures: make(chan linkFailureReport),
|
linkFailures: make(chan linkFailureReport),
|
||||||
chanCloseMsgs: make(chan *closeMsg),
|
chanCloseMsgs: make(chan *closeMsg),
|
||||||
@@ -1218,8 +1230,9 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
|
|||||||
"delivery addr: %w", err)
|
"delivery addr: %w", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
chanCloser, err := p.createChanCloser(
|
negotiateChanCloser, err := p.createChanCloser(
|
||||||
lnChan, addr, feePerKw, nil, info.Closer(),
|
lnChan, addr, feePerKw, nil,
|
||||||
|
info.Closer(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
shutdownInfoErr = fmt.Errorf("unable to "+
|
shutdownInfoErr = fmt.Errorf("unable to "+
|
||||||
@@ -1232,10 +1245,14 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
|
|||||||
lnChan.State().FundingOutpoint,
|
lnChan.State().FundingOutpoint,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
chanCloser := makeNegotiateCloser(
|
||||||
|
negotiateChanCloser,
|
||||||
|
)
|
||||||
|
|
||||||
p.activeChanCloses[chanID] = chanCloser
|
p.activeChanCloses[chanID] = chanCloser
|
||||||
|
|
||||||
// Create the Shutdown message.
|
// Create the Shutdown message.
|
||||||
shutdown, err := chanCloser.ShutdownChan()
|
shutdown, err := negotiateChanCloser.ShutdownChan()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
delete(p.activeChanCloses, chanID)
|
delete(p.activeChanCloses, chanID)
|
||||||
shutdownInfoErr = err
|
shutdownInfoErr = err
|
||||||
@@ -2947,7 +2964,7 @@ func (p *Brontide) reenableActiveChannels() {
|
|||||||
// Otherwise, either an existing state machine will be returned, or a new one
|
// Otherwise, either an existing state machine will be returned, or a new one
|
||||||
// will be created.
|
// will be created.
|
||||||
func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
||||||
*chancloser.ChanCloser, error) {
|
*chanCloserFsm, error) {
|
||||||
|
|
||||||
chanCloser, found := p.activeChanCloses[chanID]
|
chanCloser, found := p.activeChanCloses[chanID]
|
||||||
if found {
|
if found {
|
||||||
@@ -2955,7 +2972,7 @@ func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
|||||||
// created for a non-pending channel or for a channel that had
|
// created for a non-pending channel or for a channel that had
|
||||||
// previously started the shutdown process but the connection
|
// previously started the shutdown process but the connection
|
||||||
// was restarted.
|
// was restarted.
|
||||||
return chanCloser, nil
|
return &chanCloser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, we'll ensure that we actually know of the target channel. If
|
// First, we'll ensure that we actually know of the target channel. If
|
||||||
@@ -3001,7 +3018,7 @@ func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to parse addr: %w", err)
|
return nil, fmt.Errorf("unable to parse addr: %w", err)
|
||||||
}
|
}
|
||||||
chanCloser, err = p.createChanCloser(
|
negotiateChanCloser, err := p.createChanCloser(
|
||||||
channel, addr, feePerKw, nil, lntypes.Remote,
|
channel, addr, feePerKw, nil, lntypes.Remote,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -3009,9 +3026,11 @@ func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
|||||||
return nil, fmt.Errorf("unable to create chan closer")
|
return nil, fmt.Errorf("unable to create chan closer")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chanCloser = makeNegotiateCloser(negotiateChanCloser)
|
||||||
|
|
||||||
p.activeChanCloses[chanID] = chanCloser
|
p.activeChanCloses[chanID] = chanCloser
|
||||||
|
|
||||||
return chanCloser, nil
|
return &chanCloser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// filterChannelsToEnable filters a list of channels to be enabled upon start.
|
// filterChannelsToEnable filters a list of channels to be enabled upon start.
|
||||||
@@ -3265,7 +3284,7 @@ func (p *Brontide) restartCoopClose(lnChan *lnwallet.LightningChannel) (
|
|||||||
// goroutine since this is done before the channelManager goroutine is
|
// goroutine since this is done before the channelManager goroutine is
|
||||||
// created.
|
// created.
|
||||||
chanID := lnwire.NewChanIDFromOutPoint(c.FundingOutpoint)
|
chanID := lnwire.NewChanIDFromOutPoint(c.FundingOutpoint)
|
||||||
p.activeChanCloses[chanID] = chanCloser
|
p.activeChanCloses[chanID] = makeNegotiateCloser(chanCloser)
|
||||||
|
|
||||||
// Create the Shutdown message.
|
// Create the Shutdown message.
|
||||||
shutdownMsg, err := chanCloser.ShutdownChan()
|
shutdownMsg, err := chanCloser.ShutdownChan()
|
||||||
@@ -3365,7 +3384,7 @@ func (p *Brontide) initNegotiateChanCloser(req *htlcswitch.ChanClose,
|
|||||||
}
|
}
|
||||||
|
|
||||||
chanID := lnwire.NewChanIDFromOutPoint(*req.ChanPoint)
|
chanID := lnwire.NewChanIDFromOutPoint(*req.ChanPoint)
|
||||||
p.activeChanCloses[chanID] = chanCloser
|
p.activeChanCloses[chanID] = makeNegotiateCloser(chanCloser)
|
||||||
|
|
||||||
// Finally, we'll initiate the channel shutdown within the
|
// Finally, we'll initiate the channel shutdown within the
|
||||||
// chanCloser, and send the shutdown message to the remote
|
// chanCloser, and send the shutdown message to the remote
|
||||||
@@ -3469,6 +3488,7 @@ func (p *Brontide) initRbfChanCloser(
|
|||||||
return p.genDeliveryScript()
|
return p.genDeliveryScript()
|
||||||
},
|
},
|
||||||
FeeEstimator: &chancloser.SimpleCoopFeeEstimator{},
|
FeeEstimator: &chancloser.SimpleCoopFeeEstimator{},
|
||||||
|
CloseSigner: channel,
|
||||||
ChanObserver: newChanObserver(
|
ChanObserver: newChanObserver(
|
||||||
channel, link, p.cfg.ChanStatusMgr,
|
channel, link, p.cfg.ChanStatusMgr,
|
||||||
),
|
),
|
||||||
@@ -4165,7 +4185,7 @@ func (p *Brontide) handleCloseMsg(msg *closeMsg) {
|
|||||||
|
|
||||||
// We'll now fetch the matching closing state machine in order to continue,
|
// We'll now fetch the matching closing state machine in order to continue,
|
||||||
// or finalize the channel closure process.
|
// or finalize the channel closure process.
|
||||||
chanCloser, err := p.fetchActiveChanCloser(msg.cid)
|
chanCloserE, err := p.fetchActiveChanCloser(msg.cid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the channel is not known to us, we'll simply ignore this message.
|
// If the channel is not known to us, we'll simply ignore this message.
|
||||||
if err == ErrChannelNotFound {
|
if err == ErrChannelNotFound {
|
||||||
@@ -4182,17 +4202,31 @@ func (p *Brontide) handleCloseMsg(msg *closeMsg) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if chanCloserE.IsRight() {
|
||||||
|
// TODO(roasbeef): assert?
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, we'll only enter this call path if a negotiate chan
|
||||||
|
// closer was used. So we'll extract that from the either now.
|
||||||
|
//
|
||||||
|
// TODO(roabeef): need extra helper func for either to make cleaner
|
||||||
|
var chanCloser *chancloser.ChanCloser
|
||||||
|
chanCloserE.WhenLeft(func(c *chancloser.ChanCloser) {
|
||||||
|
chanCloser = c
|
||||||
|
})
|
||||||
|
|
||||||
handleErr := func(err error) {
|
handleErr := func(err error) {
|
||||||
err = fmt.Errorf("unable to process close msg: %w", err)
|
err = fmt.Errorf("unable to process close msg: %w", err)
|
||||||
p.log.Error(err)
|
p.log.Error(err)
|
||||||
|
|
||||||
// As the negotiations failed, we'll reset the channel state machine to
|
// As the negotiations failed, we'll reset the channel state
|
||||||
// ensure we act to on-chain events as normal.
|
// machine to ensure we act to on-chain events as normal.
|
||||||
chanCloser.Channel().ResetState()
|
chanCloser.Channel().ResetState()
|
||||||
|
|
||||||
if chanCloser.CloseRequest() != nil {
|
if chanCloser.CloseRequest() != nil {
|
||||||
chanCloser.CloseRequest().Err <- err
|
chanCloser.CloseRequest().Err <- err
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(p.activeChanCloses, msg.cid)
|
delete(p.activeChanCloses, msg.cid)
|
||||||
|
|
||||||
p.Disconnect(err)
|
p.Disconnect(err)
|
||||||
|
Reference in New Issue
Block a user