Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 2,504 Lines • ▼ Show 20 Lines | do { | ||||
LogPrintf("Mark block %s invalid because it forks prior to the " | LogPrintf("Mark block %s invalid because it forks prior to the " | ||||
"finalization point %d.\n", | "finalization point %d.\n", | ||||
pindexNew->GetBlockHash().ToString(), | pindexNew->GetBlockHash().ToString(), | ||||
m_finalizedBlockIndex->nHeight); | m_finalizedBlockIndex->nHeight); | ||||
pindexNew->nStatus = pindexNew->nStatus.withFailed(); | pindexNew->nStatus = pindexNew->nStatus.withFailed(); | ||||
InvalidChainFound(pindexNew); | InvalidChainFound(pindexNew); | ||||
} | } | ||||
const bool fAvalancheEnabled = | |||||
gArgs.GetBoolArg("-enableavalanche", AVALANCHE_DEFAULT_ENABLED); | |||||
const bool fAutoUnpark = | |||||
gArgs.GetBoolArg("-automaticunparking", !fAvalancheEnabled); | |||||
const CBlockIndex *pindexFork = m_chain.FindFork(pindexNew); | const CBlockIndex *pindexFork = m_chain.FindFork(pindexNew); | ||||
// Check whether all blocks on the path between the currently active | // Check whether all blocks on the path between the currently active | ||||
// chain and the candidate are valid. Just going until the active chain | // chain and the candidate are valid. Just going until the active chain | ||||
// is an optimization, as we know all blocks in it are valid already. | // is an optimization, as we know all blocks in it are valid already. | ||||
CBlockIndex *pindexTest = pindexNew; | CBlockIndex *pindexTest = pindexNew; | ||||
bool hasValidAncestor = true; | bool hasValidAncestor = true; | ||||
while (hasValidAncestor && pindexTest && pindexTest != pindexFork) { | while (hasValidAncestor && pindexTest && pindexTest != pindexFork) { | ||||
assert(pindexTest->HaveTxsDownloaded() || pindexTest->nHeight == 0); | assert(pindexTest->HaveTxsDownloaded() || pindexTest->nHeight == 0); | ||||
// If this is a parked chain, but it has enough PoW, clear the park | // If this is a parked chain, but it has enough PoW, clear the park | ||||
// state. | // state. | ||||
bool fParkedChain = pindexTest->nStatus.isOnParkedChain(); | bool fParkedChain = pindexTest->nStatus.isOnParkedChain(); | ||||
if (fParkedChain && gArgs.GetBoolArg("-automaticunparking", true)) { | if (fAutoUnpark && fParkedChain) { | ||||
const CBlockIndex *pindexTip = m_chain.Tip(); | const CBlockIndex *pindexTip = m_chain.Tip(); | ||||
// During initialization, pindexTip and/or pindexFork may be | // During initialization, pindexTip and/or pindexFork may be | ||||
// null. In this case, we just ignore the fact that the chain is | // null. In this case, we just ignore the fact that the chain is | ||||
// parked. | // parked. | ||||
if (!pindexTip || !pindexFork) { | if (!pindexTip || !pindexFork) { | ||||
UnparkBlock(pindexTest); | UnparkBlock(pindexTest); | ||||
continue; | continue; | ||||
▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | do { | ||||
if (fInvalidChain || fParkedChain) { | if (fInvalidChain || fParkedChain) { | ||||
// We discovered a new chain tip that is either parked or | // We discovered a new chain tip that is either parked or | ||||
// invalid, we may want to warn. | // invalid, we may want to warn. | ||||
CheckForkWarningConditionsOnNewFork(pindexNew); | CheckForkWarningConditionsOnNewFork(pindexNew); | ||||
} | } | ||||
} | } | ||||
if (g_avalanche && | if (fAvalancheEnabled && g_avalanche) { | ||||
gArgs.GetBoolArg("-enableavalanche", AVALANCHE_DEFAULT_ENABLED)) { | |||||
g_avalanche->addBlockToReconcile(pindexNew); | g_avalanche->addBlockToReconcile(pindexNew); | ||||
} | } | ||||
// We found a candidate that has valid ancestors. This is our guy. | // We found a candidate that has valid ancestors. This is our guy. | ||||
if (hasValidAncestor) { | if (hasValidAncestor) { | ||||
return pindexNew; | return pindexNew; | ||||
} | } | ||||
} while (true); | } while (true); | ||||
▲ Show 20 Lines • Show All 3,249 Lines • Show Last 20 Lines |