mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-02 16:59:44 +01:00
Merge #18814: rpc: Relock wallet only if most recent callback
9f59dde974rpc: Relock wallet only if most recent callback (João Barbosa)a2e6db5c4frpc: Add mutex to guard deadlineTimers (João Barbosa) Pull request description: This PR fixes an early relocking race condition from #18811 where old relock callback runs after new wallet unlock code and nRelockTime update but before rpcRunLater call, causing early relock and incorrect nRelockTime time Issue introduced in #18487. Fixes #18811. ACKs for top commit: MarcoFalke: ACK9f59dde974ryanofsky: Code review ACK9f59dde974. No changes since last review except squashing commits. jonatack: ACK9f59dde974Tree-SHA512: 2f7fc03e5ab6037337f2d82dfad432495cc337c77d07c968ee2355105db6292f24543c03456f5402e0e759577a4327758f9372f7ea29de6d56dc3695fda9b379
This commit is contained in:
@@ -1892,6 +1892,9 @@ static UniValue walletpassphrase(const JSONRPCRequest& request)
|
||||
}.Check(request);
|
||||
|
||||
int64_t nSleepTime;
|
||||
int64_t relock_time;
|
||||
// Prevent concurrent calls to walletpassphrase with the same wallet.
|
||||
LOCK(pwallet->m_unlock_mutex);
|
||||
{
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
@@ -1929,6 +1932,7 @@ static UniValue walletpassphrase(const JSONRPCRequest& request)
|
||||
pwallet->TopUpKeyPool();
|
||||
|
||||
pwallet->nRelockTime = GetTime() + nSleepTime;
|
||||
relock_time = pwallet->nRelockTime;
|
||||
}
|
||||
|
||||
// rpcRunLater must be called without cs_wallet held otherwise a deadlock
|
||||
@@ -1940,9 +1944,11 @@ static UniValue walletpassphrase(const JSONRPCRequest& request)
|
||||
// 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;
|
||||
pwallet->chain().rpcRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), [weak_wallet] {
|
||||
pwallet->chain().rpcRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), [weak_wallet, relock_time] {
|
||||
if (auto shared_wallet = weak_wallet.lock()) {
|
||||
LOCK(shared_wallet->cs_wallet);
|
||||
// Skip if this is not the most recent rpcRunLater callback.
|
||||
if (shared_wallet->nRelockTime != relock_time) return;
|
||||
shared_wallet->Lock();
|
||||
shared_wallet->nRelockTime = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user