rippled
reduce_relay_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright 2020 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 #include <ripple/basics/random.h>
20 #include <ripple/beast/unit_test.h>
21 #include <ripple/overlay/Message.h>
22 #include <ripple/overlay/Peer.h>
23 #include <ripple/overlay/Slot.h>
24 #include <ripple/overlay/impl/Handshake.h>
25 #include <ripple/protocol/SecretKey.h>
26 #include <ripple.pb.h>
27 #include <test/jtx/Env.h>
28 
29 #include <boost/thread.hpp>
30 
31 #include <numeric>
32 #include <optional>
33 
34 namespace ripple {
35 
36 namespace test {
37 
38 using namespace std::chrono;
39 
40 class Link;
41 
46 using SquelchCB =
48 using UnsquelchCB = std::function<void(PublicKey const&, PeerWPtr const&)>;
50 
51 static constexpr std::uint32_t MAX_PEERS = 10;
52 static constexpr std::uint32_t MAX_VALIDATORS = 10;
53 static constexpr std::uint32_t MAX_MESSAGES = 200000;
54 
58 class PeerPartial : public Peer
59 {
60 public:
61  virtual ~PeerPartial()
62  {
63  }
64  virtual void
65  onMessage(MessageSPtr const& m, SquelchCB f) = 0;
66  virtual void
67  onMessage(protocol::TMSquelch const& squelch) = 0;
68  void
69  send(protocol::TMSquelch const& squelch)
70  {
71  onMessage(squelch);
72  }
73 
74  // dummy implementation
75  void
76  send(std::shared_ptr<Message> const& m) override
77  {
78  }
80  getRemoteAddress() const override
81  {
82  return {};
83  }
84  void
85  charge(Resource::Charge const& fee) override
86  {
87  }
88  bool
89  cluster() const override
90  {
91  return false;
92  }
93  bool
94  isHighLatency() const override
95  {
96  return false;
97  }
98  int
99  getScore(bool) const override
100  {
101  return 0;
102  }
103  PublicKey const&
104  getNodePublic() const override
105  {
106  static PublicKey key{};
107  return key;
108  }
110  json() override
111  {
112  return {};
113  }
114  bool
116  {
117  return false;
118  }
120  publisherListSequence(PublicKey const&) const override
121  {
122  return {};
123  }
124  void
126  {
127  }
128  uint256 const&
129  getClosedLedgerHash() const override
130  {
131  static uint256 hash{};
132  return hash;
133  }
134  bool
135  hasLedger(uint256 const& hash, std::uint32_t seq) const override
136  {
137  return false;
138  }
139  void
140  ledgerRange(std::uint32_t& minSeq, std::uint32_t& maxSeq) const override
141  {
142  }
143  bool
144  hasTxSet(uint256 const& hash) const override
145  {
146  return false;
147  }
148  void
149  cycleStatus() override
150  {
151  }
152  bool
153  hasRange(std::uint32_t uMin, std::uint32_t uMax) override
154  {
155  return false;
156  }
157  bool
158  compressionEnabled() const override
159  {
160  return false;
161  }
162  bool
163  txReduceRelayEnabled() const override
164  {
165  return false;
166  }
167  void
168  sendTxQueue() override
169  {
170  }
171  void
172  addTxQueue(const uint256&) override
173  {
174  }
175  void
176  removeTxQueue(const uint256&) override
177  {
178  }
179 };
180 
183 {
184 public:
185  typedef uint64_t rep;
189  inline static const bool is_steady = false;
190 
191  static void
192  advance(duration d) noexcept
193  {
194  now_ += d;
195  }
196 
197  static void
199  {
200  now_ += randDuration(min, max);
201  }
202 
203  static void
204  reset() noexcept
205  {
206  now_ = time_point(seconds(0));
207  }
208 
209  static time_point
210  now() noexcept
211  {
212  return now_;
213  }
214 
215  static duration
217  {
218  return duration(milliseconds(rand_int(min.count(), max.count())));
219  }
220 
221  explicit ManualClock() = default;
222 
223 private:
224  inline static time_point now_ = time_point(seconds(0));
225 };
226 
228 class Overlay
229 {
230 public:
231  Overlay() = default;
232  virtual ~Overlay() = default;
233 
234  virtual void
235  updateSlotAndSquelch(
236  uint256 const& key,
237  PublicKey const& validator,
238  Peer::id_t id,
239  SquelchCB f,
240  protocol::MessageType type = protocol::mtVALIDATION) = 0;
241 
242  virtual void deleteIdlePeers(UnsquelchCB) = 0;
243 
244  virtual void deletePeer(Peer::id_t, UnsquelchCB) = 0;
245 };
246 
247 class Validator;
248 
252 class Link
253 {
255 
256 public:
258  Validator& validator,
259  PeerSPtr peer,
260  Latency const& latency = {milliseconds(5), milliseconds(15)})
261  : validator_(validator), peer_(peer), latency_(latency), up_(true)
262  {
263  auto sp = peer_.lock();
264  assert(sp);
265  }
266  ~Link() = default;
267  void
269  {
270  if (!up_)
271  return;
272  auto sp = peer_.lock();
273  assert(sp);
274  auto peer = std::dynamic_pointer_cast<PeerPartial>(sp);
275  peer->onMessage(m, f);
276  }
277  Validator&
279  {
280  return validator_;
281  }
282  void
283  up(bool linkUp)
284  {
285  up_ = linkUp;
286  }
287  Peer::id_t
289  {
290  auto p = peer_.lock();
291  assert(p);
292  return p->id();
293  }
294  PeerSPtr
296  {
297  auto p = peer_.lock();
298  assert(p);
299  return p;
300  }
301 
302 private:
306  bool up_;
307 };
308 
311 {
313 
314 public:
316  {
317  pkey_ = std::get<0>(randomKeyPair(KeyType::ed25519));
318  protocol::TMValidation v;
319  v.set_validation("validation");
320  message_ = std::make_shared<Message>(v, protocol::mtVALIDATION, pkey_);
321  id_ = sid_++;
322  }
323  Validator(Validator const&) = default;
324  Validator(Validator&&) = default;
325  Validator&
326  operator=(Validator const&) = default;
327  Validator&
328  operator=(Validator&&) = default;
330  {
331  clear();
332  }
333 
334  void
336  {
337  links_.clear();
338  }
339 
340  static void
342  {
343  sid_ = 0;
344  }
345 
346  PublicKey const&
347  key()
348  {
349  return pkey_;
350  }
351 
352  operator PublicKey() const
353  {
354  return pkey_;
355  }
356 
357  void
359  {
360  links_.emplace(
361  std::make_pair(peer->id(), std::make_shared<Link>(*this, peer)));
362  }
363 
364  void
366  {
367  links_.erase(id);
368  }
369 
370  void
372  {
373  for (auto id : peers)
374  {
375  assert(links_.find(id) != links_.end());
376  f(*links_[id], message_);
377  }
378  }
379 
380  void
381  for_links(LinkIterCB f, bool simulateSlow = false)
382  {
385  links_.begin(), links_.end(), std::back_inserter(v), [](auto& kv) {
386  return kv.second;
387  });
389  std::mt19937 g(d());
390  std::shuffle(v.begin(), v.end(), g);
391 
392  for (auto& link : v)
393  {
394  f(*link, message_);
395  }
396  }
397 
399  void
401  {
402  for_links(peers, [&](Link& link, MessageSPtr m) { link.send(m, f); });
403  }
404 
406  void
408  {
409  for_links([&](Link& link, MessageSPtr m) { link.send(m, f); });
410  }
411 
414  {
415  return message_;
416  }
417 
419  id()
420  {
421  return id_;
422  }
423 
424  void
426  {
427  auto it = links_.find(id);
428  assert(it != links_.end());
429  it->second->up(true);
430  }
431 
432  void
434  {
435  auto it = links_.find(id);
436  assert(it != links_.end());
437  it->second->up(false);
438  }
439 
440 private:
442  PublicKey pkey_{};
443  MessageSPtr message_ = nullptr;
444  inline static std::uint16_t sid_ = 0;
445  std::uint16_t id_ = 0;
446 };
447 
448 class PeerSim : public PeerPartial, public std::enable_shared_from_this<PeerSim>
449 {
450 public:
451  using id_t = Peer::id_t;
452  PeerSim(Overlay& overlay, beast::Journal journal)
453  : overlay_(overlay), squelch_(journal)
454  {
455  id_ = sid_++;
456  }
457 
458  ~PeerSim() = default;
459 
460  id_t
461  id() const override
462  {
463  return id_;
464  }
465 
466  static void
468  {
469  sid_ = 0;
470  }
471 
473  void
474  onMessage(MessageSPtr const& m, SquelchCB f) override
475  {
476  auto validator = m->getValidatorKey();
477  assert(validator);
478  if (!squelch_.expireSquelch(*validator))
479  return;
480 
481  overlay_.updateSlotAndSquelch({}, *validator, id(), f);
482  }
483 
485  virtual void
486  onMessage(protocol::TMSquelch const& squelch) override
487  {
488  auto validator = squelch.validatorpubkey();
489  PublicKey key(Slice(validator.data(), validator.size()));
490  if (squelch.squelch())
491  squelch_.addSquelch(
492  key, std::chrono::seconds{squelch.squelchduration()});
493  else
494  squelch_.removeSquelch(key);
495  }
496 
497 private:
498  inline static id_t sid_ = 0;
502 };
503 
505 {
507 
508 public:
509  using id_t = Peer::id_t;
511  OverlaySim(Application& app) : slots_(app.logs(), *this), logs_(app.logs())
512  {
513  }
514 
515  ~OverlaySim() = default;
516 
517  void
519  {
520  peers_.clear();
522  slots_.deleteIdlePeers();
523  }
524 
526  inState(PublicKey const& validator, reduce_relay::PeerState state)
527  {
528  auto res = slots_.inState(validator, state);
529  return res ? *res : 0;
530  }
531 
532  void
534  uint256 const& key,
535  PublicKey const& validator,
536  Peer::id_t id,
537  SquelchCB f,
538  protocol::MessageType type = protocol::mtVALIDATION) override
539  {
540  squelch_ = f;
541  slots_.updateSlotAndSquelch(key, validator, id, type);
542  }
543 
544  void
545  deletePeer(id_t id, UnsquelchCB f) override
546  {
547  unsquelch_ = f;
548  slots_.deletePeer(id, true);
549  }
550 
551  void
553  {
554  unsquelch_ = f;
555  slots_.deleteIdlePeers();
556  }
557 
558  PeerSPtr
559  addPeer(bool useCache = true)
560  {
561  PeerSPtr peer{};
562  Peer::id_t id;
563  if (peersCache_.empty() || !useCache)
564  {
565  peer = std::make_shared<PeerSim>(*this, logs_.journal("Squelch"));
566  id = peer->id();
567  }
568  else
569  {
570  auto it = peersCache_.begin();
571  peer = it->second;
572  id = it->first;
573  peersCache_.erase(it);
574  }
575  peers_.emplace(std::make_pair(id, peer));
576  return peer;
577  }
578 
579  void
580  deletePeer(Peer::id_t id, bool useCache = true)
581  {
582  auto it = peers_.find(id);
583  assert(it != peers_.end());
584  deletePeer(id, [&](PublicKey const&, PeerWPtr) {});
585  if (useCache)
586  peersCache_.emplace(std::make_pair(id, it->second));
587  peers_.erase(it);
588  }
589 
590  void
592  {
593  while (!peers_.empty())
594  deletePeer(peers_.begin()->first);
595  while (!peersCache_.empty())
596  addPeer();
597  }
598 
601  {
602  if (peers_.empty())
603  return {};
604 
605  std::uint8_t maxId = 0;
606 
607  for (auto& [id, _] : peers_)
608  {
609  (void)_;
610  if (id > maxId)
611  maxId = id;
612  }
613 
614  deletePeer(maxId, false);
615 
616  return maxId;
617  }
618 
619  bool
620  isCountingState(PublicKey const& validator)
621  {
622  return slots_.inState(validator, reduce_relay::SlotState::Counting);
623  }
624 
626  getSelected(PublicKey const& validator)
627  {
628  return slots_.getSelected(validator);
629  }
630 
631  bool
632  isSelected(PublicKey const& validator, Peer::id_t peer)
633  {
634  auto selected = slots_.getSelected(validator);
635  return selected.find(peer) != selected.end();
636  }
637 
638  id_t
639  getSelectedPeer(PublicKey const& validator)
640  {
641  auto selected = slots_.getSelected(validator);
642  assert(selected.size());
643  return *selected.begin();
644  }
645 
647  id_t,
648  std::tuple<
652  std::uint32_t>>
653  getPeers(PublicKey const& validator)
654  {
655  return slots_.getPeers(validator);
656  }
657 
659  getNumPeers() const
660  {
661  return peers_.size();
662  }
663 
664 private:
665  void
667  PublicKey const& validator,
668  Peer::id_t id,
669  std::uint32_t squelchDuration) const override
670  {
671  if (auto it = peers_.find(id); it != peers_.end())
672  squelch_(validator, it->second, squelchDuration);
673  }
674  void
675  unsquelch(PublicKey const& validator, Peer::id_t id) const override
676  {
677  if (auto it = peers_.find(id); it != peers_.end())
678  unsquelch_(validator, it->second);
679  }
686 };
687 
688 class Network
689 {
690 public:
691  Network(Application& app) : overlay_(app)
692  {
693  init();
694  }
695 
696  void
698  {
699  validators_.resize(MAX_VALIDATORS);
700  for (int p = 0; p < MAX_PEERS; p++)
701  {
702  auto peer = overlay_.addPeer();
703  for (auto& v : validators_)
704  v.addPeer(peer);
705  }
706  }
707 
708  ~Network() = default;
709 
710  void
712  {
713  validators_.clear();
714  overlay_.clear();
717  init();
718  }
719 
720  Peer::id_t
722  {
723  auto peer = overlay_.addPeer();
724  for (auto& v : validators_)
725  v.addPeer(peer);
726  return peer->id();
727  }
728 
729  void
731  {
732  auto id = overlay_.deleteLastPeer();
733 
734  if (!id)
735  return;
736 
737  for (auto& validator : validators_)
738  validator.deletePeer(*id);
739  }
740 
741  void
743  {
744  while (overlay_.getNumPeers() > MAX_PEERS)
745  deleteLastPeer();
746  }
747 
748  Validator&
750  {
751  assert(v < validators_.size());
752  return validators_[v];
753  }
754 
755  OverlaySim&
757  {
758  return overlay_;
759  }
760 
761  void
762  enableLink(std::uint16_t validatorId, Peer::id_t peer, bool enable)
763  {
764  auto it =
765  std::find_if(validators_.begin(), validators_.end(), [&](auto& v) {
766  return v.id() == validatorId;
767  });
768  assert(it != validators_.end());
769  if (enable)
770  it->linkUp(peer);
771  else
772  it->linkDown(peer);
773  }
774 
775  void
777  {
778  // Send unsquelch to the Peer on all links. This way when
779  // the Peer "reconnects" it starts sending messages on the link.
780  // We expect that if a Peer disconnects and then reconnects, it's
781  // unsquelched.
782  protocol::TMSquelch squelch;
783  squelch.set_squelch(false);
784  for (auto& v : validators_)
785  {
786  PublicKey key = v;
787  squelch.clear_validatorpubkey();
788  squelch.set_validatorpubkey(key.data(), key.size());
789  v.for_links({peer}, [&](Link& l, MessageSPtr) {
790  std::dynamic_pointer_cast<PeerSim>(l.getPeer())->send(squelch);
791  });
792  }
793  }
794 
795  void
797  std::uint32_t min,
798  std::uint32_t max,
799  std::function<void(std::uint32_t)> f)
800  {
801  auto size = max - min;
803  std::iota(s.begin(), s.end(), min);
805  std::mt19937 g(d());
806  std::shuffle(s.begin(), s.end(), g);
807  for (auto v : s)
808  f(v);
809  }
810 
811  void
813  LinkIterCB link,
814  std::uint16_t nValidators = MAX_VALIDATORS,
815  std::uint32_t nMessages = MAX_MESSAGES,
816  bool purge = true,
817  bool resetClock = true)
818  {
819  if (resetClock)
821 
822  if (purge)
823  {
824  purgePeers();
825  overlay_.resetPeers();
826  }
827 
828  for (int m = 0; m < nMessages; ++m)
829  {
831  for_rand(0, nValidators, [&](std::uint32_t v) {
832  validators_[v].for_links(link);
833  });
834  }
835  }
836 
838  bool
840  {
841  for (auto& v : validators_)
842  {
843  if (overlay_.isSelected(v, id))
844  return true;
845  }
846  return false;
847  }
848 
853  bool
855  {
856  for (auto& v : validators_)
857  {
858  if (!overlay_.isSelected(v, peer))
859  continue;
860  auto peers = overlay_.getPeers(v);
861  for (auto& [_, v] : peers)
862  {
863  (void)_;
864  if (std::get<reduce_relay::PeerState>(v) ==
866  return false;
867  }
868  }
869  return true;
870  }
871 
872 private:
875 };
876 
877 class reduce_relay_test : public beast::unit_test::suite
878 {
880  using id_t = Peer::id_t;
881 
882 protected:
883  void
884  printPeers(const std::string& msg, std::uint16_t validator = 0)
885  {
886  auto peers = network_.overlay().getPeers(network_.validator(validator));
887  std::cout << msg << " "
888  << "num peers " << (int)network_.overlay().getNumPeers()
889  << std::endl;
890  for (auto& [k, v] : peers)
891  std::cout << k << ":" << (int)std::get<reduce_relay::PeerState>(v)
892  << " ";
893  std::cout << std::endl;
894  }
895 
897  Peer::id_t
899  PublicKey const& validator,
900  PeerWPtr const& peerPtr,
902  {
903  protocol::TMSquelch squelch;
904  bool res = duration ? true : false;
905  squelch.set_squelch(res);
906  squelch.set_validatorpubkey(validator.data(), validator.size());
907  if (res)
908  squelch.set_squelchduration(*duration);
909  auto sp = peerPtr.lock();
910  assert(sp);
911  std::dynamic_pointer_cast<PeerSim>(sp)->send(squelch);
912  return sp->id();
913  }
914 
915  enum State { On, Off, WaitReset };
916  enum EventType { LinkDown = 0, PeerDisconnected = 1 };
917  // Link down or Peer disconnect event
918  // TBD - add new peer event
919  // TBD - add overlapping type of events at any
920  // time in any quantity
921  struct Event
922  {
923  State state_ = State::Off;
924  std::uint32_t cnt_ = 0;
925  std::uint32_t handledCnt_ = 0;
926  bool isSelected_ = false;
931  bool handled_ = false;
932  };
933 
937  void
938  random(bool log)
939  {
941  {LinkDown, {}}, {PeerDisconnected, {}}};
943 
944  network_.reset();
945  network_.propagate([&](Link& link, MessageSPtr m) {
946  auto& validator = link.validator();
947  auto now = ManualClock::now();
948 
949  bool squelched = false;
950  std::stringstream str;
951 
952  link.send(
953  m,
954  [&](PublicKey const& key,
955  PeerWPtr const& peerPtr,
957  assert(key == validator);
958  auto p = sendSquelch(key, peerPtr, duration);
959  squelched = true;
960  str << p << " ";
961  });
962 
963  if (squelched)
964  {
965  auto selected = network_.overlay().getSelected(validator);
966  str << " selected: ";
967  for (auto s : selected)
968  str << s << " ";
969  if (log)
970  std::cout
971  << (double)reduce_relay::epoch<milliseconds>(now)
972  .count() /
973  1000.
974  << " random, squelched, validator: " << validator.id()
975  << " peers: " << str.str() << std::endl;
976  auto countingState =
977  network_.overlay().isCountingState(validator);
978  BEAST_EXPECT(
979  countingState == false &&
980  selected.size() == reduce_relay::MAX_SELECTED_PEERS);
981  }
982 
983  // Trigger Link Down or Peer Disconnect event
984  // Only one Link Down at a time
985  if (events[EventType::LinkDown].state_ == State::Off)
986  {
987  auto update = [&](EventType event) {
988  events[event].cnt_++;
989  events[event].validator_ = validator.id();
990  events[event].key_ = validator;
991  events[event].peer_ = link.peerId();
992  events[event].state_ = State::On;
993  events[event].time_ = now;
994  if (event == EventType::LinkDown)
995  {
996  network_.enableLink(
997  validator.id(), link.peerId(), false);
998  events[event].isSelected_ =
999  network_.overlay().isSelected(
1000  validator, link.peerId());
1001  }
1002  else
1003  events[event].isSelected_ =
1004  network_.isSelected(link.peerId());
1005  };
1006  auto r = rand_int(0, 1000);
1007  if (r == (int)EventType::LinkDown ||
1008  r == (int)EventType::PeerDisconnected)
1009  {
1010  update(static_cast<EventType>(r));
1011  }
1012  }
1013 
1014  if (events[EventType::PeerDisconnected].state_ == State::On)
1015  {
1016  auto& event = events[EventType::PeerDisconnected];
1017  bool allCounting = network_.allCounting(event.peer_);
1018  network_.overlay().deletePeer(
1019  event.peer_,
1020  [&](PublicKey const& v, PeerWPtr const& peerPtr) {
1021  if (event.isSelected_)
1022  sendSquelch(v, peerPtr, {});
1023  event.handled_ = true;
1024  });
1025  // Should only be unsquelched if the peer is in Selected state
1026  // If in Selected state it's possible unsquelching didn't
1027  // take place because there is no peers in Squelched state in
1028  // any of the slots where the peer is in Selected state
1029  // (allCounting is true)
1030  bool handled =
1031  (event.isSelected_ == false && !event.handled_) ||
1032  (event.isSelected_ == true &&
1033  (event.handled_ || allCounting));
1034  BEAST_EXPECT(handled);
1035  event.state_ = State::Off;
1036  event.isSelected_ = false;
1037  event.handledCnt_ += handled;
1038  event.handled_ = false;
1039  network_.onDisconnectPeer(event.peer_);
1040  }
1041 
1042  auto& event = events[EventType::LinkDown];
1043  // Check every sec for idled peers. Idled peers are
1044  // created by Link Down event.
1045  if (now - lastCheck > milliseconds(1000))
1046  {
1047  lastCheck = now;
1048  // Check if Link Down event must be handled by
1049  // deleteIdlePeer(): 1) the peer is in Selected state;
1050  // 2) the peer has not received any messages for IDLED time;
1051  // 3) there are peers in Squelched state in the slot.
1052  // 4) peer is in Slot's peers_ (if not then it is deleted
1053  // by Slots::deleteIdlePeers())
1054  bool mustHandle = false;
1055  if (event.state_ == State::On)
1056  {
1057  event.isSelected_ =
1058  network_.overlay().isSelected(event.key_, event.peer_);
1059  auto peers = network_.overlay().getPeers(event.key_);
1060  auto d = reduce_relay::epoch<milliseconds>(now).count() -
1061  std::get<3>(peers[event.peer_]);
1062  mustHandle = event.isSelected_ &&
1064  network_.overlay().inState(
1065  event.key_, reduce_relay::PeerState::Squelched) >
1066  0 &&
1067  peers.find(event.peer_) != peers.end();
1068  }
1069  network_.overlay().deleteIdlePeers(
1070  [&](PublicKey const& v, PeerWPtr const& ptr) {
1071  event.handled_ = true;
1072  if (mustHandle && v == event.key_)
1073  {
1074  event.state_ = State::WaitReset;
1075  sendSquelch(validator, ptr, {});
1076  }
1077  });
1078  bool handled =
1079  (event.handled_ && event.state_ == State::WaitReset) ||
1080  (!event.handled_ && !mustHandle);
1081  BEAST_EXPECT(handled);
1082  }
1083  if (event.state_ == State::WaitReset ||
1084  (event.state_ == State::On &&
1085  (now - event.time_ > (reduce_relay::IDLED + seconds(2)))))
1086  {
1087  bool handled =
1088  event.state_ == State::WaitReset || !event.handled_;
1089  BEAST_EXPECT(handled);
1090  event.state_ = State::Off;
1091  event.isSelected_ = false;
1092  event.handledCnt_ += handled;
1093  event.handled_ = false;
1094  network_.enableLink(event.validator_, event.peer_, true);
1095  }
1096  });
1097 
1098  auto& down = events[EventType::LinkDown];
1099  auto& disconnected = events[EventType::PeerDisconnected];
1100  // It's possible the last Down Link event is not handled
1101  BEAST_EXPECT(down.handledCnt_ >= down.cnt_ - 1);
1102  // All Peer Disconnect events must be handled
1103  BEAST_EXPECT(disconnected.cnt_ == disconnected.handledCnt_);
1104  if (log)
1105  std::cout << "link down count: " << down.cnt_ << "/"
1106  << down.handledCnt_
1107  << " peer disconnect count: " << disconnected.cnt_ << "/"
1108  << disconnected.handledCnt_;
1109  }
1110 
1111  bool
1112  checkCounting(PublicKey const& validator, bool isCountingState)
1113  {
1114  auto countingState = network_.overlay().isCountingState(validator);
1115  BEAST_EXPECT(countingState == isCountingState);
1116  return countingState == isCountingState;
1117  }
1118 
1119  void
1120  doTest(const std::string& msg, bool log, std::function<void(bool)> f)
1121  {
1122  testcase(msg);
1123  f(log);
1124  }
1125 
1131  void
1133  {
1134  doTest("Initial Round", log, [this](bool log) {
1135  BEAST_EXPECT(propagateAndSquelch(log));
1136  });
1137  }
1138 
1142  void
1144  {
1145  doTest("Peer Unsquelched Too Soon", log, [this](bool log) {
1146  BEAST_EXPECT(propagateNoSquelch(log, 1, false, false, false));
1147  });
1148  }
1149 
1153  void
1155  {
1157  doTest("Peer Unsquelched", log, [this](bool log) {
1158  BEAST_EXPECT(propagateNoSquelch(log, 2, true, true, false));
1159  });
1160  }
1161 
1163  bool
1164  propagateAndSquelch(bool log, bool purge = true, bool resetClock = true)
1165  {
1166  int n = 0;
1167  network_.propagate(
1168  [&](Link& link, MessageSPtr message) {
1169  std::uint16_t squelched = 0;
1170  link.send(
1171  message,
1172  [&](PublicKey const& key,
1173  PeerWPtr const& peerPtr,
1175  squelched++;
1176  sendSquelch(key, peerPtr, duration);
1177  });
1178  if (squelched)
1179  {
1180  BEAST_EXPECT(
1181  squelched ==
1183  n++;
1184  }
1185  },
1186  1,
1188  purge,
1189  resetClock);
1190  auto selected = network_.overlay().getSelected(network_.validator(0));
1191  BEAST_EXPECT(selected.size() == reduce_relay::MAX_SELECTED_PEERS);
1192  BEAST_EXPECT(n == 1); // only one selection round
1193  auto res = checkCounting(network_.validator(0), false);
1194  BEAST_EXPECT(res);
1195  return n == 1 && res;
1196  }
1197 
1199  bool
1201  bool log,
1202  std::uint16_t nMessages,
1203  bool countingState,
1204  bool purge = true,
1205  bool resetClock = true)
1206  {
1207  bool squelched = false;
1208  network_.propagate(
1209  [&](Link& link, MessageSPtr message) {
1210  link.send(
1211  message,
1212  [&](PublicKey const& key,
1213  PeerWPtr const& peerPtr,
1215  squelched = true;
1216  BEAST_EXPECT(false);
1217  });
1218  },
1219  1,
1220  nMessages,
1221  purge,
1222  resetClock);
1223  auto res = checkCounting(network_.validator(0), countingState);
1224  return !squelched && res;
1225  }
1226 
1230  void
1231  testNewPeer(bool log)
1232  {
1233  doTest("New Peer", log, [this](bool log) {
1234  BEAST_EXPECT(propagateAndSquelch(log, true, false));
1235  network_.addPeer();
1236  BEAST_EXPECT(propagateNoSquelch(log, 1, true, false, false));
1237  });
1238  }
1239 
1242  void
1244  {
1245  doTest("Selected Peer Disconnects", log, [this](bool log) {
1247  BEAST_EXPECT(propagateAndSquelch(log, true, false));
1248  auto id = network_.overlay().getSelectedPeer(network_.validator(0));
1249  std::uint16_t unsquelched = 0;
1250  network_.overlay().deletePeer(
1251  id, [&](PublicKey const& key, PeerWPtr const& peer) {
1252  unsquelched++;
1253  });
1254  BEAST_EXPECT(
1255  unsquelched == MAX_PEERS - reduce_relay::MAX_SELECTED_PEERS);
1256  BEAST_EXPECT(checkCounting(network_.validator(0), true));
1257  });
1258  }
1259 
1262  void
1264  {
1265  doTest("Selected Peer Stops Relaying", log, [this](bool log) {
1267  BEAST_EXPECT(propagateAndSquelch(log, true, false));
1269  std::uint16_t unsquelched = 0;
1270  network_.overlay().deleteIdlePeers(
1271  [&](PublicKey const& key, PeerWPtr const& peer) {
1272  unsquelched++;
1273  });
1274  auto peers = network_.overlay().getPeers(network_.validator(0));
1275  BEAST_EXPECT(
1276  unsquelched == MAX_PEERS - reduce_relay::MAX_SELECTED_PEERS);
1277  BEAST_EXPECT(checkCounting(network_.validator(0), true));
1278  });
1279  }
1280 
1283  void
1285  {
1286  doTest("Squelched Peer Disconnects", log, [this](bool log) {
1288  BEAST_EXPECT(propagateAndSquelch(log, true, false));
1289  auto peers = network_.overlay().getPeers(network_.validator(0));
1290  auto it = std::find_if(peers.begin(), peers.end(), [&](auto it) {
1291  return std::get<reduce_relay::PeerState>(it.second) ==
1292  reduce_relay::PeerState::Squelched;
1293  });
1294  assert(it != peers.end());
1295  std::uint16_t unsquelched = 0;
1296  network_.overlay().deletePeer(
1297  it->first, [&](PublicKey const& key, PeerWPtr const& peer) {
1298  unsquelched++;
1299  });
1300  BEAST_EXPECT(unsquelched == 0);
1301  BEAST_EXPECT(checkCounting(network_.validator(0), false));
1302  });
1303  }
1304 
1305  void
1306  testConfig(bool log)
1307  {
1308  doTest("Config Test", log, [&](bool log) {
1309  Config c;
1310 
1311  std::string toLoad(R"rippleConfig(
1312 [reduce_relay]
1313 vp_enable=1
1314 vp_squelch=1
1315 )rippleConfig");
1316 
1317  c.loadFromString(toLoad);
1318  BEAST_EXPECT(c.VP_REDUCE_RELAY_ENABLE == true);
1319  BEAST_EXPECT(c.VP_REDUCE_RELAY_SQUELCH == true);
1320 
1321  Config c1;
1322 
1323  toLoad = (R"rippleConfig(
1324 [reduce_relay]
1325 vp_enable=0
1326 vp_squelch=0
1327 )rippleConfig");
1328 
1329  c1.loadFromString(toLoad);
1330  BEAST_EXPECT(c1.VP_REDUCE_RELAY_ENABLE == false);
1331  BEAST_EXPECT(c1.VP_REDUCE_RELAY_SQUELCH == false);
1332 
1333  Config c2;
1334 
1335  toLoad = R"rippleConfig(
1336 [reduce_relay]
1337 vp_enabled=1
1338 vp_squelched=1
1339 )rippleConfig";
1340 
1341  c2.loadFromString(toLoad);
1342  BEAST_EXPECT(c2.VP_REDUCE_RELAY_ENABLE == false);
1343  BEAST_EXPECT(c2.VP_REDUCE_RELAY_SQUELCH == false);
1344  });
1345  }
1346 
1347  void
1349  {
1350  doTest("Duplicate Message", log, [&](bool log) {
1351  network_.reset();
1352  // update message count for the same peer/validator
1353  std::int16_t nMessages = 5;
1354  for (int i = 0; i < nMessages; i++)
1355  {
1356  uint256 key(i);
1357  network_.overlay().updateSlotAndSquelch(
1358  key,
1359  network_.validator(0),
1360  0,
1361  [&](PublicKey const&, PeerWPtr, std::uint32_t) {});
1362  }
1363  auto peers = network_.overlay().getPeers(network_.validator(0));
1364  // first message changes Slot state to Counting and is not counted,
1365  // hence '-1'.
1366  BEAST_EXPECT(std::get<1>(peers[0]) == (nMessages - 1));
1367  // add duplicate
1368  uint256 key(nMessages - 1);
1369  network_.overlay().updateSlotAndSquelch(
1370  key,
1371  network_.validator(0),
1372  0,
1373  [&](PublicKey const&, PeerWPtr, std::uint32_t) {});
1374  // confirm the same number of messages
1375  peers = network_.overlay().getPeers(network_.validator(0));
1376  BEAST_EXPECT(std::get<1>(peers[0]) == (nMessages - 1));
1377  // advance the clock
1379  network_.overlay().updateSlotAndSquelch(
1380  key,
1381  network_.validator(0),
1382  0,
1383  [&](PublicKey const&, PeerWPtr, std::uint32_t) {});
1384  peers = network_.overlay().getPeers(network_.validator(0));
1385  // confirm message number increased
1386  BEAST_EXPECT(std::get<1>(peers[0]) == nMessages);
1387  });
1388  }
1389 
1391  {
1392  Handler() : maxDuration_(0)
1393  {
1394  }
1395  void
1397  const override
1398  {
1399  if (duration > maxDuration_)
1400  maxDuration_ = duration;
1401  }
1402  void
1403  unsquelch(PublicKey const&, Peer::id_t) const override
1404  {
1405  }
1406  mutable int maxDuration_;
1407  };
1408 
1409  void
1411  {
1412  doTest("Random Squelch", l, [&](bool l) {
1414  Handler handler;
1415 
1416  auto run = [&](int npeers) {
1417  handler.maxDuration_ = 0;
1419  env_.app().logs(), handler);
1420  // 1st message from a new peer switches the slot
1421  // to counting state and resets the counts of all peers +
1422  // MAX_MESSAGE_THRESHOLD + 1 messages to reach the threshold
1423  // and switch the slot's state to peer selection.
1424  for (int m = 1; m <= reduce_relay::MAX_MESSAGE_THRESHOLD + 2;
1425  m++)
1426  {
1427  for (int peer = 0; peer < npeers; peer++)
1428  {
1429  // make unique message hash to make the
1430  // slot's internal hash router accept the message
1431  std::uint64_t mid = m * 1000 + peer;
1432  uint256 const message{mid};
1433  slots.updateSlotAndSquelch(
1434  message,
1435  validator,
1436  peer,
1437  protocol::MessageType::mtVALIDATION);
1438  }
1439  }
1440  // make Slot's internal hash router expire all messages
1442  };
1443 
1444  using namespace reduce_relay;
1445  // expect max duration less than MAX_UNSQUELCH_EXPIRE_DEFAULT with
1446  // less than or equal to 60 peers
1447  run(20);
1448  BEAST_EXPECT(
1449  handler.maxDuration_ >= MIN_UNSQUELCH_EXPIRE.count() &&
1450  handler.maxDuration_ <= MAX_UNSQUELCH_EXPIRE_DEFAULT.count());
1451  run(60);
1452  BEAST_EXPECT(
1453  handler.maxDuration_ >= MIN_UNSQUELCH_EXPIRE.count() &&
1454  handler.maxDuration_ <= MAX_UNSQUELCH_EXPIRE_DEFAULT.count());
1455  // expect max duration greater than MIN_UNSQUELCH_EXPIRE and less
1456  // than MAX_UNSQUELCH_EXPIRE_PEERS with peers greater than 60
1457  // and less than 360
1458  run(350);
1459  // can't make this condition stronger. squelch
1460  // duration is probabilistic and max condition may still fail.
1461  // log when the value is low
1462  BEAST_EXPECT(
1463  handler.maxDuration_ >= MIN_UNSQUELCH_EXPIRE.count() &&
1464  handler.maxDuration_ <= MAX_UNSQUELCH_EXPIRE_PEERS.count());
1465  using namespace beast::unit_test::detail;
1466  if (handler.maxDuration_ <= MAX_UNSQUELCH_EXPIRE_DEFAULT.count())
1467  log << make_reason(
1468  "warning: squelch duration is low",
1469  __FILE__,
1470  __LINE__)
1471  << std::endl
1472  << std::flush;
1473  // more than 400 is still less than MAX_UNSQUELCH_EXPIRE_PEERS
1474  run(400);
1475  BEAST_EXPECT(
1476  handler.maxDuration_ >= MIN_UNSQUELCH_EXPIRE.count() &&
1477  handler.maxDuration_ <= MAX_UNSQUELCH_EXPIRE_PEERS.count());
1478  if (handler.maxDuration_ <= MAX_UNSQUELCH_EXPIRE_DEFAULT.count())
1479  log << make_reason(
1480  "warning: squelch duration is low",
1481  __FILE__,
1482  __LINE__)
1483  << std::endl
1484  << std::flush;
1485  });
1486  }
1487 
1488  void
1489  testHandshake(bool log)
1490  {
1491  doTest("Handshake", log, [&](bool log) {
1492  auto setEnv = [&](bool enable) {
1493  Config c;
1494  std::stringstream str;
1495  str << "[reduce_relay]\n"
1496  << "vp_enable=" << enable << "\n"
1497  << "vp_squelch=" << enable << "\n"
1498  << "[compression]\n"
1499  << "1\n";
1500  c.loadFromString(str.str());
1501  env_.app().config().VP_REDUCE_RELAY_ENABLE =
1503  env_.app().config().VP_REDUCE_RELAY_SQUELCH =
1505  env_.app().config().COMPRESSION = c.COMPRESSION;
1506  };
1507  auto handshake = [&](int outboundEnable, int inboundEnable) {
1508  beast::IP::Address addr =
1509  boost::asio::ip::address::from_string("172.1.1.100");
1510 
1511  setEnv(outboundEnable);
1512  auto request = ripple::makeRequest(
1513  true,
1514  env_.app().config().COMPRESSION,
1515  false,
1516  env_.app().config().TX_REDUCE_RELAY_ENABLE,
1517  env_.app().config().VP_REDUCE_RELAY_ENABLE);
1518  http_request_type http_request;
1519  http_request.version(request.version());
1520  http_request.base() = request.base();
1521  // feature enabled on the peer's connection only if both sides
1522  // are enabled
1523  auto const peerEnabled = inboundEnable && outboundEnable;
1524  // inbound is enabled if the request's header has the feature
1525  // enabled and the peer's configuration is enabled
1526  auto const inboundEnabled = peerFeatureEnabled(
1527  http_request, FEATURE_VPRR, inboundEnable);
1528  BEAST_EXPECT(!(peerEnabled ^ inboundEnabled));
1529 
1530  setEnv(inboundEnable);
1531  auto http_resp = ripple::makeResponse(
1532  true,
1533  http_request,
1534  addr,
1535  addr,
1536  uint256{1},
1537  1,
1538  {1, 0},
1539  env_.app());
1540  // outbound is enabled if the response's header has the feature
1541  // enabled and the peer's configuration is enabled
1542  auto const outboundEnabled =
1543  peerFeatureEnabled(http_resp, FEATURE_VPRR, outboundEnable);
1544  BEAST_EXPECT(!(peerEnabled ^ outboundEnabled));
1545  };
1546  handshake(1, 1);
1547  handshake(1, 0);
1548  handshake(0, 1);
1549  handshake(0, 0);
1550  });
1551  }
1552 
1555 
1556 public:
1557  reduce_relay_test() : env_(*this), network_(env_.app())
1558  {
1559  }
1560 
1561  void
1562  run() override
1563  {
1564  bool log = false;
1565  testConfig(log);
1566  testInitialRound(log);
1567  testPeerUnsquelchedTooSoon(log);
1568  testPeerUnsquelched(log);
1569  testNewPeer(log);
1570  testSquelchedPeerDisconnects(log);
1571  testSelectedPeerDisconnects(log);
1572  testSelectedPeerStopsRelaying(log);
1573  testInternalHashRouter(log);
1574  testRandomSquelch(log);
1575  testHandshake(log);
1576  }
1577 };
1578 
1580 {
1581  void
1582  testRandom(bool log)
1583  {
1584  doTest("Random Test", log, [&](bool log) { random(log); });
1585  }
1586 
1587  void
1588  run() override
1589  {
1590  bool log = false;
1591  testRandom(log);
1592  }
1593 };
1594 
1595 BEAST_DEFINE_TESTSUITE(reduce_relay, ripple_data, ripple);
1596 BEAST_DEFINE_TESTSUITE_MANUAL(reduce_relay_simulate, ripple_data, ripple);
1597 
1598 } // namespace test
1599 
1600 } // namespace ripple
ripple::PublicKey::data
std::uint8_t const * data() const noexcept
Definition: PublicKey.h:81
ripple::test::Validator::clear
void clear()
Definition: reduce_relay_test.cpp:335
ripple::test::Validator
Simulate Validator.
Definition: reduce_relay_test.cpp:310
ripple::Application
Definition: Application.h:115
ripple::test::OverlaySim::deleteIdlePeers
void deleteIdlePeers(UnsquelchCB f) override
Definition: reduce_relay_test.cpp:552
ripple::test::OverlaySim::getNumPeers
std::uint16_t getNumPeers() const
Definition: reduce_relay_test.cpp:659
ripple::test::reduce_relay_test::reduce_relay_test
reduce_relay_test()
Definition: reduce_relay_test.cpp:1557
ripple::test::reduce_relay_test::run
void run() override
Definition: reduce_relay_test.cpp:1562
ripple::test::OverlaySim::isSelected
bool isSelected(PublicKey const &validator, Peer::id_t peer)
Definition: reduce_relay_test.cpp:632
std::weak_ptr::lock
T lock(T... args)
ripple::test::reduce_relay_test::testConfig
void testConfig(bool log)
Definition: reduce_relay_test.cpp:1306
ripple::reduce_relay::SquelchHandler
Abstract class.
Definition: overlay/Slot.h:71
ripple::test::ManualClock::randDuration
static duration randDuration(milliseconds min, milliseconds max)
Definition: reduce_relay_test.cpp:216
ripple::test::PeerSim::overlay_
Overlay & overlay_
Definition: reduce_relay_test.cpp:500
ripple::test::reduce_relay_test::testInternalHashRouter
void testInternalHashRouter(bool log)
Definition: reduce_relay_test.cpp:1348
ripple::test::PeerPartial::txReduceRelayEnabled
bool txReduceRelayEnabled() const override
Definition: reduce_relay_test.cpp:163
ripple::test::PeerPartial::cycleStatus
void cycleStatus() override
Definition: reduce_relay_test.cpp:149
ripple::test::Network::isSelected
bool isSelected(Peer::id_t id)
Is peer in Selected state in any of the slots.
Definition: reduce_relay_test.cpp:839
ripple::test::OverlaySim::peers_
Peers peers_
Definition: reduce_relay_test.cpp:682
std::string
STL class.
std::shared_ptr< Message >
ripple::test::PeerPartial::getClosedLedgerHash
uint256 const & getClosedLedgerHash() const override
Definition: reduce_relay_test.cpp:129
ripple::test::OverlaySim::unsquelch
void unsquelch(PublicKey const &validator, Peer::id_t id) const override
Unsquelch handler.
Definition: reduce_relay_test.cpp:675
ripple::test::ManualClock::randAdvance
static void randAdvance(milliseconds min, milliseconds max)
Definition: reduce_relay_test.cpp:198
ripple::test::reduce_relay_test
Definition: reduce_relay_test.cpp:877
ripple::test::OverlaySim::inState
std::uint16_t inState(PublicKey const &validator, reduce_relay::PeerState state)
Definition: reduce_relay_test.cpp:526
ripple::test::PeerSim::resetId
static void resetId()
Definition: reduce_relay_test.cpp:467
ripple::Logs
Manages partitions for logging.
Definition: Log.h:48
ripple::test::reduce_relay_test::Handler::squelch
void squelch(PublicKey const &, Peer::id_t, std::uint32_t duration) const override
Squelch handler.
Definition: reduce_relay_test.cpp:1396
ripple::test::Network
Definition: reduce_relay_test.cpp:688
ripple::test::reduce_relay_test::network_
Network network_
Definition: reduce_relay_test.cpp:1554
ripple::test::Validator::message
MessageSPtr message()
Definition: reduce_relay_test.cpp:413
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::test::OverlaySim::logs_
Logs & logs_
Definition: reduce_relay_test.cpp:685
ripple::test::reduce_relay_test::propagateNoSquelch
bool propagateNoSquelch(bool log, std::uint16_t nMessages, bool countingState, bool purge=true, bool resetClock=true)
Send fewer message so that squelch event is not generated.
Definition: reduce_relay_test.cpp:1200
std::pair< milliseconds, milliseconds >
ripple::test::OverlaySim::peersCache_
Peers peersCache_
Definition: reduce_relay_test.cpp:683
ripple::test::Network::validator
Validator & validator(std::uint16_t v)
Definition: reduce_relay_test.cpp:749
ripple::test::Network::overlay_
OverlaySim overlay_
Definition: reduce_relay_test.cpp:873
ripple::test::reduce_relay_test::Event::validator_
std::uint16_t validator_
Definition: reduce_relay_test.cpp:928
ripple::Peer::id_t
std::uint32_t id_t
Uniquely identifies a peer.
Definition: ripple/overlay/Peer.h:55
ripple::test::reduce_relay_test::printPeers
void printPeers(const std::string &msg, std::uint16_t validator=0)
Definition: reduce_relay_test.cpp:884
ripple::test::jtx::validator
std::unique_ptr< Config > validator(std::unique_ptr< Config >, std::string const &)
adjust configuration with params needed to be a validator
Definition: envconfig.cpp:116
std::vector
STL class.
std::find_if
T find_if(T... args)
ripple::reduce_relay::PeerState::Squelched
@ Squelched
std::back_inserter
T back_inserter(T... args)
ripple::test::PeerPartial::supportsFeature
bool supportsFeature(ProtocolFeature f) const override
Definition: reduce_relay_test.cpp:115
ripple::test::OverlaySim::slots_
reduce_relay::Slots< ManualClock > slots_
Definition: reduce_relay_test.cpp:684
ripple::test::OverlaySim::getPeers
std::unordered_map< id_t, std::tuple< reduce_relay::PeerState, std::uint16_t, std::uint32_t, std::uint32_t > > getPeers(PublicKey const &validator)
Definition: reduce_relay_test.cpp:653
ripple::test::PeerPartial::getScore
int getScore(bool) const override
Definition: reduce_relay_test.cpp:99
std::chrono::duration
ripple::test::PeerPartial::setPublisherListSequence
void setPublisherListSequence(PublicKey const &, std::size_t const) override
Definition: reduce_relay_test.cpp:125
ripple::test::Validator::id
std::uint16_t id()
Definition: reduce_relay_test.cpp:419
ripple::test::OverlaySim::addPeer
PeerSPtr addPeer(bool useCache=true)
Definition: reduce_relay_test.cpp:559
std::stringstream
STL class.
ripple::reduce_relay::MAX_MESSAGE_THRESHOLD
static constexpr uint16_t MAX_MESSAGE_THRESHOLD
Definition: ReduceRelayCommon.h:45
ripple::squelch
constexpr Number squelch(Number const &x, Number const &limit) noexcept
Definition: Number.h:358
ripple::test::PeerPartial::cluster
bool cluster() const override
Returns true if this connection is a member of the cluster.
Definition: reduce_relay_test.cpp:89
ripple::test::MAX_VALIDATORS
static constexpr std::uint32_t MAX_VALIDATORS
Definition: reduce_relay_test.cpp:52
std::tuple
ripple::test::reduce_relay_test::testSelectedPeerDisconnects
void testSelectedPeerDisconnects(bool log)
Selected peer disconnects.
Definition: reduce_relay_test.cpp:1243
std::function< void(PublicKey const &, PeerWPtr const &, std::uint32_t)>
ripple::test::ManualClock::time_point
std::chrono::time_point< ManualClock > time_point
Definition: reduce_relay_test.cpp:188
ripple::ProtocolFeature
ProtocolFeature
Definition: ripple/overlay/Peer.h:38
ripple::test::Validator::linkUp
void linkUp(Peer::id_t id)
Definition: reduce_relay_test.cpp:425
ripple::test::OverlaySim::resetPeers
void resetPeers()
Definition: reduce_relay_test.cpp:591
ripple::reduce_relay::PeerState
PeerState
Peer's State.
Definition: overlay/Slot.h:49
ripple::test::Validator::for_links
void for_links(LinkIterCB f, bool simulateSlow=false)
Definition: reduce_relay_test.cpp:381
ripple::FEATURE_VPRR
static constexpr char FEATURE_VPRR[]
Definition: Handshake.h:144
ripple::test::ManualClock::duration
std::chrono::duration< std::uint32_t, period > duration
Definition: reduce_relay_test.cpp:187
ripple::test::reduce_relay_test::checkCounting
bool checkCounting(PublicKey const &validator, bool isCountingState)
Definition: reduce_relay_test.cpp:1112
ripple::Config::VP_REDUCE_RELAY_SQUELCH
bool VP_REDUCE_RELAY_SQUELCH
Definition: Config.h:262
ripple::test::PeerPartial::getNodePublic
PublicKey const & getNodePublic() const override
Definition: reduce_relay_test.cpp:104
ripple::test::Overlay
Simulate server's OverlayImpl.
Definition: reduce_relay_test.cpp:228
ripple::test::PeerSim::onMessage
virtual void onMessage(protocol::TMSquelch const &squelch) override
Remote Peer (Directly connected Peer)
Definition: reduce_relay_test.cpp:486
ripple::test::PeerPartial::json
Json::Value json() override
Definition: reduce_relay_test.cpp:110
std::mt19937
std::cout
ripple::KeyType::ed25519
@ ed25519
ripple::base_uint< 256 >
ripple::test::PeerSim::onMessage
void onMessage(MessageSPtr const &m, SquelchCB f) override
Local Peer (PeerImp)
Definition: reduce_relay_test.cpp:474
ripple::test::reduce_relay_test::random
void random(bool log)
Randomly brings the link between a validator and a peer down.
Definition: reduce_relay_test.cpp:938
ripple::test::reduce_relay_test::Event::peer_
Peer::id_t peer_
Definition: reduce_relay_test.cpp:927
ripple::reduce_relay::Squelch
Maintains squelching of relaying messages from validators.
Definition: Squelch.h:38
ripple::test::reduce_relay_test::Event::key_
PublicKey key_
Definition: reduce_relay_test.cpp:929
ripple::test::PeerSim::id_
id_t id_
Definition: reduce_relay_test.cpp:499
ripple::test::Network::propagate
void propagate(LinkIterCB link, std::uint16_t nValidators=MAX_VALIDATORS, std::uint32_t nMessages=MAX_MESSAGES, bool purge=true, bool resetClock=true)
Definition: reduce_relay_test.cpp:812
ripple::test::Network::reset
void reset()
Definition: reduce_relay_test.cpp:711
ripple::test::PeerPartial::compressionEnabled
bool compressionEnabled() const override
Definition: reduce_relay_test.cpp:158
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::Config::loadFromString
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Definition: Config.cpp:457
ripple::test::Network::allCounting
bool allCounting(Peer::id_t peer)
Check if there are peers to unsquelch - peer is in Selected state in any of the slots and there are p...
Definition: reduce_relay_test.cpp:854
beast::IP::Address
boost::asio::ip::address Address
Definition: IPAddress.h:41
std::milli
ripple::test::PeerSim::squelch_
reduce_relay::Squelch< ManualClock > squelch_
Definition: reduce_relay_test.cpp:501
ripple::test::reduce_relay_test::testHandshake
void testHandshake(bool log)
Definition: reduce_relay_test.cpp:1489
std::random_device
ripple::test::reduce_relay_test::EventType
EventType
Definition: reduce_relay_test.cpp:916
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::Config
Definition: Config.h:89
ripple::test::reduce_relay_test::propagateAndSquelch
bool propagateAndSquelch(bool log, bool purge=true, bool resetClock=true)
Propagate enough messages to generate one squelch event.
Definition: reduce_relay_test.cpp:1164
ripple::PublicKey::size
std::size_t size() const noexcept
Definition: PublicKey.h:87
ripple::test::PeerPartial::send
void send(std::shared_ptr< Message > const &m) override
Definition: reduce_relay_test.cpp:76
ripple::test::PeerPartial::publisherListSequence
std::optional< std::size_t > publisherListSequence(PublicKey const &) const override
Definition: reduce_relay_test.cpp:120
ripple::test::Network::overlay
OverlaySim & overlay()
Definition: reduce_relay_test.cpp:756
ripple::test::Network::addPeer
Peer::id_t addPeer()
Definition: reduce_relay_test.cpp:721
ripple::test::OverlaySim::clear
void clear()
Definition: reduce_relay_test.cpp:518
ripple::reduce_relay::IDLED
static constexpr auto IDLED
Definition: ReduceRelayCommon.h:39
ripple::test::OverlaySim::deletePeer
void deletePeer(Peer::id_t id, bool useCache=true)
Definition: reduce_relay_test.cpp:580
ripple::test::Validator::linkDown
void linkDown(Peer::id_t id)
Definition: reduce_relay_test.cpp:433
ripple::test::Validator::send
void send(std::vector< Peer::id_t > peers, SquelchCB f)
Send to specific peers.
Definition: reduce_relay_test.cpp:400
ripple::test::OverlaySim::isCountingState
bool isCountingState(PublicKey const &validator)
Definition: reduce_relay_test.cpp:620
std::enable_shared_from_this
std::flush
T flush(T... args)
ripple::test::PeerPartial::ledgerRange
void ledgerRange(std::uint32_t &minSeq, std::uint32_t &maxSeq) const override
Definition: reduce_relay_test.cpp:140
std::chrono::time_point
ripple::test::reduce_relay_test::Handler::Handler
Handler()
Definition: reduce_relay_test.cpp:1392
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
ripple::test::Validator::deletePeer
void deletePeer(Peer::id_t id)
Definition: reduce_relay_test.cpp:365
ripple::test::OverlaySim::deletePeer
void deletePeer(id_t id, UnsquelchCB f) override
Definition: reduce_relay_test.cpp:545
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::test::Network::onDisconnectPeer
void onDisconnectPeer(Peer::id_t peer)
Definition: reduce_relay_test.cpp:776
ripple::peerFeatureEnabled
bool peerFeatureEnabled(headers const &request, std::string const &feature, std::string value, bool config)
Check if a feature should be enabled for a peer.
Definition: Handshake.h:199
std::uint32_t
ripple::test::OverlaySim::OverlaySim
OverlaySim(Application &app)
Definition: reduce_relay_test.cpp:511
ripple::test::PeerPartial::hasRange
bool hasRange(std::uint32_t uMin, std::uint32_t uMax) override
Definition: reduce_relay_test.cpp:153
ripple::test::ManualClock
Manually advanced clock.
Definition: reduce_relay_test.cpp:182
std::transform
T transform(T... args)
ripple::test::Network::enableLink
void enableLink(std::uint16_t validatorId, Peer::id_t peer, bool enable)
Definition: reduce_relay_test.cpp:762
ripple::test::reduce_relay_test::testSelectedPeerStopsRelaying
void testSelectedPeerStopsRelaying(bool log)
Selected peer stops relaying.
Definition: reduce_relay_test.cpp:1263
ripple::test::ManualClock::period
std::milli period
Definition: reduce_relay_test.cpp:186
ripple::test::MAX_MESSAGES
static constexpr std::uint32_t MAX_MESSAGES
Definition: reduce_relay_test.cpp:53
ripple::test::reduce_relay_test::Event
Definition: reduce_relay_test.cpp:921
ripple::test::jtx::fee
Set the fee on a JTx.
Definition: fee.h:35
ripple::test::PeerPartial::hasTxSet
bool hasTxSet(uint256 const &hash) const override
Definition: reduce_relay_test.cpp:144
ripple::test::Network::purgePeers
void purgePeers()
Definition: reduce_relay_test.cpp:742
ripple::test::reduce_relay_test::sendSquelch
Peer::id_t sendSquelch(PublicKey const &validator, PeerWPtr const &peerPtr, std::optional< std::uint32_t > duration)
Send squelch (if duration is set) or unsquelch (if duration not set)
Definition: reduce_relay_test.cpp:898
ripple::test::OverlaySim::updateSlotAndSquelch
void updateSlotAndSquelch(uint256 const &key, PublicKey const &validator, Peer::id_t id, SquelchCB f, protocol::MessageType type=protocol::mtVALIDATION) override
Definition: reduce_relay_test.cpp:533
std::weak_ptr< Peer >
ripple::test::Network::for_rand
void for_rand(std::uint32_t min, std::uint32_t max, std::function< void(std::uint32_t)> f)
Definition: reduce_relay_test.cpp:796
ripple::test::OverlaySim::deleteLastPeer
std::optional< Peer::id_t > deleteLastPeer()
Definition: reduce_relay_test.cpp:600
ripple::Config::VP_REDUCE_RELAY_ENABLE
bool VP_REDUCE_RELAY_ENABLE
Definition: Config.h:253
ripple::test::Network::Network
Network(Application &app)
Definition: reduce_relay_test.cpp:691
ripple::test::Validator::Validator
Validator()
Definition: reduce_relay_test.cpp:315
ripple::test::PeerPartial::hasLedger
bool hasLedger(uint256 const &hash, std::uint32_t seq) const override
Definition: reduce_relay_test.cpp:135
ripple::randomKeyPair
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
Definition: SecretKey.cpp:368
ripple::test::reduce_relay_simulate_test
Definition: reduce_relay_test.cpp:1579
ripple::test::Validator::send
void send(SquelchCB f)
Send to all peers.
Definition: reduce_relay_test.cpp:407
ripple::test::PeerPartial::isHighLatency
bool isHighLatency() const override
Definition: reduce_relay_test.cpp:94
ripple::test::reduce_relay_test::Handler
Definition: reduce_relay_test.cpp:1390
ripple::test::OverlaySim::squelch
void squelch(PublicKey const &validator, Peer::id_t id, std::uint32_t squelchDuration) const override
Squelch handler.
Definition: reduce_relay_test.cpp:666
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:33
ripple::test::reduce_relay_test::testNewPeer
void testNewPeer(bool log)
Receiving a message from new peer should change the slot's state to Counting.
Definition: reduce_relay_test.cpp:1231
ripple::test::PeerSim::id
id_t id() const override
Definition: reduce_relay_test.cpp:461
ripple::test::reduce_relay_test::testPeerUnsquelchedTooSoon
void testPeerUnsquelchedTooSoon(bool log)
Receiving message from squelched peer too soon should not change the slot's state to Counting.
Definition: reduce_relay_test.cpp:1143
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::reduce_relay_simulate_test::run
void run() override
Definition: reduce_relay_test.cpp:1588
ripple::test::reduce_relay_test::env_
jtx::Env env_
Definition: reduce_relay_test.cpp:1553
ripple::test::Validator::addPeer
void addPeer(PeerSPtr peer)
Definition: reduce_relay_test.cpp:358
ripple::test::Network::deleteLastPeer
void deleteLastPeer()
Definition: reduce_relay_test.cpp:730
std::endl
T endl(T... args)
ripple::test::PeerPartial::send
void send(protocol::TMSquelch const &squelch)
Definition: reduce_relay_test.cpp:69
ripple::test::reduce_relay_test::doTest
void doTest(const std::string &msg, bool log, std::function< void(bool)> f)
Definition: reduce_relay_test.cpp:1120
ripple::test::ManualClock::reset
static void reset() noexcept
Definition: reduce_relay_test.cpp:204
ripple::reduce_relay::SlotState::Counting
@ Counting
ripple::test::PeerPartial::addTxQueue
void addTxQueue(const uint256 &) override
Aggregate transaction's hash.
Definition: reduce_relay_test.cpp:172
ripple::test::PeerPartial::sendTxQueue
void sendTxQueue() override
Send aggregated transactions' hashes.
Definition: reduce_relay_test.cpp:168
std::vector::begin
T begin(T... args)
ripple::test::Validator::~Validator
~Validator()
Definition: reduce_relay_test.cpp:329
ripple::test::reduce_relay_test::testInitialRound
void testInitialRound(bool log)
Initial counting round: three peers receive message "faster" then others.
Definition: reduce_relay_test.cpp:1132
std::iota
T iota(T... args)
ripple::Resource::Charge
A consumption charge.
Definition: Charge.h:30
ripple::test::Validator::links_
Links links_
Definition: reduce_relay_test.cpp:441
ripple::test::PeerPartial::charge
void charge(Resource::Charge const &fee) override
Adjust this peer's load balance based on the type of load imposed.
Definition: reduce_relay_test.cpp:85
ripple::test::PeerPartial::removeTxQueue
void removeTxQueue(const uint256 &) override
Remove hash from the transactions' hashes queue.
Definition: reduce_relay_test.cpp:176
ripple::Config::COMPRESSION
bool COMPRESSION
Definition: Config.h:225
ripple::test::PeerSim
Definition: reduce_relay_test.cpp:448
ripple::test::PeerPartial::getRemoteAddress
beast::IP::Endpoint getRemoteAddress() const override
Definition: reduce_relay_test.cpp:80
std::chrono::milliseconds::count
T count(T... args)
ripple::test::PeerPartial::~PeerPartial
virtual ~PeerPartial()
Definition: reduce_relay_test.cpp:61
ripple::test::OverlaySim::unsquelch_
UnsquelchCB unsquelch_
Definition: reduce_relay_test.cpp:681
ripple::test::MessageSPtr
std::shared_ptr< Message > MessageSPtr
Definition: reduce_relay_test.cpp:42
optional
ripple::test::PeerPartial
Simulate two entities - peer directly connected to the server (via squelch in PeerSim) and PeerImp (v...
Definition: reduce_relay_test.cpp:58
ripple::test::Network::validators_
std::vector< Validator > validators_
Definition: reduce_relay_test.cpp:874
std::stringstream::str
T str(T... args)
ripple::test::MAX_PEERS
static constexpr std::uint32_t MAX_PEERS
Definition: reduce_relay_test.cpp:51
std::size_t
std::make_pair
T make_pair(T... args)
beast::IP::Endpoint
A version-independent IP address and port combination.
Definition: IPEndpoint.h:38
std::vector::end
T end(T... args)
ripple::test::OverlaySim::getSelectedPeer
id_t getSelectedPeer(PublicKey const &validator)
Definition: reduce_relay_test.cpp:639
ripple::test::OverlaySim
Definition: reduce_relay_test.cpp:504
ripple::test::ManualClock::rep
uint64_t rep
Definition: reduce_relay_test.cpp:185
ripple::test::ManualClock::now
static time_point now() noexcept
Definition: reduce_relay_test.cpp:210
ripple::test::reduce_relay_test::Event::time_
time_point< ManualClock > time_
Definition: reduce_relay_test.cpp:930
ripple::test::reduce_relay_test::testRandomSquelch
void testRandomSquelch(bool l)
Definition: reduce_relay_test.cpp:1410
numeric
ripple::test::Validator::key
PublicKey const & key()
Definition: reduce_relay_test.cpp:347
ripple::test::reduce_relay_test::State
State
Definition: reduce_relay_test.cpp:915
ripple::test::reduce_relay_test::Handler::unsquelch
void unsquelch(PublicKey const &, Peer::id_t) const override
Unsquelch handler.
Definition: reduce_relay_test.cpp:1403
ripple::test::Validator::resetId
static void resetId()
Definition: reduce_relay_test.cpp:341
ripple::makeRequest
auto makeRequest(bool crawlPublic, bool comprEnabled, bool ledgerReplayEnabled, bool txReduceRelayEnabled, bool vpReduceRelayEnabled) -> request_type
Make outbound http request.
Definition: Handshake.cpp:365
ripple::test::reduce_relay_test::Handler::maxDuration_
int maxDuration_
Definition: reduce_relay_test.cpp:1406
ripple::makeResponse
http_response_type makeResponse(bool crawlPublic, http_request_type const &req, beast::IP::Address public_ip, beast::IP::Address remote_ip, uint256 const &sharedValue, std::optional< std::uint32_t > networkID, ProtocolVersion protocol, Application &app)
Make http response.
Definition: Handshake.cpp:392
ripple::test::Validator::for_links
void for_links(std::vector< Peer::id_t > peers, LinkIterCB f)
Definition: reduce_relay_test.cpp:371
ripple::http_request_type
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition: Handshake.h:47
std::shuffle
T shuffle(T... args)
ripple::test::ManualClock::advance
static void advance(duration d) noexcept
Definition: reduce_relay_test.cpp:192
ripple::test::PeerSim::PeerSim
PeerSim(Overlay &overlay, beast::Journal journal)
Definition: reduce_relay_test.cpp:452
std::unordered_map< Peer::id_t, LinkSPtr >
ripple::test::reduce_relay_test::testSquelchedPeerDisconnects
void testSquelchedPeerDisconnects(bool log)
Squelched peer disconnects.
Definition: reduce_relay_test.cpp:1284
std::set
STL class.
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:116
ripple::reduce_relay::MAX_SELECTED_PEERS
static constexpr uint16_t MAX_SELECTED_PEERS
Definition: ReduceRelayCommon.h:47
ripple::test::BEAST_DEFINE_TESTSUITE_MANUAL
BEAST_DEFINE_TESTSUITE_MANUAL(LedgerReplayerLong, app, ripple)
ripple::test::reduce_relay_test::testPeerUnsquelched
void testPeerUnsquelched(bool log)
Receiving message from squelched peer should change the slot's state to Counting.
Definition: reduce_relay_test.cpp:1154
ripple::test::OverlaySim::getSelected
std::set< id_t > getSelected(PublicKey const &validator)
Definition: reduce_relay_test.cpp:626
ripple::test::Network::init
void init()
Definition: reduce_relay_test.cpp:697
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::test::OverlaySim::squelch_
SquelchCB squelch_
Definition: reduce_relay_test.cpp:680
ripple::test::reduce_relay_simulate_test::testRandom
void testRandom(bool log)
Definition: reduce_relay_test.cpp:1582
ripple::Peer
Represents a peer connection in the overlay.
Definition: ripple/overlay/Peer.h:45
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)
ripple::reduce_relay::Slot
Slot is associated with a specific validator via validator's public key.
Definition: overlay/Slot.h:104
std::chrono