Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/peermanager.cpp
Show First 20 Lines • Show All 181 Lines • ▼ Show 20 Lines | |||||
PeerId PeerManager::getPeerId(const Proof &proof) { | PeerId PeerManager::getPeerId(const Proof &proof) { | ||||
auto it = fetchOrCreatePeer(proof); | auto it = fetchOrCreatePeer(proof); | ||||
return it == peers.end() ? NO_PEER : it->peerid; | return it == peers.end() ? NO_PEER : it->peerid; | ||||
} | } | ||||
PeerManager::PeerSet::iterator | PeerManager::PeerSet::iterator | ||||
PeerManager::fetchOrCreatePeer(const Proof &proof) { | PeerManager::fetchOrCreatePeer(const Proof &proof) { | ||||
ProofValidationState state; | |||||
return fetchOrCreatePeer(proof, state); | |||||
} | |||||
PeerManager::PeerSet::iterator | |||||
PeerManager::fetchOrCreatePeer(const Proof &proof, | |||||
ProofValidationState &state) { | |||||
{ | { | ||||
// Check if we already know of that peer. | // Check if we already know of that peer. | ||||
auto &pview = peers.get<proof_index>(); | auto &pview = peers.get<proof_index>(); | ||||
auto it = pview.find(proof.getId()); | auto it = pview.find(proof.getId()); | ||||
if (it != pview.end()) { | if (it != pview.end()) { | ||||
return peers.project<0>(it); | return peers.project<0>(it); | ||||
} | } | ||||
} | } | ||||
{ | { | ||||
// Reject invalid proof. | // Reject invalid proof. | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | const CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | ||||
ProofValidationState state; | |||||
if (!proof.verify(state, coins)) { | if (!proof.verify(state, coins)) { | ||||
return peers.end(); | return peers.end(); | ||||
} | } | ||||
} | } | ||||
// New peer means new peerid! | // New peer means new peerid! | ||||
const PeerId peerid = nextPeerId++; | const PeerId peerid = nextPeerId++; | ||||
▲ Show 20 Lines • Show All 238 Lines • ▼ Show 20 Lines | std::vector<NodeId> PeerManager::getNodeIdsForPeer(PeerId peerId) const { | ||||
auto &nview = nodes.get<next_request_time>(); | auto &nview = nodes.get<next_request_time>(); | ||||
auto nodeRange = nview.equal_range(peerId); | auto nodeRange = nview.equal_range(peerId); | ||||
for (auto it = nodeRange.first; it != nodeRange.second; ++it) { | for (auto it = nodeRange.first; it != nodeRange.second; ++it) { | ||||
nodeids.emplace_back(it->nodeid); | nodeids.emplace_back(it->nodeid); | ||||
} | } | ||||
return nodeids; | return nodeids; | ||||
} | } | ||||
const Proof *PeerManager::getProof(const ProofId proofId) const { | |||||
auto &peerView = peers.get<proof_index>(); | |||||
auto peerIt = peerView.find(proofId); | |||||
if (peerIt != peerView.end()) { | |||||
return &peerIt->proof; | |||||
} | |||||
auto proofIt = orphanProofs.find(proofId); | |||||
if (proofIt != orphanProofs.end()) { | |||||
return &proofIt->second; | |||||
} | |||||
return nullptr; | |||||
} | |||||
bool PeerManager::addProof(Proof &&proof) { | |||||
if (getProof(proof.getId())) { | |||||
return false; | |||||
} | |||||
ProofValidationState state; | |||||
// Store good proof in a new peer | |||||
if (fetchOrCreatePeer(proof, state) != peers.end()) { | |||||
return true; | |||||
} | |||||
if (state.GetResult() == ProofValidationResult::MISSING_UTXO) { | |||||
// Maybe it can become valid later | |||||
return orphanProofs | |||||
.insert(std::make_pair(proof.getId(), std::move(proof))) | |||||
.second; | |||||
} | |||||
return false; | |||||
} | |||||
} // namespace avalanche | } // namespace avalanche |