Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 2,834 Lines • ▼ Show 20 Lines | bool InvalidateBlock(const Config &config, CValidationState &state, | ||||
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); | ||||
} | } | ||||
template <typename F> bool UpdateFlags(CBlockIndex *pindex, F f) { | template <typename F> | ||||
void UpdateFlagsForBlock(CBlockIndex *pindexBase, CBlockIndex *pindex, F f) { | |||||
BlockStatus newStatus = f(pindex->nStatus); | |||||
if (pindex->nStatus != newStatus && | |||||
pindex->GetAncestor(pindexBase->nHeight) == pindexBase) { | |||||
pindex->nStatus = newStatus; | |||||
setDirtyBlockIndex.insert(pindex); | |||||
if (pindex->IsValid(BlockValidity::TRANSACTIONS) && pindex->nChainTx && | |||||
setBlockIndexCandidates.value_comp()(chainActive.Tip(), pindex)) { | |||||
setBlockIndexCandidates.insert(pindex); | |||||
} | |||||
} | |||||
} | |||||
template <typename F, typename C> | |||||
void UpdateFlags(CBlockIndex *pindex, F f, C fchild) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
int nHeight = pindex->nHeight; | // Update the current block. | ||||
UpdateFlagsForBlock(pindex, pindex, f); | |||||
// Update the flags from this block and all its descendants. | // Update the flags from this block and all its descendants. | ||||
BlockMap::iterator it = mapBlockIndex.begin(); | BlockMap::iterator it = mapBlockIndex.begin(); | ||||
while (it != mapBlockIndex.end()) { | while (it != mapBlockIndex.end()) { | ||||
BlockStatus newStatus = f(it->second->nStatus); | UpdateFlagsForBlock(pindex, it->second, fchild); | ||||
if (it->second->nStatus != newStatus && | |||||
it->second->GetAncestor(nHeight) == pindex) { | |||||
it->second->nStatus = newStatus; | |||||
setDirtyBlockIndex.insert(it->second); | |||||
if (it->second->IsValid(BlockValidity::TRANSACTIONS) && | |||||
it->second->nChainTx && | |||||
setBlockIndexCandidates.value_comp()(chainActive.Tip(), | |||||
it->second)) { | |||||
setBlockIndexCandidates.insert(it->second); | |||||
} | |||||
} | |||||
it++; | it++; | ||||
} | } | ||||
// Update the flags from all ancestors too. | // Update the flags from all ancestors too. | ||||
while (pindex != nullptr) { | while (pindex != nullptr) { | ||||
BlockStatus newStatus = f(pindex->nStatus); | BlockStatus newStatus = f(pindex->nStatus); | ||||
if (pindex->nStatus != newStatus) { | if (pindex->nStatus != newStatus) { | ||||
pindex->nStatus = newStatus; | pindex->nStatus = newStatus; | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
} | } | ||||
pindex = pindex->pprev; | pindex = pindex->pprev; | ||||
} | } | ||||
} | |||||
return true; | template <typename F> void UpdateFlags(CBlockIndex *pindex, F f) { | ||||
// Handy shorthand. | |||||
UpdateFlags(pindex, f, f); | |||||
} | } | ||||
bool ResetBlockFailureFlags(CBlockIndex *pindex) { | bool ResetBlockFailureFlags(CBlockIndex *pindex) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
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; | ||||
} | } | ||||
return UpdateFlags(pindex, [](const BlockStatus status) { | UpdateFlags(pindex, [](const BlockStatus status) { | ||||
return status.withClearedFailureFlags(); | return status.withClearedFailureFlags(); | ||||
}); | }); | ||||
return true; | |||||
} | } | ||||
bool UnparkBlock(CBlockIndex *pindex) { | static bool UnparkBlockImpl(CBlockIndex *pindex, bool fClearChildren) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
if (pindexBestParked && | if (pindexBestParked && | ||||
(pindexBestParked->GetAncestor(pindex->nHeight) == pindex || | (pindexBestParked->GetAncestor(pindex->nHeight) == pindex || | ||||
pindex->GetAncestor(pindexBestParked->nHeight) == pindexBestParked)) { | pindex->GetAncestor(pindexBestParked->nHeight) == pindexBestParked)) { | ||||
// Reset the parked block marker if it is about to be cleared. | // Reset the parked block marker if it is about to be cleared. | ||||
pindexBestParked = nullptr; | pindexBestParked = nullptr; | ||||
} | } | ||||
return UpdateFlags(pindex, [](const BlockStatus status) { | UpdateFlags(pindex, | ||||
[](const BlockStatus status) { | |||||
return status.withClearedParkedFlags(); | return status.withClearedParkedFlags(); | ||||
}, | |||||
[fClearChildren](const BlockStatus status) { | |||||
return fClearChildren ? status.withClearedParkedFlags() | |||||
: status.withParkedParent(false); | |||||
}); | }); | ||||
return true; | |||||
} | |||||
bool UnparkBlockAndChildren(CBlockIndex *pindex) { | |||||
return UnparkBlockImpl(pindex, true); | |||||
} | |||||
bool UnparkBlock(CBlockIndex *pindex) { | |||||
return UnparkBlockImpl(pindex, false); | |||||
} | } | ||||
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,409 Lines • Show Last 20 Lines |