MCPcopy Create free account
hub / github.com/bitcoinxt/bitcoinxt / FindNextBlocksToDownload

Function FindNextBlocksToDownload

src/main.cpp:375–458  ·  view source on GitHub ↗

Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has * at most count entries. */

Source from the content-addressed store, hash-verified

373/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
374 * at most count entries. */
375void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, std::set<NodeId>& nodeStaller) {
376 if (count == 0)
377 return;
378
379 AssertLockHeld(cs_main);
380 vBlocks.reserve(vBlocks.size() + count);
381 NodeStatePtr state(nodeid);
382 assert(!state.IsNull());
383
384 // Make sure pindexBestKnownBlock is up to date, we'll need it.
385 ProcessBlockAvailability(state);
386
387 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
388 // This peer has nothing interesting.
389 return;
390 }
391
392 if (state->pindexLastCommonBlock == NULL) {
393 // Bootstrap quickly by guessing a parent of our best tip is the forking point.
394 // Guessing wrong in either direction is not a problem.
395 state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
396 }
397
398 // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
399 // of its current tip anymore. Go back enough to fix that.
400 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
401 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
402 return;
403
404 std::vector<CBlockIndex*> vToFetch;
405 CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
406 // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
407 // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
408 // download that next block if the window were 1 larger.
409 int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
410 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
411 std::set<NodeId> waitingfor;
412 while (pindexWalk->nHeight < nMaxHeight) {
413 // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
414 // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
415 // as iterating over ~100 CBlockIndex* entries anyway.
416 int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
417 vToFetch.resize(nToFetch);
418 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
419 vToFetch[nToFetch - 1] = pindexWalk;
420 for (unsigned int i = nToFetch - 1; i > 0; i--) {
421 vToFetch[i - 1] = vToFetch[i]->pprev;
422 }
423
424 // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
425 // are not yet downloaded and not in flight to vBlocks. In the mean time, update
426 // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
427 // already part of our chain (and therefore don't need it even if pruned).
428 BOOST_FOREACH(CBlockIndex* pindex, vToFetch) {
429 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
430 // We consider the chain that this peer is on invalid.
431 return;
432 }

Callers 1

SendMessagesFunction · 0.85

Calls 9

ProcessBlockAvailabilityFunction · 0.85
LastCommonAncestorFunction · 0.85
reserveMethod · 0.80
HeightMethod · 0.80
resizeMethod · 0.80
GetAncestorMethod · 0.80
sizeMethod · 0.45
IsNullMethod · 0.45
TipMethod · 0.45

Tested by

no test coverage detected