Merge #14453: rpc: Fix wallet unload during walletpassphrase timeout

8907df9e02 qa: Ensure wallet unload during walletpassphrase timeout (João Barbosa)
321decffa1 rpc: Fix wallet unload during walletpassphrase timeout (João Barbosa)

Pull request description:

  Replaces the raw wallet pointer in the `RPCRunLater` callback with a `std::weak_ptr` to check if the wallet is not expired.

  To test:
  ```
  bitcoind -regtest
  bitcoin-cli -regtest encryptwallet foobar
  bitcoin-cli -regtest walletpassphrase foobar 5 && bitcoin-cli -regtest unloadwallet ""
  ```

  Fixes #14452.

Tree-SHA512: 311e839234f5fb7955ab5412a2cfc1903ee7132ea56a8ab992ede3614586834886bd65192b76531ae0aa3a526b38e70ca2e1cdbabe52995906ff97b49d93c268
This commit is contained in:
Wladimir J. van der Laan
2018-10-24 16:41:18 +02:00
2 changed files with 17 additions and 8 deletions
+12 -8
View File
@@ -1803,13 +1803,6 @@ static UniValue keypoolrefill(const JSONRPCRequest& request)
}
static void LockWallet(CWallet* pWallet)
{
LOCK(pWallet->cs_wallet);
pWallet->nRelockTime = 0;
pWallet->Lock();
}
static UniValue walletpassphrase(const JSONRPCRequest& request)
{
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
@@ -1879,7 +1872,18 @@ static UniValue walletpassphrase(const JSONRPCRequest& request)
pwallet->TopUpKeyPool();
pwallet->nRelockTime = GetTime() + nSleepTime;
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), std::bind(LockWallet, pwallet), nSleepTime);
// Keep a weak pointer to the wallet so that it is possible to unload the
// wallet before the following callback is called. If a valid shared pointer
// is acquired in the callback then the wallet is still loaded.
std::weak_ptr<CWallet> weak_wallet = wallet;
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), [weak_wallet] {
if (auto shared_wallet = weak_wallet.lock()) {
LOCK(shared_wallet->cs_wallet);
shared_wallet->Lock();
shared_wallet->nRelockTime = 0;
}
}, nSleepTime);
return NullUniValue;
}