diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3022,6 +3022,7 @@ LOCK(cs_main); const auto current_time = GetTime(); + uint256 *best_block{nullptr}; for (CInv &inv : vInv) { if (interruptMsgProc) { @@ -3037,21 +3038,12 @@ UpdateBlockAvailability(pfrom.GetId(), hash); if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(hash)) { - // We used to request the full block here, but since - // headers-announcements are now the primary method of - // announcement on the network, and since, in the case that - // a node fell back to inv we probably have a reorg which we - // should get the headers for first, we now only provide a - // getheaders response here. When we receive the headers, we - // will then ask for the blocks we need. - m_connman.PushMessage( - &pfrom, msgMaker.Make(NetMsgType::GETHEADERS, - ::ChainActive().GetLocator( - pindexBestHeader), - hash)); - LogPrint(BCLog::NET, "getheaders (%d) %s to peer=%d\n", - pindexBestHeader->nHeight, hash.ToString(), - pfrom.GetId()); + // Headers-first is the primary method of announcement on + // the network. If a node fell back to sending blocks by + // inv, it's probably for a re-org. The final block hash + // provided should be the highest, so send a getheaders and + // then fetch the blocks we need to catch up. + best_block = &inv.hash; } } else { const TxId txid(inv.hash); @@ -3069,6 +3061,18 @@ } } } + + if (best_block != nullptr) { + const BlockHash hash(*best_block); + m_connman.PushMessage( + &pfrom, + msgMaker.Make(NetMsgType::GETHEADERS, + ::ChainActive().GetLocator(pindexBestHeader), + hash)); + LogPrint(BCLog::NET, "getheaders (%d) %s to peer=%d\n", + pindexBestHeader->nHeight, hash.ToString(), pfrom.GetId()); + } + return; }