Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
| Show First 20 Lines • Show All 2,096 Lines • ▼ Show 20 Lines | void PeerManagerImpl::FindNextBlocks(std::vector<const CBlockIndex *> &vBlocks, | ||||
| const Peer &peer, CNodeState *state, | const Peer &peer, CNodeState *state, | ||||
| const CBlockIndex *pindexWalk, | const CBlockIndex *pindexWalk, | ||||
| unsigned int count, int nWindowEnd, | unsigned int count, int nWindowEnd, | ||||
| const CChain *activeChain, | const CChain *activeChain, | ||||
| NodeId *nodeStaller) { | NodeId *nodeStaller) { | ||||
| std::vector<const CBlockIndex *> vToFetch; | std::vector<const CBlockIndex *> vToFetch; | ||||
| int nMaxHeight = | int nMaxHeight = | ||||
| std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1); | std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1); | ||||
| const bool is_limited_peer = IsLimitedPeer(peer); | |||||
| NodeId waitingfor = -1; | NodeId waitingfor = -1; | ||||
| while (pindexWalk->nHeight < nMaxHeight) { | while (pindexWalk->nHeight < nMaxHeight) { | ||||
| // Read up to 128 (or more, if more blocks than that are needed) | // Read up to 128 (or more, if more blocks than that are needed) | ||||
| // successors of pindexWalk (towards pindexBestKnownBlock) into | // successors of pindexWalk (towards pindexBestKnownBlock) into | ||||
| // vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as | // vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as | ||||
| // expensive as iterating over ~100 CBlockIndex* entries anyway. | // expensive as iterating over ~100 CBlockIndex* entries anyway. | ||||
| int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, | int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, | ||||
| std::max<int>(count - vBlocks.size(), 128)); | std::max<int>(count - vBlocks.size(), 128)); | ||||
| Show All 10 Lines | while (pindexWalk->nHeight < nMaxHeight) { | ||||
| // the meantime, update pindexLastCommonBlock as long as all ancestors | // the meantime, update pindexLastCommonBlock as long as all ancestors | ||||
| // are already downloaded, or if it's already part of our chain (and | // are already downloaded, or if it's already part of our chain (and | ||||
| // therefore don't need it even if pruned). | // therefore don't need it even if pruned). | ||||
| for (const CBlockIndex *pindex : vToFetch) { | for (const CBlockIndex *pindex : vToFetch) { | ||||
| if (!pindex->IsValid(BlockValidity::TREE)) { | if (!pindex->IsValid(BlockValidity::TREE)) { | ||||
| // We consider the chain that this peer is on invalid. | // We consider the chain that this peer is on invalid. | ||||
| return; | return; | ||||
| } | } | ||||
| if (pindex->nStatus.hasData() || | if (pindex->nStatus.hasData() || | ||||
| (activeChain && activeChain->Contains(pindex))) { | (activeChain && activeChain->Contains(pindex))) { | ||||
| if (activeChain && pindex->HaveNumChainTxs()) { | if (activeChain && pindex->HaveNumChainTxs()) { | ||||
| state->pindexLastCommonBlock = pindex; | state->pindexLastCommonBlock = pindex; | ||||
| } | } | ||||
| } else if (!IsBlockRequested(pindex->GetBlockHash())) { | 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; | |||||
| } | |||||
| continue; | |||||
| } | |||||
| // The block is not already downloaded, and not yet in flight. | // The block is not already downloaded, and not yet in flight. | ||||
| if (pindex->nHeight > nWindowEnd) { | if (pindex->nHeight > nWindowEnd) { | ||||
| // We reached the end of the window. | // We reached the end of the window. | ||||
| if (vBlocks.size() == 0 && waitingfor != peer.m_id) { | if (vBlocks.size() == 0 && waitingfor != peer.m_id) { | ||||
| // We aren't able to fetch anything, but we would be if | // We aren't able to fetch anything, but we would be if | ||||
| // the download window was one larger. | // the download window was one larger. | ||||
| if (nodeStaller) { | if (nodeStaller) { | ||||
| *nodeStaller = waitingfor; | *nodeStaller = waitingfor; | ||||
| } | } | ||||
| } | } | ||||
| return; | return; | ||||
| } | } | ||||
| // Don't request blocks that go further than what limited peers can | |||||
| // provide, with a buffer of two blocks buffer for possible races | |||||
| if (is_limited_peer && | |||||
| (state->pindexBestKnownBlock->nHeight - pindex->nHeight >= | |||||
| static_cast<int>(NODE_NETWORK_LIMITED_MIN_BLOCKS) - 2)) { | |||||
| continue; | |||||
| } | |||||
| vBlocks.push_back(pindex); | vBlocks.push_back(pindex); | ||||
| if (vBlocks.size() == count) { | if (vBlocks.size() == count) { | ||||
| return; | return; | ||||
| } | } | ||||
| } else if (waitingfor == -1) { | |||||
| // This is the first already-in-flight block. | |||||
| waitingfor = | |||||
| mapBlocksInFlight.lower_bound(pindex->GetBlockHash()) | |||||
| ->second.first; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } // namespace | } // namespace | ||||
| template <class InvId> | template <class InvId> | ||||
| static bool TooManyAnnouncements(const CNode &node, | static bool TooManyAnnouncements(const CNode &node, | ||||
| ▲ Show 20 Lines • Show All 7,172 Lines • Show Last 20 Lines | |||||