MCPcopy Create free account
hub / github.com/LUX-Core/lux / FindNextBlocksToDownload

Function FindNextBlocksToDownload

src/main.cpp:482–563  ·  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

480/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
481 * at most count entries. */
482void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<CBlockIndex*>& vBlocks, NodeId& nodeStaller)
483{
484 if (count == 0)
485 return;
486
487 vBlocks.reserve(vBlocks.size() + count);
488 CNodeState* state = State(nodeid);
489 assert(state != NULL);
490
491 // Make sure pindexBestKnownBlock is up to date, we'll need it.
492 ProcessBlockAvailability(nodeid);
493
494 if (state->pindexBestKnownBlock == NULL || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
495 // This peer has nothing interesting.
496 return;
497 }
498
499 if (state->pindexLastCommonBlock == NULL) {
500 // Bootstrap quickly by guessing a parent of our best tip is the forking point.
501 // Guessing wrong in either direction is not a problem.
502 state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
503 }
504
505 // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
506 // of their current tip anymore. Go back enough to fix that.
507 state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
508 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
509 return;
510
511 std::vector<CBlockIndex*> vToFetch;
512 CBlockIndex* pindexWalk = state->pindexLastCommonBlock;
513 // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
514 // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
515 // download that next block if the window were 1 larger.
516 int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
517 int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
518 NodeId waitingfor = -1;
519 while (pindexWalk->nHeight < nMaxHeight) {
520 // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
521 // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
522 // as iterating over ~100 CBlockIndex* entries anyway.
523 int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
524 vToFetch.resize(nToFetch);
525 pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
526 vToFetch[nToFetch - 1] = pindexWalk;
527 for (unsigned int i = nToFetch - 1; i > 0; i--) {
528 vToFetch[i - 1] = vToFetch[i]->pprev;
529 }
530
531 // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
532 // are not yet downloaded and not in flight to vBlocks. In the mean time, update
533 // pindexLastCommonBlock as long as all ancestors are already downloaded, or if it's
534 // already part of our chain (and therefore don't need it even if pruned).
535 for (CBlockIndex* pindex : vToFetch) {
536 if (!pindex->IsValid(BLOCK_VALID_TREE)) {
537 // We consider the chain that this peer is on invalid.
538 return;
539 }

Callers 1

SendMessagesFunction · 0.85

Calls 14

ProcessBlockAvailabilityFunction · 0.85
LastCommonAncestorFunction · 0.85
TipMethod · 0.80
HeightMethod · 0.80
GetAncestorMethod · 0.80
StateFunction · 0.70
reserveMethod · 0.45
sizeMethod · 0.45
resizeMethod · 0.45
IsValidMethod · 0.45
ContainsMethod · 0.45
countMethod · 0.45

Tested by

no test coverage detected