Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/netbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ static Proxy nameProxy GUARDED_BY(g_proxyinfo_mutex);
int nConnectTimeout = DEFAULT_CONNECT_TIMEOUT;
bool fNameLookup = DEFAULT_NAME_LOOKUP;

// Need ample time for negotiation for very slow proxies such as Tor (milliseconds)
int g_socks5_recv_timeout = 20 * 1000;
// Need ample time for negotiation for very slow proxies such as Tor
std::chrono::milliseconds g_socks5_recv_timeout = 20s;
static std::atomic<bool> interruptSocks5Recv(false);

ReachableNets g_reachable_nets;
Expand Down Expand Up @@ -300,7 +300,7 @@ enum class IntrRecvError {
*
* @param data The buffer where the read bytes should be stored.
* @param len The number of bytes to read into the specified buffer.
* @param timeout The total timeout in milliseconds for this read.
* @param timeout The total timeout for this read.
* @param sock The socket (has to be in non-blocking mode) from which to read bytes.
*
* @returns An IntrRecvError indicating the resulting status of this read.
Expand All @@ -310,10 +310,10 @@ enum class IntrRecvError {
* @see This function can be interrupted by calling InterruptSocks5(bool).
* Sockets can be made non-blocking with Sock::SetNonBlocking().
*/
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, const Sock& sock)
static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, std::chrono::milliseconds timeout, const Sock& sock)
{
int64_t curTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
int64_t endTime = curTime + timeout;
auto curTime{Now<SteadyMilliseconds>()};
const auto endTime{curTime + timeout};
while (len > 0 && curTime < endTime) {
ssize_t ret = sock.Recv(data, len, 0); // Optimistically try the recv first
if (ret > 0) {
Expand All @@ -337,7 +337,7 @@ static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, int timeout, c
}
if (interruptSocks5Recv)
return IntrRecvError::Interrupted;
curTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
curTime = Now<SteadyMilliseconds>();
}
return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
}
Expand Down
10 changes: 5 additions & 5 deletions src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
#include <QThread>
#include <QTimer>

static int64_t nLastHeaderTipUpdateNotification = 0;
static int64_t nLastBlockTipUpdateNotification = 0;
static SteadyClock::time_point g_last_header_tip_update_notification{};
static SteadyClock::time_point g_last_block_tip_update_notification{};

ClientModel::ClientModel(interfaces::Node& node, OptionsModel *_optionsModel, QObject *parent) :
QObject(parent),
Expand Down Expand Up @@ -268,9 +268,9 @@ void ClientModel::TipChanged(SynchronizationState sync_state, interfaces::BlockT

// Throttle GUI notifications about (a) blocks during initial sync, and (b) both blocks and headers during reindex.
const bool throttle = (sync_state != SynchronizationState::POST_INIT && !header) || sync_state == SynchronizationState::INIT_REINDEX;
const int64_t now = throttle ? TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) : 0;
int64_t& nLastUpdateNotification = header ? nLastHeaderTipUpdateNotification : nLastBlockTipUpdateNotification;
if (throttle && now < nLastUpdateNotification + count_milliseconds(MODEL_UPDATE_DELAY)) {
const auto now{throttle ? SteadyClock::now() : SteadyClock::time_point{}};
auto& nLastUpdateNotification = header ? g_last_header_tip_update_notification : g_last_block_tip_update_notification;
if (throttle && now < nLastUpdateNotification + MODEL_UPDATE_DELAY) {
return;
}

Expand Down
7 changes: 6 additions & 1 deletion src/test/blockfilter_index_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,12 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
BOOST_REQUIRE(filter_index.Start(m_node.chainman->ActiveChainstate()));

// Allow filter index to catch up with the block index.
IndexWaitSynced(filter_index);
constexpr auto timeout{10s};
const auto time_start{SteadyClock::now()};
while (!filter_index.BlockUntilSyncedToCurrentChain()) {
BOOST_REQUIRE(time_start + timeout > SteadyClock::now());
UninterruptibleSleep(std::chrono::milliseconds{100});
}

// Check that filter index has all blocks that were in the chain before it started.
{
Expand Down
8 changes: 4 additions & 4 deletions src/test/fuzz/socks5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
#include <string>
#include <vector>

extern std::chrono::milliseconds g_socks5_recv_timeout;

namespace {
int default_socks5_recv_timeout;
decltype(g_socks5_recv_timeout) default_socks5_recv_timeout;
};
Comment on lines +16 to 20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add required header for chrono types

This TU now uses std::chrono::milliseconds; explicitly include to avoid relying on transitive includes:

+#include <chrono>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
extern std::chrono::milliseconds g_socks5_recv_timeout;
namespace {
int default_socks5_recv_timeout;
decltype(g_socks5_recv_timeout) default_socks5_recv_timeout;
};
#include <chrono>
extern std::chrono::milliseconds g_socks5_recv_timeout;
namespace {
decltype(g_socks5_recv_timeout) default_socks5_recv_timeout;
};
🤖 Prompt for AI Agents
In src/test/fuzz/socks5.cpp around lines 16 to 20, the translation unit uses
std::chrono::milliseconds but does not include the <chrono> header; add an
explicit #include <chrono> at the top of the file (or before any use of
std::chrono types) so the code does not rely on transitive includes and builds
correctly across compilers.


extern int g_socks5_recv_timeout;

void initialize_socks5()
{
static const auto testing_setup = MakeNoLogFileContext<>();
Expand All @@ -34,7 +34,7 @@ FUZZ_TARGET(socks5, .init = initialize_socks5)
InterruptSocks5(fuzzed_data_provider.ConsumeBool());
// Set FUZZED_SOCKET_FAKE_LATENCY=1 to exercise recv timeout code paths. This
// will slow down fuzzing.
g_socks5_recv_timeout = (fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) ? 1 : default_socks5_recv_timeout;
g_socks5_recv_timeout = (fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) ? 1ms : default_socks5_recv_timeout;
FuzzedSock fuzzed_sock = ConsumeSock(fuzzed_data_provider);
// This Socks5(...) fuzzing harness would have caught CVE-2017-18350 within
// a few seconds of fuzzing.
Expand Down
7 changes: 6 additions & 1 deletion src/test/txindex_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
BOOST_REQUIRE(txindex.Start(m_node.chainman->ActiveChainstate()));

// Allow tx index to catch up with the block index.
IndexWaitSynced(txindex);
constexpr auto timeout{10s};
const auto time_start{SteadyClock::now()};
while (!txindex.BlockUntilSyncedToCurrentChain()) {
BOOST_REQUIRE(time_start + timeout > SteadyClock::now());
UninterruptibleSleep(std::chrono::milliseconds{100});
}

// Check that txindex excludes genesis block transactions.
const CBlock& genesis_block = Params().GenesisBlock();
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/rpc/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ static RPCHelpMan getwalletinfo()
obj.pushKV("avoid_reuse", pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE));
if (pwallet->IsScanning()) {
UniValue scanning(UniValue::VOBJ);
scanning.pushKV("duration", pwallet->ScanningDuration() / 1000);
scanning.pushKV("duration", Ticks<std::chrono::seconds>(pwallet->ScanningDuration()));
scanning.pushKV("progress", pwallet->ScanningProgress());
obj.pushKV("scanning", scanning);
} else {
Expand Down
18 changes: 10 additions & 8 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,13 +494,14 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
return false;
if (Unlock(_vMasterKey))
{
int64_t nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
constexpr MillisecondsDouble target{100};
auto start{SteadyClock::now()};
crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime))));
pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start));

nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
start = SteadyClock::now();
crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime)))) / 2;
pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;

Comment on lines +497 to 505
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Use a standard chrono type; avoid undefined MillisecondsDouble

MillisecondsDouble may not exist in Dash’s util/time.h. Prefer std::chrono types:

-                constexpr MillisecondsDouble target{100};
+                constexpr std::chrono::milliseconds target{100};
                 auto start{SteadyClock::now()};
 ...
-                pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start));
+                pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() - start)));
 ...
-                start = SteadyClock::now();
+                start = SteadyClock::now();
 ...
-                pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;
+                pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() - start)))) / 2;

This keeps the intended ratio (100 ms per measurement window) while eliminating a likely missing alias.

Quick check for alias presence:


🏁 Script executed:

#!/bin/bash
rg -n 'MillisecondsDouble' src/util src/wallet

Length of output: 155


🏁 Script executed:

#!/bin/bash
set -e
# Locate util/time.h
file=$(fd --full-path time.h src/util)
echo "Inspecting $file"
# Check for Double aliases
rg -n 'using .*Double' "$file"
rg -n 'typedef .*Double' "$file"

Length of output: 194


Replace undefined MillisecondsDouble with std::chrono::duration<double, std::milli>

MillisecondsDouble isn’t defined in src/util/time.h. Replace both occurrences with a double-precision duration and wrap the ratio in parentheses for correct precision:

--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ lines 497,704
-    constexpr MillisecondsDouble target{100};
+    constexpr std::chrono::duration<double, std::milli> target{100.0};

@@ lines 500,707
-    pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start));
+    pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(
+        pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() - start))
+    );

@@ lines 504,711
-    pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;
+    pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(
+        (pMasterKey.second.nDeriveIterations +
+         pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() - start)))
+        / 2
+    );

This eliminates the undefined alias while preserving fractional-millisecond precision.

🤖 Prompt for AI Agents
In src/wallet/wallet.cpp around lines 497 to 505, the code uses an undefined
MillisecondsDouble type; replace both occurrences with
std::chrono::duration<double, std::milli> to preserve fractional-millisecond
precision, and wrap the division used to scale nDeriveIterations in parentheses
so the ratio is computed in double precision (e.g. static_cast<unsigned
int>(pMasterKey.second.nDeriveIterations * (target / (SteadyClock::now() -
start)))); update both lines that compute nDeriveIterations accordingly.

if (pMasterKey.second.nDeriveIterations < 25000)
pMasterKey.second.nDeriveIterations = 25000;
Expand Down Expand Up @@ -700,13 +701,14 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
GetStrongRandBytes(kMasterKey.vchSalt);

CCrypter crypter;
int64_t nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
constexpr MillisecondsDouble target{100};
auto start{SteadyClock::now()};
crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
kMasterKey.nDeriveIterations = static_cast<unsigned int>(2500000 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime)));
kMasterKey.nDeriveIterations = static_cast<unsigned int>(25000 * target / (SteadyClock::now() - start));

nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
start = SteadyClock::now();
crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * 100 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime)))) / 2;
kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;

if (kMasterKey.nDeriveIterations < 25000)
Comment on lines 703 to 713
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Same MillisecondsDouble issue here

Mirror the change as above:

-    constexpr MillisecondsDouble target{100};
+    constexpr std::chrono::milliseconds target{100};
     auto start{SteadyClock::now()};
 ...
-    kMasterKey.nDeriveIterations = static_cast<unsigned int>(25000 * target / (SteadyClock::now() - start));
+    kMasterKey.nDeriveIterations = static_cast<unsigned int>(25000 * (target / (SteadyClock::now() - start)));
 ...
-    start = SteadyClock::now();
+    start = SteadyClock::now();
 ...
-    kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;
+    kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * (target / (SteadyClock::now() - start)))) / 2;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CCrypter crypter;
int64_t nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
constexpr MillisecondsDouble target{100};
auto start{SteadyClock::now()};
crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
kMasterKey.nDeriveIterations = static_cast<unsigned int>(2500000 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime)));
kMasterKey.nDeriveIterations = static_cast<unsigned int>(25000 * target / (SteadyClock::now() - start));
nStartTime = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
start = SteadyClock::now();
crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * 100 / ((double)(TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - nStartTime)))) / 2;
kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * target / (SteadyClock::now() - start))) / 2;
if (kMasterKey.nDeriveIterations < 25000)
CCrypter crypter;
constexpr std::chrono::milliseconds target{100};
auto start{SteadyClock::now()};
crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
kMasterKey.nDeriveIterations = static_cast<unsigned int>(25000 * (target / (SteadyClock::now() - start)));
start = SteadyClock::now();
crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations
+ static_cast<unsigned int>(kMasterKey.nDeriveIterations * (target / (SteadyClock::now() - start))))
/ 2;
if (kMasterKey.nDeriveIterations < 25000)
🤖 Prompt for AI Agents
In src/wallet/wallet.cpp around lines 703 to 713, the timing math uses
SteadyClock durations implicitly against MillisecondsDouble which causes the
same MillisecondsDouble-type issue noted earlier; change both places so you
first compute the elapsed time as a MillisecondsDouble from (SteadyClock::now()
- start) and use that explicit MillisecondsDouble value in the nDeriveIterations
calculations (i.e., divide target by the elapsed MillisecondsDouble), and guard
the divisor against zero before assigning to kMasterKey.nDeriveIterations.

kMasterKey.nDeriveIterations = 25000;
Expand Down
9 changes: 6 additions & 3 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
std::atomic<bool> fAbortRescan{false}; // reset by WalletRescanReserver::reserve()
std::atomic<bool> fScanningWallet{false}; // controlled by WalletRescanReserver
std::atomic<bool> m_attaching_chain{false};
std::atomic<int64_t> m_scanning_start{0};
std::atomic<bool> m_scanning_with_passphrase{false};
std::atomic<SteadyClock::time_point> m_scanning_start{SteadyClock::time_point{}};
std::atomic<double> m_scanning_progress{0};
Comment on lines +270 to 272
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Missing include for SteadyClock types used in header

SteadyClock::time_point requires <util/time.h> (your alias) in this header to avoid ODR/order-dependent builds.

Add at the top near other util includes:

+#include <util/time.h>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
std::atomic<bool> m_scanning_with_passphrase{false};
std::atomic<SteadyClock::time_point> m_scanning_start{SteadyClock::time_point{}};
std::atomic<double> m_scanning_progress{0};
#include <util/time.h>
🤖 Prompt for AI Agents
In src/wallet/wallet.h around lines 270 to 272, the header uses
SteadyClock::time_point in an atomic member but does not include the util/time.h
alias that defines SteadyClock; add #include "util/time.h" near the other util
includes at the top of the file so SteadyClock::time_point is defined in this
translation unit and avoids ODR/order-dependent build issues.

friend class WalletRescanReserver;

Expand Down Expand Up @@ -576,7 +577,8 @@ class CWallet final : public WalletStorage, public interfaces::Chain::Notificati
void AbortRescan() { fAbortRescan = true; }
bool IsAbortingRescan() const { return fAbortRescan; }
bool IsScanning() const { return fScanningWallet; }
int64_t ScanningDuration() const { return fScanningWallet ? TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()) - m_scanning_start : 0; }
bool IsScanningWithPassphrase() const { return m_scanning_with_passphrase; }
SteadyClock::duration ScanningDuration() const { return fScanningWallet ? SteadyClock::now() - m_scanning_start.load() : SteadyClock::duration{}; }
double ScanningProgress() const { return fScanningWallet ? (double) m_scanning_progress : 0; }

//! Upgrade stored CKeyMetadata objects to store key origin info as KeyOriginInfo
Expand Down Expand Up @@ -1085,7 +1087,8 @@ class WalletRescanReserver
if (m_wallet.fScanningWallet.exchange(true)) {
return false;
}
m_wallet.m_scanning_start = TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now());
m_wallet.m_scanning_with_passphrase.exchange(with_passphrase);
m_wallet.m_scanning_start = SteadyClock::now();
m_wallet.m_scanning_progress = 0;
Comment on lines +1090 to 1092
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Compile error: undefined identifier ‘with_passphrase’

WalletRescanReserver::reserve() references with_passphrase which is not in scope and the method takes no parameter. Minimal fix (keep prior behavior) is to drop the assignment:

-        m_wallet.m_scanning_with_passphrase.exchange(with_passphrase);
+        m_wallet.m_scanning_with_passphrase = false; // or plumb a parameter from the call sites if needed

Alternatively, extend reserve(bool with_passphrase) and update all call sites, but that exceeds backport scope.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
m_wallet.m_scanning_with_passphrase.exchange(with_passphrase);
m_wallet.m_scanning_start = SteadyClock::now();
m_wallet.m_scanning_progress = 0;
m_wallet.m_scanning_with_passphrase = false; // or plumb a parameter from the call sites if needed
m_wallet.m_scanning_start = SteadyClock::now();
m_wallet.m_scanning_progress = 0;
🤖 Prompt for AI Agents
In src/wallet/wallet.h around lines 1090-1092, the reserve() method references
an undefined identifier with_passphrase; remove the call that assigns
m_wallet.m_scanning_with_passphrase.exchange(with_passphrase) so the method
compiles and preserves prior behavior, leaving the m_wallet.m_scanning_start and
m_wallet.m_scanning_progress assignments intact; do not add new parameters or
change call sites.

m_wallet.fAbortRescan = false;
m_could_reserve = true;
Expand Down
Loading