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