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