mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
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:
commit
a74ed3a05b
2 changed files with 17 additions and 8 deletions
|
@ -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)
|
static UniValue walletpassphrase(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
|
||||||
|
@ -1879,7 +1872,18 @@ static UniValue walletpassphrase(const JSONRPCRequest& request)
|
||||||
pwallet->TopUpKeyPool();
|
pwallet->TopUpKeyPool();
|
||||||
|
|
||||||
pwallet->nRelockTime = GetTime() + nSleepTime;
|
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;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ Verify that a bitcoind node can load multiple wallet files
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import time
|
||||||
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.test_node import ErrorMatch
|
from test_framework.test_node import ErrorMatch
|
||||||
|
@ -273,7 +274,11 @@ class MultiWalletTest(BitcoinTestFramework):
|
||||||
assert 'w1' not in self.nodes[0].listwallets()
|
assert 'w1' not in self.nodes[0].listwallets()
|
||||||
|
|
||||||
# Successfully unload the wallet referenced by the request endpoint
|
# Successfully unload the wallet referenced by the request endpoint
|
||||||
|
# Also ensure unload works during walletpassphrase timeout
|
||||||
|
w2.encryptwallet('test')
|
||||||
|
w2.walletpassphrase('test', 1)
|
||||||
w2.unloadwallet()
|
w2.unloadwallet()
|
||||||
|
time.sleep(1.1)
|
||||||
assert 'w2' not in self.nodes[0].listwallets()
|
assert 'w2' not in self.nodes[0].listwallets()
|
||||||
|
|
||||||
# Successfully unload all wallets
|
# Successfully unload all wallets
|
||||||
|
|
Loading…
Add table
Reference in a new issue