| 1042 | } |
| 1043 | |
| 1044 | void PeerManagerImpl::FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller) |
| 1045 | { |
| 1046 | if (count == 0) |
| 1047 | return; |
| 1048 | |
| 1049 | vBlocks.reserve(vBlocks.size() + count); |
| 1050 | CNodeState *state = State(nodeid); |
| 1051 | assert(state != nullptr); |
| 1052 | |
| 1053 | // Make sure pindexBestKnownBlock is up to date, we'll need it. |
| 1054 | ProcessBlockAvailability(nodeid); |
| 1055 | |
| 1056 | if (state->pindexBestKnownBlock == nullptr || state->pindexBestKnownBlock->nChainWork < m_chainman.ActiveChain().Tip()->nChainWork || state->pindexBestKnownBlock->nChainWork < nMinimumChainWork) { |
| 1057 | // This peer has nothing interesting. |
| 1058 | return; |
| 1059 | } |
| 1060 | |
| 1061 | if (state->pindexLastCommonBlock == nullptr) { |
| 1062 | // Bootstrap quickly by guessing a parent of our best tip is the forking point. |
| 1063 | // Guessing wrong in either direction is not a problem. |
| 1064 | state->pindexLastCommonBlock = m_chainman.ActiveChain()[std::min(state->pindexBestKnownBlock->nHeight, m_chainman.ActiveChain().Height())]; |
| 1065 | } |
| 1066 | |
| 1067 | // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor |
| 1068 | // of its current tip anymore. Go back enough to fix that. |
| 1069 | state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock); |
| 1070 | if (state->pindexLastCommonBlock == state->pindexBestKnownBlock) |
| 1071 | return; |
| 1072 | |
| 1073 | const Consensus::Params& consensusParams = m_chainparams.GetConsensus(); |
| 1074 | std::vector<const CBlockIndex*> vToFetch; |
| 1075 | const CBlockIndex *pindexWalk = state->pindexLastCommonBlock; |
| 1076 | // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last |
| 1077 | // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to |
| 1078 | // download that next block if the window were 1 larger. |
| 1079 | int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW; |
| 1080 | int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1); |
| 1081 | NodeId waitingfor = -1; |
| 1082 | while (pindexWalk->nHeight < nMaxHeight) { |
| 1083 | // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards |
| 1084 | // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive |
| 1085 | // as iterating over ~100 CBlockIndex* entries anyway. |
| 1086 | int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128)); |
| 1087 | vToFetch.resize(nToFetch); |
| 1088 | pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch); |
| 1089 | vToFetch[nToFetch - 1] = pindexWalk; |
| 1090 | for (unsigned int i = nToFetch - 1; i > 0; i--) { |
| 1091 | vToFetch[i - 1] = vToFetch[i]->pprev; |
| 1092 | } |
| 1093 | |
| 1094 | // Iterate over those blocks in vToFetch (in forward direction), adding the ones that |
| 1095 | // are not yet downloaded and not in flight to vBlocks. In the meantime, update |
| 1096 | // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's |
| 1097 | // already part of our chain (and therefore don't need it even if pruned). |
| 1098 | for (const CBlockIndex* pindex : vToFetch) { |
| 1099 | if (!pindex->IsValid(BLOCK_VALID_TREE)) { |
| 1100 | // We consider the chain that this peer is on invalid. |
| 1101 | return; |
nothing calls this directly
no test coverage detected