Bitcoin ABC  0.22.13
P2P Digital Currency
peermanager.h
Go to the documentation of this file.
1 // Copyright (c) 2020 The Bitcoin developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_AVALANCHE_PEERMANAGER_H
6 #define BITCOIN_AVALANCHE_PEERMANAGER_H
7 
8 #include <avalanche/node.h>
9 #include <avalanche/proof.h>
10 #include <coins.h>
11 #include <net.h>
12 #include <pubkey.h>
13 #include <salteduint256hasher.h>
14 
15 #include <boost/multi_index/composite_key.hpp>
16 #include <boost/multi_index/hashed_index.hpp>
17 #include <boost/multi_index/member.hpp>
18 #include <boost/multi_index/ordered_index.hpp>
19 #include <boost/multi_index_container.hpp>
20 
21 #include <chrono>
22 #include <cstdint>
23 #include <vector>
24 
25 namespace avalanche {
26 
27 class Delegation;
28 
29 struct Slot {
30 private:
31  uint64_t start;
32  uint32_t score;
34 
35 public:
36  Slot(uint64_t startIn, uint32_t scoreIn, PeerId peeridIn)
37  : start(startIn), score(scoreIn), peerid(peeridIn) {}
38 
39  Slot withStart(uint64_t startIn) const {
40  return Slot(startIn, score, peerid);
41  }
42  Slot withScore(uint64_t scoreIn) const {
43  return Slot(start, scoreIn, peerid);
44  }
45  Slot withPeerId(PeerId peeridIn) const {
46  return Slot(start, score, peeridIn);
47  }
48 
49  uint64_t getStart() const { return start; }
50  uint64_t getStop() const { return start + score; }
51  uint32_t getScore() const { return score; }
52  PeerId getPeerId() const { return peerid; }
53 
54  bool contains(uint64_t slot) const {
55  return getStart() <= slot && slot < getStop();
56  }
57  bool precedes(uint64_t slot) const { return slot >= getStop(); }
58  bool follows(uint64_t slot) const { return getStart() > slot; }
59 };
60 
61 struct Peer {
63  uint32_t index = -1;
64  uint32_t node_count = 0;
65 
67 
68  Peer(PeerId peerid_, Proof proof_)
69  : peerid(peerid_), proof(std::move(proof_)) {}
70 
71  const ProofId &getProofId() const { return proof.getId(); }
72  uint32_t getScore() const { return proof.getScore(); }
73 };
74 
75 struct proof_index {
77  result_type operator()(const Peer &p) const { return p.proof.getId(); }
78 };
79 
81 public:
83 
84  size_t operator()(const ProofId &proofid) const { return hash(proofid); }
85 };
86 
88 
89 class PeerManager {
90  std::vector<Slot> slots;
91  uint64_t slotCount = 0;
92  uint64_t fragmentation = 0;
93 
98  using PeerSet = boost::multi_index_container<
99  Peer, boost::multi_index::indexed_by<
100  // index by peerid
101  boost::multi_index::hashed_unique<
102  boost::multi_index::member<Peer, PeerId, &Peer::peerid>>,
103  // index by proof
104  boost::multi_index::hashed_unique<
105  boost::multi_index::tag<proof_index>, proof_index,
107 
108  PeerId nextPeerId = 0;
110 
111  std::unordered_map<COutPoint, PeerId, SaltedOutpointHasher> utxos;
112 
113  using NodeSet = boost::multi_index_container<
114  Node,
115  boost::multi_index::indexed_by<
116  // index by nodeid
117  boost::multi_index::hashed_unique<
118  boost::multi_index::member<Node, NodeId, &Node::nodeid>>,
119  // sorted by peerid/nextRequestTime
120  boost::multi_index::ordered_non_unique<
121  boost::multi_index::tag<next_request_time>,
122  boost::multi_index::composite_key<
123  Node,
124  boost::multi_index::member<Node, PeerId, &Node::peerid>,
125  boost::multi_index::member<Node, TimePoint,
127 
129 
130  static constexpr int SELECT_PEER_MAX_RETRY = 3;
131  static constexpr int SELECT_NODE_MAX_RETRY = 3;
132 
133 public:
137  bool addNode(NodeId nodeid, const Proof &proof,
138  const Delegation &delegation);
139  bool removeNode(NodeId nodeid);
140 
141  bool forNode(NodeId nodeid, std::function<bool(const Node &n)> func) const;
142  bool updateNextRequestTime(NodeId nodeid, TimePoint timeout);
143 
147  NodeId selectNode();
148 
152  void updatedBlockTip();
153 
154  /****************************************************
155  * Functions which are public for testing purposes. *
156  ****************************************************/
161  PeerId getPeerId(const Proof &proof);
162 
166  bool removePeer(const PeerId peerid);
167 
171  PeerId selectPeer() const;
172 
177  uint64_t compact();
178 
182  bool verify() const;
183 
184  // Accssors.
185  uint64_t getSlotCount() const { return slotCount; }
186  uint64_t getFragmentation() const { return fragmentation; }
187 
188 private:
189  PeerSet::iterator fetchOrCreatePeer(const Proof &proof);
190  bool addNodeToPeer(const PeerSet::iterator &it);
191  bool removeNodeFromPeer(const PeerSet::iterator &it, uint32_t count = 1);
192 };
193 
197 PeerId selectPeerImpl(const std::vector<Slot> &slots, const uint64_t slot,
198  const uint64_t max);
199 
200 } // namespace avalanche
201 
202 #endif // BITCOIN_AVALANCHE_PEERMANAGER_H
uint32_t getScore() const
Definition: peermanager.h:51
uint64_t getFragmentation() const
Definition: peermanager.h:186
boost::multi_index_container< Peer, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< boost::multi_index::member< Peer, PeerId, &Peer::peerid > >, boost::multi_index::hashed_unique< boost::multi_index::tag< proof_index >, proof_index, SaltedProofIdHasher > >> PeerSet
Several nodes can make an avalanche peer.
Definition: peermanager.h:106
uint32_t getScore() const
Definition: proof.cpp:41
result_type operator()(const Peer &p) const
Definition: peermanager.h:77
PeerId getPeerId() const
Definition: peermanager.h:52
Slot withScore(uint64_t scoreIn) const
Definition: peermanager.h:42
PeerId selectPeerImpl(const std::vector< Slot > &slots, const uint64_t slot, const uint64_t max)
This is an internal method that is exposed for testing purposes.
Peer(PeerId peerid_, Proof proof_)
Definition: peermanager.h:68
uint64_t getStart() const
Definition: peermanager.h:49
bool precedes(uint64_t slot) const
Definition: peermanager.h:57
bool follows(uint64_t slot) const
Definition: peermanager.h:58
boost::multi_index_container< Node, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< boost::multi_index::member< Node, NodeId, &Node::nodeid > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< next_request_time >, boost::multi_index::composite_key< Node, boost::multi_index::member< Node, PeerId, &Node::peerid >, boost::multi_index::member< Node, TimePoint, &Node::nextRequestTime > >> >> NodeSet
Definition: peermanager.h:126
uint32_t getScore() const
Definition: peermanager.h:72
Slot withStart(uint64_t startIn) const
Definition: peermanager.h:39
Slot(uint64_t startIn, uint32_t scoreIn, PeerId peeridIn)
Definition: peermanager.h:36
int64_t NodeId
Definition: net.h:99
Slot withPeerId(PeerId peeridIn) const
Definition: peermanager.h:45
bool contains(uint64_t slot) const
Definition: peermanager.h:54
const ProofId & getId() const
Definition: proof.h:116
uint32_t score
Definition: peermanager.h:32
TimePoint nextRequestTime
Definition: node.h:24
std::vector< Slot > slots
Definition: peermanager.h:90
uint64_t start
Definition: peermanager.h:31
static int count
Definition: tests.c:35
std::chrono::time_point< std::chrono::steady_clock > TimePoint
Definition: node.h:17
uint64_t getStop() const
Definition: peermanager.h:50
std::unordered_map< COutPoint, PeerId, SaltedOutpointHasher > utxos
Definition: peermanager.h:111
uint64_t getSlotCount() const
Definition: peermanager.h:185
size_t operator()(const ProofId &proofid) const
Definition: peermanager.h:84
const ProofId & getProofId() const
Definition: peermanager.h:71
uint32_t PeerId
Definition: node.h:14