@@ -567,6 +567,8 @@ class PeerManagerImpl final : public PeerManager
567
567
void HandleFewUnconnectingHeaders (CNode& pfrom, Peer& peer, const std::vector<CBlockHeader>& headers);
568
568
/* * Return true if the headers connect to each other, false otherwise */
569
569
bool CheckHeadersAreContinuous (const std::vector<CBlockHeader>& headers) const ;
570
+ /* * Request further headers from this peer from a given block header */
571
+ void FetchMoreHeaders (CNode& pfrom, const CBlockIndex *pindexLast, const Peer& peer);
570
572
571
573
void SendBlockTransactions (CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req);
572
574
@@ -2255,6 +2257,25 @@ bool PeerManagerImpl::CheckHeadersAreContinuous(const std::vector<CBlockHeader>&
2255
2257
return true ;
2256
2258
}
2257
2259
2260
+ /*
2261
+ * Continue fetching headers from a given point.
2262
+ * pindexLast should be the last header we learned from a peer in their prior
2263
+ * headers message.
2264
+ *
2265
+ * This is used for headers sync with a peer; even if pindexLast is an ancestor
2266
+ * of a known chain (such as our tip) we don't yet know where the peer's chain
2267
+ * might fork from what we know, so we continue exactly from where the peer
2268
+ * left off.
2269
+ */
2270
+ void PeerManagerImpl::FetchMoreHeaders (CNode& pfrom, const CBlockIndex *pindexLast, const Peer& peer)
2271
+ {
2272
+ const CNetMsgMaker msgMaker (pfrom.GetCommonVersion ());
2273
+
2274
+ LogPrint (BCLog::NET, " more getheaders (%d) to end to peer=%d (startheight:%d)\n " ,
2275
+ pindexLast->nHeight , pfrom.GetId (), peer.m_starting_height );
2276
+ m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::GETHEADERS, m_chainman.ActiveChain ().GetLocator (pindexLast), uint256 ()));
2277
+ }
2278
+
2258
2279
void PeerManagerImpl::ProcessHeadersMessage (CNode& pfrom, Peer& peer,
2259
2280
const std::vector<CBlockHeader>& headers,
2260
2281
bool via_compact_block)
@@ -2309,6 +2330,12 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
2309
2330
}
2310
2331
}
2311
2332
2333
+ // Consider fetching more headers.
2334
+ if (nCount == MAX_HEADERS_RESULTS) {
2335
+ // Headers message had its maximum size; the peer may have more headers.
2336
+ FetchMoreHeaders (pfrom, pindexLast, peer);
2337
+ }
2338
+
2312
2339
{
2313
2340
LOCK (cs_main);
2314
2341
CNodeState *nodestate = State (pfrom.GetId ());
@@ -2328,15 +2355,6 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
2328
2355
nodestate->m_last_block_announcement = GetTime ();
2329
2356
}
2330
2357
2331
- if (nCount == MAX_HEADERS_RESULTS) {
2332
- // Headers message had its maximum size; the peer may have more headers.
2333
- // TODO: optimize: if pindexLast is an ancestor of m_chainman.ActiveChain().Tip or m_chainman.m_best_header, continue
2334
- // from there instead.
2335
- LogPrint (BCLog::NET, " more getheaders (%d) to end to peer=%d (startheight:%d)\n " ,
2336
- pindexLast->nHeight , pfrom.GetId (), peer.m_starting_height );
2337
- m_connman.PushMessage (&pfrom, msgMaker.Make (NetMsgType::GETHEADERS, m_chainman.ActiveChain ().GetLocator (pindexLast), uint256 ()));
2338
- }
2339
-
2340
2358
// If this set of headers is valid and ends in a block with at least as
2341
2359
// much work as our tip, download as much as possible.
2342
2360
if (CanDirectFetch () && pindexLast->IsValid (BLOCK_VALID_TREE) && m_chainman.ActiveChain ().Tip ()->nChainWork <= pindexLast->nChainWork ) {
0 commit comments