diff options
author | Ava Chow <github@achow101.com> | 2024-03-11 08:09:23 -0400 |
---|---|---|
committer | Ava Chow <github@achow101.com> | 2024-03-11 08:15:42 -0400 |
commit | 4a903741b0bc128745b1096586329456d1f1c447 (patch) | |
tree | 614630ceb37d00658e4e1702a22020e6023d163d /src | |
parent | 10d7b6e201311891f0a9dc63b3d9517ec4b5aaad (diff) | |
parent | c5b5843d8f10d96f76ee6b95f2b1b1b4ce755f75 (diff) |
Merge bitcoin/bitcoin#28120: p2p: make block download logic aware of limited peers threshold
c5b5843d8f10d96f76ee6b95f2b1b1b4ce755f75 test: avoid requesting blocks beyond limited peer threshold (furszy)
2f6a05512fa86d086b2b976c401394571d88bd93 p2p: sync from limited peer, only request blocks below threshold (furszy)
73127722a2d2b5c8da4102284f9d0cf504a2e72d refactor: Make FindNextBlocks friendlier (furszy)
Pull request description:
Even when the node believes it has IBD completed, need to avoid
requesting historical blocks from network-limited peers.
Otherwise, the limited peer will disconnect right away.
The simplest scenario could be a node that gets synced, drops
connections, and stays inactive for a while. Then, once it re-connects
(IBD stays completed), the node tries to fetch all the missing blocks
from any peer, getting disconnected by the limited ones.
Note:
Can verify the behavior by cherry-picking the test commit alone on
master. It will fail there.
ACKs for top commit:
achow101:
ACK c5b5843d8f10d96f76ee6b95f2b1b1b4ce755f75
vasild:
ACK c5b5843d8f10d96f76ee6b95f2b1b1b4ce755f75
mzumsande:
Code Review ACK c5b5843d8f10d96f76ee6b95f2b1b1b4ce755f75
pinheadmz:
ACK c5b5843d8f10d96f76ee6b95f2b1b1b4ce755f75
Tree-SHA512: 9e550698bc6e63cc587b2b988a87d0ab555a8fa188c91c3f33287f8201d77c28b373331845356ad86f17bb21c15950b6466bc1cafd0ce8139d70364cb71c2ad2
Diffstat (limited to 'src')
-rw-r--r-- | src/net_processing.cpp | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 30d2d43e58..c77fcbff3e 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1451,6 +1451,7 @@ void PeerManagerImpl::FindNextBlocks(std::vector<const CBlockIndex*>& vBlocks, c { std::vector<const CBlockIndex*> vToFetch; int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1); + bool is_limited_peer = IsLimitedPeer(peer); NodeId waitingfor = -1; while (pindexWalk->nHeight < nMaxHeight) { // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards @@ -1473,30 +1474,46 @@ void PeerManagerImpl::FindNextBlocks(std::vector<const CBlockIndex*>& vBlocks, c // We consider the chain that this peer is on invalid. return; } + if (!CanServeWitnesses(peer) && DeploymentActiveAt(*pindex, m_chainman, Consensus::DEPLOYMENT_SEGWIT)) { // We wouldn't download this block or its descendants from this peer. return; } + if (pindex->nStatus & BLOCK_HAVE_DATA || (activeChain && activeChain->Contains(pindex))) { - if (activeChain && pindex->HaveNumChainTxs()) + if (activeChain && pindex->HaveNumChainTxs()) { state->pindexLastCommonBlock = pindex; - } else if (!IsBlockRequested(pindex->GetBlockHash())) { - // The block is not already downloaded, and not yet in flight. - if (pindex->nHeight > nWindowEnd) { - // We reached the end of the window. - if (vBlocks.size() == 0 && waitingfor != peer.m_id) { - // We aren't able to fetch anything, but we would be if the download window was one larger. - if (nodeStaller) *nodeStaller = waitingfor; - } - return; } - vBlocks.push_back(pindex); - if (vBlocks.size() == count) { - return; + continue; + } + + // Is block in-flight? + if (IsBlockRequested(pindex->GetBlockHash())) { + if (waitingfor == -1) { + // This is the first already-in-flight block. + waitingfor = mapBlocksInFlight.lower_bound(pindex->GetBlockHash())->second.first; } - } else if (waitingfor == -1) { - // This is the first already-in-flight block. - waitingfor = mapBlocksInFlight.lower_bound(pindex->GetBlockHash())->second.first; + continue; + } + + // The block is not already downloaded, and not yet in flight. + if (pindex->nHeight > nWindowEnd) { + // We reached the end of the window. + if (vBlocks.size() == 0 && waitingfor != peer.m_id) { + // We aren't able to fetch anything, but we would be if the download window was one larger. + if (nodeStaller) *nodeStaller = waitingfor; + } + return; + } + + // Don't request blocks that go further than what limited peers can provide + if (is_limited_peer && (state->pindexBestKnownBlock->nHeight - pindex->nHeight >= static_cast<int>(NODE_NETWORK_LIMITED_MIN_BLOCKS) - 2 /* two blocks buffer for possible races */)) { + continue; + } + + vBlocks.push_back(pindex); + if (vBlocks.size() == count) { + return; } } } |