Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche.cpp
// Copyright (c) 2018 The Bitcoin developers | // Copyright (c) 2018 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "avalanche.h" | #include "avalanche.h" | ||||
#include "chain.h" | #include "chain.h" | ||||
#include "netmessagemaker.h" | #include "netmessagemaker.h" | ||||
#include "scheduler.h" | #include "scheduler.h" | ||||
#include "validation.h" | #include "validation.h" | ||||
#include <boost/range/adaptor/reversed.hpp> | #include <boost/range/adaptor/reversed.hpp> | ||||
static bool IsWorthPolling(const CBlockIndex *pindex) { | |||||
AssertLockHeld(cs_main); | |||||
if (pindex->nStatus.isInvalid()) { | |||||
// No point polling invalid blocks. | |||||
return false; | |||||
} | |||||
if (IsBlockFinalized(pindex)) { | |||||
// There is no point polling finalized block. | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
bool AvalancheProcessor::addBlockToReconcile(const CBlockIndex *pindex) { | bool AvalancheProcessor::addBlockToReconcile(const CBlockIndex *pindex) { | ||||
bool isAccepted; | |||||
{ | |||||
LOCK(cs_main); | |||||
if (!IsWorthPolling(pindex)) { | |||||
// There is no point polling this block. | |||||
return false; | |||||
} | |||||
isAccepted = chainActive.Contains(pindex); | |||||
} | |||||
return vote_records.getWriteView() | return vote_records.getWriteView() | ||||
->insert(std::make_pair(pindex, VoteRecord())) | ->insert(std::make_pair(pindex, VoteRecord(isAccepted))) | ||||
.second; | .second; | ||||
} | } | ||||
static const VoteRecord * | static const VoteRecord * | ||||
GetRecord(const RWCollection<BlockVoteMap> &vote_records, | GetRecord(const RWCollection<BlockVoteMap> &vote_records, | ||||
const CBlockIndex *pindex) { | const CBlockIndex *pindex) { | ||||
auto r = vote_records.getReadView(); | auto r = vote_records.getReadView(); | ||||
auto it = r->find(pindex); | auto it = r->find(pindex); | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | std::map<CBlockIndex *, AvalancheVote> responseIndex; | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
for (auto &v : votes) { | for (auto &v : votes) { | ||||
BlockMap::iterator mi = mapBlockIndex.find(v.GetHash()); | BlockMap::iterator mi = mapBlockIndex.find(v.GetHash()); | ||||
if (mi == mapBlockIndex.end()) { | if (mi == mapBlockIndex.end()) { | ||||
// This should not happen, but just in case... | // This should not happen, but just in case... | ||||
continue; | continue; | ||||
} | } | ||||
responseIndex.insert(std::make_pair(mi->second, v)); | CBlockIndex *pindex = mi->second; | ||||
if (!IsWorthPolling(pindex)) { | |||||
// There is no point polling this block. | |||||
continue; | |||||
} | |||||
responseIndex.insert(std::make_pair(pindex, v)); | |||||
} | } | ||||
} | } | ||||
{ | { | ||||
// Register votes. | // Register votes. | ||||
auto w = vote_records.getWriteView(); | auto w = vote_records.getWriteView(); | ||||
for (auto &p : responseIndex) { | for (auto &p : responseIndex) { | ||||
CBlockIndex *pindex = p.first; | CBlockIndex *pindex = p.first; | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
std::vector<CInv> AvalancheProcessor::getInvsForNextPoll() const { | std::vector<CInv> AvalancheProcessor::getInvsForNextPoll() const { | ||||
std::vector<CInv> invs; | std::vector<CInv> invs; | ||||
auto r = vote_records.getReadView(); | auto r = vote_records.getReadView(); | ||||
for (const std::pair<const CBlockIndex *, VoteRecord> &p : | for (const std::pair<const CBlockIndex *, VoteRecord> &p : | ||||
boost::adaptors::reverse(r)) { | boost::adaptors::reverse(r)) { | ||||
const VoteRecord &v = p.second; | const CBlockIndex *pindex = p.first; | ||||
if (v.hasFinalized()) { | if (!IsWorthPolling(pindex)) { | ||||
// If this has finalized, we can just skip. | // Obviously do not poll if the block is not worth polling. | ||||
continue; | continue; | ||||
} | } | ||||
// We don't have a decision, we need more votes. | // We don't have a decision, we need more votes. | ||||
invs.emplace_back(MSG_BLOCK, p.first->GetBlockHash()); | invs.emplace_back(MSG_BLOCK, p.first->GetBlockHash()); | ||||
if (invs.size() >= AVALANCHE_MAX_ELEMENT_POLL) { | if (invs.size() >= AVALANCHE_MAX_ELEMENT_POLL) { | ||||
// Make sure we do not produce more invs than specified by the | // Make sure we do not produce more invs than specified by the | ||||
// protocol. | // protocol. | ||||
▲ Show 20 Lines • Show All 70 Lines • Show Last 20 Lines |