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