Add functions to construct locators without CChain

This introduces an insignificant performance penalty, as it means locator
construction needs to use the skiplist-based CBlockIndex::GetAncestor()
function instead of the lookup-based CChain, but avoids the need for
callers to have access to a relevant CChain object.
This commit is contained in:
Pieter Wuille
2022-08-07 20:56:17 -04:00
committed by Suhas Daftuar
parent 84852bb6bb
commit ed470940cd
5 changed files with 41 additions and 34 deletions

View File

@@ -28,32 +28,33 @@ void CChain::SetTip(CBlockIndex& block)
}
}
CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
int nStep = 1;
std::vector<uint256> vHave;
vHave.reserve(32);
std::vector<uint256> LocatorEntries(const CBlockIndex* index)
{
int step = 1;
std::vector<uint256> have;
if (index == nullptr) return have;
if (!pindex)
pindex = Tip();
while (pindex) {
vHave.push_back(pindex->GetBlockHash());
// Stop when we have added the genesis block.
if (pindex->nHeight == 0)
break;
have.reserve(32);
while (index) {
have.emplace_back(index->GetBlockHash());
if (index->nHeight == 0) break;
// Exponentially larger steps back, plus the genesis block.
int nHeight = std::max(pindex->nHeight - nStep, 0);
if (Contains(pindex)) {
// Use O(1) CChain index if possible.
pindex = (*this)[nHeight];
} else {
// Otherwise, use O(log n) skiplist.
pindex = pindex->GetAncestor(nHeight);
}
if (vHave.size() > 10)
nStep *= 2;
int height = std::max(index->nHeight - step, 0);
// Use skiplist.
index = index->GetAncestor(height);
if (have.size() > 10) step *= 2;
}
return have;
}
return CBlockLocator(vHave);
CBlockLocator GetLocator(const CBlockIndex* index)
{
return CBlockLocator{std::move(LocatorEntries(index))};
}
CBlockLocator CChain::GetLocator() const
{
return ::GetLocator(Tip());
}
const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {