Skip to content

Commit

Permalink
Optimize sending of getheaders when pindexLast is an ancestor of
Browse files Browse the repository at this point in the history
pindexBestHeader

Needed since bitcoin#4468
  • Loading branch information
rebroad committed Apr 15, 2020
1 parent 7e180d9 commit d8a680b
Showing 1 changed file with 33 additions and 4 deletions.
37 changes: 33 additions & 4 deletions src/net_processing.cpp
Expand Up @@ -2392,10 +2392,39 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr

if (nCount == MAX_HEADERS_RESULTS) {
// Headers message had its maximum size; the peer may have more headers.
// TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
// from there instead.
LogPrint("block", "send more getheaders (%d) to end. peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->id, pfrom->nStartingHeight);
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexLast), uint256()));
//
// Optimize where to fetch the next headers from. Places the last header could be;-
// 1 - neither an ancestor of chainActive.Tip() nor BestHeader. fetch from pindexLast
// 2 - ancestor of chainActive.Tip() and BestHeader. fetch from BestHeader
// 3 - ancestor of BestHeader not chainActive.Tip(). Tip is an ancestor of BestHeader
// fetch from BestHeader
// 4 - ancestor of chainActive.Tip and BestHeader. Tip is forked from BestHeader
// fetch from the point where tip forks from BestHeader (since we don't know which fork
// the other peer is following but can nevertheless assume they don't fork before our fork).
// 5 - ancestor of BestHeader not chainActive.Tip(). Tip is forked from BestHeader.
// fetch from pindexLast (not BestHeader, given the unusual circumstances)
// 6 - ancestor of chainActive.Tip not BestHeader. Tip is forked from BestHeader.
// fetch from pindexLast (not Tip, given the unusual circumstances)

const CBlockIndex *pindexContinue = pindexLast;
std::string strDesc;
if (LastCommonAncestor(pindexLast, pindexBestHeader) == pindexLast) {
// received header is an ancestor of pindexBestHeader (cases 2, 3, 4, 5)
const CBlockIndex *pindexFork = LastCommonAncestor(pindexBestHeader, chainActive.Tip());
if (pindexFork == chainActive.Tip()) {
// Our current tip is an ancestor of pindexBestHeader
pindexContinue = pindexBestHeader; // cases 2, 3
if (pindexLast != pindexBestHeader)
strDesc += "best: ";
} else if (LastCommonAncestor(pindexFork, pindexLast) == pindexLast) {
// received header is an ancestor of where the tip and BestHeader diverges
pindexContinue = pindexFork; // case 4
strDesc += "fork: ";
}
}

LogPrint("block", "send more getheaders (%s%d) to end. peer=%d (startheight:%d)\n", strDesc, pindexContinue->nHeight, pfrom->id, pfrom->nStartingHeight);
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexContinue), uint256()));
}

bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus());
Expand Down

0 comments on commit d8a680b

Please sign in to comment.