fix(wallet): stamp syncedHere only after identity verified + guard the startup wallet file (W1-3)
- W1-3 (Med): updateWalletIndexForActiveWallet stamped syncedHere in the markOpened block at bare connect (idHash still empty), letting a freshly-restored wallet skip its needed rescan. syncedHere is now stamped only once the wallet's identity is verified (idHash non-empty), so it takes effect at the post-address-refresh index update; lastOpenedEpoch still records at open. - Startup guard (the W1-1 launch counterpart): App::init now exists()-checks the recorded active wallet before the daemon is configured. A non-default active wallet moved/deleted between sessions falls back to the default wallet.dat with a warning, instead of the daemon silently auto-creating an empty wallet under the missing name. Runs before the PIN vault init so the vault is scoped to the wallet actually opened. Completes P1-B. Remaining P1: W3-3 (sweep opid persistence) deferred for careful adversarially-reviewed work — re-tracking a stale opid could hang the migration if the op poller doesn't time out; the existing balance/mined gates already prevent fund loss. See docs/wallet-hardening.md. Build-clean; ctest 1/1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
22
src/app.cpp
22
src/app.cpp
@@ -341,6 +341,28 @@ bool App::init()
|
||||
// Ensure ObsidianDragon config directory and template files exist
|
||||
util::Platform::ensureObsidianDragonSetup();
|
||||
|
||||
// W1-1 (startup): if the recorded active wallet file was moved/deleted between sessions, don't hand a
|
||||
// missing -wallet=<name> to the daemon — it would auto-create a fresh empty wallet under that name,
|
||||
// silently "opening" as a zero-balance wallet at launch. Fall back to the always-present default and
|
||||
// warn. (The default "wallet.dat" is legitimately absent on first run, so it is skipped.) Runs before
|
||||
// the vault init below so the vault is scoped to the wallet actually opened.
|
||||
if (settings_) {
|
||||
const std::string active = settings_->getActiveWalletFile();
|
||||
if (!active.empty() && active != "wallet.dat") {
|
||||
std::error_code walEc;
|
||||
const std::string walPath = util::Platform::getDragonXDataDir() + "/" + active;
|
||||
if (!std::filesystem::exists(walPath, walEc)) {
|
||||
DEBUG_LOGF("[App] active wallet '%s' not found at startup — falling back to wallet.dat\n",
|
||||
active.c_str());
|
||||
settings_->setActiveWalletFile("wallet.dat");
|
||||
settings_->save();
|
||||
ui::Notifications::instance().warning(
|
||||
"Your last-used wallet file (" + active + ") was not found — opened the default wallet "
|
||||
"instead. If you moved it, restore it and switch back from the wallet list.", 20.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize PIN vault, scoped to the active wallet so one wallet's stored passphrase is never
|
||||
// offered for another (the default wallet keeps the legacy vault.dat).
|
||||
vault_ = std::make_unique<util::SecureVault>(settings_ ? settings_->getActiveWalletFile() : "");
|
||||
|
||||
@@ -1096,9 +1096,16 @@ void App::updateWalletIndexForActiveWallet(bool markOpened)
|
||||
if (!ec) e.sizeBytesAtLastOpen = static_cast<long long>(sz);
|
||||
}
|
||||
|
||||
// W1-3: record "synced here" only once the wallet's identity is actually verified (its addresses are
|
||||
// known -> idHash non-empty). Stamping it on the bare connect (before any address readback) would let
|
||||
// a freshly-restored wallet skip its needed rescan. It's idempotent, so the post-refresh update
|
||||
// (updateWalletIndexForActiveWallet after addresses load) sets it once; lastOpenedEpoch is still
|
||||
// recorded at open time here.
|
||||
if (!idHash.empty()) {
|
||||
e.syncedHere = true; // loaded + identity-verified in this datadir -> catch-up (no full rescan)
|
||||
}
|
||||
if (markOpened) {
|
||||
e.lastOpenedEpoch = static_cast<long long>(std::time(nullptr));
|
||||
e.syncedHere = true; // we've loaded it in this datadir -> catch-up (no full rescan) on switch
|
||||
}
|
||||
|
||||
if (wallet_index_.upsert(e)) wallet_index_.save();
|
||||
|
||||
Reference in New Issue
Block a user