use WalletContext scheduler for walletpassphrase callback
This commit is contained in:
2 files changed
+14
-11
No files matched your search
@@ -3,6 +3,8 @@
|
|||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <rpc/util.h>
|
#include <rpc/util.h>
|
||||||
|
#include <scheduler.h>
|
||||||
|
#include <wallet/context.h>
|
||||||
#include <wallet/rpc/util.h>
|
#include <wallet/rpc/util.h>
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
|
|
||||||
@@ -88,24 +90,24 @@ RPCHelpMan walletpassphrase()
|
|||||||
relock_time = pwallet->nRelockTime;
|
relock_time = pwallet->nRelockTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rpcRunLater must be called without cs_wallet held otherwise a deadlock
|
// Get wallet scheduler to queue up the relock callback in the future.
|
||||||
// can occur. The deadlock would happen when RPCRunLater removes the
|
// Scheduled events don't get destructed until they are executed,
|
||||||
// previous timer (and waits for the callback to finish if already running)
|
// and they are executed in series in a single scheduler thread so
|
||||||
// and the callback locks cs_wallet.
|
// no cs_wallet lock is needed.
|
||||||
AssertLockNotHeld(wallet->cs_wallet);
|
WalletContext& context = EnsureWalletContext(request.context);
|
||||||
// Keep a weak pointer to the wallet so that it is possible to unload the
|
// 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
|
// wallet before the following callback is called. If a valid shared pointer
|
||||||
// is acquired in the callback then the wallet is still loaded.
|
// is acquired in the callback then the wallet is still loaded.
|
||||||
std::weak_ptr<CWallet> weak_wallet = wallet;
|
std::weak_ptr<CWallet> weak_wallet = wallet;
|
||||||
pwallet->chain().rpcRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), [weak_wallet, relock_time] {
|
context.scheduler->scheduleFromNow([weak_wallet, relock_time] {
|
||||||
if (auto shared_wallet = weak_wallet.lock()) {
|
if (auto shared_wallet = weak_wallet.lock()) {
|
||||||
LOCK2(shared_wallet->m_relock_mutex, shared_wallet->cs_wallet);
|
LOCK2(shared_wallet->m_relock_mutex, shared_wallet->cs_wallet);
|
||||||
// Skip if this is not the most recent rpcRunLater callback.
|
// Skip if this is not the most recent relock callback.
|
||||||
if (shared_wallet->nRelockTime != relock_time) return;
|
if (shared_wallet->nRelockTime != relock_time) return;
|
||||||
shared_wallet->Lock();
|
shared_wallet->Lock();
|
||||||
shared_wallet->nRelockTime = 0;
|
shared_wallet->nRelockTime = 0;
|
||||||
}
|
}
|
||||||
}, nSleepTime);
|
}, std::chrono::seconds(nSleepTime));
|
||||||
|
|
||||||
return UniValue::VNULL;
|
return UniValue::VNULL;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test the wallet keypool and interaction with wallet encryption/locking."""
|
"""Test the wallet keypool and interaction with wallet encryption/locking."""
|
||||||
|
|
||||||
import time
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
@@ -127,8 +126,10 @@ class KeyPoolTest(BitcoinTestFramework):
|
|||||||
nodes[0].keypoolrefill(3)
|
nodes[0].keypoolrefill(3)
|
||||||
|
|
||||||
# test walletpassphrase timeout
|
# test walletpassphrase timeout
|
||||||
time.sleep(1.1)
|
# CScheduler relies on condition_variable::wait_until() which does not
|
||||||
assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0)
|
# guarantee accurate timing. We'll wait up to 5 seconds to execute a 1
|
||||||
|
# second scheduled event.
|
||||||
|
nodes[0].wait_until(lambda: nodes[0].getwalletinfo()["unlocked_until"] == 0, timeout=5)
|
||||||
|
|
||||||
# drain the keypool
|
# drain the keypool
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
|
|||||||
Reference in new issue
Block a user