Skip to content

Commit

Permalink
Merge bitcoin#7827: Speed up getchaintips.
Browse files Browse the repository at this point in the history
87049e8 Speed up getchaintips. (mrbandrews)
  • Loading branch information
laanwj authored and codablock committed Dec 20, 2017
1 parent 1b17e94 commit 4f5bb79
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions src/rpc/blockchain.cpp
Expand Up @@ -959,17 +959,30 @@ UniValue getchaintips(const UniValue& params, bool fHelp)

LOCK(cs_main);

/* Build up a list of chain tips. We start with the list of all
known blocks, and successively remove blocks that appear as pprev
of another block. */
/*
* Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
* Algorithm:
* - Make one pass through mapBlockIndex, picking out the orphan blocks, and also storing a set of the orphan block's pprev pointers.
* - Iterate through the orphan blocks. If the block isn't pointed to by another orphan, it is a chain tip.
* - add chainActive.Tip()
*/
std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
setTips.insert(item.second);
std::set<const CBlockIndex*> setOrphans;
std::set<const CBlockIndex*> setPrevs;

BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
{
const CBlockIndex* pprev = item.second->pprev;
if (pprev)
setTips.erase(pprev);
if (!chainActive.Contains(item.second)) {
setOrphans.insert(item.second);
setPrevs.insert(item.second->pprev);
}
}

for (std::set<const CBlockIndex*>::iterator it = setOrphans.begin(); it != setOrphans.end(); ++it)
{
if (setPrevs.erase(*it) == 0) {
setTips.insert(*it);
}
}

// Always report the currently active tip.
Expand Down

0 comments on commit 4f5bb79

Please sign in to comment.