Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/peermanager.h
Show First 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | struct Peer { | ||||
Peer(PeerId peerid_, Proof proof_) | Peer(PeerId peerid_, Proof proof_) | ||||
: peerid(peerid_), proof(std::move(proof_)) {} | : peerid(peerid_), proof(std::move(proof_)) {} | ||||
const ProofId &getProofId() const { return proof.getId(); } | const ProofId &getProofId() const { return proof.getId(); } | ||||
uint32_t getScore() const { return proof.getScore(); } | uint32_t getScore() const { return proof.getScore(); } | ||||
}; | }; | ||||
struct proof_index { | struct proof_index_peer { | ||||
using result_type = ProofId; | using result_type = ProofId; | ||||
result_type operator()(const Peer &p) const { return p.proof.getId(); } | result_type operator()(const Peer &p) const { return p.proof.getId(); } | ||||
}; | }; | ||||
struct proof_index_proof { | |||||
using result_type = ProofId; | |||||
result_type operator()(const Proof &p) const { return p.getId(); } | |||||
}; | |||||
class SaltedProofIdHasher : private SaltedUint256Hasher { | class SaltedProofIdHasher : private SaltedUint256Hasher { | ||||
public: | public: | ||||
SaltedProofIdHasher() : SaltedUint256Hasher() {} | SaltedProofIdHasher() : SaltedUint256Hasher() {} | ||||
size_t operator()(const ProofId &proofid) const { return hash(proofid); } | size_t operator()(const ProofId &proofid) const { return hash(proofid); } | ||||
}; | }; | ||||
struct next_request_time {}; | struct next_request_time {}; | ||||
struct expiration_time {}; | |||||
class CompareProofByExpirationTime { | |||||
public: | |||||
bool operator()(const Proof &a, const Proof &b) const { | |||||
return a.getExpirationTime() < b.getExpirationTime(); | |||||
} | |||||
}; | |||||
class PeerManager { | class PeerManager { | ||||
std::vector<Slot> slots; | std::vector<Slot> slots; | ||||
uint64_t slotCount = 0; | uint64_t slotCount = 0; | ||||
uint64_t fragmentation = 0; | uint64_t fragmentation = 0; | ||||
/** | /** | ||||
* Several nodes can make an avalanche peer. In this case, all nodes are | * Several nodes can make an avalanche peer. In this case, all nodes are | ||||
* considered interchangeable parts of the same peer. | * considered interchangeable parts of the same peer. | ||||
*/ | */ | ||||
using PeerSet = boost::multi_index_container< | using PeerSet = boost::multi_index_container< | ||||
Peer, boost::multi_index::indexed_by< | Peer, boost::multi_index::indexed_by< | ||||
// index by peerid | // index by peerid | ||||
boost::multi_index::hashed_unique< | boost::multi_index::hashed_unique< | ||||
boost::multi_index::member<Peer, PeerId, &Peer::peerid>>, | boost::multi_index::member<Peer, PeerId, &Peer::peerid>>, | ||||
// index by proof | // index by proof | ||||
boost::multi_index::hashed_unique< | boost::multi_index::hashed_unique< | ||||
boost::multi_index::tag<proof_index>, proof_index, | boost::multi_index::tag<proof_index_peer>, | ||||
SaltedProofIdHasher>>>; | proof_index_peer, SaltedProofIdHasher>>>; | ||||
PeerId nextPeerId = 0; | PeerId nextPeerId = 0; | ||||
PeerSet peers; | PeerSet peers; | ||||
std::unordered_map<COutPoint, PeerId, SaltedOutpointHasher> utxos; | std::unordered_map<COutPoint, PeerId, SaltedOutpointHasher> utxos; | ||||
using NodeSet = boost::multi_index_container< | using NodeSet = boost::multi_index_container< | ||||
Node, | Node, | ||||
boost::multi_index::indexed_by< | boost::multi_index::indexed_by< | ||||
// index by nodeid | // index by nodeid | ||||
boost::multi_index::hashed_unique< | boost::multi_index::hashed_unique< | ||||
boost::multi_index::member<Node, NodeId, &Node::nodeid>>, | boost::multi_index::member<Node, NodeId, &Node::nodeid>>, | ||||
// sorted by peerid/nextRequestTime | // sorted by peerid/nextRequestTime | ||||
boost::multi_index::ordered_non_unique< | boost::multi_index::ordered_non_unique< | ||||
boost::multi_index::tag<next_request_time>, | boost::multi_index::tag<next_request_time>, | ||||
boost::multi_index::composite_key< | boost::multi_index::composite_key< | ||||
Node, | Node, | ||||
boost::multi_index::member<Node, PeerId, &Node::peerid>, | boost::multi_index::member<Node, PeerId, &Node::peerid>, | ||||
boost::multi_index::member<Node, TimePoint, | boost::multi_index::member<Node, TimePoint, | ||||
&Node::nextRequestTime>>>>>; | &Node::nextRequestTime>>>>>; | ||||
NodeSet nodes; | NodeSet nodes; | ||||
using ProofPool = boost::multi_index_container< | |||||
Proof, boost::multi_index::indexed_by< | |||||
// index by proofid | |||||
boost::multi_index::hashed_unique< | |||||
boost::multi_index::tag<proof_index_proof>, | |||||
proof_index_proof, SaltedProofIdHasher>, | |||||
// sorted by expiration time | |||||
boost::multi_index::ordered_non_unique< | |||||
boost::multi_index::tag<expiration_time>, | |||||
boost::multi_index::identity<Proof>, | |||||
CompareProofByExpirationTime>>>; | |||||
/** Pool of proofs not associated with any known node */ | |||||
ProofPool unassignedProofs; | |||||
static constexpr int SELECT_PEER_MAX_RETRY = 3; | static constexpr int SELECT_PEER_MAX_RETRY = 3; | ||||
static constexpr int SELECT_NODE_MAX_RETRY = 3; | static constexpr int SELECT_NODE_MAX_RETRY = 3; | ||||
public: | public: | ||||
/** | /** | ||||
* Node API. | * Node API. | ||||
*/ | */ | ||||
bool addNode(NodeId nodeid, const Proof &proof, | bool addNode(NodeId nodeid, const Proof &proof, | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | public: | ||||
// Accssors. | // Accssors. | ||||
uint64_t getSlotCount() const { return slotCount; } | uint64_t getSlotCount() const { return slotCount; } | ||||
uint64_t getFragmentation() const { return fragmentation; } | uint64_t getFragmentation() const { return fragmentation; } | ||||
std::vector<Peer> getPeers() const; | std::vector<Peer> getPeers() const; | ||||
std::vector<NodeId> getNodeIdsForPeer(PeerId peerId) const; | std::vector<NodeId> getNodeIdsForPeer(PeerId peerId) const; | ||||
/** Return true if we already have this proof */ | |||||
bool hasProof(const ProofId proofId) const; | |||||
private: | private: | ||||
PeerSet::iterator fetchOrCreatePeer(const Proof &proof); | PeerSet::iterator fetchOrCreatePeer(const Proof &proof); | ||||
bool addNodeToPeer(const PeerSet::iterator &it); | bool addNodeToPeer(const PeerSet::iterator &it); | ||||
bool removeNodeFromPeer(const PeerSet::iterator &it, uint32_t count = 1); | bool removeNodeFromPeer(const PeerSet::iterator &it, uint32_t count = 1); | ||||
}; | }; | ||||
/** | /** | ||||
* This is an internal method that is exposed for testing purposes. | * This is an internal method that is exposed for testing purposes. | ||||
*/ | */ | ||||
PeerId selectPeerImpl(const std::vector<Slot> &slots, const uint64_t slot, | PeerId selectPeerImpl(const std::vector<Slot> &slots, const uint64_t slot, | ||||
const uint64_t max); | const uint64_t max); | ||||
} // namespace avalanche | } // namespace avalanche | ||||
#endif // BITCOIN_AVALANCHE_PEERMANAGER_H | #endif // BITCOIN_AVALANCHE_PEERMANAGER_H |