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