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/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> init;
498  return std::accumulate(
499  peers_.begin(), peers_.end(), init, [](auto& init, auto const& it) {
500  if (it.second.state == PeerState::Selected)
501  {
502  init.insert(it.first);
503  return init;
504  }
505  return init;
506  });
507 }
508 
509 template <typename clock_type>
511  typename Peer::id_t,
514 {
515  using namespace std::chrono;
516  auto init = std::unordered_map<
517  id_t,
519  return std::accumulate(
520  peers_.begin(), peers_.end(), init, [](auto& init, auto const& it) {
521  init.emplace(std::make_pair(
522  it.first,
523  std::move(std::make_tuple(
524  it.second.state,
525  it.second.count,
526  epoch<milliseconds>(it.second.expire).count(),
527  epoch<milliseconds>(it.second.lastMessage).count()))));
528  return init;
529  });
530 }
531 
536 template <typename clock_type>
537 class Slots final
538 {
539  using time_point = typename clock_type::time_point;
540  using id_t = typename Peer::id_t;
542  uint256,
544  clock_type,
546 
547 public:
552  Slots(Application& app, SquelchHandler const& handler)
553  : handler_(handler), app_(app), journal_(app.journal("Slots"))
554  {
555  }
556  ~Slots() = default;
563  void
565  uint256 const& key,
566  PublicKey const& validator,
567  id_t id,
568  protocol::MessageType type);
569 
573  void
574  deleteIdlePeers();
575 
578  inState(PublicKey const& validator, PeerState state) const
579  {
580  auto const& it = slots_.find(validator);
581  if (it != slots_.end())
582  return it->second.inState(state);
583  return {};
584  }
585 
588  notInState(PublicKey const& validator, PeerState state) const
589  {
590  auto const& it = slots_.find(validator);
591  if (it != slots_.end())
592  return it->second.notInState(state);
593  return {};
594  }
595 
597  bool
598  inState(PublicKey const& validator, SlotState state) const
599  {
600  auto const& it = slots_.find(validator);
601  if (it != slots_.end())
602  return it->second.state_ == state;
603  return false;
604  }
605 
608  getSelected(PublicKey const& validator)
609  {
610  auto const& it = slots_.find(validator);
611  if (it != slots_.end())
612  return it->second.getSelected();
613  return {};
614  }
615 
620  typename Peer::id_t,
622  getPeers(PublicKey const& validator)
623  {
624  auto const& it = slots_.find(validator);
625  if (it != slots_.end())
626  return it->second.getPeers();
627  return {};
628  }
629 
632  getState(PublicKey const& validator)
633  {
634  auto const& it = slots_.find(validator);
635  if (it != slots_.end())
636  return it->second.getState();
637  return {};
638  }
639 
646  void
647  deletePeer(id_t id, bool erase);
648 
649 private:
653  bool
654  addPeerMessage(uint256 const& key, id_t id);
655 
657  SquelchHandler const& handler_; // squelch/unsquelch handler
660  // Maintain aged container of message/peers. This is required
661  // to discard duplicate message from the same peer. A message
662  // is aged after IDLED seconds. A message received IDLED seconds
663  // after it was relayed is ignored by PeerImp.
665  beast::get_abstract_clock<clock_type>()};
666 };
667 
668 template <typename clock_type>
669 bool
671 {
672  beast::expire(peersWithMessage_, reduce_relay::IDLED);
673 
674  if (key.isNonZero())
675  {
676  auto it = peersWithMessage_.find(key);
677  if (it == peersWithMessage_.end())
678  {
679  JLOG(journal_.trace())
680  << "addPeerMessage: new " << to_string(key) << " " << id;
681  peersWithMessage_.emplace(key, std::unordered_set<id_t>{id});
682  return true;
683  }
684 
685  if (it->second.find(id) != it->second.end())
686  {
687  JLOG(journal_.trace()) << "addPeerMessage: duplicate message "
688  << to_string(key) << " " << id;
689  return false;
690  }
691 
692  JLOG(journal_.trace())
693  << "addPeerMessage: added " << to_string(key) << " " << id;
694 
695  it->second.insert(id);
696  }
697 
698  return true;
699 }
700 
701 template <typename clock_type>
702 void
704  uint256 const& key,
705  PublicKey const& validator,
706  id_t id,
707  protocol::MessageType type)
708 {
709  if (!addPeerMessage(key, id))
710  return;
711 
712  auto it = slots_.find(validator);
713  if (it == slots_.end())
714  {
715  JLOG(journal_.trace())
716  << "updateSlotAndSquelch: new slot " << Slice(validator);
717  auto it = slots_
718  .emplace(std::make_pair(
719  validator,
720  Slot<clock_type>(handler_, app_.journal("Slot"))))
721  .first;
722  it->second.update(validator, id, type);
723  }
724  else
725  it->second.update(validator, id, type);
726 }
727 
728 template <typename clock_type>
729 void
731 {
732  for (auto& [validator, slot] : slots_)
733  slot.deletePeer(validator, id, erase);
734 }
735 
736 template <typename clock_type>
737 void
739 {
740  auto now = clock_type::now();
741 
742  for (auto it = slots_.begin(); it != slots_.end();)
743  {
744  it->second.deleteIdlePeer(it->first);
745  if (now - it->second.getLastSelected() > MAX_UNSQUELCH_EXPIRE_DEFAULT)
746  {
747  JLOG(journal_.trace())
748  << "deleteIdlePeers: deleting idle slot " << Slice(it->first);
749  it = slots_.erase(it);
750  }
751  else
752  ++it;
753  }
754 }
755 
756 } // namespace reduce_relay
757 
758 } // namespace ripple
759 
760 #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:79
ripple::Application
Definition: Application.h:101
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::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:444
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:703
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:513
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:54
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:540
tuple
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:45
ripple::reduce_relay::Slots< ripple::UptimeClock >::time_point
typename ripple::UptimeClock ::time_point time_point
Definition: overlay/Slot.h:539
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:588
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:598
algorithm
ripple::reduce_relay::Slot::state_
SlotState state_
Definition: overlay/Slot.h:233
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:457
ripple::reduce_relay::Slots::slots_
hash_map< PublicKey, Slot< clock_type > > slots_
Definition: overlay/Slot.h:656
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:659
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:578
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:738
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
std::accumulate
T accumulate(T... args)
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:664
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:632
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:622
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::Slots::app_
Application & app_
Definition: overlay/Slot.h:658
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:670
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
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:608
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::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::Slots
Slots(Application &app, SquelchHandler const &handler)
Definition: overlay/Slot.h:552
ripple::reduce_relay::Slots::handler_
SquelchHandler const & handler_
Definition: overlay/Slot.h:657
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:730
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