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:
Johan T. Halseth committed 2021-05-06 12:37:11 +02:00
1 parent bdc1f3100d
commit ac49031396
3 files changed
+58 -35

No files matched your search

+8 -3
View File
@@ -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