synchronize recovery shutdown
synchronize recovery shutdown

(*Wallet).recovery is the only internal consumer of (*RecoveryManager).Resurrect
and (*Wallet).recoverScopedAddresses, which together account for all uses
of (*ScopedKeyManager).DeriveFromKeyPath. The (*ScopedKeyManager).mtx is locked
there, but not the (*ScopedKeyManager).rootManager.mtx, which is what protects
the `cryptoKeyPriv` and `cryptoKeyScript` during `(*Manager).Lock`. There
some care taken to prevent operations with these keys with the *Manager
locked, but the actualy operations involving the key are done outside
of the rootManager.mtx lock, meaning a (*Manager).Lock could occur between
the (*Manager).IsLocked check and the use of the key, resulting in data
being encrypted with a zeroed key. The data race was observed in
independent testing with the Go -race detector.

Other approaches were considered. Unfortunately, the ScopedKeyManager
cannot forego its own mutex and share the Manager's mutex, since there
are multiple recursions. We could carefully lock the (*Manager).mtx
only around the places it's used, and check the (*Manager).locked
every time after locking and before use, returning an error if
locked, but that is rather tedious and doesn't solve the larger
issue of synchronizing wallet locking with the end of recovery.

btcsuite/btcwallet,btcsuite/btcwallet