Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 3,855 Lines • ▼ Show 20 Lines | if (hash != chainparams.GetConsensus().hashGenesisBlock) { | ||||
} | } | ||||
if (!ContextualCheckBlockHeader(chainparams, block, state, pindexPrev, | if (!ContextualCheckBlockHeader(chainparams, block, state, pindexPrev, | ||||
GetAdjustedTime())) { | GetAdjustedTime())) { | ||||
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", | return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", | ||||
__func__, hash.ToString(), FormatStateMessage(state)); | __func__, hash.ToString(), FormatStateMessage(state)); | ||||
} | } | ||||
// If the previous block index isn't valid, determine if it descends | /* Determine if this block descends from any block which has been found | ||||
// from any block which has been found invalid (m_failed_blocks), then | * invalid (m_failed_blocks), then mark pindexPrev and any blocks | ||||
// mark pindexPrev and any blocks between them as failed. | * between them as failed. For example: | ||||
* | |||||
* D3 | |||||
* / | |||||
* B2 - C2 | |||||
* / \ | |||||
* A D2 - E2 - F2 | |||||
* \ | |||||
* B1 - C1 - D1 - E1 | |||||
* | |||||
* In the case that we attempted to reorg from E1 to F2, only to find | |||||
* C2 to be invalid, we would mark D2, E2, and F2 as BLOCK_FAILED_CHILD | |||||
* but NOT D3 (it was not in any of our candidate sets at the time). | |||||
* | |||||
* In any case D3 will also be marked as BLOCK_FAILED_CHILD at restart | |||||
* in LoadBlockIndex. | |||||
*/ | |||||
if (!pindexPrev->IsValid(BlockValidity::SCRIPTS)) { | if (!pindexPrev->IsValid(BlockValidity::SCRIPTS)) { | ||||
// The above does not mean "invalid": it checks if the previous | |||||
// block hasn't been validated up to BLOCK_VALID_SCRIPTS. This is a | |||||
// performance optimization, in the common case of adding a new | |||||
// block to the tip, we don't need to iterate over the failed blocks | |||||
// list. | |||||
for (const CBlockIndex *failedit : m_failed_blocks) { | for (const CBlockIndex *failedit : m_failed_blocks) { | ||||
if (pindexPrev->GetAncestor(failedit->nHeight) == failedit) { | if (pindexPrev->GetAncestor(failedit->nHeight) == failedit) { | ||||
assert(failedit->nStatus.hasFailed()); | assert(failedit->nStatus.hasFailed()); | ||||
CBlockIndex *invalid_walk = pindexPrev; | CBlockIndex *invalid_walk = pindexPrev; | ||||
while (invalid_walk != failedit) { | while (invalid_walk != failedit) { | ||||
invalid_walk->nStatus = | invalid_walk->nStatus = | ||||
invalid_walk->nStatus.withFailedParent(); | invalid_walk->nStatus.withFailedParent(); | ||||
setDirtyBlockIndex.insert(invalid_walk); | setDirtyBlockIndex.insert(invalid_walk); | ||||
▲ Show 20 Lines • Show All 1,896 Lines • Show Last 20 Lines |