From 4fea06db25108e7f72710bf22c3d1896707eeb74 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 10 Aug 2012 15:13:57 +0200 Subject: [PATCH] Automatically reorganize at startup to best known block Given that the block tree database (chain.dat) and the active chain database (coins.dat) are entirely separate now, it becomes legal to swap one with another instance without affecting the other. This commit introduces a check in the startup code that detects the presence of a better chain in chain.dat that has not been activated yet, and does so efficiently (in batch, while reusing the blk???.dat files). --- src/db.cpp | 1 - src/init.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/db.cpp b/src/db.cpp index 06e5543b..5ca9ea2c 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -636,7 +636,6 @@ bool LoadBlockIndex(CChainDB &chaindb) { if (pindexGenesisBlock == NULL) return true; - return error("CTxDB::LoadBlockIndex() : hashBestChain not loaded"); } hashBestChain = pindexBest->GetBlockHash(); nBestHeight = pindexBest->nHeight; diff --git a/src/init.cpp b/src/init.cpp index b05d57ab..85aa4f60 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -780,6 +780,40 @@ bool AppInit2() // ********************************************************* Step 9: import blocks + // scan for better chains in the block chain database, that are not yet connected in the active best chain + CBlockIndex *pindexFoundBest = pindexBest; + for (std::map::iterator it = mapBlockIndex.begin(); it != mapBlockIndex.end(); it++) { + CBlockIndex *pindex = it->second; + if (pindexFoundBest==NULL || pindex->bnChainWork > pindexFoundBest->bnChainWork) + pindexFoundBest = pindex; + } + if (pindexFoundBest != pindexBest) { + uiInterface.InitMessage(_("Importing blocks from block database...")); + uint64 nTxs = 0; + uint64 nBlocks = 0; + std::vector vAttach; + vAttach.reserve(pindexFoundBest->nHeight - (pindexBest==NULL ? 0 : pindexBest->nHeight)); + while (pindexFoundBest && pindexFoundBest->bnChainWork > (pindexBest==NULL ? 0 : pindexBest->bnChainWork)) { + vAttach.push_back(pindexFoundBest); + pindexFoundBest = pindexFoundBest->pprev; + } + for (std::vector::reverse_iterator it = vAttach.rbegin(); it != vAttach.rend(); it++) { + CBlockIndex *pindex = *it; + CBlock block; + if (!block.ReadFromDisk(pindex)) + break; + nTxs += block.vtx.size(); + nBlocks++; + if (pindex->nHeight == 0 || nTxs + nBlocks*3 > 500) { + nTxs=0; + nBlocks=0; + block.SetBestChain(pindex); + } + if (fRequestShutdown) + break; + } + } + std::vector *vPath = new std::vector(); if (mapArgs.count("-loadblock")) {