rpcserver: prevent shutdown during wallet recovery

If the wallet recovery chain rescan was aborted before it finished, the
user would need to remember to use a positive recovery_window value the
next time they unlock the wallet for the rescan to continue. Because
forgetting to do so could lead to an incomplete wallet state (and
therefore potential missing funds) we rather don't allow shutting down
lnd through the RPC while a rescan is in progress.
This won't prevent any user from manually signaling Ctrl+C to kill lnd.
But that user might also check the log and see there's still something
going on that's preventing lnd from shutting down.
This commit is contained in:
Oliver Gugger 2021-06-07 13:15:10 +02:00
parent 42099ef5e1
commit ce9ccd3f14
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

@ -5531,8 +5531,24 @@ func (r *rpcServer) GetNetworkInfo(ctx context.Context,
// StopDaemon will send a shutdown request to the interrupt handler, triggering // StopDaemon will send a shutdown request to the interrupt handler, triggering
// a graceful shutdown of the daemon. // a graceful shutdown of the daemon.
func (r *rpcServer) StopDaemon(ctx context.Context, func (r *rpcServer) StopDaemon(_ context.Context,
_ *lnrpc.StopRequest) (*lnrpc.StopResponse, error) { _ *lnrpc.StopRequest) (*lnrpc.StopResponse, error) {
// Before we even consider a shutdown, are we currently in recovery
// mode? We don't want to allow shutting down during recovery because
// that would mean the user would have to manually continue the rescan
// process next time by using `lncli unlock --recovery_window X`
// otherwise some funds wouldn't be picked up.
isRecoveryMode, progress, err := r.server.cc.Wallet.GetRecoveryInfo()
if err != nil {
return nil, fmt.Errorf("unable to get wallet recovery info: %v",
err)
}
if isRecoveryMode && progress < 1 {
return nil, fmt.Errorf("wallet recovery in progress, cannot " +
"shut down, please wait until rescan finishes")
}
r.interceptor.RequestShutdown() r.interceptor.RequestShutdown()
return &lnrpc.StopResponse{}, nil return &lnrpc.StopResponse{}, nil
} }