lnd: allow shutdown signal during IsSynced check

Prior to this commit, lnd could become unresponsive to shutdown signals
during the `IsSynced` check. Since the `IsSynced` check can occasionally
take a long time to complete, this could result in lnd failing to shut
down promptly.
This commit is contained in:
Viktor Tigerström 2024-09-24 17:58:08 +02:00
parent 1acc8393bc
commit 52b3a06733
No known key found for this signature in database
GPG Key ID: B984570980684DCC
2 changed files with 49 additions and 15 deletions

View File

@ -27,6 +27,10 @@
cause a nil pointer dereference during the probing of a payment request that cause a nil pointer dereference during the probing of a payment request that
does not contain a payment address. does not contain a payment address.
* [Fix a bug](https://github.com/lightningnetwork/lnd/pull/9137) that prevented
a graceful shutdown of LND during the main chain backend sync check in certain
cases.
# New Features # New Features
## Functional Enhancements ## Functional Enhancements
## RPC Additions ## RPC Additions
@ -75,4 +79,5 @@
* CharlieZKSmith * CharlieZKSmith
* Elle Mouton * Elle Mouton
* Pins * Pins
* Viktor Tigerström
* Ziggie * Ziggie

59
lnd.go
View File

@ -667,25 +667,54 @@ func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg,
ltndLog.Infof("Waiting for chain backend to finish sync, "+ ltndLog.Infof("Waiting for chain backend to finish sync, "+
"start_height=%v", bestHeight) "start_height=%v", bestHeight)
type syncResult struct {
synced bool
bestBlockTime int64
err error
}
var syncedResChan = make(chan syncResult, 1)
for { for {
if !interceptor.Alive() { // We check if the wallet is synced in a separate goroutine as
// the call is blocking, and we want to be able to interrupt it
// if the daemon is shutting down.
go func() {
synced, bestBlockTime, err := activeChainControl.Wallet.
IsSynced()
syncedResChan <- syncResult{synced, bestBlockTime, err}
}()
select {
case <-interceptor.ShutdownChannel():
return nil return nil
case res := <-syncedResChan:
if res.err != nil {
return mkErr("unable to determine if wallet "+
"is synced: %v", res.err)
}
ltndLog.Debugf("Syncing to block timestamp: %v, is "+
"synced=%v", time.Unix(res.bestBlockTime, 0),
res.synced)
if res.synced {
break
}
// If we're not yet synced, we'll wait for a second
// before checking again.
select {
case <-interceptor.ShutdownChannel():
return nil
case <-time.After(time.Second):
continue
}
} }
synced, ts, err := activeChainControl.Wallet.IsSynced() break
if err != nil {
return mkErr("unable to determine if wallet is "+
"synced: %v", err)
}
ltndLog.Debugf("Syncing to block timestamp: %v, is synced=%v",
time.Unix(ts, 0), synced)
if synced {
break
}
time.Sleep(time.Second * 1)
} }
_, bestHeight, err = activeChainControl.ChainIO.GetBestBlock() _, bestHeight, err = activeChainControl.ChainIO.GetBestBlock()