Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/peermanager.cpp
// Copyright (c) 2020 The Bitcoin developers | // Copyright (c) 2020 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/peermanager.h> | #include <avalanche/peermanager.h> | ||||
#include <avalanche/delegation.h> | #include <avalanche/delegation.h> | ||||
#include <avalanche/validation.h> | #include <avalanche/validation.h> | ||||
#include <random.h> | #include <random.h> | ||||
#include <validation.h> // For ChainstateActive() | #include <validation.h> // For ChainstateActive() | ||||
#include <cassert> | #include <cassert> | ||||
namespace avalanche { | namespace avalanche { | ||||
bool PeerManager::addNode(NodeId nodeid, const Proof &proof, | bool PeerManager::addNode(NodeId nodeid, Proof proof, | ||||
const Delegation &delegation) { | const Delegation &delegation) { | ||||
auto it = fetchOrCreatePeer(proof); | auto it = fetchOrCreatePeer(std::move(proof)); | ||||
if (it == peers.end()) { | if (it == peers.end()) { | ||||
return false; | return false; | ||||
} | } | ||||
const PeerId peerid = it->peerid; | const PeerId peerid = it->peerid; | ||||
DelegationState state; | DelegationState state; | ||||
CPubKey pubkey; | CPubKey pubkey; | ||||
if (!delegation.verify(state, proof, pubkey)) { | if (!delegation.verify(state, it->proof, pubkey)) { | ||||
return false; | return false; | ||||
} | } | ||||
auto nit = nodes.find(nodeid); | auto nit = nodes.find(nodeid); | ||||
if (nit == nodes.end()) { | if (nit == nodes.end()) { | ||||
if (!nodes.emplace(nodeid, peerid, std::move(pubkey)).second) { | if (!nodes.emplace(nodeid, peerid, std::move(pubkey)).second) { | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | std::vector<PeerId> invalidPeers; | ||||
} | } | ||||
} | } | ||||
for (const auto &pid : invalidPeers) { | for (const auto &pid : invalidPeers) { | ||||
removePeer(pid); | removePeer(pid); | ||||
} | } | ||||
} | } | ||||
PeerId PeerManager::getPeerId(const Proof &proof) { | PeerId PeerManager::getPeerId(Proof proof) { | ||||
auto it = fetchOrCreatePeer(proof); | auto it = fetchOrCreatePeer(std::move(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(Proof proof) { | ||||
PeerManager::fetchOrCreatePeer(const Proof &proof) { | |||||
{ | { | ||||
// 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); | ||||
deadalnix: Does it take ownership of the proof when going through this code path? | |||||
} | } | ||||
} | } | ||||
{ | { | ||||
// Reject invalid proof. | // Reject invalid proof. | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
const CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | const CCoinsViewCache &coins = ::ChainstateActive().CoinsTip(); | ||||
ProofValidationState state; | ProofValidationState state; | ||||
if (!proof.verify(state, coins)) { | if (!proof.verify(state, coins)) { | ||||
return peers.end(); | return peers.end(); | ||||
deadalnixUnsubmitted Not Done Inline ActionsOr this copdepath? deadalnix: Or this copdepath? | |||||
PiRKAuthorUnsubmitted Done Inline ActionsThis code path will take ownership, in some cases, once we start storing the orphan proofs. PiRK: This code path will take ownership, in some cases, once we start storing the orphan proofs. | |||||
} | } | ||||
} | } | ||||
// New peer means new peerid! | // New peer means new peerid! | ||||
const PeerId peerid = nextPeerId++; | const PeerId peerid = nextPeerId++; | ||||
// Attach UTXOs to this proof. | // Attach UTXOs to this proof. | ||||
std::unordered_set<PeerId> conflicting_peerids; | std::unordered_set<PeerId> conflicting_peerids; | ||||
Show All 16 Lines | if (conflicting_peerids.size() > 0) { | ||||
utxos.erase(it); | utxos.erase(it); | ||||
} | } | ||||
} | } | ||||
return peers.end(); | return peers.end(); | ||||
} | } | ||||
// We have no peer for this proof, time to create it. | // We have no peer for this proof, time to create it. | ||||
auto inserted = peers.emplace(peerid, proof); | auto inserted = peers.emplace(peerid, std::move(proof)); | ||||
assert(inserted.second); | assert(inserted.second); | ||||
return inserted.first; | return inserted.first; | ||||
} | } | ||||
bool PeerManager::removePeer(const PeerId peerid) { | bool PeerManager::removePeer(const PeerId peerid) { | ||||
auto it = peers.find(peerid); | auto it = peers.find(peerid); | ||||
if (it == peers.end()) { | if (it == peers.end()) { | ||||
▲ Show 20 Lines • Show All 212 Lines • Show Last 20 Lines |
Does it take ownership of the proof when going through this code path?