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).
This commit is contained in:
Pieter Wuille 2012-08-10 15:13:57 +02:00
parent 13c51f20f6
commit 4fea06db25
2 changed files with 34 additions and 1 deletions

View file

@ -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;

View file

@ -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"))
{