Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/peermanager.h
// 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. | ||||
#ifndef BITCOIN_AVALANCHE_PEERMANAGER_H | #ifndef BITCOIN_AVALANCHE_PEERMANAGER_H | ||||
#define BITCOIN_AVALANCHE_PEERMANAGER_H | #define BITCOIN_AVALANCHE_PEERMANAGER_H | ||||
#include <avalanche/node.h> | #include <avalanche/node.h> | ||||
#include <avalanche/proof.h> | |||||
#include <net.h> | #include <net.h> | ||||
#include <pubkey.h> | #include <pubkey.h> | ||||
#include <salteduint256hasher.h> | |||||
#include <boost/multi_index/composite_key.hpp> | #include <boost/multi_index/composite_key.hpp> | ||||
#include <boost/multi_index/hashed_index.hpp> | #include <boost/multi_index/hashed_index.hpp> | ||||
#include <boost/multi_index/member.hpp> | #include <boost/multi_index/member.hpp> | ||||
#include <boost/multi_index/ordered_index.hpp> | #include <boost/multi_index/ordered_index.hpp> | ||||
#include <boost/multi_index_container.hpp> | #include <boost/multi_index_container.hpp> | ||||
#include <chrono> | #include <chrono> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <unordered_map> | |||||
#include <vector> | #include <vector> | ||||
namespace avalanche { | namespace avalanche { | ||||
struct Slot { | struct Slot { | ||||
private: | private: | ||||
uint64_t start; | uint64_t start; | ||||
uint32_t score; | uint32_t score; | ||||
Show All 20 Lines | public: | ||||
bool contains(uint64_t slot) const { | bool contains(uint64_t slot) const { | ||||
return getStart() <= slot && slot < getStop(); | return getStart() <= slot && slot < getStop(); | ||||
} | } | ||||
bool precedes(uint64_t slot) const { return slot >= getStop(); } | bool precedes(uint64_t slot) const { return slot >= getStop(); } | ||||
bool follows(uint64_t slot) const { return getStart() > slot; } | bool follows(uint64_t slot) const { return getStart() > slot; } | ||||
}; | }; | ||||
struct proof_index {}; | |||||
struct next_request_time {}; | struct next_request_time {}; | ||||
class SaltedProofIdHasher : private SaltedUint256Hasher { | |||||
public: | |||||
SaltedProofIdHasher() : SaltedUint256Hasher() {} | |||||
size_t operator()(const ProofId &proofid) const { return hash(proofid); } | |||||
}; | |||||
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. | ||||
*/ | */ | ||||
struct Peer { | struct Peer { | ||||
PeerId peerid; | |||||
uint32_t score; | uint32_t score; | ||||
uint32_t index; | uint32_t index; | ||||
Peer(uint32_t score_, uint32_t index_) : score(score_), index(index_) {} | ProofId proofid; | ||||
Peer(PeerId peerid_, uint32_t score_, uint32_t index_, ProofId proofid_) | |||||
: peerid(peerid_), score(score_), index(index_), | |||||
proofid(std::move(proofid_)) {} | |||||
}; | }; | ||||
using PeerSet = boost::multi_index_container< | |||||
Peer, boost::multi_index::indexed_by< | |||||
// index by peerid | |||||
boost::multi_index::hashed_unique< | |||||
boost::multi_index::member<Peer, PeerId, &Peer::peerid>>, | |||||
// index by proof | |||||
boost::multi_index::hashed_unique< | |||||
boost::multi_index::tag<proof_index>, | |||||
boost::multi_index::member<Peer, ProofId, &Peer::proofid>, | |||||
SaltedProofIdHasher>>>; | |||||
PeerId nextPeerId = 0; | PeerId nextPeerId = 0; | ||||
std::unordered_map<PeerId, Peer> peers; | PeerSet peers; | ||||
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 | ||||
Show All 10 Lines | class PeerManager { | ||||
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: | ||||
/** | /** | ||||
* Peer API. | * Peer API. | ||||
*/ | */ | ||||
PeerId addPeer(uint32_t score) { return addPeer(nextPeerId++, score); } | PeerId addPeer(uint32_t score) { return addPeer(nextPeerId++, score); } | ||||
bool removePeer(PeerId p); | bool removePeer(const PeerId peerid); | ||||
bool rescorePeer(PeerId p, uint32_t score); | bool rescorePeer(const PeerId peerid, uint32_t score); | ||||
/** | /** | ||||
* Node API. | * Node API. | ||||
*/ | */ | ||||
bool addNodeToPeer(PeerId peerid, NodeId nodeid, CPubKey pubkey); | bool addNodeToPeer(PeerId peerid, NodeId nodeid, CPubKey pubkey); | ||||
bool removeNode(NodeId nodeid); | bool removeNode(NodeId nodeid); | ||||
bool forNode(NodeId nodeid, std::function<bool(const Node &n)> func) const; | bool forNode(NodeId nodeid, std::function<bool(const Node &n)> func) const; | ||||
Show All 39 Lines |