contractcourt: process channel close event on new beat
This commit is contained in:
3 files changed
+86
-5
No files matched your search
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user