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 <net.h> | |||||
#include <pubkey.h> | |||||
#include <boost/multi_index/hashed_index.hpp> | |||||
#include <boost/multi_index/member.hpp> | |||||
#include <boost/multi_index/ordered_index.hpp> | |||||
#include <boost/multi_index_container.hpp> | |||||
#include <chrono> | |||||
#include <cstdint> | #include <cstdint> | ||||
#include <unordered_map> | #include <unordered_map> | ||||
#include <vector> | #include <vector> | ||||
using PeerId = uint32_t; | using PeerId = uint32_t; | ||||
static constexpr PeerId NO_PEER = ~uint32_t(0); | static constexpr PeerId NO_PEER = ~uint32_t(0); | ||||
struct Slot { | struct Slot { | ||||
Show All 23 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 next_request_time {}; | |||||
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 | |||||
* considered interchangeable parts of the same peer. | |||||
*/ | |||||
struct Peer { | |||||
using TimePoint = std::chrono::time_point<std::chrono::steady_clock>; | |||||
struct Node { | |||||
NodeId nodeid; | |||||
TimePoint nextRequestTime; | |||||
CPubKey pubkey; | |||||
}; | |||||
using NodeSet = boost::multi_index_container< | |||||
Node, | |||||
boost::multi_index::indexed_by< | |||||
// index by nodeid | |||||
boost::multi_index::hashed_unique< | |||||
boost::multi_index::member<Node, NodeId, &Node::nodeid>>, | |||||
// sorted by nextRequestTime | |||||
boost::multi_index::ordered_non_unique< | |||||
boost::multi_index::tag<next_request_time>, | |||||
boost::multi_index::member<Node, TimePoint, | |||||
&Node::nextRequestTime>>>>; | |||||
NodeSet nodes; | |||||
uint32_t score; | |||||
uint32_t index; | |||||
Peer(uint32_t score_, uint32_t index_) : score(score_), index(index_) {} | |||||
}; | |||||
PeerId nextPeerId = 0; | PeerId nextPeerId = 0; | ||||
std::unordered_map<PeerId, uint32_t> peerIndices; | std::unordered_map<PeerId, Peer> peers; | ||||
static constexpr int SELECT_PEER_MAX_RETRY = 3; | static constexpr int SELECT_PEER_MAX_RETRY = 3; | ||||
public: | public: | ||||
PeerId addPeer(uint32_t score) { return addPeer(nextPeerId++, score); } | PeerId addPeer(uint32_t score) { return addPeer(nextPeerId++, score); } | ||||
bool removePeer(PeerId p); | bool removePeer(PeerId p); | ||||
bool rescorePeer(PeerId p, uint32_t score); | bool rescorePeer(PeerId p, uint32_t score); | ||||
Show All 29 Lines |