aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.h
diff options
context:
space:
mode:
authorAndrew Chow <github@achow101.com>2023-02-21 13:56:29 -0500
committerAndrew Chow <github@achow101.com>2023-02-21 14:02:49 -0500
commit80f4979322b574be29c684b2e106804432420ebf (patch)
tree12fb2150c7a520ca1dd460d93bbecac2cbfa696f /src/wallet/wallet.h
parentad461416025eb1581e8b20a95a4f316107b9431b (diff)
parent6a5b348f2e526f048d0b448b01f6c4ab608569af (diff)
Merge bitcoin/bitcoin#26347: wallet: ensure the wallet is unlocked when needed for rescanning
6a5b348f2e526f048d0b448b01f6c4ab608569af test: test rescanning encrypted wallets (ishaanam) 493b813e171a389a8b6750b4f2e42e8363a0267e wallet: ensure that the passphrase is not deleted from memory when being used to rescan (ishaanam) 66a86ebabb26a055ca92af846bfa39dbd2f9f722 wallet: keep track of when the passphrase is needed when rescanning (ishaanam) Pull request description: Wallet passphrases are needed to top up the keypool of encrypted wallets during a rescan. The following RPCs need the passphrase when rescanning: - `importdescriptors` - `rescanblockchain` The following RPCs use the information about whether or not the passphrase is being used to ensure that full rescans are able to take place (meaning the following RPCs should not be able to run if a rescan requiring the wallet to be unlocked is taking place): - `walletlock` - `encryptwallet` - `walletpassphrasechange` `m_relock_mutex` is also introduced so that the passphrase is not deleted from memory when the timeout provided in `walletpassphrase` is up and the wallet is still rescanning. Fixes #25702, #11249 Thanks to achow101 for coming up with the idea of using a new mutex to solve this issue and for answering related questions. ACKs for top commit: achow101: ACK 6a5b348f2e526f048d0b448b01f6c4ab608569af hernanmarino: ACK 6a5b348f2e526f048d0b448b01f6c4ab608569af furszy: Tested ACK 6a5b348f Tree-SHA512: 0b6db692714f6f94594fa47249f5ee24f85713bfa70ac295a7e84b9ca6c07dda65df7b47781a2dc73e5b603a8725343a2f864428ae20d3e126c5b4802abc4ab5
Diffstat (limited to 'src/wallet/wallet.h')
-rw-r--r--src/wallet/wallet.h9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 6ec95220d6..5dd694e114 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -243,6 +243,7 @@ private:
std::atomic<bool> fAbortRescan{false};
std::atomic<bool> fScanningWallet{false}; // controlled by WalletRescanReserver
std::atomic<bool> m_attaching_chain{false};
+ std::atomic<bool> m_scanning_with_passphrase{false};
std::atomic<int64_t> m_scanning_start{0};
std::atomic<double> m_scanning_progress{0};
friend class WalletRescanReserver;
@@ -463,6 +464,7 @@ public:
void AbortRescan() { fAbortRescan = true; }
bool IsAbortingRescan() const { return fAbortRescan; }
bool IsScanning() const { return fScanningWallet; }
+ bool IsScanningWithPassphrase() const { return m_scanning_with_passphrase; }
int64_t ScanningDuration() const { return fScanningWallet ? GetTimeMillis() - m_scanning_start : 0; }
double ScanningProgress() const { return fScanningWallet ? (double) m_scanning_progress : 0; }
@@ -482,6 +484,9 @@ public:
// Used to prevent concurrent calls to walletpassphrase RPC.
Mutex m_unlock_mutex;
+ // Used to prevent deleting the passphrase from memory when it is still in use.
+ RecursiveMutex m_relock_mutex;
+
bool Unlock(const SecureString& strWalletPassphrase, bool accept_no_keys = false);
bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
bool EncryptWallet(const SecureString& strWalletPassphrase);
@@ -962,12 +967,13 @@ private:
public:
explicit WalletRescanReserver(CWallet& w) : m_wallet(w) {}
- bool reserve()
+ bool reserve(bool with_passphrase = false)
{
assert(!m_could_reserve);
if (m_wallet.fScanningWallet.exchange(true)) {
return false;
}
+ m_wallet.m_scanning_with_passphrase.exchange(with_passphrase);
m_wallet.m_scanning_start = GetTimeMillis();
m_wallet.m_scanning_progress = 0;
m_could_reserve = true;
@@ -987,6 +993,7 @@ public:
{
if (m_could_reserve) {
m_wallet.fScanningWallet = false;
+ m_wallet.m_scanning_with_passphrase = false;
}
}
};