MCPcopy Create free account
hub / github.com/ElementsProject/elements / FindNextBlocksToDownload

Method FindNextBlocksToDownload

src/net_processing.cpp:1044–1130  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1042}
1043
1044void 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;

Callers

nothing calls this directly

Calls 14

LastCommonAncestorFunction · 0.85
DeploymentActiveAtFunction · 0.85
HeightMethod · 0.80
GetAncestorMethod · 0.80
HaveTxsDownloadedMethod · 0.80
StateEnum · 0.70
reserveMethod · 0.45
sizeMethod · 0.45
TipMethod · 0.45
resizeMethod · 0.45
IsValidMethod · 0.45
ContainsMethod · 0.45

Tested by

no test coverage detected