rippled
Validations_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-2017 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 
20 #include <ripple/basics/tagged_integer.h>
21 #include <ripple/beast/clock/manual_clock.h>
22 #include <ripple/beast/unit_test.h>
23 #include <ripple/consensus/Validations.h>
24 #include <memory>
25 #include <test/csf/Validation.h>
26 #include <test/unit_test/SuiteJournal.h>
27 #include <tuple>
28 #include <type_traits>
29 #include <vector>
30 
31 namespace ripple {
32 namespace test {
33 namespace csf {
34 class Validations_test : public beast::unit_test::suite
35 {
37 
38  // Helper to convert steady_clock to a reasonable NetClock
39  // This allows a single manual clock in the unit tests
42  {
43  // We don't care about the actual epochs, but do want the
44  // generated NetClock time to be well past its epoch to ensure
45  // any subtractions are positive
46  using namespace std::chrono;
47  return NetClock::time_point(duration_cast<NetClock::duration>(
48  c.now().time_since_epoch() + 86400s));
49  }
50 
51  // Represents a node that can issue validations
52  class Node
53  {
54  clock_type const& c_;
56  bool trusted_ = true;
59 
60  public:
62  {
63  }
64 
65  void
67  {
68  trusted_ = false;
69  }
70 
71  void
73  {
74  trusted_ = true;
75  }
76 
77  void
79  {
80  loadFee_ = fee;
81  }
82 
83  PeerID
84  nodeID() const
85  {
86  return nodeID_;
87  }
88 
89  void
91  {
92  signIdx_++;
93  }
94 
95  PeerKey
96  currKey() const
97  {
99  }
100 
101  PeerKey
102  masterKey() const
103  {
104  return std::make_pair(nodeID_, 0);
105  }
107  now() const
108  {
109  return toNetClock(c_);
110  }
111 
112  // Issue a new validation with given sequence number and id and
113  // with signing and seen times offset from the common clock
114  Validation
116  Ledger::ID id,
118  NetClock::duration signOffset,
119  NetClock::duration seenOffset,
120  bool full) const
121  {
122  Validation v{
123  id,
124  seq,
125  now() + signOffset,
126  now() + seenOffset,
127  currKey(),
128  nodeID_,
129  full,
130  loadFee_};
131  if (trusted_)
132  v.setTrusted();
133  return v;
134  }
135 
136  Validation
138  Ledger ledger,
139  NetClock::duration signOffset,
140  NetClock::duration seenOffset) const
141  {
142  return validate(
143  ledger.id(), ledger.seq(), signOffset, seenOffset, true);
144  }
145 
146  Validation
147  validate(Ledger ledger) const
148  {
149  return validate(
150  ledger.id(),
151  ledger.seq(),
154  true);
155  }
156 
157  Validation
158  partial(Ledger ledger) const
159  {
160  return validate(
161  ledger.id(),
162  ledger.seq(),
165  false);
166  }
167  };
168 
169  // Generic Validations adaptor
170  class Adaptor
171  {
174 
175  public:
176  // Non-locking mutex to avoid locks in generic Validations
177  struct Mutex
178  {
179  void
181  {
182  }
183 
184  void
186  {
187  }
188  };
189 
192 
194  {
195  }
196 
198  now() const
199  {
200  return toNetClock(c_);
201  }
202 
204  acquire(Ledger::ID const& id)
205  {
206  return oracle_.lookup(id);
207  }
208  };
209 
210  // Specialize generic Validations using the above types
212 
213  // Gather the dependencies of TestValidations in a single class and provide
214  // accessors for simplifying test logic
216  {
221 
222  public:
224  {
225  }
226 
227  ValStatus
228  add(Validation const& v)
229  {
230  return tv_.add(v.nodeID(), v);
231  }
232 
235  {
236  return tv_;
237  }
238 
239  Node
241  {
242  return Node(nextNodeId_++, clock_);
243  }
244 
246  parms() const
247  {
248  return p_;
249  }
250 
251  auto&
253  {
254  return clock_;
255  }
256  };
257 
259 
260  void
262  {
263  using namespace std::chrono_literals;
264 
265  testcase("Add validation");
267  Ledger ledgerA = h["a"];
268  Ledger ledgerAB = h["ab"];
269  Ledger ledgerAZ = h["az"];
270  Ledger ledgerABC = h["abc"];
271  Ledger ledgerABCD = h["abcd"];
272  Ledger ledgerABCDE = h["abcde"];
273 
274  {
275  TestHarness harness(h.oracle);
276  Node n = harness.makeNode();
277 
278  auto const v = n.validate(ledgerA);
279 
280  // Add a current validation
281  BEAST_EXPECT(ValStatus::current == harness.add(v));
282 
283  // Re-adding violates the increasing seq requirement for full
284  // validations
285  BEAST_EXPECT(ValStatus::badSeq == harness.add(v));
286 
287  harness.clock().advance(1s);
288 
289  BEAST_EXPECT(
290  ValStatus::current == harness.add(n.validate(ledgerAB)));
291 
292  // Test the node changing signing key
293 
294  // Confirm old ledger on hand, but not new ledger
295  BEAST_EXPECT(
296  harness.vals().numTrustedForLedger(ledgerAB.id()) == 1);
297  BEAST_EXPECT(
298  harness.vals().numTrustedForLedger(ledgerABC.id()) == 0);
299 
300  // Rotate signing keys
301  n.advanceKey();
302 
303  harness.clock().advance(1s);
304 
305  // Cannot re-do the same full validation sequence
306  BEAST_EXPECT(
307  ValStatus::conflicting == harness.add(n.validate(ledgerAB)));
308  // Cannot send the same partial validation sequence
309  BEAST_EXPECT(
310  ValStatus::conflicting == harness.add(n.partial(ledgerAB)));
311 
312  // Now trusts the newest ledger too
313  harness.clock().advance(1s);
314  BEAST_EXPECT(
315  ValStatus::current == harness.add(n.validate(ledgerABC)));
316  BEAST_EXPECT(
317  harness.vals().numTrustedForLedger(ledgerAB.id()) == 1);
318  BEAST_EXPECT(
319  harness.vals().numTrustedForLedger(ledgerABC.id()) == 1);
320 
321  // Processing validations out of order should ignore the older
322  // validation
323  harness.clock().advance(2s);
324  auto const valABCDE = n.validate(ledgerABCDE);
325 
326  harness.clock().advance(4s);
327  auto const valABCD = n.validate(ledgerABCD);
328 
329  BEAST_EXPECT(ValStatus::current == harness.add(valABCD));
330 
331  BEAST_EXPECT(ValStatus::stale == harness.add(valABCDE));
332  }
333 
334  {
335  // Process validations out of order with shifted times
336 
337  TestHarness harness(h.oracle);
338  Node n = harness.makeNode();
339 
340  // Establish a new current validation
341  BEAST_EXPECT(
342  ValStatus::current == harness.add(n.validate(ledgerA)));
343 
344  // Process a validation that has "later" seq but early sign time
345  BEAST_EXPECT(
347  harness.add(n.validate(ledgerAB, -1s, -1s)));
348 
349  // Process a validation that has a later seq and later sign
350  // time
351  BEAST_EXPECT(
353  harness.add(n.validate(ledgerABC, 1s, 1s)));
354  }
355 
356  {
357  // Test stale on arrival validations
358  TestHarness harness(h.oracle);
359  Node n = harness.makeNode();
360 
361  BEAST_EXPECT(
363  harness.add(n.validate(
364  ledgerA, -harness.parms().validationCURRENT_EARLY, 0s)));
365 
366  BEAST_EXPECT(
368  harness.add(n.validate(
369  ledgerA, harness.parms().validationCURRENT_WALL, 0s)));
370 
371  BEAST_EXPECT(
373  harness.add(n.validate(
374  ledgerA, 0s, harness.parms().validationCURRENT_LOCAL)));
375  }
376 
377  {
378  // Test that full or partials cannot be sent for older sequence
379  // numbers, unless time-out has happened
380  for (bool doFull : {true, false})
381  {
382  TestHarness harness(h.oracle);
383  Node n = harness.makeNode();
384 
385  auto process = [&](Ledger& lgr) {
386  if (doFull)
387  return harness.add(n.validate(lgr));
388  return harness.add(n.partial(lgr));
389  };
390 
391  BEAST_EXPECT(ValStatus::current == process(ledgerABC));
392  harness.clock().advance(1s);
393  BEAST_EXPECT(ledgerAB.seq() < ledgerABC.seq());
394  BEAST_EXPECT(ValStatus::badSeq == process(ledgerAB));
395 
396  // If we advance far enough for AB to expire, we can fully
397  // validate or partially validate that sequence number again
398  BEAST_EXPECT(ValStatus::conflicting == process(ledgerAZ));
399  harness.clock().advance(
400  harness.parms().validationSET_EXPIRES + 1ms);
401  BEAST_EXPECT(ValStatus::current == process(ledgerAZ));
402  }
403  }
404  }
405 
406  void
408  {
409  testcase("Stale validation");
410  // Verify validation becomes stale based solely on time passing, but
411  // use different functions to trigger the check for staleness
412 
414  Ledger ledgerA = h["a"];
415  Ledger ledgerAB = h["ab"];
416 
417  using Trigger = std::function<void(TestValidations&)>;
418 
419  std::vector<Trigger> triggers = {
420  [&](TestValidations& vals) { vals.currentTrusted(); },
421  [&](TestValidations& vals) { vals.getCurrentNodeIDs(); },
422  [&](TestValidations& vals) { vals.getPreferred(genesisLedger); },
423  [&](TestValidations& vals) {
424  vals.getNodesAfter(ledgerA, ledgerA.id());
425  }};
426  for (Trigger trigger : triggers)
427  {
428  TestHarness harness(h.oracle);
429  Node n = harness.makeNode();
430 
431  BEAST_EXPECT(
432  ValStatus::current == harness.add(n.validate(ledgerAB)));
433  trigger(harness.vals());
434  BEAST_EXPECT(
435  harness.vals().getNodesAfter(ledgerA, ledgerA.id()) == 1);
436  BEAST_EXPECT(
437  harness.vals().getPreferred(genesisLedger) ==
438  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
439  harness.clock().advance(harness.parms().validationCURRENT_LOCAL);
440 
441  // trigger check for stale
442  trigger(harness.vals());
443 
444  BEAST_EXPECT(
445  harness.vals().getNodesAfter(ledgerA, ledgerA.id()) == 0);
446  BEAST_EXPECT(
447  harness.vals().getPreferred(genesisLedger) == std::nullopt);
448  }
449  }
450 
451  void
453  {
454  // Test getting number of nodes working on a validation descending
455  // a prescribed one. This count should only be for trusted nodes, but
456  // includes partial and full validations
457 
458  using namespace std::chrono_literals;
459  testcase("Get nodes after");
460 
462  Ledger ledgerA = h["a"];
463  Ledger ledgerAB = h["ab"];
464  Ledger ledgerABC = h["abc"];
465  Ledger ledgerAD = h["ad"];
466 
467  TestHarness harness(h.oracle);
468  Node a = harness.makeNode(), b = harness.makeNode(),
469  c = harness.makeNode(), d = harness.makeNode();
470  c.untrust();
471 
472  // first round a,b,c agree, d has is partial
473  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
474  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
475  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerA)));
476  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerA)));
477 
478  for (Ledger const& ledger : {ledgerA, ledgerAB, ledgerABC, ledgerAD})
479  BEAST_EXPECT(
480  harness.vals().getNodesAfter(ledger, ledger.id()) == 0);
481 
482  harness.clock().advance(5s);
483 
484  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerAB)));
485  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerABC)));
486  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerAB)));
487  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerABC)));
488 
489  BEAST_EXPECT(harness.vals().getNodesAfter(ledgerA, ledgerA.id()) == 3);
490  BEAST_EXPECT(
491  harness.vals().getNodesAfter(ledgerAB, ledgerAB.id()) == 2);
492  BEAST_EXPECT(
493  harness.vals().getNodesAfter(ledgerABC, ledgerABC.id()) == 0);
494  BEAST_EXPECT(
495  harness.vals().getNodesAfter(ledgerAD, ledgerAD.id()) == 0);
496 
497  // If given a ledger inconsistent with the id, is still able to check
498  // using slower method
499  BEAST_EXPECT(harness.vals().getNodesAfter(ledgerAD, ledgerA.id()) == 1);
500  BEAST_EXPECT(
501  harness.vals().getNodesAfter(ledgerAD, ledgerAB.id()) == 2);
502  }
503 
504  void
506  {
507  using namespace std::chrono_literals;
508  testcase("Current trusted validations");
509 
511  Ledger ledgerA = h["a"];
512  Ledger ledgerB = h["b"];
513  Ledger ledgerAC = h["ac"];
514 
515  TestHarness harness(h.oracle);
516  Node a = harness.makeNode(), b = harness.makeNode();
517  b.untrust();
518 
519  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
520  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerB)));
521 
522  // Only a is trusted
523  BEAST_EXPECT(harness.vals().currentTrusted().size() == 1);
524  BEAST_EXPECT(
525  harness.vals().currentTrusted()[0].ledgerID() == ledgerA.id());
526  BEAST_EXPECT(harness.vals().currentTrusted()[0].seq() == ledgerA.seq());
527 
528  harness.clock().advance(3s);
529 
530  for (auto const& node : {a, b})
531  BEAST_EXPECT(
532  ValStatus::current == harness.add(node.validate(ledgerAC)));
533 
534  // New validation for a
535  BEAST_EXPECT(harness.vals().currentTrusted().size() == 1);
536  BEAST_EXPECT(
537  harness.vals().currentTrusted()[0].ledgerID() == ledgerAC.id());
538  BEAST_EXPECT(
539  harness.vals().currentTrusted()[0].seq() == ledgerAC.seq());
540 
541  // Pass enough time for it to go stale
542  harness.clock().advance(harness.parms().validationCURRENT_LOCAL);
543  BEAST_EXPECT(harness.vals().currentTrusted().empty());
544  }
545 
546  void
548  {
549  using namespace std::chrono_literals;
550  testcase("Current public keys");
551 
553  Ledger ledgerA = h["a"];
554  Ledger ledgerAC = h["ac"];
555 
556  TestHarness harness(h.oracle);
557  Node a = harness.makeNode(), b = harness.makeNode();
558  b.untrust();
559 
560  for (auto const& node : {a, b})
561  BEAST_EXPECT(
562  ValStatus::current == harness.add(node.validate(ledgerA)));
563 
564  {
565  hash_set<PeerID> const expectedKeys = {a.nodeID(), b.nodeID()};
566  BEAST_EXPECT(harness.vals().getCurrentNodeIDs() == expectedKeys);
567  }
568 
569  harness.clock().advance(3s);
570 
571  // Change keys and issue partials
572  a.advanceKey();
573  b.advanceKey();
574 
575  for (auto const& node : {a, b})
576  BEAST_EXPECT(
577  ValStatus::current == harness.add(node.partial(ledgerAC)));
578 
579  {
580  hash_set<PeerID> const expectedKeys = {a.nodeID(), b.nodeID()};
581  BEAST_EXPECT(harness.vals().getCurrentNodeIDs() == expectedKeys);
582  }
583 
584  // Pass enough time for them to go stale
585  harness.clock().advance(harness.parms().validationCURRENT_LOCAL);
586  BEAST_EXPECT(harness.vals().getCurrentNodeIDs().empty());
587  }
588 
589  void
591  {
592  // Test the Validations functions that calculate a value by ledger ID
593  using namespace std::chrono_literals;
594  testcase("By ledger functions");
595 
596  // Several Validations functions return a set of values associated
597  // with trusted ledgers sharing the same ledger ID. The tests below
598  // exercise this logic by saving the set of trusted Validations, and
599  // verifying that the Validations member functions all calculate the
600  // proper transformation of the available ledgers.
601 
603  TestHarness harness(h.oracle);
604 
605  Node a = harness.makeNode(), b = harness.makeNode(),
606  c = harness.makeNode(), d = harness.makeNode(),
607  e = harness.makeNode();
608 
609  c.untrust();
610  // Mix of load fees
611  a.setLoadFee(12);
612  b.setLoadFee(1);
613  c.setLoadFee(12);
614  e.setLoadFee(12);
615 
617  trustedValidations;
618 
619  //----------------------------------------------------------------------
620  // checkers
621  auto sorted = [](auto vec) {
622  std::sort(vec.begin(), vec.end());
623  return vec;
624  };
625  auto compare = [&]() {
626  for (auto& it : trustedValidations)
627  {
628  auto const& id = it.first.first;
629  auto const& seq = it.first.second;
630  auto const& expectedValidations = it.second;
631 
632  BEAST_EXPECT(
633  harness.vals().numTrustedForLedger(id) ==
634  expectedValidations.size());
635  BEAST_EXPECT(
636  sorted(harness.vals().getTrustedForLedger(id, seq)) ==
637  sorted(expectedValidations));
638 
639  std::uint32_t baseFee = 0;
640  std::vector<uint32_t> expectedFees;
641  for (auto const& val : expectedValidations)
642  {
643  expectedFees.push_back(val.loadFee().value_or(baseFee));
644  }
645 
646  BEAST_EXPECT(
647  sorted(harness.vals().fees(id, baseFee)) ==
648  sorted(expectedFees));
649  }
650  };
651 
652  //----------------------------------------------------------------------
653  Ledger ledgerA = h["a"];
654  Ledger ledgerB = h["b"];
655  Ledger ledgerAC = h["ac"];
656 
657  // Add a dummy ID to cover unknown ledger identifiers
658  trustedValidations[{Ledger::ID{100}, Ledger::Seq{100}}] = {};
659 
660  // first round a,b,c agree
661  for (auto const& node : {a, b, c})
662  {
663  auto const val = node.validate(ledgerA);
664  BEAST_EXPECT(ValStatus::current == harness.add(val));
665  if (val.trusted())
666  trustedValidations[{val.ledgerID(), val.seq()}].emplace_back(
667  val);
668  }
669  // d disagrees
670  {
671  auto const val = d.validate(ledgerB);
672  BEAST_EXPECT(ValStatus::current == harness.add(val));
673  trustedValidations[{val.ledgerID(), val.seq()}].emplace_back(val);
674  }
675  // e only issues partials
676  {
677  BEAST_EXPECT(ValStatus::current == harness.add(e.partial(ledgerA)));
678  }
679 
680  harness.clock().advance(5s);
681  // second round, a,b,c move to ledger 2
682  for (auto const& node : {a, b, c})
683  {
684  auto const val = node.validate(ledgerAC);
685  BEAST_EXPECT(ValStatus::current == harness.add(val));
686  if (val.trusted())
687  trustedValidations[{val.ledgerID(), val.seq()}].emplace_back(
688  val);
689  }
690  // d now thinks ledger 1, but cannot re-issue a previously used seq
691  // and attempting it should generate a conflict.
692  {
693  BEAST_EXPECT(
694  ValStatus::conflicting == harness.add(d.partial(ledgerA)));
695  }
696  // e only issues partials
697  {
698  BEAST_EXPECT(
699  ValStatus::current == harness.add(e.partial(ledgerAC)));
700  }
701 
702  compare();
703  }
704 
705  void
707  {
708  // Verify expiring clears out validations stored by ledger
709  testcase("Expire validations");
710  SuiteJournal j("Validations_test", *this);
712  TestHarness harness(h.oracle);
713  Node const a = harness.makeNode();
714  constexpr Ledger::Seq one(1);
715  constexpr Ledger::Seq two(2);
716 
717  // simple cases
718  Ledger const ledgerA = h["a"];
719  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
720  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
721  harness.vals().expire(j);
722  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
723  harness.clock().advance(harness.parms().validationSET_EXPIRES);
724  harness.vals().expire(j);
725  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 0);
726 
727  // use setSeqToKeep to keep the validation from expire
728  Ledger const ledgerB = h["ab"];
729  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerB)));
730  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerB.id()) == 1);
731  harness.vals().setSeqToKeep(ledgerB.seq(), ledgerB.seq() + one);
732  harness.clock().advance(harness.parms().validationSET_EXPIRES);
733  harness.vals().expire(j);
734  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerB.id()) == 1);
735  // change toKeep
736  harness.vals().setSeqToKeep(ledgerB.seq() + one, ledgerB.seq() + two);
737  // advance clock slowly
738  int const loops = harness.parms().validationSET_EXPIRES /
739  harness.parms().validationFRESHNESS +
740  1;
741  for (int i = 0; i < loops; ++i)
742  {
743  harness.clock().advance(harness.parms().validationFRESHNESS);
744  harness.vals().expire(j);
745  }
746  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerB.id()) == 0);
747 
748  // Allow the validation with high seq to expire
749  Ledger const ledgerC = h["abc"];
750  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerC)));
751  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerC.id()) == 1);
752  harness.vals().setSeqToKeep(ledgerC.seq() - one, ledgerC.seq());
753  harness.clock().advance(harness.parms().validationSET_EXPIRES);
754  harness.vals().expire(j);
755  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerC.id()) == 0);
756  }
757 
758  void
760  {
761  // Test final flush of validations
762  using namespace std::chrono_literals;
763  testcase("Flush validations");
764 
766  TestHarness harness(h.oracle);
767  Node a = harness.makeNode(), b = harness.makeNode(),
768  c = harness.makeNode();
769  c.untrust();
770 
771  Ledger ledgerA = h["a"];
772  Ledger ledgerAB = h["ab"];
773 
775  for (auto const& node : {a, b, c})
776  {
777  auto const val = node.validate(ledgerA);
778  BEAST_EXPECT(ValStatus::current == harness.add(val));
779  expected.emplace(node.nodeID(), val);
780  }
781 
782  // Send in a new validation for a, saving the new one into the expected
783  // map after setting the proper prior ledger ID it replaced
784  harness.clock().advance(1s);
785  auto newVal = a.validate(ledgerAB);
786  BEAST_EXPECT(ValStatus::current == harness.add(newVal));
787  expected.find(a.nodeID())->second = newVal;
788  }
789 
790  void
792  {
793  using namespace std::chrono_literals;
794  testcase("Preferred Ledger");
795 
797  TestHarness harness(h.oracle);
798  Node a = harness.makeNode(), b = harness.makeNode(),
799  c = harness.makeNode(), d = harness.makeNode();
800  c.untrust();
801 
802  Ledger ledgerA = h["a"];
803  Ledger ledgerB = h["b"];
804  Ledger ledgerAC = h["ac"];
805  Ledger ledgerACD = h["acd"];
806 
807  using Seq = Ledger::Seq;
808  using ID = Ledger::ID;
809 
810  auto pref = [](Ledger ledger) {
811  return std::make_pair(ledger.seq(), ledger.id());
812  };
813 
814  // Empty (no ledgers)
815  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == std::nullopt);
816 
817  // Single ledger
818  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerB)));
819  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
820  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
821 
822  // Minimum valid sequence
823  BEAST_EXPECT(
824  harness.vals().getPreferred(ledgerA, Seq{10}) == ledgerA.id());
825 
826  // Untrusted doesn't impact preferred ledger
827  // (ledgerB has tie-break over ledgerA)
828  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
829  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerA)));
830  BEAST_EXPECT(ledgerB.id() > ledgerA.id());
831  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
832  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
833 
834  // Partial does break ties
835  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerA)));
836  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
837  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerA));
838 
839  harness.clock().advance(5s);
840 
841  // Parent of preferred-> stick with ledger
842  for (auto const& node : {a, b, c, d})
843  BEAST_EXPECT(
844  ValStatus::current == harness.add(node.validate(ledgerAC)));
845  // Parent of preferred stays put
846  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
847  // Earlier different chain, switch
848  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerAC));
849  // Later on chain, stays where it is
850  BEAST_EXPECT(harness.vals().getPreferred(ledgerACD) == pref(ledgerACD));
851 
852  // Any later grandchild or different chain is preferred
853  harness.clock().advance(5s);
854  for (auto const& node : {a, b, c, d})
855  BEAST_EXPECT(
856  ValStatus::current == harness.add(node.validate(ledgerACD)));
857  for (auto const& ledger : {ledgerA, ledgerB, ledgerACD})
858  BEAST_EXPECT(
859  harness.vals().getPreferred(ledger) == pref(ledgerACD));
860  }
861 
862  void
864  {
865  using namespace std::chrono_literals;
866  testcase("Get preferred LCL");
867 
869  TestHarness harness(h.oracle);
870  Node a = harness.makeNode();
871 
872  Ledger ledgerA = h["a"];
873  Ledger ledgerB = h["b"];
874  Ledger ledgerC = h["c"];
875 
876  using ID = Ledger::ID;
877  using Seq = Ledger::Seq;
878 
879  hash_map<ID, std::uint32_t> peerCounts;
880 
881  // No trusted validations or counts sticks with current ledger
882  BEAST_EXPECT(
883  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
884  ledgerA.id());
885 
886  ++peerCounts[ledgerB.id()];
887 
888  // No trusted validations, rely on peer counts
889  BEAST_EXPECT(
890  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
891  ledgerB.id());
892 
893  ++peerCounts[ledgerC.id()];
894  // No trusted validations, tied peers goes with larger ID
895  BEAST_EXPECT(ledgerC.id() > ledgerB.id());
896 
897  BEAST_EXPECT(
898  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
899  ledgerC.id());
900 
901  peerCounts[ledgerC.id()] += 1000;
902 
903  // Single trusted always wins over peer counts
904  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
905  BEAST_EXPECT(
906  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
907  ledgerA.id());
908  BEAST_EXPECT(
909  harness.vals().getPreferredLCL(ledgerB, Seq{0}, peerCounts) ==
910  ledgerA.id());
911  BEAST_EXPECT(
912  harness.vals().getPreferredLCL(ledgerC, Seq{0}, peerCounts) ==
913  ledgerA.id());
914 
915  // Stick with current ledger if trusted validation ledger has too old
916  // of a sequence
917  BEAST_EXPECT(
918  harness.vals().getPreferredLCL(ledgerB, Seq{2}, peerCounts) ==
919  ledgerB.id());
920  }
921 
922  void
924  {
925  using namespace std::chrono_literals;
926  testcase("Acquire validated ledger");
927 
929  TestHarness harness(h.oracle);
930  Node a = harness.makeNode();
931  Node b = harness.makeNode();
932 
933  using ID = Ledger::ID;
934  using Seq = Ledger::Seq;
935 
936  // Validate the ledger before it is actually available
937  Validation val = a.validate(ID{2}, Seq{2}, 0s, 0s, true);
938 
939  BEAST_EXPECT(ValStatus::current == harness.add(val));
940  // Validation is available
941  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{2}) == 1);
942  // but ledger based data is not
943  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 0);
944  // Initial preferred branch falls back to the ledger we are trying to
945  // acquire
946  BEAST_EXPECT(
947  harness.vals().getPreferred(genesisLedger) ==
948  std::make_pair(Seq{2}, ID{2}));
949 
950  // After adding another unavailable validation, the preferred ledger
951  // breaks ties via higher ID
952  BEAST_EXPECT(
954  harness.add(b.validate(ID{3}, Seq{2}, 0s, 0s, true)));
955  BEAST_EXPECT(
956  harness.vals().getPreferred(genesisLedger) ==
957  std::make_pair(Seq{2}, ID{3}));
958 
959  // Create the ledger
960  Ledger ledgerAB = h["ab"];
961  // Now it should be available
962  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 1);
963 
964  // Create a validation that is not available
965  harness.clock().advance(5s);
966  Validation val2 = a.validate(ID{4}, Seq{4}, 0s, 0s, true);
967  BEAST_EXPECT(ValStatus::current == harness.add(val2));
968  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 1);
969  BEAST_EXPECT(
970  harness.vals().getPreferred(genesisLedger) ==
971  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
972 
973  // Another node requesting that ledger still doesn't change things
974  Validation val3 = b.validate(ID{4}, Seq{4}, 0s, 0s, true);
975  BEAST_EXPECT(ValStatus::current == harness.add(val3));
976  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 2);
977  BEAST_EXPECT(
978  harness.vals().getPreferred(genesisLedger) ==
979  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
980 
981  // Switch to validation that is available
982  harness.clock().advance(5s);
983  Ledger ledgerABCDE = h["abcde"];
984  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerABCDE)));
985  BEAST_EXPECT(ValStatus::current == harness.add(b.partial(ledgerABCDE)));
986  BEAST_EXPECT(
987  harness.vals().getPreferred(genesisLedger) ==
988  std::make_pair(ledgerABCDE.seq(), ledgerABCDE.id()));
989  }
990 
991  void
993  {
994  testcase("NumTrustedForLedger");
996  TestHarness harness(h.oracle);
997  Node a = harness.makeNode();
998  Node b = harness.makeNode();
999  Ledger ledgerA = h["a"];
1000 
1001  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerA)));
1002  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 0);
1003 
1004  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
1005  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
1006  }
1007 
1008  void
1010  {
1011  testcase("SeqEnforcer");
1012  using Seq = Ledger::Seq;
1013  using namespace std::chrono;
1014 
1016  SeqEnforcer<Seq> enforcer;
1017 
1018  ValidationParms p;
1019 
1020  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
1021  BEAST_EXPECT(enforcer(clock.now(), Seq{10}, p));
1022  BEAST_EXPECT(!enforcer(clock.now(), Seq{5}, p));
1023  BEAST_EXPECT(!enforcer(clock.now(), Seq{9}, p));
1024  clock.advance(p.validationSET_EXPIRES - 1ms);
1025  BEAST_EXPECT(!enforcer(clock.now(), Seq{1}, p));
1026  clock.advance(2ms);
1027  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
1028  }
1029 
1030  void
1032  {
1033  testcase("TrustChanged");
1034  using namespace std::chrono;
1035 
1036  auto checker = [this](
1037  TestValidations& vals,
1038  hash_set<PeerID> const& listed,
1039  std::vector<Validation> const& trustedVals) {
1040  Ledger::ID testID = trustedVals.empty() ? this->genesisLedger.id()
1041  : trustedVals[0].ledgerID();
1042  Ledger::Seq testSeq = trustedVals.empty()
1043  ? this->genesisLedger.seq()
1044  : trustedVals[0].seq();
1045  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1046  BEAST_EXPECT(vals.getCurrentNodeIDs() == listed);
1047  BEAST_EXPECT(
1048  vals.getNodesAfter(this->genesisLedger, genesisLedger.id()) ==
1049  trustedVals.size());
1050  if (trustedVals.empty())
1051  BEAST_EXPECT(
1052  vals.getPreferred(this->genesisLedger) == std::nullopt);
1053  else
1054  BEAST_EXPECT(
1055  vals.getPreferred(this->genesisLedger)->second == testID);
1056  BEAST_EXPECT(
1057  vals.getTrustedForLedger(testID, testSeq) == trustedVals);
1058  BEAST_EXPECT(
1059  vals.numTrustedForLedger(testID) == trustedVals.size());
1060  };
1061 
1062  {
1063  // Trusted to untrusted
1065  TestHarness harness(h.oracle);
1066  Node a = harness.makeNode();
1067  Ledger ledgerAB = h["ab"];
1068  Validation v = a.validate(ledgerAB);
1069  BEAST_EXPECT(ValStatus::current == harness.add(v));
1070 
1071  hash_set<PeerID> listed({a.nodeID()});
1072  std::vector<Validation> trustedVals({v});
1073  checker(harness.vals(), listed, trustedVals);
1074 
1075  trustedVals.clear();
1076  harness.vals().trustChanged({}, {a.nodeID()});
1077  checker(harness.vals(), listed, trustedVals);
1078  }
1079 
1080  {
1081  // Untrusted to trusted
1083  TestHarness harness(h.oracle);
1084  Node a = harness.makeNode();
1085  a.untrust();
1086  Ledger ledgerAB = h["ab"];
1087  Validation v = a.validate(ledgerAB);
1088  BEAST_EXPECT(ValStatus::current == harness.add(v));
1089 
1090  hash_set<PeerID> listed({a.nodeID()});
1091  std::vector<Validation> trustedVals;
1092  checker(harness.vals(), listed, trustedVals);
1093 
1094  trustedVals.push_back(v);
1095  harness.vals().trustChanged({a.nodeID()}, {});
1096  checker(harness.vals(), listed, trustedVals);
1097  }
1098 
1099  {
1100  // Trusted but not acquired -> untrusted
1102  TestHarness harness(h.oracle);
1103  Node a = harness.makeNode();
1104  Validation v =
1105  a.validate(Ledger::ID{2}, Ledger::Seq{2}, 0s, 0s, true);
1106  BEAST_EXPECT(ValStatus::current == harness.add(v));
1107 
1108  hash_set<PeerID> listed({a.nodeID()});
1109  std::vector<Validation> trustedVals({v});
1110  auto& vals = harness.vals();
1111  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1112  BEAST_EXPECT(
1113  vals.getPreferred(genesisLedger)->second == v.ledgerID());
1114  BEAST_EXPECT(
1115  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1116 
1117  trustedVals.clear();
1118  harness.vals().trustChanged({}, {a.nodeID()});
1119  // make acquiring ledger available
1120  h["ab"];
1121  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1122  BEAST_EXPECT(vals.getPreferred(genesisLedger) == std::nullopt);
1123  BEAST_EXPECT(
1124  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1125  }
1126  }
1127 
1128  void
1129  run() override
1130  {
1132  testOnStale();
1137  testExpire();
1138  testFlush();
1143  testSeqEnforcer();
1144  testTrustChanged();
1145  }
1146 };
1147 
1149 } // namespace csf
1150 } // namespace test
1151 } // namespace ripple
ripple::test::csf::Validations_test::TestHarness::parms
ValidationParms parms() const
Definition: Validations_test.cpp:246
ripple::test::csf::Validations_test::TestHarness
Definition: Validations_test.cpp:215
ripple::test::csf::Validations_test::Adaptor::Mutex
Definition: Validations_test.cpp:177
ripple::test::csf::Validations_test::testOnStale
void testOnStale()
Definition: Validations_test.cpp:407
ripple::test::csf::Validations_test::Node::now
NetClock::time_point now() const
Definition: Validations_test.cpp:107
ripple::test::csf::Validations_test::testCurrentTrusted
void testCurrentTrusted()
Definition: Validations_test.cpp:505
ripple::test::csf::Validations_test::Node::Node
Node(PeerID nodeID, clock_type const &c)
Definition: Validations_test.cpp:61
ripple::test::csf::Validations_test::TestHarness::clock_
beast::manual_clock< std::chrono::steady_clock > clock_
Definition: Validations_test.cpp:218
ripple::SeqEnforcer
Enforce validation increasing sequence requirement.
Definition: Validations.h:98
ripple::test::csf::Validations_test::testFlush
void testFlush()
Definition: Validations_test.cpp:759
ripple::test::csf::Validations_test::Node::validate
Validation validate(Ledger ledger) const
Definition: Validations_test.cpp:147
ripple::test::csf::Validations_test::Node::masterKey
PeerKey masterKey() const
Definition: Validations_test.cpp:102
std::unordered_set
STL class.
std::pair< PeerID, std::uint32_t >
ripple::Validations::fees
std::vector< std::uint32_t > fees(ID const &ledgerID, std::uint32_t baseFee)
Returns fees reported by trusted full validators in the given ledger.
Definition: Validations.h:1079
ripple::test::csf::Validations_test::Adaptor::acquire
std::optional< Ledger > acquire(Ledger::ID const &id)
Definition: Validations_test.cpp:204
vector
std::unordered_map::find
T find(T... args)
ripple::Validations::trustChanged
void trustChanged(hash_set< NodeID > const &added, hash_set< NodeID > const &removed)
Update trust status of validations.
Definition: Validations.h:792
ripple::test::csf::Validations_test::TestHarness::makeNode
Node makeNode()
Definition: Validations_test.cpp:240
ripple::test::csf::Validations_test::genesisLedger
const Ledger genesisLedger
Definition: Validations_test.cpp:258
ripple::Validations::getPreferredLCL
ID getPreferredLCL(Ledger const &lcl, Seq minSeq, hash_map< ID, std::uint32_t > const &peerCounts)
Determine the preferred last closed ledger for the next consensus round.
Definition: Validations.h:933
std::chrono::duration
ripple::test::csf::Validation::nodeID
PeerID const & nodeID() const
Definition: Validation.h:118
std::unordered_map::emplace
T emplace(T... args)
ripple::ValStatus
ValStatus
Status of validation we received.
Definition: Validations.h:168
ripple::ValidationParms::validationCURRENT_EARLY
std::chrono::seconds validationCURRENT_EARLY
Duration pre-close in which validations are acceptable.
Definition: Validations.h:70
ripple::test::csf::Validations_test::TestHarness::add
ValStatus add(Validation const &v)
Definition: Validations_test.cpp:228
ripple::test::csf::Validations_test::Node::untrust
void untrust()
Definition: Validations_test.cpp:66
ripple::test::csf::Validations_test::Node::loadFee_
std::optional< std::uint32_t > loadFee_
Definition: Validations_test.cpp:58
tuple
ripple::test::csf::Ledger
A ledger is a set of observed transactions and a sequence number identifying the ledger.
Definition: ledgers.h:58
ripple::test::csf::Ledger::seq
Seq seq() const
Definition: ledgers.h:173
std::function
ripple::test::csf::Validations_test::testGetNodesAfter
void testGetNodesAfter()
Definition: Validations_test.cpp:452
std::sort
T sort(T... args)
ripple::test::csf::Validations_test::Node
Definition: Validations_test.cpp:52
ripple::test::csf::Ledger::MakeGenesis
Definition: ledgers.h:69
ripple::test::csf::Validations_test::clock_type
beast::abstract_clock< std::chrono::steady_clock > const clock_type
Definition: Validations_test.cpp:36
ripple::test::csf::LedgerHistoryHelper
Helper for writing unit tests with controlled ledger histories.
Definition: ledgers.h:323
std::vector::push_back
T push_back(T... args)
ripple::ValStatus::badSeq
@ badSeq
A validation violates the increasing seq requirement.
ripple::test::csf::LedgerOracle::lookup
std::optional< Ledger > lookup(Ledger::ID const &id) const
Find the ledger with the given ID.
Definition: ledgers.cpp:129
ripple::test::csf::Validations_test::Node::nodeID
PeerID nodeID() const
Definition: Validations_test.cpp:84
ripple::test::csf::Validations_test::testTrustChanged
void testTrustChanged()
Definition: Validations_test.cpp:1031
ripple::test::csf::Validations_test::Adaptor::c_
clock_type & c_
Definition: Validations_test.cpp:172
ripple::test::csf::Validations_test::TestHarness::TestHarness
TestHarness(LedgerOracle &o)
Definition: Validations_test.cpp:223
ripple::test::csf::Validations_test::TestHarness::vals
TestValidations & vals()
Definition: Validations_test.cpp:234
ripple::Validations::add
ValStatus add(NodeID const &nodeID, Validation const &val)
Add a new validation.
Definition: Validations.h:622
ripple::test::csf::Validations_test::Node::partial
Validation partial(Ledger ledger) const
Definition: Validations_test.cpp:158
ripple::test::csf::Validations_test::TestHarness::clock
auto & clock()
Definition: Validations_test.cpp:252
ripple::test::csf::Validations_test::Node::setLoadFee
void setLoadFee(std::uint32_t fee)
Definition: Validations_test.cpp:78
ripple::Validations::getNodesAfter
std::size_t getNodesAfter(Ledger const &ledger, ID const &ledgerID)
Count the number of current trusted validators working on a ledger after the specified one.
Definition: Validations.h:971
ripple::Validations::numTrustedForLedger
std::size_t numTrustedForLedger(ID const &ledgerID)
Count the number of trusted full validations for the given ledger.
Definition: Validations.h:1034
ripple::test::csf::LedgerOracle
Oracle maintaining unique ledgers for a simulation.
Definition: ledgers.h:244
ripple::test::csf::LedgerHistoryHelper::oracle
LedgerOracle oracle
Definition: ledgers.h:325
ripple::test::csf::Validations_test::Node::advanceKey
void advanceKey()
Definition: Validations_test.cpp:90
std::chrono::time_point
ripple::ValStatus::stale
@ stale
Not current or was older than current from this node.
ripple::test::csf::Validations_test::testGetCurrentPublicKeys
void testGetCurrentPublicKeys()
Definition: Validations_test.cpp:547
ripple::ValStatus::current
@ current
This was a new validation and was added.
ripple::ValidationParms::validationCURRENT_LOCAL
std::chrono::seconds validationCURRENT_LOCAL
Duration a validation remains current after first observed.
Definition: Validations.h:63
std::uint32_t
ripple::test::csf::Validations_test::Node::c_
clock_type const & c_
Definition: Validations_test.cpp:54
ripple::ValidationParms::validationCURRENT_WALL
std::chrono::seconds validationCURRENT_WALL
The number of seconds a validation remains current after its ledger's close time.
Definition: Validations.h:55
ripple::test::csf::Validations_test::Node::validate
Validation validate(Ledger ledger, NetClock::duration signOffset, NetClock::duration seenOffset) const
Definition: Validations_test.cpp:137
beast::abstract_clock< std::chrono::steady_clock >
memory
ripple::test::jtx::fee
Set the fee on a JTx.
Definition: fee.h:35
ripple::test::SuiteJournal
Definition: SuiteJournal.h:88
ripple::test::csf::Validations_test::testTrustedByLedgerFunctions
void testTrustedByLedgerFunctions()
Definition: Validations_test.cpp:590
ripple::test::csf::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(Validations, consensus, ripple)
ripple::test::csf::Validations_test::TestHarness::nextNodeId_
PeerID nextNodeId_
Definition: Validations_test.cpp:220
ripple::ValStatus::conflicting
@ conflicting
Multiple validations by a validator for different ledgers.
ripple::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:33
ripple::one
constexpr Number one
Definition: Number.cpp:169
ripple::test::csf::Ledger::id
ID id() const
Definition: ledgers.h:167
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::csf::Validations_test::TestHarness::tv_
TestValidations tv_
Definition: Validations_test.cpp:219
ripple::test::csf::Validations_test::Node::nodeID_
PeerID nodeID_
Definition: Validations_test.cpp:55
ripple::ValidationParms::validationFRESHNESS
std::chrono::seconds validationFRESHNESS
How long we consider a validation fresh.
Definition: Validations.h:88
ripple::test::csf::Validations_test::testNumTrustedForLedger
void testNumTrustedForLedger()
Definition: Validations_test.cpp:992
ripple::test::csf::Validation
Validation of a specific ledger by a specific Peer.
Definition: Validation.h:47
ripple::ValidationParms::validationSET_EXPIRES
std::chrono::seconds validationSET_EXPIRES
Duration a set of validations for a given ledger hash remain valid.
Definition: Validations.h:78
ripple::test::csf::Ledger::ID
tagged_integer< std::uint32_t, IdTag > ID
Definition: ledgers.h:67
ripple::test::csf::Validations_test::run
void run() override
Definition: Validations_test.cpp:1129
ripple::Validations::setSeqToKeep
void setSeqToKeep(Seq const &low, Seq const &high)
Set the range [low, high) of validations to keep from expire.
Definition: Validations.h:714
ripple::test::csf::Validations_test::Adaptor
Definition: Validations_test.cpp:170
ripple::test::csf::Validations_test::Node::signIdx_
std::size_t signIdx_
Definition: Validations_test.cpp:57
ripple::test::csf::Ledger::Seq
tagged_integer< std::uint32_t, SeqTag > Seq
Definition: ledgers.h:64
ripple::test::csf::Validations_test::testSeqEnforcer
void testSeqEnforcer()
Definition: Validations_test.cpp:1009
ripple::test::csf::Validation::ledgerID
Ledger::ID ledgerID() const
Definition: Validation.h:88
ripple::Validations::getPreferred
std::optional< std::pair< Seq, ID > > getPreferred(Ledger const &curr)
Return the sequence number and ID of the preferred working ledger.
Definition: Validations.h:847
ripple::Validations
Maintains current and recent ledger validations.
Definition: Application.h:111
std::optional< std::uint32_t >
ripple::test::csf::Validations_test::Node::validate
Validation validate(Ledger::ID id, Ledger::Seq seq, NetClock::duration signOffset, NetClock::duration seenOffset, bool full) const
Definition: Validations_test.cpp:115
ripple::test::csf::Validations_test::Adaptor::Adaptor
Adaptor(clock_type &c, LedgerOracle &o)
Definition: Validations_test.cpp:193
std::size_t
std::make_pair
T make_pair(T... args)
ripple::test::csf::Validations_test::testExpire
void testExpire()
Definition: Validations_test.cpp:706
ripple::test::csf::Validations_test::Adaptor::now
NetClock::time_point now() const
Definition: Validations_test.cpp:198
ripple::test::csf::Validations_test
Definition: Validations_test.cpp:34
ripple::test::csf::Validations_test::Node::trusted_
bool trusted_
Definition: Validations_test.cpp:56
ripple::Validations::getCurrentNodeIDs
auto getCurrentNodeIDs() -> hash_set< NodeID >
Get the set of node ids associated with current validations.
Definition: Validations.h:1016
ripple::test::csf::Validations_test::TestHarness::p_
ValidationParms p_
Definition: Validations_test.cpp:217
ripple::tagged_integer< std::uint32_t, PeerIDTag >
ripple::test::csf::Validations_test::testGetPreferredLedger
void testGetPreferredLedger()
Definition: Validations_test.cpp:791
beast::manual_clock< std::chrono::steady_clock >
ripple::Validations::expire
void expire(beast::Journal &j)
Expire old validation sets.
Definition: Validations.h:727
ripple::test::csf::Validations_test::Adaptor::Mutex::unlock
void unlock()
Definition: Validations_test.cpp:185
ripple::test::csf::Validations_test::testAcquireValidatedLedger
void testAcquireValidatedLedger()
Definition: Validations_test.cpp:923
ripple::test::csf::Validations_test::testAddValidation
void testAddValidation()
Definition: Validations_test.cpp:261
ripple::ValidationParms
Timing parameters to control validation staleness and expiration.
Definition: Validations.h:45
ripple::test::csf::Validations_test::Node::trust
void trust()
Definition: Validations_test.cpp:72
ripple::Validations::getTrustedForLedger
std::vector< WrappedValidationType > getTrustedForLedger(ID const &ledgerID, Seq const &seq)
Get trusted full validations for a specific ledger.
Definition: Validations.h:1056
std::unordered_map
STL class.
ripple::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition: chrono.h:56
ripple::test::csf::Validations_test::Adaptor::oracle_
LedgerOracle & oracle_
Definition: Validations_test.cpp:173
type_traits
ripple::test::csf::Validations_test::testGetPreferredLCL
void testGetPreferredLCL()
Definition: Validations_test.cpp:863
ripple::Validations::currentTrusted
std::vector< WrappedValidationType > currentTrusted()
Get the currently trusted full validations.
Definition: Validations.h:997
ripple::test::csf::Validations_test::toNetClock
static NetClock::time_point toNetClock(clock_type const &c)
Definition: Validations_test.cpp:41
ripple::test::csf::Validations_test::Node::currKey
PeerKey currKey() const
Definition: Validations_test.cpp:96
std::chrono
ripple::test::csf::Validations_test::Adaptor::Mutex::lock
void lock()
Definition: Validations_test.cpp:180