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/basics/Log.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/ReduceRelayCommon.h>
29 #include <ripple/overlay/Squelch.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 reduce_relay {
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 std::chrono::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 
207 
208 private:
210  void
211  resetCounts();
212 
214  void
215  initCounting();
216 
218  struct PeerInfo
219  {
220  PeerState state; // peer's state
221  std::size_t count; // message count
222  time_point expire; // squelch expiration time
223  time_point lastMessage; // time last message received
224  };
226  // pool of peers considered as the source of messages
227  // from validator - peers that reached MIN_MESSAGE_THRESHOLD
229  // number of peers that reached MAX_MESSAGE_THRESHOLD
231  // last time peers were selected, used to age the slot
232  typename clock_type::time_point lastSelected_;
233  SlotState state_; // slot's state
234  SquelchHandler const& handler_; // squelch/unsquelch handler
235  beast::Journal const journal_; // logging
236 };
237 
238 template <typename clock_type>
239 void
241 {
242  using namespace std::chrono;
243  auto now = clock_type::now();
244  for (auto it = peers_.begin(); it != peers_.end();)
245  {
246  auto& peer = it->second;
247  auto id = it->first;
248  ++it;
249  if (now - peer.lastMessage > IDLED)
250  {
251  JLOG(journal_.trace())
252  << "deleteIdlePeer: " << Slice(validator) << " " << id
253  << " idled "
254  << duration_cast<seconds>(now - peer.lastMessage).count()
255  << " selected " << (peer.state == PeerState::Selected);
256  deletePeer(validator, id, false);
257  }
258  }
259 }
260 
261 template <typename clock_type>
262 void
264  PublicKey const& validator,
265  id_t id,
266  protocol::MessageType type)
267 {
268  using namespace std::chrono;
269  auto now = clock_type::now();
270  auto it = peers_.find(id);
271  // First message from this peer
272  if (it == peers_.end())
273  {
274  JLOG(journal_.trace())
275  << "update: adding peer " << Slice(validator) << " " << id;
276  peers_.emplace(
277  std::make_pair(id, PeerInfo{PeerState::Counting, 0, now, now}));
278  initCounting();
279  return;
280  }
281  // Message from a peer with expired squelch
282  if (it->second.state == PeerState::Squelched && now > it->second.expire)
283  {
284  JLOG(journal_.trace())
285  << "update: squelch expired " << Slice(validator) << " " << id;
286  it->second.state = PeerState::Counting;
287  it->second.lastMessage = now;
288  initCounting();
289  return;
290  }
291 
292  auto& peer = it->second;
293 
294  JLOG(journal_.trace())
295  << "update: existing peer " << Slice(validator) << " " << id
296  << " slot state " << static_cast<int>(state_) << " peer state "
297  << static_cast<int>(peer.state) << " count " << peer.count << " last "
298  << duration_cast<milliseconds>(now - peer.lastMessage).count()
299  << " pool " << considered_.size() << " threshold " << reachedThreshold_
300  << " " << (type == protocol::mtVALIDATION ? "validation" : "proposal");
301 
302  peer.lastMessage = now;
303 
304  if (state_ != SlotState::Counting || peer.state == PeerState::Squelched)
305  return;
306 
307  if (++peer.count > MIN_MESSAGE_THRESHOLD)
308  considered_.insert(id);
309  if (peer.count == (MAX_MESSAGE_THRESHOLD + 1))
310  ++reachedThreshold_;
311 
312  if (now - lastSelected_ > 2 * MAX_UNSQUELCH_EXPIRE_DEFAULT)
313  {
314  JLOG(journal_.trace())
315  << "update: resetting due to inactivity " << Slice(validator) << " "
316  << id << " " << duration_cast<seconds>(now - lastSelected_).count();
317  initCounting();
318  return;
319  }
320 
321  if (reachedThreshold_ == MAX_SELECTED_PEERS)
322  {
323  // Randomly select MAX_SELECTED_PEERS peers from considered.
324  // Exclude peers that have been idling > IDLED -
325  // it's possible that deleteIdlePeer() has not been called yet.
326  // If number of remaining peers != MAX_SELECTED_PEERS
327  // then reset the Counting state and let deleteIdlePeer() handle
328  // idled peers.
329  std::unordered_set<id_t> selected;
330  auto const consideredPoolSize = considered_.size();
331  while (selected.size() != MAX_SELECTED_PEERS && considered_.size() != 0)
332  {
333  auto i =
334  considered_.size() == 1 ? 0 : rand_int(considered_.size() - 1);
335  auto it = std::next(considered_.begin(), i);
336  auto id = *it;
337  considered_.erase(it);
338  auto const& itpeers = peers_.find(id);
339  if (itpeers == peers_.end())
340  {
341  JLOG(journal_.error()) << "update: peer not found "
342  << Slice(validator) << " " << id;
343  continue;
344  }
345  if (now - itpeers->second.lastMessage < IDLED)
346  selected.insert(id);
347  }
348 
349  if (selected.size() != MAX_SELECTED_PEERS)
350  {
351  JLOG(journal_.trace())
352  << "update: selection failed " << Slice(validator) << " " << id;
353  initCounting();
354  return;
355  }
356 
357  lastSelected_ = now;
358 
359  auto s = selected.begin();
360  JLOG(journal_.trace())
361  << "update: " << Slice(validator) << " " << id << " pool size "
362  << consideredPoolSize << " selected " << *s << " "
363  << *std::next(s, 1) << " " << *std::next(s, 2);
364 
365  assert(peers_.size() >= MAX_SELECTED_PEERS);
366 
367  // squelch peers which are not selected and
368  // not already squelched
369  std::stringstream str;
370  for (auto& [k, v] : peers_)
371  {
372  v.count = 0;
373 
374  if (selected.find(k) != selected.end())
375  v.state = PeerState::Selected;
376  else if (v.state != PeerState::Squelched)
377  {
378  if (journal_.trace())
379  str << k << " ";
380  v.state = PeerState::Squelched;
382  getSquelchDuration(peers_.size() - MAX_SELECTED_PEERS);
383  v.expire = now + duration;
384  handler_.squelch(validator, k, duration.count());
385  }
386  }
387  JLOG(journal_.trace()) << "update: squelching " << Slice(validator)
388  << " " << id << " " << str.str();
389  considered_.clear();
390  reachedThreshold_ = 0;
391  state_ = SlotState::Selected;
392  }
393 }
394 
395 template <typename clock_type>
398 {
399  using namespace std::chrono;
400  auto m = std::max(
403  {
405  JLOG(journal_.warn())
406  << "getSquelchDuration: unexpected squelch duration " << npeers;
407  }
408  return seconds{ripple::rand_int(MIN_UNSQUELCH_EXPIRE / 1s, m / 1s)};
409 }
410 
411 template <typename clock_type>
412 void
414 {
415  auto it = peers_.find(id);
416  if (it != peers_.end())
417  {
418  JLOG(journal_.trace())
419  << "deletePeer: " << Slice(validator) << " " << id << " selected "
420  << (it->second.state == PeerState::Selected) << " considered "
421  << (considered_.find(id) != considered_.end()) << " erase "
422  << erase;
423  auto now = clock_type::now();
424  if (it->second.state == PeerState::Selected)
425  {
426  for (auto& [k, v] : peers_)
427  {
428  if (v.state == PeerState::Squelched)
429  handler_.unsquelch(validator, k);
430  v.state = PeerState::Counting;
431  v.count = 0;
432  v.expire = now;
433  }
434 
435  considered_.clear();
436  reachedThreshold_ = 0;
437  state_ = SlotState::Counting;
438  }
439  else if (considered_.find(id) != considered_.end())
440  {
441  if (it->second.count > MAX_MESSAGE_THRESHOLD)
442  --reachedThreshold_;
443  considered_.erase(id);
444  }
445 
446  it->second.lastMessage = now;
447  it->second.count = 0;
448 
449  if (erase)
450  peers_.erase(it);
451  }
452 }
453 
454 template <typename clock_type>
455 void
457 {
458  for (auto& [_, peer] : peers_)
459  {
460  (void)_;
461  peer.count = 0;
462  }
463 }
464 
465 template <typename clock_type>
466 void
468 {
469  state_ = SlotState::Counting;
470  considered_.clear();
471  reachedThreshold_ = 0;
472  resetCounts();
473 }
474 
475 template <typename clock_type>
478 {
479  return std::count_if(peers_.begin(), peers_.end(), [&](auto const& it) {
480  return (it.second.state == state);
481  });
482 }
483 
484 template <typename clock_type>
487 {
488  return std::count_if(peers_.begin(), peers_.end(), [&](auto const& it) {
489  return (it.second.state != state);
490  });
491 }
492 
493 template <typename clock_type>
496 {
497  std::set<id_t> r;
498  for (auto const& [id, info] : peers_)
499  if (info.state == PeerState::Selected)
500  r.insert(id);
501  return r;
502 }
503 
504 template <typename clock_type>
506  typename Peer::id_t,
509 {
510  using namespace std::chrono;
511  auto r = std::unordered_map<
512  id_t,
514 
515  for (auto const& [id, info] : peers_)
516  r.emplace(std::make_pair(
517  id,
518  std::move(std::make_tuple(
519  info.state,
520  info.count,
521  epoch<milliseconds>(info.expire).count(),
522  epoch<milliseconds>(info.lastMessage).count()))));
523 
524  return r;
525 }
526 
531 template <typename clock_type>
532 class Slots final
533 {
534  using time_point = typename clock_type::time_point;
535  using id_t = typename Peer::id_t;
537  uint256,
539  clock_type,
541 
542 public:
547  Slots(Logs& logs, SquelchHandler const& handler)
548  : handler_(handler), logs_(logs), journal_(logs.journal("Slots"))
549  {
550  }
551  ~Slots() = default;
558  void
560  uint256 const& key,
561  PublicKey const& validator,
562  id_t id,
563  protocol::MessageType type);
564 
568  void
569  deleteIdlePeers();
570 
573  inState(PublicKey const& validator, PeerState state) const
574  {
575  auto const& it = slots_.find(validator);
576  if (it != slots_.end())
577  return it->second.inState(state);
578  return {};
579  }
580 
583  notInState(PublicKey const& validator, PeerState state) const
584  {
585  auto const& it = slots_.find(validator);
586  if (it != slots_.end())
587  return it->second.notInState(state);
588  return {};
589  }
590 
592  bool
593  inState(PublicKey const& validator, SlotState state) const
594  {
595  auto const& it = slots_.find(validator);
596  if (it != slots_.end())
597  return it->second.state_ == state;
598  return false;
599  }
600 
603  getSelected(PublicKey const& validator)
604  {
605  auto const& it = slots_.find(validator);
606  if (it != slots_.end())
607  return it->second.getSelected();
608  return {};
609  }
610 
615  typename Peer::id_t,
617  getPeers(PublicKey const& validator)
618  {
619  auto const& it = slots_.find(validator);
620  if (it != slots_.end())
621  return it->second.getPeers();
622  return {};
623  }
624 
627  getState(PublicKey const& validator)
628  {
629  auto const& it = slots_.find(validator);
630  if (it != slots_.end())
631  return it->second.getState();
632  return {};
633  }
634 
641  void
642  deletePeer(id_t id, bool erase);
643 
644 private:
648  bool
649  addPeerMessage(uint256 const& key, id_t id);
650 
652  SquelchHandler const& handler_; // squelch/unsquelch handler
655  // Maintain aged container of message/peers. This is required
656  // to discard duplicate message from the same peer. A message
657  // is aged after IDLED seconds. A message received IDLED seconds
658  // after it was relayed is ignored by PeerImp.
660  beast::get_abstract_clock<clock_type>()};
661 };
662 
663 template <typename clock_type>
664 bool
666 {
667  beast::expire(peersWithMessage_, reduce_relay::IDLED);
668 
669  if (key.isNonZero())
670  {
671  auto it = peersWithMessage_.find(key);
672  if (it == peersWithMessage_.end())
673  {
674  JLOG(journal_.trace())
675  << "addPeerMessage: new " << to_string(key) << " " << id;
676  peersWithMessage_.emplace(key, std::unordered_set<id_t>{id});
677  return true;
678  }
679 
680  if (it->second.find(id) != it->second.end())
681  {
682  JLOG(journal_.trace()) << "addPeerMessage: duplicate message "
683  << to_string(key) << " " << id;
684  return false;
685  }
686 
687  JLOG(journal_.trace())
688  << "addPeerMessage: added " << to_string(key) << " " << id;
689 
690  it->second.insert(id);
691  }
692 
693  return true;
694 }
695 
696 template <typename clock_type>
697 void
699  uint256 const& key,
700  PublicKey const& validator,
701  id_t id,
702  protocol::MessageType type)
703 {
704  if (!addPeerMessage(key, id))
705  return;
706 
707  auto it = slots_.find(validator);
708  if (it == slots_.end())
709  {
710  JLOG(journal_.trace())
711  << "updateSlotAndSquelch: new slot " << Slice(validator);
712  auto it = slots_
713  .emplace(std::make_pair(
714  validator,
715  Slot<clock_type>(handler_, logs_.journal("Slot"))))
716  .first;
717  it->second.update(validator, id, type);
718  }
719  else
720  it->second.update(validator, id, type);
721 }
722 
723 template <typename clock_type>
724 void
726 {
727  for (auto& [validator, slot] : slots_)
728  slot.deletePeer(validator, id, erase);
729 }
730 
731 template <typename clock_type>
732 void
734 {
735  auto now = clock_type::now();
736 
737  for (auto it = slots_.begin(); it != slots_.end();)
738  {
739  it->second.deleteIdlePeer(it->first);
740  if (now - it->second.getLastSelected() > MAX_UNSQUELCH_EXPIRE_DEFAULT)
741  {
742  JLOG(journal_.trace())
743  << "deleteIdlePeers: deleting idle slot " << Slice(it->first);
744  it = slots_.erase(it);
745  }
746  else
747  ++it;
748  }
749 }
750 
751 } // namespace reduce_relay
752 
753 } // namespace ripple
754 
755 #endif // RIPPLE_OVERLAY_SLOT_H_INCLUDED
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:80
std::make_tuple
T make_tuple(T... args)
ripple::reduce_relay::SquelchHandler
Abstract class.
Definition: overlay/Slot.h:71
ripple::reduce_relay::Slot::peers_
std::unordered_map< id_t, PeerInfo > peers_
Definition: overlay/Slot.h:225
ripple::reduce_relay::epoch
Unit epoch(TP const &t)
Definition: overlay/Slot.h:62
ripple::reduce_relay::SlotState
SlotState
Slot's State.
Definition: overlay/Slot.h:55
ripple::Logs
Manages partitions for logging.
Definition: Log.h:48
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:537
ripple::reduce_relay::Slots::updateSlotAndSquelch
void updateSlotAndSquelch(uint256 const &key, PublicKey const &validator, id_t id, protocol::MessageType type)
Calls Slot::update of Slot associated with the validator.
Definition: overlay/Slot.h:698
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
ripple::reduce_relay::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:508
unordered_set
ripple::reduce_relay::Slot::journal_
const beast::Journal journal_
Definition: overlay/Slot.h:235
ripple::reduce_relay::Slot::handler_
SquelchHandler const & handler_
Definition: overlay/Slot.h:234
ripple::Peer::id_t
std::uint32_t id_t
Uniquely identifies a peer.
Definition: ripple/overlay/Peer.h:55
ripple::reduce_relay::Slots::logs_
Logs & logs_
Definition: overlay/Slot.h:653
std::unordered_set::find
T find(T... args)
std::unordered_set::size
T size(T... args)
ripple::reduce_relay::SQUELCH_PER_PEER
static constexpr auto SQUELCH_PER_PEER
Definition: ReduceRelayCommon.h:36
ripple::reduce_relay::Slot::initCounting
void initCounting()
Initialize slot to Counting state.
Definition: overlay/Slot.h:467
ripple::reduce_relay::PeerState::Squelched
@ Squelched
std::chrono::seconds
ripple::reduce_relay::MAX_UNSQUELCH_EXPIRE_DEFAULT
static constexpr auto MAX_UNSQUELCH_EXPIRE_DEFAULT
Definition: ReduceRelayCommon.h:35
ripple::reduce_relay::Slot::Slot
Slot(SquelchHandler const &handler, beast::Journal journal)
Constructor.
Definition: overlay/Slot.h:115
ripple::reduce_relay::Slot::reachedThreshold_
std::uint16_t reachedThreshold_
Definition: overlay/Slot.h:230
std::stringstream
STL class.
ripple::reduce_relay::MAX_MESSAGE_THRESHOLD
static constexpr uint16_t MAX_MESSAGE_THRESHOLD
Definition: ReduceRelayCommon.h:45
ripple::reduce_relay::SquelchHandler::squelch
virtual void squelch(PublicKey const &validator, Peer::id_t id, std::uint32_t duration) const =0
Squelch handler.
ripple::reduce_relay::Slot::getSquelchDuration
std::chrono::seconds getSquelchDuration(std::size_t npeers)
Get random squelch duration between MIN_UNSQUELCH_EXPIRE and min(max(MAX_UNSQUELCH_EXPIRE_DEFAULT,...
Definition: overlay/Slot.h:397
ripple::reduce_relay::Slots< ripple::UptimeClock >::id_t
typename Peer::id_t id_t
Definition: overlay/Slot.h:535
tuple
ripple::reduce_relay::Slots< ripple::UptimeClock >::time_point
typename ripple::UptimeClock ::time_point time_point
Definition: overlay/Slot.h:534
ripple::reduce_relay::PeerState::Counting
@ Counting
ripple::reduce_relay::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:583
ripple::reduce_relay::PeerState
PeerState
Peer's State.
Definition: overlay/Slot.h:49
ripple::reduce_relay::Slots::inState
bool inState(PublicKey const &validator, SlotState state) const
Return true if Slot is in state.
Definition: overlay/Slot.h:593
algorithm
ripple::reduce_relay::Slot::state_
SlotState state_
Definition: overlay/Slot.h:233
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:550
ripple::reduce_relay::Slots::slots_
hash_map< PublicKey, Slot< clock_type > > slots_
Definition: overlay/Slot.h:651
ripple::erase
void erase(STObject &st, TypedField< U > const &f)
Remove a field in an STObject.
Definition: STExchange.h:171
ripple::reduce_relay::Slot::PeerInfo::lastMessage
time_point lastMessage
Definition: overlay/Slot.h:223
ripple::base_uint< 256 >
ripple::reduce_relay::Slots::journal_
const beast::Journal journal_
Definition: overlay/Slot.h:654
ripple::reduce_relay::Slot::PeerInfo::state
PeerState state
Definition: overlay/Slot.h:220
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::reduce_relay::PeerState::Selected
@ Selected
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::reduce_relay::Slot::resetCounts
void resetCounts()
Reset counts of peers in Selected or Counting state.
Definition: overlay/Slot.h:456
ripple::reduce_relay::Slots::inState
std::optional< std::uint16_t > inState(PublicKey const &validator, PeerState state) const
Return number of peers in state.
Definition: overlay/Slot.h:573
ripple::reduce_relay::IDLED
static constexpr auto IDLED
Definition: ReduceRelayCommon.h:39
ripple::reduce_relay::Slots::deleteIdlePeers
void deleteIdlePeers()
Check if peers stopped relaying messages and if slots stopped receiving messages from the validator.
Definition: overlay/Slot.h:733
ripple::reduce_relay::Slot::PeerInfo::expire
time_point expire
Definition: overlay/Slot.h:222
ripple::reduce_relay::Slot::deleteIdlePeer
void deleteIdlePeer(PublicKey const &validator)
Check if peers stopped relaying messages.
Definition: overlay/Slot.h:240
ripple::hardened_hash
Seed functor once per construction.
Definition: hardened_hash.h:96
ripple::reduce_relay::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
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::reduce_relay::Slots::peersWithMessage_
static messages peersWithMessage_
Definition: overlay/Slot.h:659
ripple::reduce_relay::MIN_MESSAGE_THRESHOLD
static constexpr uint16_t MIN_MESSAGE_THRESHOLD
Definition: ReduceRelayCommon.h:44
ripple::reduce_relay::Slots::getState
std::optional< SlotState > getState(PublicKey const &validator)
Get Slot's state.
Definition: overlay/Slot.h:627
memory
ripple::reduce_relay::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:617
ripple::reduce_relay::Slot< ripple::UptimeClock >::time_point
typename ripple::UptimeClock ::time_point time_point
Definition: overlay/Slot.h:109
ripple::reduce_relay::Slot::deletePeer
void deletePeer(PublicKey const &validator, id_t id, bool erase)
Handle peer deletion when a peer disconnects.
Definition: overlay/Slot.h:413
ripple::reduce_relay::Slot::getState
SlotState getState() const
Return Slot's state.
Definition: overlay/Slot.h:175
ripple::reduce_relay::MIN_UNSQUELCH_EXPIRE
static constexpr auto MIN_UNSQUELCH_EXPIRE
Definition: ReduceRelayCommon.h:34
beast::detail::aged_unordered_container
Associative container where each element is also indexed by time.
Definition: aged_unordered_container.h:85
ripple::reduce_relay::Slots::addPeerMessage
bool addPeerMessage(uint256 const &key, id_t id)
Add message/peer if have not seen this message from the peer.
Definition: overlay/Slot.h:665
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::reduce_relay::Slots::Slots
Slots(Logs &logs, SquelchHandler const &handler)
Definition: overlay/Slot.h:547
ripple::reduce_relay::SlotState::Counting
@ Counting
std::unordered_set::begin
T begin(T... args)
ripple::reduce_relay::Slot::considered_
std::unordered_set< id_t > considered_
Definition: overlay/Slot.h:228
ripple::reduce_relay::Slot::lastSelected_
clock_type::time_point lastSelected_
Definition: overlay/Slot.h:232
std::unordered_set::insert
T insert(T... args)
std::chrono::duration::count
T count(T... args)
ripple::reduce_relay::SquelchHandler::unsquelch
virtual void unsquelch(PublicKey const &validator, Peer::id_t id) const =0
Unsquelch handler.
ripple::reduce_relay::Slots::getSelected
std::set< id_t > getSelected(PublicKey const &validator)
Get selected peers.
Definition: overlay/Slot.h:603
optional
ripple::reduce_relay::Slot::getSelected
std::set< id_t > getSelected() const
Return selected peers.
Definition: overlay/Slot.h:495
std::stringstream::str
T str(T... args)
std::size_t
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::reduce_relay::Slot::notInState
std::uint16_t notInState(PeerState state) const
Return number of peers not in state.
Definition: overlay/Slot.h:486
ripple::reduce_relay::MAX_UNSQUELCH_EXPIRE_PEERS
static constexpr auto MAX_UNSQUELCH_EXPIRE_PEERS
Definition: ReduceRelayCommon.h:37
std::make_pair
T make_pair(T... args)
ripple::reduce_relay::Slot::PeerInfo::count
std::size_t count
Definition: overlay/Slot.h:221
std::unordered_set::end
T end(T... args)
ripple::reduce_relay::Slot::PeerInfo
Data maintained for each peer.
Definition: overlay/Slot.h:218
std::max
T max(T... args)
ripple::reduce_relay::Slots::~Slots
~Slots()=default
ripple::reduce_relay::Slots::handler_
SquelchHandler const & handler_
Definition: overlay/Slot.h:652
ripple::reduce_relay::Slot::inState
std::uint16_t inState(PeerState state) const
Return number of peers in state.
Definition: overlay/Slot.h:477
unordered_map
ripple::reduce_relay::SlotState::Selected
@ Selected
ripple::reduce_relay::Slot::getLastSelected
const time_point & getLastSelected() const
Get the time of the last peer selection round.
Definition: overlay/Slot.h:160
ripple::reduce_relay::Slot::id_t
Peer::id_t id_t
Definition: overlay/Slot.h:108
set
ripple::reduce_relay::SquelchHandler::~SquelchHandler
virtual ~SquelchHandler()
Definition: overlay/Slot.h:74
ripple::reduce_relay::Slot::update
void update(PublicKey const &validator, id_t id, protocol::MessageType type)
Update peer info.
Definition: overlay/Slot.h:263
ripple::reduce_relay::Slots::deletePeer
void deletePeer(id_t id, bool erase)
Called when a peer is deleted.
Definition: overlay/Slot.h:725
ripple::reduce_relay::MAX_SELECTED_PEERS
static constexpr uint16_t MAX_SELECTED_PEERS
Definition: ReduceRelayCommon.h:47
std::next
T next(T... args)
ripple::reduce_relay::Slot
Slot is associated with a specific validator via validator's public key.
Definition: overlay/Slot.h:104
std::chrono