Browse Source

Merge #7827: Speed up getchaintips.

87049e8 Speed up getchaintips. (mrbandrews)
0.13
Wladimir J. van der Laan 9 years ago
parent
commit
4205ad7ca2
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 29
      src/rpc/blockchain.cpp

29
src/rpc/blockchain.cpp

@ -815,17 +815,30 @@ UniValue getchaintips(const UniValue& params, bool fHelp)
LOCK(cs_main); 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 * Idea: the set of chain tips is chainActive.tip, plus orphan blocks which do not have another orphan building off of them.
of another block. */ * 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; std::set<const CBlockIndex*, CompareBlocksByHeight> setTips;
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) std::set<const CBlockIndex*> setOrphans;
setTips.insert(item.second); std::set<const CBlockIndex*> setPrevs;
BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex)
{ {
const CBlockIndex* pprev = item.second->pprev; if (!chainActive.Contains(item.second)) {
if (pprev) setOrphans.insert(item.second);
setTips.erase(pprev); 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. // Always report the currently active tip.

Loading…
Cancel
Save