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

Close wallet db on shutdown #566

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

roeierez
Copy link
Contributor

This PR ensure that after the wallet is shut down the database will be closed as well.
To do so the "syncWithChain" go routine was added to the wait group to make sure it competes before we attempt to close the wallet db.
In addition I added explicit db.Close call after all go routines have exited.
This is crucial to be able to use dependent systems such LND as library (such as in mobile) and run it multiple times on the same process.

@howardpen9
Copy link

Hi, would you support SegWit and LND?

// some reason, however, the wallet will not be marked synced
// and many methods will error early since the wallet is known
// to be out of date.
defer w.wg.Done()
Copy link
Contributor

Choose a reason for hiding this comment

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

style nit: move this to the top of the method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

wallet/wallet.go Outdated

//We can close the db now that we know all go routines have exited and
//we are sure no further attempts to write to the wallet db will be done.
w.db.Close()
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice catch!

However, I don't think this is the correct place to close the db. Ideally it should be closed from the same context as where it is opened. Since the db is opened by the wallet loader, we should instead make sure UnloadWallet is called properly from the loader.

It looks like UnloadWallet waits for the wallet to shutdown before closing the db, so maybe just adding the onClientConnected goroutine is enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your review @halseth and sorry for my late response, somehow lost track of this issue.
To see that I understand:

  1. I will leave the onClientConnected function since it adds a waiting for the syncToChain go routine that is needed.
  2. I will remove the db.Close call.

The impact of this is that users that uses btcwallet as library will be responsible to call loader.UnloadWallet on shutdown and not only wallet.Stop (as it is now in LND).
If this is what you think needed I will need to create another fix in LND to explicitly call UnloadWallet on shutdown.
LMK your thoughts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At the moment I removed the db.Close and rebased.

Copy link
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

Yes, I think that's correct. In lnd's case that means that it should be unloaded from this context: https://github.com/lightningnetwork/lnd/blob/d6d833c2421f4a65c6db5190d1dcd73f549fbf70/lnwallet/btcwallet/btcwallet.go#L116. Haven't looked into where exactly it should be called from though.

@@ -317,6 +317,22 @@ func (w *Wallet) activeData(dbtx walletdb.ReadTx) ([]btcutil.Address, []wtxmgr.C
return addrs, unspent, err
}

func (w *Wallet) onClientConnected(birthdayStamp *waddrmgr.BlockStamp) {
w.wg.Add(1)
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be called the line before the goroutine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

Copy link
Contributor Author

@roeierez roeierez Dec 17, 2018

Choose a reason for hiding this comment

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

@halseth another issue with the syncWithChain function related to the shutdown is that it runs in a loop and doesn't check for ShuttingDown() during its run. The problem even gets worst when the shutdown request comes at time where the code is at this point: https://github.com/btcsuite/btcwallet/blob/master/wallet/wallet.go#L460
the go routine keeps running forever stuck inside this block preventing from wallet shutdown.
I can add such kind of check inside this block and on every iteration of the outer loop. Do you think it is a good solution or can suggest a better one?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, checking the quit signal on every iteration sounds like a good idea :)

Copy link
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

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

LGTM after squashing the two commits into one! 👍

@roeierez roeierez force-pushed the gracefull_shutdown branch from 0cfec82 to 92a6c73 Compare March 19, 2019 07:06
@roeierez
Copy link
Contributor Author

Squashed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants