rippled
overlay/Slot.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_OVERLAY_SLOT_H_INCLUDED
21 #define RIPPLE_OVERLAY_SLOT_H_INCLUDED
22 
23 #include <ripple/app/main/Application.h>
24 #include <ripple/basics/chrono.h>
25 #include <ripple/beast/container/aged_unordered_map.h>
26 #include <ripple/beast/utility/Journal.h>
27 #include <ripple/overlay/Peer.h>
28 #include <ripple/overlay/Squelch.h>
29 #include <ripple/overlay/SquelchCommon.h>
30 #include <ripple/protocol/PublicKey.h>
31 #include <ripple.pb.h>
32 
33 #include <algorithm>
34 #include <memory>
35 #include <optional>
36 #include <set>
37 #include <tuple>
38 #include <unordered_map>
39 #include <unordered_set>
40 
41 namespace ripple {
42 
43 namespace squelch {
44 
45 template <typename clock_type>
46 class Slots;
47 
49 enum class PeerState : uint8_t {
50  Counting, // counting messages
51  Selected, // selected to relay, counting if Slot in Counting
52  Squelched, // squelched, doesn't relay
53 };
55 enum class SlotState : uint8_t {
56  Counting, // counting messages
57  Selected, // peers selected, stop counting
58 };
59 
60 template <typename Unit, typename TP>
61 Unit
62 epoch(TP const& t)
63 {
64  return duration_cast<Unit>(t.time_since_epoch());
65 }
66 
72 {
73 public:
74  virtual ~SquelchHandler()
75  {
76  }
82  virtual void
83  squelch(PublicKey const& validator, Peer::id_t id, std::uint32_t duration)
84  const = 0;
89  virtual void
90  unsquelch(PublicKey const& validator, Peer::id_t id) const = 0;
91 };
92 
103 template <typename clock_type>
104 class Slot final
105 {
106 private:
107  friend class Slots<clock_type>;
108  using id_t = Peer::id_t;
109  using time_point = typename clock_type::time_point;
110 
115  Slot(SquelchHandler const& handler, beast::Journal journal)
116  : reachedThreshold_(0)
117  , lastSelected_(clock_type::now())
119  , handler_(handler)
120  , journal_(journal)
121  {
122  }
123 
142  void
143  update(PublicKey const& validator, id_t id, protocol::MessageType type);
144 
155  void
156  deletePeer(PublicKey const& validator, id_t id, bool erase);
157 
159  const time_point&
161  {
162  return lastSelected_;
163  }
164 
167  inState(PeerState state) const;
168 
171  notInState(PeerState state) const;
172 
174  SlotState
175  getState() const
176  {
177  return state_;
178  }
179 
182  getSelected() const;
183 
187  std::
188  unordered_map<id_t, std::tuple<PeerState, uint16_t, uint32_t, uint32_t>>
189  getPeers() const;
190 
197  void
198  deleteIdlePeer(PublicKey const& validator);
199 
200 private:
202  void
203  resetCounts();
204 
206  void
207  initCounting();
208 
210  struct PeerInfo
211  {
212  PeerState state; // peer's state
213  std::size_t count; // message count
214  time_point expire; // squelch expiration time
215  time_point lastMessage; // time last message received
216  };
218  // pool of peers considered as the source of messages
219  // from validator - peers that reached MIN_MESSAGE_THRESHOLD
221  // number of peers that reached MAX_MESSAGE_THRESHOLD
223  // last time peers were selected, used to age the slot
224  typename clock_type::time_point lastSelected_;
225  SlotState state_; // slot's state
226  SquelchHandler const& handler_; // squelch/unsquelch handler
227  beast::Journal const journal_; // logging
228 };
229 
230 template <typename clock_type>
231 void
233 {
234  auto now = clock_type::now();
235  for (auto it = peers_.begin(); it != peers_.end();)
236  {
237  auto& peer = it->second;
238  auto id = it->first;
239  ++it;
240  if (now - peer.lastMessage > IDLED)
241  {
242  JLOG(journal_.debug())
243  << "deleteIdlePeer: " << Slice(validator) << " " << id
244  << " idled "
245  << duration_cast<seconds>(now - peer.lastMessage).count()
246  << " selected " << (peer.state == PeerState::Selected);
247  deletePeer(validator, id, false);
248  }
249  }
250 }
251 
252 template <typename clock_type>
253 void
255  PublicKey const& validator,
256  id_t id,
257  protocol::MessageType type)
258 {
259  auto now = clock_type::now();
260  auto it = peers_.find(id);
261  // First message from this peer
262  if (it == peers_.end())
263  {
264  JLOG(journal_.debug())
265  << "update: adding peer " << Slice(validator) << " " << id;
266  peers_.emplace(
267  std::make_pair(id, PeerInfo{PeerState::Counting, 0, now, now}));
268  initCounting();
269  return;
270  }
271  // Message from a peer with expired squelch
272  if (it->second.state == PeerState::Squelched && now > it->second.expire)
273  {
274  JLOG(journal_.debug())
275  << "update: squelch expired " << Slice(validator) << " " << id;
276  it->second.state = PeerState::Counting;
277  it->second.lastMessage = now;
278  initCounting();
279  return;
280  }
281 
282  auto& peer = it->second;
283 
284  JLOG(journal_.debug())
285  << "update: existing peer " << Slice(validator) << " " << id
286  << " slot state " << static_cast<int>(state_) << " peer state "
287  << static_cast<int>(peer.state) << " count " << peer.count << " last "
288  << duration_cast<milliseconds>(now - peer.lastMessage).count()
289  << " pool " << considered_.size() << " threshold " << reachedThreshold_
290  << " " << (type == protocol::mtVALIDATION ? "validation" : "proposal");
291 
292  peer.lastMessage = now;
293 
294  if (state_ != SlotState::Counting || peer.state == PeerState::Squelched)
295  return;
296 
297  if (++peer.count > MIN_MESSAGE_THRESHOLD)
298  considered_.insert(id);
299  if (peer.count == (MAX_MESSAGE_THRESHOLD + 1))
300  ++reachedThreshold_;
301 
302  if (now - lastSelected_ > 2 * MAX_UNSQUELCH_EXPIRE)
303  {
304  JLOG(journal_.debug())
305  << "update: resetting due to inactivity " << Slice(validator) << " "
306  << id << " " << duration_cast<seconds>(now - lastSelected_).count();
307  initCounting();
308  return;
309  }
310 
311  if (reachedThreshold_ == MAX_SELECTED_PEERS)
312  {
313  // Randomly select MAX_SELECTED_PEERS peers from considered.
314  // Exclude peers that have been idling > IDLED -
315  // it's possible that deleteIdlePeer() has not been called yet.
316  // If number of remaining peers != MAX_SELECTED_PEERS
317  // then reset the Counting state and let deleteIdlePeer() handle
318  // idled peers.
319  std::unordered_set<id_t> selected;
320  auto const consideredPoolSize = considered_.size();
321  while (selected.size() != MAX_SELECTED_PEERS && considered_.size() != 0)
322  {
323  auto i =
324  considered_.size() == 1 ? 0 : rand_int(considered_.size() - 1);
325  auto it = std::next(considered_.begin(), i);
326  auto id = *it;
327  considered_.erase(it);
328  auto const& itpeers = peers_.find(id);
329  if (itpeers == peers_.end())
330  {
331  JLOG(journal_.error()) << "update: peer not found "
332  << Slice(validator) << " " << id;
333  continue;
334  }
335  if (now - itpeers->second.lastMessage < IDLED)
336  selected.insert(id);
337  }
338 
339  if (selected.size() != MAX_SELECTED_PEERS)
340  {
341  JLOG(journal_.debug())
342  << "update: selection failed " << Slice(validator) << " " << id;
343  initCounting();
344  return;
345  }
346 
347  lastSelected_ = now;
348 
349  auto s = selected.begin();
350  JLOG(journal_.debug())
351  << "update: " << Slice(validator) << " " << id << " pool size "
352  << consideredPoolSize << " selected " << *s << " "
353  << *std::next(s, 1) << " " << *std::next(s, 2);
354 
355  // squelch peers which are not selected and
356  // not already squelched
357  std::stringstream str;
358  for (auto& [k, v] : peers_)
359  {
360  v.count = 0;
361 
362  if (selected.find(k) != selected.end())
363  v.state = PeerState::Selected;
364  else if (v.state != PeerState::Squelched)
365  {
366  if (journal_.debug())
367  str << k << " ";
368  v.state = PeerState::Squelched;
370  v.expire = now + duration;
371  handler_.squelch(
372  validator,
373  k,
374  duration_cast<milliseconds>(duration).count());
375  }
376  }
377  JLOG(journal_.debug()) << "update: squelching " << Slice(validator)
378  << " " << id << " " << str.str();
379  considered_.clear();
380  reachedThreshold_ = 0;
381  state_ = SlotState::Selected;
382  }
383 }
384 
385 template <typename clock_type>
386 void
388 {
389  auto it = peers_.find(id);
390  if (it != peers_.end())
391  {
392  JLOG(journal_.debug())
393  << "deletePeer: " << Slice(validator) << " " << id << " selected "
394  << (it->second.state == PeerState::Selected) << " considered "
395  << (considered_.find(id) != considered_.end()) << " erase "
396  << erase;
397  auto now = clock_type::now();
398  if (it->second.state == PeerState::Selected)
399  {
400  for (auto& [k, v] : peers_)
401  {
402  if (v.state == PeerState::Squelched)
403  handler_.unsquelch(validator, k);
404  v.state = PeerState::Counting;
405  v.count = 0;
406  v.expire = now;
407  }
408 
409  considered_.clear();
410  reachedThreshold_ = 0;
411  state_ = SlotState::Counting;
412  }
413  else if (considered_.find(id) != considered_.end())
414  {
415  if (it->second.count > MAX_MESSAGE_THRESHOLD)
416  --reachedThreshold_;
417  considered_.erase(id);
418  }
419 
420  it->second.lastMessage = now;
421  it->second.count = 0;
422 
423  if (erase)
424  peers_.erase(it);
425  }
426 }
427 
428 template <typename clock_type>
429 void
431 {
432  for (auto& [_, peer] : peers_)
433  {
434  (void)_;
435  peer.count = 0;
436  }
437 }
438 
439 template <typename clock_type>
440 void
442 {
443  state_ = SlotState::Counting;
444  considered_.clear();
445  reachedThreshold_ = 0;
446  resetCounts();
447 }
448 
449 template <typename clock_type>
452 {
453  return std::count_if(peers_.begin(), peers_.end(), [&](auto const& it) {
454  return (it.second.state == state);
455  });
456 }
457 
458 template <typename clock_type>
461 {
462  return std::count_if(peers_.begin(), peers_.end(), [&](auto const& it) {
463  return (it.second.state != state);
464  });
465 }
466 
467 template <typename clock_type>
470 {
471  std::set<id_t> init;
472  return std::accumulate(
473  peers_.begin(), peers_.end(), init, [](auto& init, auto const& it) {
474  if (it.second.state == PeerState::Selected)
475  {
476  init.insert(it.first);
477  return init;
478  }
479  return init;
480  });
481 }
482 
483 template <typename clock_type>
485  typename Peer::id_t,
488 {
489  auto init = std::unordered_map<
490  id_t,
492  return std::accumulate(
493  peers_.begin(), peers_.end(), init, [](auto& init, auto const& it) {
494  init.emplace(std::make_pair(
495  it.first,
496  std::move(std::make_tuple(
497  it.second.state,
498  it.second.count,
499  epoch<milliseconds>(it.second.expire).count(),
500  epoch<milliseconds>(it.second.lastMessage).count()))));
501  return init;
502  });
503 }
504 
509 template <typename clock_type>
510 class Slots final
511 {
512  using time_point = typename clock_type::time_point;
513  using id_t = typename Peer::id_t;
515  uint256,
517  clock_type,
519 
520 public:
525  Slots(Application& app, SquelchHandler const& handler)
526  : handler_(handler), app_(app), journal_(app.journal("Slots"))
527  {
528  }
529  ~Slots() = default;
537  void
538  updateSlotAndSquelch(
539  uint256 const& key,
540  PublicKey const& validator,
541  id_t id,
542  protocol::MessageType type);
543 
547  void
548  deleteIdlePeers();
549 
552  inState(PublicKey const& validator, PeerState state) const
553  {
554  auto const& it = slots_.find(validator);
555  if (it != slots_.end())
556  return it->second.inState(state);
557  return {};
558  }
559 
562  notInState(PublicKey const& validator, PeerState state) const
563  {
564  auto const& it = slots_.find(validator);
565  if (it != slots_.end())
566  return it->second.notInState(state);
567  return {};
568  }
569 
571  bool
572  inState(PublicKey const& validator, SlotState state) const
573  {
574  auto const& it = slots_.find(validator);
575  if (it != slots_.end())
576  return it->second.state_ == state;
577  return false;
578  }
579 
582  getSelected(PublicKey const& validator)
583  {
584  auto const& it = slots_.find(validator);
585  if (it != slots_.end())
586  return it->second.getSelected();
587  return {};
588  }
589 
594  typename Peer::id_t,
596  getPeers(PublicKey const& validator)
597  {
598  auto const& it = slots_.find(validator);
599  if (it != slots_.end())
600  return it->second.getPeers();
601  return {};
602  }
603 
606  getState(PublicKey const& validator)
607  {
608  auto const& it = slots_.find(validator);
609  if (it != slots_.end())
610  return it->second.getState();
611  return {};
612  }
613 
620  void
621  deletePeer(id_t id, bool erase);
622 
623 private:
627  bool
628  addPeerMessage(uint256 const& key, id_t id);
629 
631  SquelchHandler const& handler_; // squelch/unsquelch handler
634  // Maintain aged container of message/peers. This is required
635  // to discard duplicate message from the same peer. A message
636  // is aged after IDLED seconds. A message received IDLED seconds
637  // after it was relayed is ignored by PeerImp.
638  inline static messages peersWithMessage_{
639  beast::get_abstract_clock<clock_type>()};
640 };
641 
642 template <typename clock_type>
643 bool
645 {
646  beast::expire(peersWithMessage_, squelch::IDLED);
647 
648  if (key.isNonZero())
649  {
650  auto it = peersWithMessage_.find(key);
651  if (it == peersWithMessage_.end())
652  {
653  JLOG(journal_.trace())
654  << "addPeerMessage: new " << to_string(key) << " " << id;
655  peersWithMessage_.emplace(key, std::unordered_set<id_t>{id});
656  return true;
657  }
658 
659  if (it->second.find(id) != it->second.end())
660  {
661  JLOG(journal_.trace()) << "addPeerMessage: duplicate message "
662  << to_string(key) << " " << id;
663  return false;
664  }
665 
666  JLOG(journal_.trace())
667  << "addPeerMessage: added " << to_string(key) << " " << id;
668 
669  it->second.insert(id);
670  }
671 
672  return true;
673 }
674 
675 template <typename clock_type>
676 void
678  uint256 const& key,
679  PublicKey const& validator,
680  id_t id,
681  protocol::MessageType type)
682 {
683  if (!addPeerMessage(key, id))
684  return;
685 
686  auto it = slots_.find(validator);
687  if (it == slots_.end())
688  {
689  JLOG(journal_.debug())
690  << "updateSlotAndSquelch: new slot " << Slice(validator);
691  auto it = slots_
692  .emplace(std::make_pair(
693  validator,
694  Slot<clock_type>(handler_, app_.journal("Slot"))))
695  .first;
696  it->second.update(validator, id, type);
697  }
698  else
699  it->second.update(validator, id, type);
700 }
701 
702 template <typename clock_type>
703 void
705 {
706  for (auto& [validator, slot] : slots_)
707  slot.deletePeer(validator, id, erase);
708 }
709 
710 template <typename clock_type>
711 void
713 {
714  auto now = clock_type::now();
715 
716  for (auto it = slots_.begin(); it != slots_.end();)
717  {
718  it->second.deleteIdlePeer(it->first);
719  if (now - it->second.getLastSelected() > MAX_UNSQUELCH_EXPIRE)
720  {
721  JLOG(journal_.debug())
722  << "deleteIdlePeers: deleting idle slot " << Slice(it->first);
723  it = slots_.erase(it);
724  }
725  else
726  ++it;
727  }
728 }
729 
730 } // namespace squelch
731 
732 } // namespace ripple
733 
734 #endif // RIPPLE_OVERLAY_SLOT_H_INCLUDED
ripple::squelch::Slots::Slots
Slots(Application &app, SquelchHandler const &handler)
Definition: overlay/Slot.h:525
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:79
ripple::squelch::Slots::notInState
std::optional< std::uint16_t > notInState(PublicKey const &validator, PeerState state) const
Return number of peers not in state.
Definition: overlay/Slot.h:562
ripple::squelch::SquelchHandler::~SquelchHandler
virtual ~SquelchHandler()
Definition: overlay/Slot.h:74
ripple::Application
Definition: Application.h:97
ripple::squelch::MAX_UNSQUELCH_EXPIRE
static constexpr seconds MAX_UNSQUELCH_EXPIRE
Definition: SquelchCommon.h:33
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:444
ripple::squelch::Slots::app_
Application & app_
Definition: overlay/Slot.h:632
ripple::squelch::Slot::PeerInfo::state
PeerState state
Definition: overlay/Slot.h:212
ripple::squelch::Slot::Slot
Slot(SquelchHandler const &handler, beast::Journal journal)
Constructor.
Definition: overlay/Slot.h:115
ripple::squelch::MAX_SELECTED_PEERS
static constexpr uint16_t MAX_SELECTED_PEERS
Definition: SquelchCommon.h:43
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
unordered_set
ripple::squelch::Slots::getState
std::optional< SlotState > getState(PublicKey const &validator)
Get Slot's state.
Definition: overlay/Slot.h:606
ripple::squelch::Slots::slots_
hash_map< PublicKey, Slot< clock_type > > slots_
Definition: overlay/Slot.h:630
ripple::Peer::id_t
std::uint32_t id_t
Uniquely identifies a peer.
Definition: ripple/overlay/Peer.h:53
std::unordered_set::find
T find(T... args)
std::unordered_set::size
T size(T... args)
ripple::squelch::SlotState::Counting
@ Counting
ripple::squelch::Slot::notInState
std::uint16_t notInState(PeerState state) const
Return number of peers not in state.
Definition: overlay/Slot.h:460
std::chrono::duration
ripple::squelch::Slot::getSelected
std::set< id_t > getSelected() const
Return selected peers.
Definition: overlay/Slot.h:469
ripple::squelch::Squelch::getSquelchDuration
static seconds getSquelchDuration()
Get random squelch duration between MIN_UNSQUELCH_EXPIRE and MAX_UNSQUELCH_EXPIRE.
Definition: Squelch.h:111
std::stringstream
STL class.
ripple::squelch::Slots::handler_
SquelchHandler const & handler_
Definition: overlay/Slot.h:631
ripple::squelch::Slots::deletePeer
void deletePeer(id_t id, bool erase)
Called when a peer is deleted.
Definition: overlay/Slot.h:704
ripple::squelch::Slot::peers_
std::unordered_map< id_t, PeerInfo > peers_
Definition: overlay/Slot.h:217
ripple::squelch::PeerState::Counting
@ Counting
tuple
ripple::squelch::Slots::inState
bool inState(PublicKey const &validator, SlotState state) const
Return true if Slot is in state.
Definition: overlay/Slot.h:572
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
ripple::squelch::SquelchHandler
Abstract class.
Definition: overlay/Slot.h:71
algorithm
ripple::squelch::PeerState
PeerState
Peer's State.
Definition: overlay/Slot.h:49
ripple::squelch::Slot::id_t
Peer::id_t id_t
Definition: overlay/Slot.h:108
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:457
ripple::erase
void erase(STObject &st, TypedField< U > const &f)
Remove a field in an STObject.
Definition: STExchange.h:171
ripple::base_uint< 256 >
ripple::squelch::Slot::PeerInfo::count
std::size_t count
Definition: overlay/Slot.h:213
ripple::squelch::Slots::inState
std::optional< std::uint16_t > inState(PublicKey const &validator, PeerState state) const
Return number of peers in state.
Definition: overlay/Slot.h:552
ripple::squelch::Slots::journal_
const beast::Journal journal_
Definition: overlay/Slot.h:633
ripple::rand_int
std::enable_if_t< std::is_integral< Integral >::value &&detail::is_engine< Engine >::value, Integral > rand_int(Engine &engine, Integral min, Integral max)
Return a uniformly distributed random integer.
Definition: ripple/basics/random.h:115
ripple::squelch::Slot::initCounting
void initCounting()
Initialize slot to Counting state.
Definition: overlay/Slot.h:441
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::squelch::Slot::PeerInfo
Data maintained for each peer.
Definition: overlay/Slot.h:210
ripple::squelch::Slot::lastSelected_
clock_type::time_point lastSelected_
Definition: overlay/Slot.h:224
ripple::squelch::MAX_MESSAGE_THRESHOLD
static constexpr uint16_t MAX_MESSAGE_THRESHOLD
Definition: SquelchCommon.h:41
ripple::squelch::Slot::reachedThreshold_
std::uint16_t reachedThreshold_
Definition: overlay/Slot.h:222
ripple::squelch::Slot::getPeers
std::unordered_map< id_t, std::tuple< PeerState, uint16_t, uint32_t, uint32_t > > getPeers() const
Get peers info.
Definition: overlay/Slot.h:487
std::chrono::time_point
ripple::hardened_hash
Seed functor once per construction.
Definition: hardened_hash.h:96
ripple::squelch::SquelchHandler::squelch
virtual void squelch(PublicKey const &validator, Peer::id_t id, std::uint32_t duration) const =0
Squelch handler.
std::accumulate
T accumulate(T... args)
ripple::squelch::Slot::PeerInfo::lastMessage
time_point lastMessage
Definition: overlay/Slot.h:215
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
beast::expire
std::enable_if< is_aged_container< AgedContainer >::value, std::size_t >::type expire(AgedContainer &c, std::chrono::duration< Rep, Period > const &age)
Expire aged container items past the specified age.
Definition: aged_container_utility.h:33
std::uint32_t
ripple::squelch::PeerState::Selected
@ Selected
ripple::squelch::Slot::deleteIdlePeer
void deleteIdlePeer(PublicKey const &validator)
Check if peers stopped relaying messages.
Definition: overlay/Slot.h:232
memory
ripple::squelch::Slots< ripple::UptimeClock >::id_t
typename Peer::id_t id_t
Definition: overlay/Slot.h:513
ripple::squelch::Slot::inState
std::uint16_t inState(PeerState state) const
Return number of peers in state.
Definition: overlay/Slot.h:451
beast::detail::aged_unordered_container
Associative container where each element is also indexed by time.
Definition: aged_unordered_container.h:85
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::squelch::Slot::considered_
std::unordered_set< id_t > considered_
Definition: overlay/Slot.h:220
ripple::squelch::SlotState::Selected
@ Selected
ripple::squelch::Slot::state_
SlotState state_
Definition: overlay/Slot.h:225
ripple::squelch::IDLED
static constexpr seconds IDLED
Definition: SquelchCommon.h:35
std::unordered_set::begin
T begin(T... args)
std::unordered_set::insert
T insert(T... args)
ripple::squelch::Slot::resetCounts
void resetCounts()
Reset counts of peers in Selected or Counting state.
Definition: overlay/Slot.h:430
ripple::squelch::Slot::PeerInfo::expire
time_point expire
Definition: overlay/Slot.h:214
std::count_if
T count_if(T... args)
ripple::squelch::epoch
Unit epoch(TP const &t)
Definition: overlay/Slot.h:62
optional
std::stringstream::str
T str(T... args)
std::size_t
ripple::squelch::Slots::getPeers
std::unordered_map< typename Peer::id_t, std::tuple< PeerState, uint16_t, uint32_t, std::uint32_t > > getPeers(PublicKey const &validator)
Get peers info.
Definition: overlay/Slot.h:596
std::make_pair
T make_pair(T... args)
ripple::squelch::SquelchHandler::unsquelch
virtual void unsquelch(PublicKey const &validator, Peer::id_t id) const =0
Unsquelch handler.
ripple::squelch::Slots
Slots is a container for validator's Slot and handles Slot update when a message is received from a v...
Definition: overlay/Slot.h:46
std::unordered_set::end
T end(T... args)
ripple::squelch::Slot
Slot is associated with a specific validator via validator's public key.
Definition: overlay/Slot.h:104
ripple::squelch::Slot::journal_
const beast::Journal journal_
Definition: overlay/Slot.h:227
ripple::squelch::Slots< ripple::UptimeClock >::time_point
typename ripple::UptimeClock ::time_point time_point
Definition: overlay/Slot.h:512
ripple::squelch::Slot::getLastSelected
const time_point & getLastSelected() const
Get the time of the last peer selection round.
Definition: overlay/Slot.h:160
unordered_map
ripple::squelch::Slot::getState
SlotState getState() const
Return Slot's state.
Definition: overlay/Slot.h:175
ripple::squelch::PeerState::Squelched
@ Squelched
ripple::squelch::SlotState
SlotState
Slot's State.
Definition: overlay/Slot.h:55
set
ripple::squelch::Slot< ripple::UptimeClock >::time_point
typename ripple::UptimeClock ::time_point time_point
Definition: overlay/Slot.h:109
ripple::squelch::Slot::deletePeer
void deletePeer(PublicKey const &validator, id_t id, bool erase)
Handle peer deletion when a peer disconnects.
Definition: overlay/Slot.h:387
ripple::squelch::Slots::getSelected
std::set< id_t > getSelected(PublicKey const &validator)
Get selected peers.
Definition: overlay/Slot.h:582
ripple::squelch::Slot::handler_
SquelchHandler const & handler_
Definition: overlay/Slot.h:226
ripple::squelch::MIN_MESSAGE_THRESHOLD
static constexpr uint16_t MIN_MESSAGE_THRESHOLD
Definition: SquelchCommon.h:40
ripple::squelch::Slot::update
void update(PublicKey const &validator, id_t id, protocol::MessageType type)
Update peer info.
Definition: overlay/Slot.h:254
std::next
T next(T... args)