Merge bitcoin/bitcoin#32180: p2p: Advance pindexLastCommonBlock early after connecting blocks

01cc20f330 test: improve coverage for a resolved stalling situation (Martin Zumsande)
9af6daf07e test: remove magic number when checking for blocks that have arrived (Martin Zumsande)
3069d66dca p2p: During block download, adjust pindexLastCommonBlock better (Martin Zumsande)

Pull request description:

  As described in #32179, `pindexLastCommonBlock` is updated later than necessary
  in master.
  In case of a linear chain with no forks, it can be moved forward at the beginning of
  `FindNextBlocksToDownload`, so that the updated value can be used to better estimate `nWindowEnd`.
  This helps the node to request all blocks from peers within the correct 1024-block-window and avoids peers being incorrectly marked as stallers.

  I also changed `p2p_ibd_stalling.py` to cover the situation after a resolved situation, making sure that no additional peers are marked for stalling.

  Fixes #32179

ACKs for top commit:
  Crypt-iQ:
    crACK 01cc20f330
  stringintech:
    re-ACK 01cc20f
  achow101:
    ACK 01cc20f330
  sipa:
    utACK 01cc20f330

Tree-SHA512: a97f7a7ef5ded538ee35576e04b3fbcdd46a6d0189c7ba3abacc6e0d81e800aac5b0c2d2565d0462ef6fd4acc751989f577fd6adfd450171a7d6ab26f437df32
This commit is contained in:
Ava Chow
2025-11-10 08:48:49 -08:00
2 changed files with 28 additions and 34 deletions

View File

@@ -1393,17 +1393,16 @@ void PeerManagerImpl::FindNextBlocksToDownload(const Peer& peer, unsigned int co
return;
}
// Bootstrap quickly by guessing a parent of our best tip is the forking point.
// Guessing wrong in either direction is not a problem.
// Also reset pindexLastCommonBlock after a snapshot was loaded, so that blocks after the snapshot will be prioritised for download.
// Determine the forking point between the peer's chain and our chain:
// pindexLastCommonBlock is required to be an ancestor of pindexBestKnownBlock, and will be used as a starting point.
// It is being set to the fork point between the peer's best known block and the current tip, unless it is already set to
// an ancestor with more work than the fork point.
auto fork_point = LastCommonAncestor(state->pindexBestKnownBlock, m_chainman.ActiveTip());
if (state->pindexLastCommonBlock == nullptr ||
(snap_base && state->pindexLastCommonBlock->nHeight < snap_base->nHeight)) {
state->pindexLastCommonBlock = m_chainman.ActiveChain()[std::min(state->pindexBestKnownBlock->nHeight, m_chainman.ActiveChain().Height())];
fork_point->nChainWork > state->pindexLastCommonBlock->nChainWork ||
state->pindexBestKnownBlock->GetAncestor(state->pindexLastCommonBlock->nHeight) != state->pindexLastCommonBlock) {
state->pindexLastCommonBlock = fork_point;
}
// If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
// of its current tip anymore. Go back enough to fix that.
state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
return;