Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has * at most count entries. */
| 480 | /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has |
| 481 | * at most count entries. */ |
| 482 | void 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 | } |
no test coverage detected