diff --git a/src/ui/windows/wallets_dialog.h b/src/ui/windows/wallets_dialog.h index 2c720dc..cdadd43 100644 --- a/src/ui/windows/wallets_dialog.h +++ b/src/ui/windows/wallets_dialog.h @@ -502,33 +502,40 @@ private: targets.reserve(s_rows.size()); for (std::size_t i = 0; i < s_rows.size(); ++i) targets.emplace_back(s_rows[i].dir + "/" + s_rows[i].fileName, i); - if (!targets.empty()) { - std::thread([batch, targets]() { - // Per-file 256 MB (BDB sorts long-keyed mkey/hdchain LATE, so a small cap risks a - // false-negative); a shared budget bounds total I/O, charged by bytes actually read. - std::size_t budget = 768u * 1024u * 1024u; - constexpr std::size_t kPerFile = 256u * 1024u * 1024u; - for (const auto& t : targets) { - if (batch->cancel.load()) return; - ProbeResult res; - if (budget > 0) { - // Primary: an exact btree walk (encryption/seed flags + address/tx counts). If it - // can't fully parse (unknown BDB variant, or a >cap file), fall back to the cheap - // byte-scan for badges only (no counts). - const auto bt = util::parseWalletBtree(t.first, std::min(budget, kPerFile)); - if (bt.parsed && bt.complete) { - res = ProbeResult{ true, true, bt.encrypted, bt.hdSeed, true, bt.addresses(), bt.txCount }; - budget -= std::min(budget, bt.bytesRead); - } else { - const auto pr = util::probeWalletFile(t.first, std::min(budget, kPerFile)); - res = ProbeResult{ pr.isBerkeleyDB, pr.scanComplete, pr.encrypted, pr.hdSeed }; - budget -= std::min(budget, std::max(bt.bytesRead, pr.bytesRead)); - } + + auto runProbe = [](std::shared_ptr batch, + std::vector> targets) { + // Per-file 256 MB (BDB sorts long-keyed mkey/hdchain LATE, so a small cap risks a + // false-negative); a shared budget bounds total I/O, charged by bytes actually read. + std::size_t budget = 768u * 1024u * 1024u; + constexpr std::size_t kPerFile = 256u * 1024u * 1024u; + for (const auto& t : targets) { + if (batch->cancel.load()) return; + ProbeResult res; + if (budget > 0) { + // Primary: an exact btree walk (encryption/seed flags + address/tx counts). If it + // can't fully parse (unknown BDB variant, or a >cap file), fall back to the cheap + // byte-scan for badges only (no counts). + const auto bt = util::parseWalletBtree(t.first, std::min(budget, kPerFile)); + if (bt.parsed && bt.complete) { + res = ProbeResult{ true, true, bt.encrypted, bt.hdSeed, true, bt.addresses(), bt.txCount }; + budget -= std::min(budget, bt.bytesRead); + } else { + const auto pr = util::probeWalletFile(t.first, std::min(budget, kPerFile)); + res = ProbeResult{ pr.isBerkeleyDB, pr.scanComplete, pr.encrypted, pr.hdSeed }; + budget -= std::min(budget, std::max(bt.bytesRead, pr.bytesRead)); } - std::lock_guard lk(batch->mtx); - if (t.second < batch->results.size()) batch->results[t.second] = res; } - }).detach(); + std::lock_guard lk(batch->mtx); + if (t.second < batch->results.size()) batch->results[t.second] = res; + } + }; + if (targets.empty()) { + // nothing to probe + } else if (s_app && s_app->isScreenshotSweeping()) { + runProbe(batch, targets); // offline sweep: probe synchronously so the captured frame is populated + } else { + std::thread(runProbe, batch, targets).detach(); } }