Skip to content

Commit a74ed3a

Browse files
committed
Merge #14453: rpc: Fix wallet unload during walletpassphrase timeout
8907df9 qa: Ensure wallet unload during walletpassphrase timeout (João Barbosa) 321decf 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
2 parents 9886590 + 8907df9 commit a74ed3a

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

src/wallet/rpcwallet.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,13 +1803,6 @@ static UniValue keypoolrefill(const JSONRPCRequest& request)
18031803
}
18041804

18051805

1806-
static void LockWallet(CWallet* pWallet)
1807-
{
1808-
LOCK(pWallet->cs_wallet);
1809-
pWallet->nRelockTime = 0;
1810-
pWallet->Lock();
1811-
}
1812-
18131806
static UniValue walletpassphrase(const JSONRPCRequest& request)
18141807
{
18151808
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
@@ -1879,7 +1872,18 @@ static UniValue walletpassphrase(const JSONRPCRequest& request)
18791872
pwallet->TopUpKeyPool();
18801873

18811874
pwallet->nRelockTime = GetTime() + nSleepTime;
1882-
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), std::bind(LockWallet, pwallet), nSleepTime);
1875+
1876+
// Keep a weak pointer to the wallet so that it is possible to unload the
1877+
// wallet before the following callback is called. If a valid shared pointer
1878+
// is acquired in the callback then the wallet is still loaded.
1879+
std::weak_ptr<CWallet> weak_wallet = wallet;
1880+
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), [weak_wallet] {
1881+
if (auto shared_wallet = weak_wallet.lock()) {
1882+
LOCK(shared_wallet->cs_wallet);
1883+
shared_wallet->Lock();
1884+
shared_wallet->nRelockTime = 0;
1885+
}
1886+
}, nSleepTime);
18831887

18841888
return NullUniValue;
18851889
}

test/functional/wallet_multiwallet.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"""
99
import os
1010
import shutil
11+
import time
1112

1213
from test_framework.test_framework import BitcoinTestFramework
1314
from test_framework.test_node import ErrorMatch
@@ -273,7 +274,11 @@ def wallet_file(name):
273274
assert 'w1' not in self.nodes[0].listwallets()
274275

275276
# Successfully unload the wallet referenced by the request endpoint
277+
# Also ensure unload works during walletpassphrase timeout
278+
w2.encryptwallet('test')
279+
w2.walletpassphrase('test', 1)
276280
w2.unloadwallet()
281+
time.sleep(1.1)
277282
assert 'w2' not in self.nodes[0].listwallets()
278283

279284
# Successfully unload all wallets

0 commit comments

Comments
 (0)