From 75b5d8c4ead9c41f08fe53f9fffd3ffc984d6684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Wed, 10 Oct 2018 00:32:27 +0100 Subject: [PATCH] rpc: Fix wallet unload during walletpassphrase timeout Github-Pull: #14453 Rebased-From: 321decf --- src/wallet/rpcwallet.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 6400b4470..193da7655 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2546,13 +2546,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 const wallet = GetWalletForJSONRPCRequest(request); @@ -2622,7 +2615,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 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; }