rippled
Counts.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_PEERFINDER_COUNTS_H_INCLUDED
21 #define RIPPLE_PEERFINDER_COUNTS_H_INCLUDED
22 
23 #include <ripple/basics/random.h>
24 #include <ripple/peerfinder/PeerfinderManager.h>
25 #include <ripple/peerfinder/Slot.h>
26 #include <ripple/peerfinder/impl/Tuning.h>
27 
28 #include <cmath>
29 
30 namespace ripple {
31 namespace PeerFinder {
32 
34 class Counts
35 {
36 public:
38  : m_attempts(0)
39  , m_active(0)
40  , m_in_max(0)
41  , m_in_active(0)
42  , m_out_max(0)
43  , m_out_active(0)
44  , m_fixed(0)
45  , m_fixed_active(0)
46  , m_reserved(0)
47 
48  , m_acceptCount(0)
49  , m_closingCount(0)
50  {
52  std::generate_canonical<double, 10>(default_prng());
53  }
54 
55  //--------------------------------------------------------------------------
56 
58  void
59  add(Slot const& s)
60  {
61  adjust(s, 1);
62  }
63 
65  void
66  remove(Slot const& s)
67  {
68  adjust(s, -1);
69  }
70 
72  bool
73  can_activate(Slot const& s) const
74  {
75  // Must be handshaked and in the right state
76  assert(s.state() == Slot::connected || s.state() == Slot::accept);
77 
78  if (s.fixed() || s.reserved())
79  return true;
80 
81  if (s.inbound())
82  return m_in_active < m_in_max;
83 
84  return m_out_active < m_out_max;
85  }
86 
90  {
92  return 0;
94  }
95 
98  attempts() const
99  {
100  return m_attempts;
101  }
102 
104  int
105  out_max() const
106  {
107  return m_out_max;
108  }
109 
113  int
114  out_active() const
115  {
116  return m_out_active;
117  }
118 
121  fixed() const
122  {
123  return m_fixed;
124  }
125 
128  fixed_active() const
129  {
130  return m_fixed_active;
131  }
132 
133  //--------------------------------------------------------------------------
134 
136  void
137  onConfig(Config const& config)
138  {
139  // Calculate the number of outbound peers we want. If we dont want or
140  // can't accept incoming, this will simply be equal to maxPeers.
141  // Otherwise we calculate a fractional amount based on percentages and
142  // pseudo-randomly round up or down.
143  //
144  if (config.wantIncoming)
145  {
146  // Round outPeers upwards using a Bernoulli distribution
147  m_out_max = std::floor(config.outPeers);
148  if (m_roundingThreshold < (config.outPeers - m_out_max))
149  ++m_out_max;
150  }
151  else
152  {
153  m_out_max = config.maxPeers;
154  }
155 
156  // Calculate the largest number of inbound connections we could take.
157  if (config.maxPeers >= m_out_max)
158  m_in_max = config.maxPeers - m_out_max;
159  else
160  m_in_max = 0;
161  }
162 
164  int
165  acceptCount() const
166  {
167  return m_acceptCount;
168  }
169 
171  int
172  connectCount() const
173  {
174  return m_attempts;
175  }
176 
178  int
179  closingCount() const
180  {
181  return m_closingCount;
182  }
183 
185  int
186  inboundSlots() const
187  {
188  return m_in_max;
189  }
190 
192  int
194  {
195  return m_in_active;
196  }
197 
199  int
200  totalActive() const
201  {
202  return m_in_active + m_out_active;
203  }
204 
208  int
210  {
211  if (m_in_active < m_in_max)
212  return m_in_max - m_in_active;
213  return 0;
214  }
215 
219  int
221  {
222  if (m_out_active < m_out_max)
223  return m_out_max - m_out_active;
224  return 0;
225  }
226 
227  //--------------------------------------------------------------------------
228 
231  bool
233  {
234  // We will consider ourselves connected if we have reached
235  // the number of outgoing connections desired, or if connect
236  // automatically is false.
237  //
238  // Fixed peers do not count towards the active outgoing total.
239 
240  if (m_out_max > 0)
241  return false;
242 
243  return true;
244  }
245 
247  void
249  {
250  map["accept"] = acceptCount();
251  map["connect"] = connectCount();
252  map["close"] = closingCount();
253  map["in"] << m_in_active << "/" << m_in_max;
254  map["out"] << m_out_active << "/" << m_out_max;
255  map["fixed"] = m_fixed_active;
256  map["reserved"] = m_reserved;
257  map["total"] = m_active;
258  }
259 
262  state_string() const
263  {
265  ss << m_out_active << "/" << m_out_max << " out, " << m_in_active << "/"
266  << m_in_max << " in, " << connectCount() << " connecting, "
267  << closingCount() << " closing";
268  return ss.str();
269  }
270 
271  //--------------------------------------------------------------------------
272 private:
273  // Adjusts counts based on the specified slot, in the direction indicated.
274  void
275  adjust(Slot const& s, int const n)
276  {
277  if (s.fixed())
278  m_fixed += n;
279 
280  if (s.reserved())
281  m_reserved += n;
282 
283  switch (s.state())
284  {
285  case Slot::accept:
286  assert(s.inbound());
287  m_acceptCount += n;
288  break;
289 
290  case Slot::connect:
291  case Slot::connected:
292  assert(!s.inbound());
293  m_attempts += n;
294  break;
295 
296  case Slot::active:
297  if (s.fixed())
298  m_fixed_active += n;
299  if (!s.fixed() && !s.reserved())
300  {
301  if (s.inbound())
302  m_in_active += n;
303  else
304  m_out_active += n;
305  }
306  m_active += n;
307  break;
308 
309  case Slot::closing:
310  m_closingCount += n;
311  break;
312 
313  default:
314  assert(false);
315  break;
316  };
317  }
318 
319 private:
322 
325 
328 
331 
334 
337 
340 
343 
346 
347  // Number of inbound connections that are
348  // not active or gracefully closing.
350 
351  // Number of connections that are gracefully closing.
353 
360 };
361 
362 } // namespace PeerFinder
363 } // namespace ripple
364 
365 #endif
ripple::PeerFinder::Counts::inboundActive
int inboundActive() const
Returns the number of inbound peers assigned an open slot.
Definition: Counts.h:193
ripple::PeerFinder::Counts::state_string
std::string state_string() const
Records the state for diagnostics.
Definition: Counts.h:262
ripple::PeerFinder::Slot::state
virtual State state() const =0
Returns the state of the connection.
ripple::PeerFinder::Counts::m_acceptCount
int m_acceptCount
Definition: Counts.h:349
std::floor
T floor(T... args)
std::string
STL class.
ripple::PeerFinder::Slot::accept
@ accept
Definition: Slot.h:37
ripple::PeerFinder::Counts::m_roundingThreshold
double m_roundingThreshold
Fractional threshold below which we round down.
Definition: Counts.h:359
beast::PropertyStream::Map
Definition: PropertyStream.h:236
ripple::PeerFinder::Counts::fixed
std::size_t fixed() const
Returns the number of fixed connections.
Definition: Counts.h:121
ripple::PeerFinder::Slot::fixed
virtual bool fixed() const =0
Returns true if this is a fixed connection.
ripple::PeerFinder::Counts::m_attempts
int m_attempts
Outbound connection attempts.
Definition: Counts.h:321
ripple::PeerFinder::Slot::active
@ active
Definition: Slot.h:37
ripple::PeerFinder::Slot::reserved
virtual bool reserved() const =0
Returns true if this is a reserved connection.
ripple::PeerFinder::Counts::isConnectedToNetwork
bool isConnectedToNetwork() const
Returns true if the slot logic considers us "connected" to the network.
Definition: Counts.h:232
std::stringstream
STL class.
ripple::PeerFinder::Counts::connectCount
int connectCount() const
Returns the number of connection attempts currently active.
Definition: Counts.h:172
cmath
ripple::PeerFinder::Counts::can_activate
bool can_activate(Slot const &s) const
Returns true if the slot can become active.
Definition: Counts.h:73
ripple::PeerFinder::Counts::m_active
std::size_t m_active
Active connections, including fixed and reserved.
Definition: Counts.h:324
ripple::PeerFinder::Counts::m_in_max
std::size_t m_in_max
Total number of inbound slots.
Definition: Counts.h:327
ripple::PeerFinder::Counts::inboundSlots
int inboundSlots() const
Returns the total number of inbound slots.
Definition: Counts.h:186
ripple::PeerFinder::Counts::acceptCount
int acceptCount() const
Returns the number of accepted connections that haven't handshaked.
Definition: Counts.h:165
ripple::PeerFinder::Counts::out_max
int out_max() const
Returns the total number of outbound slots.
Definition: Counts.h:105
ripple::PeerFinder::Counts
Manages the count of available connections for the various slots.
Definition: Counts.h:34
ripple::PeerFinder::Config::wantIncoming
bool wantIncoming
true if we want to accept incoming connections.
Definition: PeerfinderManager.h:64
ripple::PeerFinder::Tuning::maxConnectAttempts
@ maxConnectAttempts
Definition: peerfinder/impl/Tuning.h:44
ripple::PeerFinder::Counts::closingCount
int closingCount() const
Returns the number of connections that are gracefully closing.
Definition: Counts.h:179
ripple::PeerFinder::Counts::outboundSlotsFree
int outboundSlotsFree() const
Returns the number of unused outbound slots.
Definition: Counts.h:220
ripple::PeerFinder::Counts::out_active
int out_active() const
Returns the number of outbound peers assigned an open slot.
Definition: Counts.h:114
ripple::PeerFinder::Slot::connected
@ connected
Definition: Slot.h:37
ripple::default_prng
beast::xor_shift_engine & default_prng()
Return the default random engine.
Definition: ripple/basics/random.h:65
ripple::PeerFinder::Config::outPeers
double outPeers
The number of automatic outbound connections to maintain.
Definition: PeerfinderManager.h:58
ripple::PeerFinder::Config::maxPeers
int maxPeers
The largest number of public peer slots to allow.
Definition: PeerfinderManager.h:46
ripple::PeerFinder::Counts::onConfig
void onConfig(Config const &config)
Called when the config is set or changed.
Definition: Counts.h:137
ripple::PeerFinder::Counts::m_in_active
std::size_t m_in_active
Number of inbound slots assigned to active peers.
Definition: Counts.h:330
ripple::PeerFinder::Slot::closing
@ closing
Definition: Slot.h:37
ripple::PeerFinder::Counts::m_closingCount
int m_closingCount
Definition: Counts.h:352
ripple::PeerFinder::Counts::inboundSlotsFree
int inboundSlotsFree() const
Returns the number of unused inbound slots.
Definition: Counts.h:209
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::PeerFinder::Counts::m_out_max
std::size_t m_out_max
Maximum desired outbound slots.
Definition: Counts.h:333
ripple::PeerFinder::Counts::fixed_active
std::size_t fixed_active() const
Returns the number of active fixed connections.
Definition: Counts.h:128
ripple::PeerFinder::Counts::Counts
Counts()
Definition: Counts.h:37
ripple::PeerFinder::Counts::m_out_active
std::size_t m_out_active
Active outbound slots.
Definition: Counts.h:336
ripple::PeerFinder::Counts::attempts
std::size_t attempts() const
Returns the number of outbound connection attempts.
Definition: Counts.h:98
ripple::PeerFinder::Counts::adjust
void adjust(Slot const &s, int const n)
Definition: Counts.h:275
ripple::PeerFinder::Counts::add
void add(Slot const &s)
Adds the slot state and properties to the slot counts.
Definition: Counts.h:59
ripple::PeerFinder::Counts::onWrite
void onWrite(beast::PropertyStream::Map &map)
Output statistics.
Definition: Counts.h:248
std::stringstream::str
T str(T... args)
std::size_t
ripple::PeerFinder::Slot::inbound
virtual bool inbound() const =0
Returns true if this is an inbound connection.
ripple::PeerFinder::Config
PeerFinder configuration settings.
Definition: PeerfinderManager.h:40
ripple::PeerFinder::Counts::attempts_needed
std::size_t attempts_needed() const
Returns the number of attempts needed to bring us to the max.
Definition: Counts.h:89
ripple::PeerFinder::Slot::connect
@ connect
Definition: Slot.h:37
ripple::PeerFinder::Counts::remove
void remove(Slot const &s)
Removes the slot state and properties from the slot counts.
Definition: Counts.h:66
ripple::PeerFinder::Counts::m_fixed
std::size_t m_fixed
Fixed connections.
Definition: Counts.h:339
ripple::PeerFinder::Counts::m_reserved
std::size_t m_reserved
Reserved connections.
Definition: Counts.h:345
ripple::PeerFinder::Counts::totalActive
int totalActive() const
Returns the total number of active peers excluding fixed peers.
Definition: Counts.h:200
ripple::PeerFinder::Slot
Properties and state associated with a peer to peer overlay connection.
Definition: Slot.h:32
ripple::PeerFinder::Counts::m_fixed_active
std::size_t m_fixed_active
Active fixed connections.
Definition: Counts.h:342