5 #ifndef BITCOIN_AVALANCHE_PEERMANAGER_H
6 #define BITCOIN_AVALANCHE_PEERMANAGER_H
20 #include <boost/multi_index/composite_key.hpp>
21 #include <boost/multi_index/hashed_index.hpp>
22 #include <boost/multi_index/mem_fun.hpp>
23 #include <boost/multi_index/member.hpp>
24 #include <boost/multi_index/ordered_index.hpp>
25 #include <boost/multi_index_container.hpp>
49 struct TestPeerManager;
59 Slot(uint64_t startIn, uint32_t scoreIn,
PeerId peeridIn)
105 std::chrono::seconds nextPossibleConflictTime_)
153 namespace bmi = boost::multi_index;
165 Peer, bmi::indexed_by<
167 bmi::hashed_unique<bmi::member<Peer, PeerId, &Peer::peerid>>,
169 bmi::hashed_unique<bmi::tag<by_proofid>,
proof_index,
172 bmi::ordered_non_unique<bmi::tag<by_score>,
score_index,
173 std::greater<uint32_t>>>>;
189 bmi::hashed_unique<bmi::member<Node, NodeId, &Node::nodeid>>,
191 bmi::ordered_non_unique<
192 bmi::tag<next_request_time>,
194 Node, bmi::member<Node, PeerId, &Node::peerid>,
195 bmi::member<Node, TimePoint, &Node::nextRequestTime>>>>>;
209 bmi::hashed_non_unique<
210 bmi::tag<by_proofid>,
211 bmi::member<PendingNode, ProofId, &PendingNode::proofid>,
216 bmi::member<PendingNode, NodeId, &PendingNode::nodeid>>>>;
277 template <
typename Callable>
279 auto it =
nodes.find(nodeid);
280 return it !=
nodes.end() && func(*it);
283 template <
typename Callable>
286 auto range = nview.equal_range(peer.
peerid);
287 for (
auto it = range.first; it != range.second; ++it) {
301 const std::chrono::seconds &nextTime);
347 return getProof(proofid) !=
nullptr;
352 template <
typename Callable>
354 auto &pview =
peers.get<by_proofid>();
355 auto it = pview.find(proofid);
356 return it != pview.end() && func(*it);
359 template <
typename Callable>
void forEachPeer(Callable &&func)
const {
360 for (
const auto &p :
peers) {
383 template <
typename Callable>
385 Callable &&getNodeAvailabilityScore) {
386 for (
auto it =
peers.begin(); it !=
peers.end(); it++) {
389 double peerScore{0.0};
391 peerScore += getNodeAvailabilityScore(
node.nodeid);
396 decayFactor * peerScore +
451 template <
typename ProofContainer>
458 friend struct ::avalanche::TestPeerManager;
std::chrono::time_point< std::chrono::steady_clock > TimePoint
RollingBloomFilter is a probabilistic "keep track of most recently inserted" set.
Simple class for background tasks that should be run periodically or once "after a while".
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Template for capturing information about block/transaction validation.
PeerManager(const Amount &stakeUtxoDustThresholdIn, ChainstateManager &chainmanIn)
boost::multi_index_container< Node, bmi::indexed_by< bmi::hashed_unique< bmi::member< Node, NodeId, &Node::nodeid > >, bmi::ordered_non_unique< bmi::tag< next_request_time >, bmi::composite_key< Node, bmi::member< Node, PeerId, &Node::peerid >, bmi::member< Node, TimePoint, &Node::nextRequestTime > >> >> NodeSet
uint32_t connectedPeersScore
boost::multi_index_container< PendingNode, bmi::indexed_by< bmi::hashed_non_unique< bmi::tag< by_proofid >, bmi::member< PendingNode, ProofId, &PendingNode::proofid >, SaltedProofIdHasher >, bmi::hashed_unique< bmi::tag< by_nodeid >, bmi::member< PendingNode, NodeId, &PendingNode::nodeid > >> > PendingNodeSet
bool removeNode(NodeId nodeid)
bool setFinalized(PeerId peerid)
Latch on that this peer has a finalized proof.
uint64_t getFragmentation() const
uint32_t getConnectedPeersScore() const
void cleanupDanglingProofs(const ProofRef &localProof)
bool addNodeToPeer(const PeerSet::iterator &it)
bool shouldRequestMoreNodes()
Returns true if we encountered a lack of node since the last call.
bool exists(const ProofId &proofid) const
bool updateNextRequestTime(NodeId nodeid, TimePoint timeout)
size_t getNodeCount() const
PendingNodeSet pendingNodes
bool verify() const
Perform consistency check on internal data structures.
bool forNode(NodeId nodeid, Callable &&func) const
bool forPeer(const ProofId &proofid, Callable &&func) const
uint32_t getTotalPeersScore() const
bool latchAvaproofsSent(NodeId nodeid)
Flag that a node did send its compact proofs.
bool registerProof(const ProofRef &proof, RegistrationMode mode=RegistrationMode::DEFAULT)
bool addNode(NodeId nodeid, const ProofId &proofid)
Node API.
uint64_t getSlotCount() const
static constexpr int SELECT_PEER_MAX_RETRY
ProofIdSet m_unbroadcast_proofids
Track proof ids to broadcast.
RejectionMode
Rejection mode.
void addUnbroadcastProof(const ProofId &proofid)
Proof broadcast API.
std::unordered_set< ProofRef, SaltedProofHasher > updatedBlockTip()
Update the peer set when a new block is connected.
void removeUnbroadcastProof(const ProofId &proofid)
bool isBoundToPeer(const ProofId &proofid) const
const ProofPool & getConflictingProofPool() const
size_t getPendingNodeCount() const
ProofRadixTree shareableProofs
uint64_t compact()
Trigger maintenance of internal data structures.
std::vector< Slot > slots
uint32_t totalPeersScore
Quorum management.
void forEachPeer(Callable &&func) const
const ProofPool & getValidProofPool() const
void forEachNode(const Peer &peer, Callable &&func) const
const Amount & getStakeUtxoDustThreshold() const
ChainstateManager & chainman
bool removePeer(const PeerId peerid)
Remove an existing peer.
const ProofPool & getImmatureProofPool() const
bool isImmature(const ProofId &proofid) const
bool addOrUpdateNode(const PeerSet::iterator &it, NodeId nodeid)
bool rejectProof(const ProofId &proofid, RejectionMode mode=RejectionMode::DEFAULT)
ProofPool immatureProofPool
Amount stakeUtxoDustThreshold
RegistrationMode
Registration mode.
ProofPool conflictingProofPool
std::atomic< bool > needMoreNodes
Flag indicating that we failed to select a node and need to expand our node set.
PeerId selectPeer() const
Randomly select a peer to poll.
const ProofRadixTree & getShareableProofsSnapshot() const
boost::multi_index_container< Peer, bmi::indexed_by< bmi::hashed_unique< bmi::member< Peer, PeerId, &Peer::peerid > >, bmi::hashed_unique< bmi::tag< by_proofid >, proof_index, SaltedProofIdHasher >, bmi::ordered_non_unique< bmi::tag< by_score >, score_index, std::greater< uint32_t > >> > PeerSet
Several nodes can make an avalanche peer.
void updateAvailabilityScores(const double decayFactor, Callable &&getNodeAvailabilityScore)
auto getUnbroadcastProofs() const
bool isInConflictingPool(const ProofId &proofid) const
static constexpr int SELECT_NODE_MAX_RETRY
ProofRef getProof(const ProofId &proofid) const
bool registerProof(const ProofRef &proof, ProofRegistrationState ®istrationState, RegistrationMode mode=RegistrationMode::DEFAULT)
bool removeNodeFromPeer(const PeerSet::iterator &it, uint32_t count=1)
bool updateNextPossibleConflictTime(PeerId peerid, const std::chrono::seconds &nextTime)
Proof and Peer related API.
void moveToConflictingPool(const ProofContainer &proofs)
CRollingBloomFilter danglingProofIds
Remember the last proofs that have been evicted because they had no node attached.
Map a proof to each utxo.
static constexpr uint32_t AVALANCHE_MAX_IMMATURE_PROOFS
Maximum number of immature proofs the peer manager will accept from the network.
std::unordered_set< ProofId, SaltedProofIdHasher > ProofIdSet
PeerId selectPeerImpl(const std::vector< Slot > &slots, const uint64_t slot, const uint64_t max)
Internal methods that are exposed for testing purposes.
std::chrono::seconds registration_time
std::chrono::seconds nextPossibleConflictTime
static constexpr auto DANGLING_TIMEOUT
Consider dropping the peer if no node is attached after this timeout expired.
const ProofId & getProofId() const
uint32_t getScore() const
Peer(PeerId peerid_, ProofRef proof_, std::chrono::seconds nextPossibleConflictTime_)
PendingNode(ProofId proofid_, NodeId nodeid_)
Slot(uint64_t startIn, uint32_t scoreIn, PeerId peeridIn)
Slot withPeerId(PeerId peeridIn) const
uint32_t getScore() const
bool follows(uint64_t slot) const
Slot withScore(uint64_t scoreIn) const
Slot withStart(uint64_t startIn) const
uint64_t getStart() const
bool precedes(uint64_t slot) const
bool contains(uint64_t slot) const
result_type operator()(const Peer &p) const
result_type operator()(const Peer &p) const
T GetTime()
Return system time (or mocked time, if set)