fix: auto-download UTXO snapshot when chain DB missing (3 root causes)
Three bugs prevented the wallet from automatically downloading the UTXO snapshot when starting with stale blk0001.dat but no chain database: 1. NeedsBootstrap() only checked for blk0001.dat existence, not the chain DB. If blk0001.dat was present (leftover from old version) but txleveldb/chainstate was missing, it reported "no bootstrap needed" and the snapshot download never triggered. Fix: check for txleveldb/ or blocks/chainstate/ instead. 2. Bootstrap HTTP download was skipped when snapshotMode was true (the default). The code deferred to P2P snapshot fetch (Step 11.6), but that runs AFTER Step 7 which errored out on the FastImport gate. Fix: always attempt HTTP bootstrap when NeedsBootstrap is true, regardless of snapshotMode. The UTXO snapshot HTTP download IS the fast path — no reason to defer to P2P when HTTP is available. 3. FastImport gate (Step 7) was a hard InitError that killed the daemon before it ever reached the snapshot fetch path. blk0001.dat present + no chain index + FastImport disabled = immediate crash. Fix: instead of erroring, remove the stale blk0001.dat and continue. The daemon syncs from the snapshot that was already loaded in Step 6b, or from P2P if that somehow failed.
This commit is contained in:
+8
-1
@@ -50,7 +50,14 @@ namespace Bootstrap {
|
||||
|
||||
bool NeedsBootstrap(const fs::path& dataDir)
|
||||
{
|
||||
return !fs::exists(dataDir / "blk0001.dat");
|
||||
// Need bootstrap if there's no chain database (the UTXO set / block index).
|
||||
// blk0001.dat alone is NOT sufficient — it's raw block data that requires
|
||||
// FastImport to build an index, and FastImport is disabled by default.
|
||||
// Check for both LevelDB (txleveldb/) and RocksDB (chainstate/) backends.
|
||||
bool hasChainDb = fs::exists(dataDir / "txleveldb")
|
||||
|| fs::exists(dataDir / "blocks" / "chainstate")
|
||||
|| fs::exists(dataDir / "chainstate");
|
||||
return !hasChainDb;
|
||||
}
|
||||
|
||||
// Direct TCP connection bypassing Tor SOCKS proxy.
|
||||
|
||||
+10
-13
@@ -1030,14 +1030,11 @@ bool AppInit2()
|
||||
fs::path dataPath = GetDataDir();
|
||||
bool needsBootstrap = Bootstrap::NeedsBootstrap(dataPath);
|
||||
|
||||
if (needsBootstrap && !noBootstrap && !snapshotMode) {
|
||||
printf("Bootstrap: no blockchain data found — downloading automatically.\n");
|
||||
if (needsBootstrap && !noBootstrap) {
|
||||
printf("Bootstrap: no blockchain data found — downloading UTXO snapshot automatically.\n");
|
||||
printf("Bootstrap: (use -nobootstrap to skip)\n");
|
||||
uiInterface.InitMessage(_("Downloading blockchain data..."));
|
||||
uiInterface.InitMessage(_("Downloading UTXO snapshot..."));
|
||||
wantsBootstrap = true;
|
||||
} else if (needsBootstrap && snapshotMode && !wantsBootstrap) {
|
||||
printf("Bootstrap: no blockchain data found — will fetch UTXO snapshot via P2P after network start.\n");
|
||||
printf("Bootstrap: (use -bootstrap for legacy clearnet HTTP bootstrap, or -snapshot=0 to disable P2P fetcher)\n");
|
||||
}
|
||||
|
||||
if (wantsBootstrap)
|
||||
@@ -1229,20 +1226,20 @@ bool AppInit2()
|
||||
{
|
||||
if (!GetBoolArg("-allowfastimport", false))
|
||||
{
|
||||
return InitError(_(
|
||||
"Block index empty and blk0001.dat is present, but FastImport is disabled "
|
||||
"(default). The snapshot path is the only supported sync start.\n\n"
|
||||
"To recover:\n"
|
||||
" 1. Place a signed utxo-snapshot.bin in the data directory and restart, OR\n"
|
||||
" 2. Delete blk0001.dat (the snapshot path will sync from network), OR\n"
|
||||
" 3. Pass -allowfastimport=1 to permit FastImport (operator opt-in only)."));
|
||||
printf("FastImport: blk0001.dat present but -allowfastimport not set — "
|
||||
"ignoring block file, will sync from network via UTXO snapshot.\n");
|
||||
// Remove the stale blk0001.dat so it doesn't trigger again
|
||||
std::filesystem::remove(GetDataDir() / "blk0001.dat");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("FastImport: WARNING -allowfastimport is set; rebuilding from local blk0001.dat.\n");
|
||||
uiInterface.InitMessage(_("Importing bootstrap blocks..."));
|
||||
printf("Block index empty but blk0001.dat exists - running fast import...\n");
|
||||
int64_t nFastImportStart = GetTimeMillis();
|
||||
FastImportBlockFile();
|
||||
StartupPerfLog("bootstrap_fast_import", GetTimeMillis() - nFastImportStart, strprintf("bestheight=%d", nBestHeight));
|
||||
}
|
||||
}
|
||||
|
||||
// as LoadBlockIndex can take several minutes, it's possible the user
|
||||
|
||||
Reference in New Issue
Block a user