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