aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2012-08-10 15:13:57 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2012-10-20 23:08:57 +0200
commit4fea06db25108e7f72710bf22c3d1896707eeb74 (patch)
treeef480d212b7da3b484bdb066453e874d2c5c6c84
parent13c51f20f619b9001bb6caf225b8cd6c5c2fbb31 (diff)
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).
-rw-r--r--src/db.cpp1
-rw-r--r--src/init.cpp34
2 files changed, 34 insertions, 1 deletions
diff --git a/src/db.cpp b/src/db.cpp
index 06e5543b2e..5ca9ea2c34 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 b05d57abfe..85aa4f6007 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<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"))
{