Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 1,041 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static void InvalidChainFound(CBlockIndex *pindexNew) { | static void InvalidChainFound(CBlockIndex *pindexNew) { | ||||
if (!pindexBestInvalid || | if (!pindexBestInvalid || | ||||
pindexNew->nChainWork > pindexBestInvalid->nChainWork) { | pindexNew->nChainWork > pindexBestInvalid->nChainWork) { | ||||
pindexBestInvalid = pindexNew; | pindexBestInvalid = pindexNew; | ||||
} | } | ||||
// If the invalid chain found is supposed to be finalized, we need to move | |||||
// back the finalization point. | |||||
if (IsBlockFinalized(pindexNew)) { | |||||
pindexFinalized = pindexNew->pprev; | |||||
} | |||||
LogPrintf( | LogPrintf( | ||||
"%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__, | "%s: invalid block=%s height=%d log2_work=%.8g date=%s\n", __func__, | ||||
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, | pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, | ||||
log(pindexNew->nChainWork.getdouble()) / log(2.0), | log(pindexNew->nChainWork.getdouble()) / log(2.0), | ||||
DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime())); | DateTimeStrFormat("%Y-%m-%d %H:%M:%S", pindexNew->GetBlockTime())); | ||||
CBlockIndex *tip = chainActive.Tip(); | CBlockIndex *tip = chainActive.Tip(); | ||||
assert(tip); | assert(tip); | ||||
LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", | LogPrintf("%s: current best=%s height=%d log2_work=%.8g date=%s\n", | ||||
▲ Show 20 Lines • Show All 1,383 Lines • ▼ Show 20 Lines | do { | ||||
// If this block will cause a finalized block to be reorged, then we | // If this block will cause a finalized block to be reorged, then we | ||||
// mark it as invalid. | // mark it as invalid. | ||||
if (pindexFinalized && !AreOnTheSameFork(pindexNew, pindexFinalized)) { | if (pindexFinalized && !AreOnTheSameFork(pindexNew, pindexFinalized)) { | ||||
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(), | ||||
pindexFinalized->nHeight); | pindexFinalized->nHeight); | ||||
pindexNew->nStatus = pindexNew->nStatus.withFailed(); | pindexNew->nStatus = pindexNew->nStatus.withFailed(); | ||||
InvalidChainFound(pindexNew); | |||||
} | } | ||||
const CBlockIndex *pindexFork = chainActive.FindFork(pindexNew); | const CBlockIndex *pindexFork = chainActive.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; | ||||
▲ Show 20 Lines • Show All 453 Lines • ▼ Show 20 Lines | if (!AreOnTheSameFork(pindex, chainActive.Tip())) { | ||||
CBlockIndex *pindexToInvalidate = | CBlockIndex *pindexToInvalidate = | ||||
chainActive.Tip()->GetAncestor(pindexFork->nHeight + 1); | chainActive.Tip()->GetAncestor(pindexFork->nHeight + 1); | ||||
return InvalidateBlock(config, state, pindexToInvalidate); | return InvalidateBlock(config, state, pindexToInvalidate); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
const CBlockIndex *GetFinalizedBlock() { | |||||
AssertLockHeld(cs_main); | |||||
return pindexFinalized; | |||||
} | |||||
bool InvalidateBlock(const Config &config, CValidationState &state, | bool InvalidateBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex) { | CBlockIndex *pindex) { | ||||
return UnwindBlock(config, state, pindex, true); | return UnwindBlock(config, state, pindex, true); | ||||
} | } | ||||
bool ParkBlock(const Config &config, CValidationState &state, | bool ParkBlock(const Config &config, CValidationState &state, | ||||
CBlockIndex *pindex) { | CBlockIndex *pindex) { | ||||
return UnwindBlock(config, state, pindex, false); | return UnwindBlock(config, state, pindex, false); | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | bool ResetBlockFailureFlags(CBlockIndex *pindex) { | ||||
if (pindexBestInvalid && | if (pindexBestInvalid && | ||||
(pindexBestInvalid->GetAncestor(pindex->nHeight) == pindex || | (pindexBestInvalid->GetAncestor(pindex->nHeight) == pindex || | ||||
pindex->GetAncestor(pindexBestInvalid->nHeight) == | pindex->GetAncestor(pindexBestInvalid->nHeight) == | ||||
pindexBestInvalid)) { | pindexBestInvalid)) { | ||||
// Reset the invalid block marker if it is about to be cleared. | // Reset the invalid block marker if it is about to be cleared. | ||||
pindexBestInvalid = nullptr; | pindexBestInvalid = nullptr; | ||||
} | } | ||||
// In case we are reconsidering something before the finalization point, | |||||
// move the finalization point to the last common ancestor. | |||||
if (pindexFinalized) { | |||||
pindexFinalized = LastCommonAncestor(pindex, pindexFinalized); | |||||
} | |||||
UpdateFlags(pindex, [](const BlockStatus status) { | UpdateFlags(pindex, [](const BlockStatus status) { | ||||
return status.withClearedFailureFlags(); | return status.withClearedFailureFlags(); | ||||
}); | }); | ||||
return true; | return true; | ||||
} | } | ||||
static bool UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren) { | static bool UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren) { | ||||
Show All 21 Lines | |||||
bool UnparkBlockAndChildren(CBlockIndex *pindex) { | bool UnparkBlockAndChildren(CBlockIndex *pindex) { | ||||
return UnparkBlockImpl(pindex, true); | return UnparkBlockImpl(pindex, true); | ||||
} | } | ||||
bool UnparkBlock(CBlockIndex *pindex) { | bool UnparkBlock(CBlockIndex *pindex) { | ||||
return UnparkBlockImpl(pindex, false); | return UnparkBlockImpl(pindex, false); | ||||
} | } | ||||
const CBlockIndex *GetFinalizedBlock() { | |||||
AssertLockHeld(cs_main); | |||||
return pindexFinalized; | |||||
} | |||||
bool IsBlockFinalized(const CBlockIndex *pindex) { | |||||
AssertLockHeld(cs_main); | |||||
return pindexFinalized && | |||||
pindexFinalized->GetAncestor(pindex->nHeight) == pindex; | |||||
} | |||||
static CBlockIndex *AddToBlockIndex(const CBlockHeader &block) { | static CBlockIndex *AddToBlockIndex(const CBlockHeader &block) { | ||||
// Check for duplicate | // Check for duplicate | ||||
uint256 hash = block.GetHash(); | uint256 hash = block.GetHash(); | ||||
BlockMap::iterator it = mapBlockIndex.find(hash); | BlockMap::iterator it = mapBlockIndex.find(hash); | ||||
if (it != mapBlockIndex.end()) { | if (it != mapBlockIndex.end()) { | ||||
return it->second; | return it->second; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,407 Lines • Show Last 20 Lines |