contractcourt: process channel close event on new beat

This commit is contained in:
yyforyongyu committed 2024-12-20 17:54:07 +08:00
1 parent c5b3033427
commit a6d3a0fa99
3 files changed
+86 -5

No files matched your search

+70
View File
@@ -2992,6 +2992,22 @@ func (c *ChannelArbitrator) handleBlockbeat(beat chainio.Blockbeat) error {
// Notify we've processed the block.
defer c.NotifyBlockProcessed(beat, nil)
// If the state is StateContractClosed, StateWaitingFullResolution, or
// StateFullyResolved, there's no need to read the close event channel
// and launch the resolvers since the arbitrator can only get to this
// state after processing a previous close event and launched all its
// resolvers.
if c.state.IsContractClosed() {
log.Infof("ChannelArbitrator(%v): skipping launching "+
"resolvers in state=%v", c.cfg.ChanPoint, c.state)
return nil
}
// Perform a non-blocking read on the close events in case the channel
// is closed in this blockbeat.
c.receiveAndProcessCloseEvent()
// Try to advance the state if we are in StateDefault.
if c.state == StateDefault {
// Now that a new block has arrived, we'll attempt to advance
@@ -3010,6 +3026,60 @@ func (c *ChannelArbitrator) handleBlockbeat(beat chainio.Blockbeat) error {
return nil
}
// receiveAndProcessCloseEvent does a non-blocking read on all the channel
// close event channels. If an event is received, it will be further processed.
func (c *ChannelArbitrator) receiveAndProcessCloseEvent() {
select {
// Received a coop close event, we now mark the channel as resolved and
// exit.
case closeInfo := <-c.cfg.ChainEvents.CooperativeClosure:
err := c.handleCoopCloseEvent(closeInfo)
if err != nil {
log.Errorf("Failed to handle coop close: %v", err)
return
}
// We have broadcast our commitment, and it is now confirmed onchain.
case closeInfo := <-c.cfg.ChainEvents.LocalUnilateralClosure:
if c.state != StateCommitmentBroadcasted {
log.Errorf("ChannelArbitrator(%v): unexpected "+
"local on-chain channel close", c.cfg.ChanPoint)
}
err := c.handleLocalForceCloseEvent(closeInfo)
if err != nil {
log.Errorf("Failed to handle local force close: %v",
err)
return
}
// The remote party has broadcast the commitment. We'll examine our
// state to determine if we need to act at all.
case uniClosure := <-c.cfg.ChainEvents.RemoteUnilateralClosure:
err := c.handleRemoteForceCloseEvent(uniClosure)
if err != nil {
log.Errorf("Failed to handle remote force close: %v",
err)
return
}
// The remote has breached the channel! We now launch the breach
// contract resolvers.
case breachInfo := <-c.cfg.ChainEvents.ContractBreach:
err := c.handleContractBreach(breachInfo)
if err != nil {
log.Errorf("Failed to handle contract breach: %v", err)
return
}
default:
log.Infof("ChannelArbitrator(%v) no close event",
c.cfg.ChanPoint)
}
}
// Name returns a human-readable string for this subsystem.
//
// NOTE: Part of chainio.Consumer interface.