While serving blocks, there is a system in place that prioritizes a peer's block requests before answering other p2p messages: See https://github.com/bitcoin/bitcoin/blob/11090c8bb359f894ef7d97b65aff52fe8191aec1/src/net_processing.cpp#L5436
As a result it can happen that if we do IBD with a low download bandwidth (that is distributed over 10 peers) a peer will not get around to answering our ping before the timeout of 20 minutes, in which case we would disconnect them, although they have done nothing wrong and are not even slow themselves (we are). This situation has been described in #35761.
This PR fixes the issue by not enforcing the ping timeout from a peer while downloading blocks from them.
In order to do that, the ping timeout check is moved out of MaybeSendPing() (which was a slightly awkward place anyway, given the name of the function) and suspended until there are no longer blocks in flight with that peer (with a grace period, so that we don't disconnect immediately after the last block was received before the peer got a chance to send us the pong).
Note that during block download, there are still other timeouts:
- A dynamic timeout (
BLOCK_DOWNLOAD_TIMEOUT_BASE/BLOCK_DOWNLOAD_TIMEOUT_PER_PEER) which will result in a timeout of600s × (1 + 0.5×9) = 55 minutesper block when downloading from 10 peers in parallel - the stalling logic which hits if the peer is much slower in comparison to other peers
- the socket inactivity check disconnects a peer that hasn't sent us anything at all in the last 20 minutes.
So the ping timeout didn't add much value anyway in that situation.
Fixes #35761