# HG changeset patch # User Pieter Wuille # Date 1344604437 -7200 # Node ID 2b9ac1b755c33de87dd1a01e3f09de9e9544fc6a # Parent 816a26c8e012792f71197e6366cf122111c61f9d 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). diff --git a/src/db.cpp b/src/db.cpp --- a/src/db.cpp +++ b/src/db.cpp @@ -636,7 +636,6 @@ { 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 --- a/src/init.cpp +++ b/src/init.cpp @@ -780,6 +780,40 @@ // ********************************************************* 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")) {