Auto merge of #5192 - LarryRuane:4624-ibd-getheaders-2, r=str4d

when rewinding, set pindexBestHeader to the highest-work block index

Further fix for #4624. #4935 eliminated unnecessary, redundant
getheaders P2P requests, but had the side-effect of causing IBD
(syncing) to sometimes stall. This happens because `RewindBlockIndex()`
sets pindexBestHeader to `chainActive.Tip()`, which is the best block we
currently know of, but may be several thousand blocks behind the latest
_header_ in the block index (`mapBlockIndex`).

`RewindBlockIndex()` is called during startup.

By issuing a `getheaders` request from a height several thousand blocks
ago, the `headers` reply will return 160 entries that are already in our
`mapBlockIndex`. Because the maximum number of entries is returned,
and the last entry isn't new to us, we don't issue any further `getheaders`
requests to this peer. The same happens with every peer, causing the
`getheaders` sequences to all stop. The node stops making any progress.

The workaround (without this PR's changes) is to restart the node
with the `-optimize-getheaders=0` option.
This commit is contained in:
Homu 2021-06-07 22:51:02 +00:00
commit 892d1c1254
1 changed files with 8 additions and 0 deletions

View File

@ -5135,6 +5135,14 @@ bool RewindBlockIndex(const CChainParams& chainparams, bool& clearWitnessCaches)
PruneBlockIndexCandidates();
// Ensure that pindexBestHeader points to the block index entry with the most work;
// setBlockIndexCandidates entries are sorted by work, highest at the end.
{
std::set<CBlockIndex*, CBlockIndexWorkComparator>::reverse_iterator it = setBlockIndexCandidates.rbegin();
assert(it != setBlockIndexCandidates.rend());
pindexBestHeader = *it;
}
CheckBlockIndex(chainparams.GetConsensus());
if (!FlushStateToDisk(chainparams, state, FLUSH_STATE_ALWAYS)) {