changeset 3653:2b9ac1b755c3 draft

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).
author Pieter Wuille <pieter.wuille@gmail.com>
date Fri, 10 Aug 2012 15:13:57 +0200
parents 816a26c8e012
children 6c563b4f0533
files src/db.cpp src/init.cpp
diffstat 2 files changed, 34 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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<uint256,CBlockIndex*>::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<CBlockIndex*> 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<CBlockIndex*>::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<boost::filesystem::path> *vPath = new std::vector<boost::filesystem::path>();
     if (mapArgs.count("-loadblock"))
     {