Changeset View
Changeset View
Standalone View
Standalone View
src/chain.cpp
Show First 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | static inline int GetSkipHeight(int height) { | ||||
// Determine which height to jump back to. Any number strictly lower than | // Determine which height to jump back to. Any number strictly lower than | ||||
// height is acceptable, but the following expression seems to perform well | // height is acceptable, but the following expression seems to perform well | ||||
// in simulations (max 110 steps to go back up to 2**18 blocks). | // in simulations (max 110 steps to go back up to 2**18 blocks). | ||||
return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 | return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 | ||||
: InvertLowestOne(height); | : InvertLowestOne(height); | ||||
} | } | ||||
CBlockIndex *CBlockIndex::GetAncestor(int height) { | const CBlockIndex *CBlockIndex::GetAncestor(int height) const { | ||||
if (height > nHeight || height < 0) { | if (height > nHeight || height < 0) { | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
CBlockIndex *pindexWalk = this; | const CBlockIndex *pindexWalk = this; | ||||
int heightWalk = nHeight; | int heightWalk = nHeight; | ||||
while (heightWalk > height) { | while (heightWalk > height) { | ||||
int heightSkip = GetSkipHeight(heightWalk); | int heightSkip = GetSkipHeight(heightWalk); | ||||
int heightSkipPrev = GetSkipHeight(heightWalk - 1); | int heightSkipPrev = GetSkipHeight(heightWalk - 1); | ||||
if (pindexWalk->pskip != nullptr && | if (pindexWalk->pskip != nullptr && | ||||
(heightSkip == height || | (heightSkip == height || | ||||
(heightSkip > height && !(heightSkipPrev < heightSkip - 2 && | (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && | ||||
heightSkipPrev >= height)))) { | heightSkipPrev >= height)))) { | ||||
// Only follow pskip if pprev->pskip isn't better than pskip->pprev. | // Only follow pskip if pprev->pskip isn't better than pskip->pprev. | ||||
pindexWalk = pindexWalk->pskip; | pindexWalk = pindexWalk->pskip; | ||||
heightWalk = heightSkip; | heightWalk = heightSkip; | ||||
} else { | } else { | ||||
assert(pindexWalk->pprev); | assert(pindexWalk->pprev); | ||||
pindexWalk = pindexWalk->pprev; | pindexWalk = pindexWalk->pprev; | ||||
heightWalk--; | heightWalk--; | ||||
} | } | ||||
} | } | ||||
return pindexWalk; | return pindexWalk; | ||||
} | } | ||||
const CBlockIndex *CBlockIndex::GetAncestor(int height) const { | CBlockIndex *CBlockIndex::GetAncestor(int height) { | ||||
return const_cast<CBlockIndex *>(this)->GetAncestor(height); | return const_cast<CBlockIndex *>( | ||||
const_cast<const CBlockIndex *>(this)->GetAncestor(height)); | |||||
} | } | ||||
void CBlockIndex::BuildSkip() { | void CBlockIndex::BuildSkip() { | ||||
if (pprev) { | if (pprev) { | ||||
pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); | pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 62 Lines • Show Last 20 Lines |