diff --git a/src/avalanche/processor.cpp b/src/avalanche/processor.cpp --- a/src/avalanche/processor.cpp +++ b/src/avalanche/processor.cpp @@ -534,21 +534,37 @@ std::vector<CInv> Processor::getInvsForNextPoll(bool forPoll) { std::vector<CInv> invs; + auto extractVoteRecordsToInvs = [&](auto vrBegin, auto vrEnd, + auto voteItemToInv) { + auto it = vrBegin; + while (it != vrEnd && invs.size() < AVALANCHE_MAX_ELEMENT_POLL) { + const bool shouldPoll = + forPoll ? it->second.registerPoll() : it->second.shouldPoll(); + + if (shouldPoll) { + invs.emplace_back(voteItemToInv(it->first)); + } + + ++it; + } + }; + auto proofVoteRecordsReadView = proofVoteRecords.getReadView(); - auto pit = proofVoteRecordsReadView.begin(); // Clamp to AVALANCHE_MAX_ELEMENT_POLL - 1 so we're always able to poll // for a new block. Since the proofs are sorted by score, the most // valuable are voted first. - while (pit != proofVoteRecordsReadView.end() && - invs.size() < AVALANCHE_MAX_ELEMENT_POLL - 1) { - const bool shouldPoll = - forPoll ? pit->second.registerPoll() : pit->second.shouldPoll(); - if (shouldPoll) { - invs.emplace_back(MSG_AVA_PROOF, pit->first->getId()); - } - ++pit; - } + auto proofVoteRecordsItEnd = + std::next(proofVoteRecordsReadView.begin(), + std::min(std::distance(proofVoteRecordsReadView.begin(), + proofVoteRecordsReadView.end()), + std::ptrdiff_t(AVALANCHE_MAX_ELEMENT_POLL - 1))); + + extractVoteRecordsToInvs(proofVoteRecordsReadView.begin(), + proofVoteRecordsItEnd, + [](const std::shared_ptr<Proof> &proof) { + return CInv(MSG_AVA_PROOF, proof->getId()); + }); // First remove all blocks that are not worth polling. { @@ -565,23 +581,10 @@ } auto r = blockVoteRecords.getReadView(); - for (const std::pair<const CBlockIndex *const, VoteRecord> &p : - reverse_iterate(r)) { - // Check if we can run poll. - const bool shouldPoll = - forPoll ? p.second.registerPoll() : p.second.shouldPoll(); - if (!shouldPoll) { - continue; - } - - // We don't have a decision, we need more votes. - invs.emplace_back(MSG_BLOCK, p.first->GetBlockHash()); - if (invs.size() >= AVALANCHE_MAX_ELEMENT_POLL) { - // Make sure we do not produce more invs than specified by the - // protocol. - return invs; - } - } + extractVoteRecordsToInvs(r.rbegin(), r.rend(), + [](const CBlockIndex *pindex) { + return CInv(MSG_BLOCK, pindex->GetBlockHash()); + }); return invs; }