Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lnd: Call loader.UnloadWallet on shutdown #4591

Merged
merged 1 commit into from Sep 15, 2020

Conversation

hsjoberg
Copy link
Contributor

@hsjoberg hsjoberg commented Sep 3, 2020

This is required to make restart work for LndMobile builds.
Not calling UnloadWallet would make UnlockWallet stall forever on the second run as the file is already opened.

This was pretty much a non-issue for the normal UNIX daemon build, as sending stopDaemon or SIGINT would close down the process and Go's runtime would presumably handle any open files.
But on mobile builds, this is not the case, thus we have to explicitly close it down.

Right now I'm just grabbing the loader all the way to Main and defer-ing the call so that it will execute once we get a shutdownChan signal, I'm unsure if this is the best approach.
N.B: wallet has to be opened for the main RPC server to function properly.

This is a part of an on-going work to address mobile restarting problems #4492.

@hsjoberg hsjoberg requested a review from Roasbeef as a code owner Sep 3, 2020
@hsjoberg hsjoberg force-pushed the walletloader-unload branch 2 times, most recently from 6849421 to aa5db41 Compare Sep 3, 2020
@hsjoberg hsjoberg changed the title Call loader.UnloadWallet on shutdown lnd: Call loader.UnloadWallet on shutdown Sep 3, 2020
@halseth halseth added the mobile label Sep 3, 2020
@halseth halseth requested review from halseth and removed request for Roasbeef Sep 3, 2020
Copy link
Collaborator

@halseth halseth left a comment

Nice, looks more or less good to me :)

lnd.go Outdated Show resolved Hide resolved
@halseth halseth requested a review from bhandras Sep 11, 2020
@@ -381,6 +381,11 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
walletInitParams = *params
privateWalletPw = walletInitParams.Password
publicWalletPw = walletInitParams.Password
defer func() {
if err := walletInitParams.Loader.UnloadWallet(); err != nil {
ltndLog.Errorf("Could not unload wallet: %v", err)
Copy link
Collaborator

@bhandras bhandras Sep 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way callers of Main would not know that there was an error with UnloadWallet() so there's no way to act (panic, or display an error message on the UI).

Copy link
Contributor Author

@hsjoberg hsjoberg Sep 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, any non-cli client will not get any feedback here.

This is the case for many things inside Main (and things that it calls), only the RPC calls get error feedback really.
For example, the healthchecker currently does play well with the mobile builds: https://github.com/lightningnetwork/lnd/blob/bc6e52888763765793dfa8887e7d88b517a6b913/server.go#L1268-L1313#

I suggest we take a look at mobile feedback issues at a later point. This is something I think is important and want to address, but it think it has to be designed to work with all the different errors Main can receive and breaking changes for the mobile build is most likely needed.

Copy link
Collaborator

@bhandras bhandras Sep 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sadly many defer code paths in Main ignore returned errors. These error cases should really be refined in the near future to allow safe restarts every time. Fortunately UnloadWallet can only fail if it's not loaded which we can ignore and if the DB cannot be closed which is unlikely. So while not ideal, I think we can postpone this refactor for now.

Copy link
Contributor Author

@hsjoberg hsjoberg Sep 12, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I'm definitely interested in helping addressing this.

@hsjoberg
Copy link
Contributor Author

hsjoberg commented Sep 11, 2020

Now passing UnloadWallet function pointer instead of Loader instance.
Also rebased.

@hsjoberg hsjoberg requested review from halseth and bhandras Sep 11, 2020
Copy link
Collaborator

@halseth halseth left a comment

LGTM 👍

Copy link
Collaborator

@bhandras bhandras left a comment

LGTM, sans the nit. Thanks @hsjoberg

walletunlocker/service.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@bhandras bhandras left a comment

I think there's one more potential issue.

@@ -1105,6 +1114,7 @@ func waitForWalletPassword(cfg *Config, restEndpoints []net.Addr,
RecoveryWindow: recoveryWindow,
Wallet: newWallet,
ChansToRestore: initMsg.ChanBackups,
UnloadWallet: loader.UnloadWallet,
Copy link
Collaborator

@bhandras bhandras Sep 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect that this will not be set if --noseedbackup is used which may eventually lead to a crash in the defer function

Copy link
Contributor Author

@hsjoberg hsjoberg Sep 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good thinking. Right now, the defer happens inside this if statement:

lnd/lnd.go

Line 375 in 97cfbec

if !cfg.NoSeedBackup {

I don't know how --noseedbackup works, but it's still opening a wallet? With the current code, the wallet file will not be unloaded if --noseedbackup is used.

Copy link
Collaborator

@bhandras bhandras Sep 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, indeed it's inside the if statement, missed that. Won't crash.

This is required to make restart work for LndMobile builds.
Not calling UnloadWallet would make `UnlockWallet` stall forever as
the file is already opened.
@halseth halseth merged commit b8eb41f into lightningnetwork:master Sep 15, 2020
11 checks passed
@Roasbeef Roasbeef added this to the 0.12.0 milestone Sep 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants