chainwatcher: only continue breach handling after successfully marked
closed This commit makes the handoff procedure between the breachabiter and chainwatcher use a function closure to mark the channel pending closed in the DB. Doing it this way we know that the channel has been markd pending closed in the DB when ProcessACK returns. The reason we do this is that we really need a "two-way ACK" to have the breacharbiter know it can go on with the breach handling. Earlier it would just send the ACK on the channel and continue. This lead to a race where breach handling could finish before the chain watcher had marked the channel pending closed in the database, which again lead to the breacharbiter failing to mark the channel fully closed. We saw this causing flakes during itests.
This commit is contained in:
3 files changed
+58
-35
No files matched your search
@@ -949,7 +949,8 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
||||
},
|
||||
IsOurAddress: cc.Wallet.IsOurAddress,
|
||||
ContractBreach: func(chanPoint wire.OutPoint,
|
||||
breachRet *lnwallet.BreachRetribution) error {
|
||||
breachRet *lnwallet.BreachRetribution,
|
||||
markClosed func() error) error {
|
||||
|
||||
// processACK will handle the breachArbiter ACKing the
|
||||
// event.
|
||||
@@ -960,7 +961,9 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
||||
return
|
||||
}
|
||||
|
||||
finalErr <- nil
|
||||
// If the breachArbiter successfully handled
|
||||
// the event, we can mark the channel closed.
|
||||
finalErr <- markClosed()
|
||||
}
|
||||
|
||||
event := &ContractBreachEvent{
|
||||
@@ -976,7 +979,9 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
||||
return ErrServerShuttingDown
|
||||
}
|
||||
|
||||
// Wait for the breachArbiter to ACK the event.
|
||||
// We'll wait for a final error to be available, either
|
||||
// from the breachArbiter or from our markClosed
|
||||
// function closure.
|
||||
select {
|
||||
case err := <-finalErr:
|
||||
return err
|
||||
|
||||
Reference in new issue
Block a user