mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-19 06:43:45 +01:00
Merge #7917: Optimize reindex
b4d24e1Report reindexing progress in GUI (Pieter Wuille)d3d7547Add -reindex-chainstate that does not rebuild block index (Pieter Wuille)fb8fad1Optimize ActivateBestChain for long chains (Pieter Wuille)316623fSwitch reindexing to AcceptBlock in-loop and ActivateBestChain afterwards (Pieter Wuille)d253ec4Make ProcessNewBlock dbp const and update comment (Pieter Wuille)
This commit is contained in:
70
src/main.cpp
70
src/main.cpp
@@ -2811,10 +2811,9 @@ static void PruneBlockIndexCandidates() {
|
||||
* Try to make some progress towards making pindexMostWork the active block.
|
||||
* pblock is either NULL or a pointer to a CBlock corresponding to pindexMostWork.
|
||||
*/
|
||||
static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock)
|
||||
static bool ActivateBestChainStep(CValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const CBlock* pblock, bool& fInvalidFound)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
bool fInvalidFound = false;
|
||||
const CBlockIndex *pindexOldTip = chainActive.Tip();
|
||||
const CBlockIndex *pindexFork = chainActive.FindFork(pindexMostWork);
|
||||
|
||||
@@ -2884,6 +2883,28 @@ static bool ActivateBestChainStep(CValidationState& state, const CChainParams& c
|
||||
return true;
|
||||
}
|
||||
|
||||
static void NotifyHeaderTip() {
|
||||
bool fNotify = false;
|
||||
bool fInitialBlockDownload = false;
|
||||
static CBlockIndex* pindexHeaderOld = NULL;
|
||||
CBlockIndex* pindexHeader = NULL;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (!setBlockIndexCandidates.empty()) {
|
||||
pindexHeader = *setBlockIndexCandidates.rbegin();
|
||||
}
|
||||
if (pindexHeader != pindexHeaderOld) {
|
||||
fNotify = true;
|
||||
fInitialBlockDownload = IsInitialBlockDownload();
|
||||
pindexHeaderOld = pindexHeader;
|
||||
}
|
||||
}
|
||||
// Send block tip changed notifications without cs_main
|
||||
if (fNotify) {
|
||||
uiInterface.NotifyHeaderTip(fInitialBlockDownload, pindexHeader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the best chain active, in multiple steps. The result is either failure
|
||||
* or an activated best chain. pblock is either NULL or a pointer to a block
|
||||
@@ -2902,15 +2923,22 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams,
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CBlockIndex *pindexOldTip = chainActive.Tip();
|
||||
pindexMostWork = FindMostWorkChain();
|
||||
if (pindexMostWork == NULL) {
|
||||
pindexMostWork = FindMostWorkChain();
|
||||
}
|
||||
|
||||
// Whether we have anything to do at all.
|
||||
if (pindexMostWork == NULL || pindexMostWork == chainActive.Tip())
|
||||
return true;
|
||||
|
||||
if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL))
|
||||
bool fInvalidFound = false;
|
||||
if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : NULL, fInvalidFound))
|
||||
return false;
|
||||
|
||||
if (fInvalidFound) {
|
||||
// Wipe cache, we may need another branch now.
|
||||
pindexMostWork = NULL;
|
||||
}
|
||||
pindexNewTip = chainActive.Tip();
|
||||
pindexFork = chainActive.FindFork(pindexOldTip);
|
||||
fInitialDownload = IsInitialBlockDownload();
|
||||
@@ -3398,11 +3426,12 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state
|
||||
}
|
||||
|
||||
/** Store block on disk. If dbp is non-NULL, the file is known to already reside on disk */
|
||||
static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, CDiskBlockPos* dbp)
|
||||
static bool AcceptBlock(const CBlock& block, CValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const CDiskBlockPos* dbp)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
||||
CBlockIndex *&pindex = *ppindex;
|
||||
CBlockIndex *pindexDummy = NULL;
|
||||
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
|
||||
|
||||
if (!AcceptBlockHeader(block, state, chainparams, &pindex))
|
||||
return false;
|
||||
@@ -3474,7 +3503,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned
|
||||
}
|
||||
|
||||
|
||||
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, CDiskBlockPos* dbp)
|
||||
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, const CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp)
|
||||
{
|
||||
{
|
||||
LOCK(cs_main);
|
||||
@@ -3492,6 +3521,8 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, c
|
||||
return error("%s: AcceptBlock FAILED", __func__);
|
||||
}
|
||||
|
||||
NotifyHeaderTip();
|
||||
|
||||
if (!ActivateBestChain(state, chainparams, pblock))
|
||||
return error("%s: ActivateBestChain failed", __func__);
|
||||
|
||||
@@ -4037,15 +4068,26 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
|
||||
|
||||
// process in case the block isn't known yet
|
||||
if (mapBlockIndex.count(hash) == 0 || (mapBlockIndex[hash]->nStatus & BLOCK_HAVE_DATA) == 0) {
|
||||
LOCK(cs_main);
|
||||
CValidationState state;
|
||||
if (ProcessNewBlock(state, chainparams, NULL, &block, true, dbp))
|
||||
if (AcceptBlock(block, state, chainparams, NULL, true, dbp))
|
||||
nLoaded++;
|
||||
if (state.IsError())
|
||||
break;
|
||||
} else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) {
|
||||
LogPrintf("Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
|
||||
LogPrint("reindex", "Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight);
|
||||
}
|
||||
|
||||
// Activate the genesis block so normal node progress can continue
|
||||
if (hash == chainparams.GetConsensus().hashGenesisBlock) {
|
||||
CValidationState state;
|
||||
if (!ActivateBestChain(state, chainparams)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NotifyHeaderTip();
|
||||
|
||||
// Recursively process earlier encountered successors of this block
|
||||
deque<uint256> queue;
|
||||
queue.push_back(hash);
|
||||
@@ -4057,10 +4099,11 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
|
||||
std::multimap<uint256, CDiskBlockPos>::iterator it = range.first;
|
||||
if (ReadBlockFromDisk(block, it->second, chainparams.GetConsensus()))
|
||||
{
|
||||
LogPrintf("%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
|
||||
LogPrint("reindex", "%s: Processing out of order child %s of %s\n", __func__, block.GetHash().ToString(),
|
||||
head.ToString());
|
||||
LOCK(cs_main);
|
||||
CValidationState dummy;
|
||||
if (ProcessNewBlock(dummy, chainparams, NULL, &block, true, &it->second))
|
||||
if (AcceptBlock(block, dummy, chainparams, NULL, true, &it->second))
|
||||
{
|
||||
nLoaded++;
|
||||
queue.push_back(block.GetHash());
|
||||
@@ -4068,6 +4111,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB
|
||||
}
|
||||
range.first++;
|
||||
mapBlocksUnknownParent.erase(it);
|
||||
NotifyHeaderTip();
|
||||
}
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
@@ -5077,6 +5121,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
|
||||
}
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
if (nCount == 0) {
|
||||
@@ -5167,6 +5212,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
|
||||
}
|
||||
|
||||
CheckBlockIndex(chainparams.GetConsensus());
|
||||
}
|
||||
|
||||
NotifyHeaderTip();
|
||||
}
|
||||
|
||||
else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
|
||||
|
||||
Reference in New Issue
Block a user