upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/db.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/db.cpp')
-rw-r--r--src/db.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/db.cpp b/src/db.cpp
index 4cc54ac..ce7b875 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -435,6 +435,47 @@ bool CTxDB::LoadBlockIndex()
435 nBestHeight = pindexBest->nHeight; 435 nBestHeight = pindexBest->nHeight;
436 printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight); 436 printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,14).c_str(), nBestHeight);
437 437
438 // Verify the tail of the best chain, and fall back to the last good block
439 // if any of it fails.
440 //
441 // A node that accepted blocks its current rules would reject -- because it
442 // was running an older build, or because the tip it landed on was never
443 // valid -- has no way to notice on its own. It keeps the branch, keeps
444 // building on it, and keeps mining coins that the rest of the network
445 // throws away. The only cure used to be deleting blk*.dat by hand, which
446 // requires knowing something is wrong in the first place. That is how a
447 // node here once mined a 323-block fork for five days.
448 //
449 // Checking every block on every start would mean a RandomX hash per block,
450 // so only the tail is checked by default. /checkblocks=0 does the lot.
451 int nCheckBlocks = nCheckBlocksOnLoad;
452 CBlockIndex* pindexFork = NULL;
453 int nChecked = 0;
454 for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
455 {
456 if (nCheckBlocks > 0 && nChecked >= nCheckBlocks)
457 break;
458 nChecked++;
459 CBlock block;
460 if (!block.ReadFromDisk(pindex->nFile, pindex->nBlockPos, true))
461 return error("LoadBlockIndex() : ReadFromDisk failed at height %d", pindex->nHeight);
462 if (!block.CheckBlock())
463 {
464 printf("LoadBlockIndex() : *** bad block at height %d, hash=%s\n",
465 pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,14).c_str());
466 // Keep going: an older bad block further back wins, because
467 // everything after it has to come off too.
468 pindexFork = pindex->pprev;
469 }
470 }
471 printf("LoadBlockIndex(): verified %d block(s)\n", nChecked);
472
473 // The repair itself happens in the caller, after this handle is closed.
474 // The cursor above is still open and holds read locks, so a write
475 // transaction opened here waits on it forever -- measured: the node came
476 // up, printed the diagnosis, and hung with no error anywhere.
477 pindexBadChainFork = pindexFork;
478
438 return true; 479 return true;
439} 480}
440 481