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 
618  //----------------------------------------------------------------------
619  // checkers
620  auto sorted = [](auto vec) {
621  std::sort(vec.begin(), vec.end());
622  return vec;
623  };
624  auto compare = [&]() {
625  for (auto& it : trustedValidations)
626  {
627  auto const& id = it.first;
628  auto const& expectedValidations = it.second;
629 
630  BEAST_EXPECT(
631  harness.vals().numTrustedForLedger(id) ==
632  expectedValidations.size());
633  BEAST_EXPECT(
634  sorted(harness.vals().getTrustedForLedger(id)) ==
635  sorted(expectedValidations));
636 
637  std::uint32_t baseFee = 0;
638  std::vector<uint32_t> expectedFees;
639  for (auto const& val : expectedValidations)
640  {
641  expectedFees.push_back(val.loadFee().value_or(baseFee));
642  }
643 
644  BEAST_EXPECT(
645  sorted(harness.vals().fees(id, baseFee)) ==
646  sorted(expectedFees));
647  }
648  };
649 
650  //----------------------------------------------------------------------
651  Ledger ledgerA = h["a"];
652  Ledger ledgerB = h["b"];
653  Ledger ledgerAC = h["ac"];
654 
655  // Add a dummy ID to cover unknown ledger identifiers
656  trustedValidations[Ledger::ID{100}] = {};
657 
658  // first round a,b,c agree
659  for (auto const& node : {a, b, c})
660  {
661  auto const val = node.validate(ledgerA);
662  BEAST_EXPECT(ValStatus::current == harness.add(val));
663  if (val.trusted())
664  trustedValidations[val.ledgerID()].emplace_back(val);
665  }
666  // d disagrees
667  {
668  auto const val = d.validate(ledgerB);
669  BEAST_EXPECT(ValStatus::current == harness.add(val));
670  trustedValidations[val.ledgerID()].emplace_back(val);
671  }
672  // e only issues partials
673  {
674  BEAST_EXPECT(ValStatus::current == harness.add(e.partial(ledgerA)));
675  }
676 
677  harness.clock().advance(5s);
678  // second round, a,b,c move to ledger 2
679  for (auto const& node : {a, b, c})
680  {
681  auto const val = node.validate(ledgerAC);
682  BEAST_EXPECT(ValStatus::current == harness.add(val));
683  if (val.trusted())
684  trustedValidations[val.ledgerID()].emplace_back(val);
685  }
686  // d now thinks ledger 1, but cannot re-issue a previously used seq
687  // and attempting it should generate a conflict.
688  {
689  BEAST_EXPECT(
690  ValStatus::conflicting == harness.add(d.partial(ledgerA)));
691  }
692  // e only issues partials
693  {
694  BEAST_EXPECT(
695  ValStatus::current == harness.add(e.partial(ledgerAC)));
696  }
697 
698  compare();
699  }
700 
701  void
703  {
704  // Verify expiring clears out validations stored by ledger
705  testcase("Expire validations");
706  SuiteJournal j("Validations_test", *this);
708  TestHarness harness(h.oracle);
709  Node const a = harness.makeNode();
710  constexpr Ledger::Seq one(1);
711  constexpr Ledger::Seq two(2);
712 
713  // simple cases
714  Ledger const ledgerA = h["a"];
715  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
716  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
717  harness.vals().expire(j);
718  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
719  harness.clock().advance(harness.parms().validationSET_EXPIRES);
720  harness.vals().expire(j);
721  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 0);
722 
723  // use setSeqToKeep to keep the validation from expire
724  Ledger const ledgerB = h["ab"];
725  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerB)));
726  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerB.id()) == 1);
727  harness.vals().setSeqToKeep(ledgerB.seq(), ledgerB.seq() + one);
728  harness.clock().advance(harness.parms().validationSET_EXPIRES);
729  harness.vals().expire(j);
730  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerB.id()) == 1);
731  // change toKeep
732  harness.vals().setSeqToKeep(ledgerB.seq() + one, ledgerB.seq() + two);
733  // advance clock slowly
734  int const loops = harness.parms().validationSET_EXPIRES /
735  harness.parms().validationFRESHNESS +
736  1;
737  for (int i = 0; i < loops; ++i)
738  {
739  harness.clock().advance(harness.parms().validationFRESHNESS);
740  harness.vals().expire(j);
741  }
742  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerB.id()) == 0);
743 
744  // Allow the validation with high seq to expire
745  Ledger const ledgerC = h["abc"];
746  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerC)));
747  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerC.id()) == 1);
748  harness.vals().setSeqToKeep(ledgerC.seq() - one, ledgerC.seq());
749  harness.clock().advance(harness.parms().validationSET_EXPIRES);
750  harness.vals().expire(j);
751  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerC.id()) == 0);
752  }
753 
754  void
756  {
757  // Test final flush of validations
758  using namespace std::chrono_literals;
759  testcase("Flush validations");
760 
762  TestHarness harness(h.oracle);
763  Node a = harness.makeNode(), b = harness.makeNode(),
764  c = harness.makeNode();
765  c.untrust();
766 
767  Ledger ledgerA = h["a"];
768  Ledger ledgerAB = h["ab"];
769 
771  for (auto const& node : {a, b, c})
772  {
773  auto const val = node.validate(ledgerA);
774  BEAST_EXPECT(ValStatus::current == harness.add(val));
775  expected.emplace(node.nodeID(), val);
776  }
777 
778  // Send in a new validation for a, saving the new one into the expected
779  // map after setting the proper prior ledger ID it replaced
780  harness.clock().advance(1s);
781  auto newVal = a.validate(ledgerAB);
782  BEAST_EXPECT(ValStatus::current == harness.add(newVal));
783  expected.find(a.nodeID())->second = newVal;
784  }
785 
786  void
788  {
789  using namespace std::chrono_literals;
790  testcase("Preferred Ledger");
791 
793  TestHarness harness(h.oracle);
794  Node a = harness.makeNode(), b = harness.makeNode(),
795  c = harness.makeNode(), d = harness.makeNode();
796  c.untrust();
797 
798  Ledger ledgerA = h["a"];
799  Ledger ledgerB = h["b"];
800  Ledger ledgerAC = h["ac"];
801  Ledger ledgerACD = h["acd"];
802 
803  using Seq = Ledger::Seq;
804  using ID = Ledger::ID;
805 
806  auto pref = [](Ledger ledger) {
807  return std::make_pair(ledger.seq(), ledger.id());
808  };
809 
810  // Empty (no ledgers)
811  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == std::nullopt);
812 
813  // Single ledger
814  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerB)));
815  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
816  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
817 
818  // Minimum valid sequence
819  BEAST_EXPECT(
820  harness.vals().getPreferred(ledgerA, Seq{10}) == ledgerA.id());
821 
822  // Untrusted doesn't impact preferred ledger
823  // (ledgerB has tie-break over ledgerA)
824  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
825  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerA)));
826  BEAST_EXPECT(ledgerB.id() > ledgerA.id());
827  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
828  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
829 
830  // Partial does break ties
831  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerA)));
832  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
833  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerA));
834 
835  harness.clock().advance(5s);
836 
837  // Parent of preferred-> stick with ledger
838  for (auto const& node : {a, b, c, d})
839  BEAST_EXPECT(
840  ValStatus::current == harness.add(node.validate(ledgerAC)));
841  // Parent of preferred stays put
842  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
843  // Earlier different chain, switch
844  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerAC));
845  // Later on chain, stays where it is
846  BEAST_EXPECT(harness.vals().getPreferred(ledgerACD) == pref(ledgerACD));
847 
848  // Any later grandchild or different chain is preferred
849  harness.clock().advance(5s);
850  for (auto const& node : {a, b, c, d})
851  BEAST_EXPECT(
852  ValStatus::current == harness.add(node.validate(ledgerACD)));
853  for (auto const& ledger : {ledgerA, ledgerB, ledgerACD})
854  BEAST_EXPECT(
855  harness.vals().getPreferred(ledger) == pref(ledgerACD));
856  }
857 
858  void
860  {
861  using namespace std::chrono_literals;
862  testcase("Get preferred LCL");
863 
865  TestHarness harness(h.oracle);
866  Node a = harness.makeNode();
867 
868  Ledger ledgerA = h["a"];
869  Ledger ledgerB = h["b"];
870  Ledger ledgerC = h["c"];
871 
872  using ID = Ledger::ID;
873  using Seq = Ledger::Seq;
874 
875  hash_map<ID, std::uint32_t> peerCounts;
876 
877  // No trusted validations or counts sticks with current ledger
878  BEAST_EXPECT(
879  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
880  ledgerA.id());
881 
882  ++peerCounts[ledgerB.id()];
883 
884  // No trusted validations, rely on peer counts
885  BEAST_EXPECT(
886  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
887  ledgerB.id());
888 
889  ++peerCounts[ledgerC.id()];
890  // No trusted validations, tied peers goes with larger ID
891  BEAST_EXPECT(ledgerC.id() > ledgerB.id());
892 
893  BEAST_EXPECT(
894  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
895  ledgerC.id());
896 
897  peerCounts[ledgerC.id()] += 1000;
898 
899  // Single trusted always wins over peer counts
900  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
901  BEAST_EXPECT(
902  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
903  ledgerA.id());
904  BEAST_EXPECT(
905  harness.vals().getPreferredLCL(ledgerB, Seq{0}, peerCounts) ==
906  ledgerA.id());
907  BEAST_EXPECT(
908  harness.vals().getPreferredLCL(ledgerC, Seq{0}, peerCounts) ==
909  ledgerA.id());
910 
911  // Stick with current ledger if trusted validation ledger has too old
912  // of a sequence
913  BEAST_EXPECT(
914  harness.vals().getPreferredLCL(ledgerB, Seq{2}, peerCounts) ==
915  ledgerB.id());
916  }
917 
918  void
920  {
921  using namespace std::chrono_literals;
922  testcase("Acquire validated ledger");
923 
925  TestHarness harness(h.oracle);
926  Node a = harness.makeNode();
927  Node b = harness.makeNode();
928 
929  using ID = Ledger::ID;
930  using Seq = Ledger::Seq;
931 
932  // Validate the ledger before it is actually available
933  Validation val = a.validate(ID{2}, Seq{2}, 0s, 0s, true);
934 
935  BEAST_EXPECT(ValStatus::current == harness.add(val));
936  // Validation is available
937  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{2}) == 1);
938  // but ledger based data is not
939  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 0);
940  // Initial preferred branch falls back to the ledger we are trying to
941  // acquire
942  BEAST_EXPECT(
943  harness.vals().getPreferred(genesisLedger) ==
944  std::make_pair(Seq{2}, ID{2}));
945 
946  // After adding another unavailable validation, the preferred ledger
947  // breaks ties via higher ID
948  BEAST_EXPECT(
950  harness.add(b.validate(ID{3}, Seq{2}, 0s, 0s, true)));
951  BEAST_EXPECT(
952  harness.vals().getPreferred(genesisLedger) ==
953  std::make_pair(Seq{2}, ID{3}));
954 
955  // Create the ledger
956  Ledger ledgerAB = h["ab"];
957  // Now it should be available
958  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 1);
959 
960  // Create a validation that is not available
961  harness.clock().advance(5s);
962  Validation val2 = a.validate(ID{4}, Seq{4}, 0s, 0s, true);
963  BEAST_EXPECT(ValStatus::current == harness.add(val2));
964  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 1);
965  BEAST_EXPECT(
966  harness.vals().getPreferred(genesisLedger) ==
967  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
968 
969  // Another node requesting that ledger still doesn't change things
970  Validation val3 = b.validate(ID{4}, Seq{4}, 0s, 0s, true);
971  BEAST_EXPECT(ValStatus::current == harness.add(val3));
972  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 2);
973  BEAST_EXPECT(
974  harness.vals().getPreferred(genesisLedger) ==
975  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
976 
977  // Switch to validation that is available
978  harness.clock().advance(5s);
979  Ledger ledgerABCDE = h["abcde"];
980  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerABCDE)));
981  BEAST_EXPECT(ValStatus::current == harness.add(b.partial(ledgerABCDE)));
982  BEAST_EXPECT(
983  harness.vals().getPreferred(genesisLedger) ==
984  std::make_pair(ledgerABCDE.seq(), ledgerABCDE.id()));
985  }
986 
987  void
989  {
990  testcase("NumTrustedForLedger");
992  TestHarness harness(h.oracle);
993  Node a = harness.makeNode();
994  Node b = harness.makeNode();
995  Ledger ledgerA = h["a"];
996 
997  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerA)));
998  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 0);
999 
1000  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
1001  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
1002  }
1003 
1004  void
1006  {
1007  testcase("SeqEnforcer");
1008  using Seq = Ledger::Seq;
1009  using namespace std::chrono;
1010 
1012  SeqEnforcer<Seq> enforcer;
1013 
1014  ValidationParms p;
1015 
1016  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
1017  BEAST_EXPECT(enforcer(clock.now(), Seq{10}, p));
1018  BEAST_EXPECT(!enforcer(clock.now(), Seq{5}, p));
1019  BEAST_EXPECT(!enforcer(clock.now(), Seq{9}, p));
1020  clock.advance(p.validationSET_EXPIRES - 1ms);
1021  BEAST_EXPECT(!enforcer(clock.now(), Seq{1}, p));
1022  clock.advance(2ms);
1023  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
1024  }
1025 
1026  void
1028  {
1029  testcase("TrustChanged");
1030  using namespace std::chrono;
1031 
1032  auto checker = [this](
1033  TestValidations& vals,
1034  hash_set<PeerID> const& listed,
1035  std::vector<Validation> const& trustedVals) {
1036  Ledger::ID testID = trustedVals.empty() ? this->genesisLedger.id()
1037  : trustedVals[0].ledgerID();
1038  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1039  BEAST_EXPECT(vals.getCurrentNodeIDs() == listed);
1040  BEAST_EXPECT(
1041  vals.getNodesAfter(this->genesisLedger, genesisLedger.id()) ==
1042  trustedVals.size());
1043  if (trustedVals.empty())
1044  BEAST_EXPECT(
1045  vals.getPreferred(this->genesisLedger) == std::nullopt);
1046  else
1047  BEAST_EXPECT(
1048  vals.getPreferred(this->genesisLedger)->second == testID);
1049  BEAST_EXPECT(vals.getTrustedForLedger(testID) == trustedVals);
1050  BEAST_EXPECT(
1051  vals.numTrustedForLedger(testID) == trustedVals.size());
1052  };
1053 
1054  {
1055  // Trusted to untrusted
1057  TestHarness harness(h.oracle);
1058  Node a = harness.makeNode();
1059  Ledger ledgerAB = h["ab"];
1060  Validation v = a.validate(ledgerAB);
1061  BEAST_EXPECT(ValStatus::current == harness.add(v));
1062 
1063  hash_set<PeerID> listed({a.nodeID()});
1064  std::vector<Validation> trustedVals({v});
1065  checker(harness.vals(), listed, trustedVals);
1066 
1067  trustedVals.clear();
1068  harness.vals().trustChanged({}, {a.nodeID()});
1069  checker(harness.vals(), listed, trustedVals);
1070  }
1071 
1072  {
1073  // Untrusted to trusted
1075  TestHarness harness(h.oracle);
1076  Node a = harness.makeNode();
1077  a.untrust();
1078  Ledger ledgerAB = h["ab"];
1079  Validation v = a.validate(ledgerAB);
1080  BEAST_EXPECT(ValStatus::current == harness.add(v));
1081 
1082  hash_set<PeerID> listed({a.nodeID()});
1083  std::vector<Validation> trustedVals;
1084  checker(harness.vals(), listed, trustedVals);
1085 
1086  trustedVals.push_back(v);
1087  harness.vals().trustChanged({a.nodeID()}, {});
1088  checker(harness.vals(), listed, trustedVals);
1089  }
1090 
1091  {
1092  // Trusted but not acquired -> untrusted
1094  TestHarness harness(h.oracle);
1095  Node a = harness.makeNode();
1096  Validation v =
1097  a.validate(Ledger::ID{2}, Ledger::Seq{2}, 0s, 0s, true);
1098  BEAST_EXPECT(ValStatus::current == harness.add(v));
1099 
1100  hash_set<PeerID> listed({a.nodeID()});
1101  std::vector<Validation> trustedVals({v});
1102  auto& vals = harness.vals();
1103  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1104  BEAST_EXPECT(
1105  vals.getPreferred(genesisLedger)->second == v.ledgerID());
1106  BEAST_EXPECT(
1107  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1108 
1109  trustedVals.clear();
1110  harness.vals().trustChanged({}, {a.nodeID()});
1111  // make acquiring ledger available
1112  h["ab"];
1113  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1114  BEAST_EXPECT(vals.getPreferred(genesisLedger) == std::nullopt);
1115  BEAST_EXPECT(
1116  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1117  }
1118  }
1119 
1120  void
1121  run() override
1122  {
1124  testOnStale();
1129  testExpire();
1130  testFlush();
1135  testSeqEnforcer();
1136  testTrustChanged();
1137  }
1138 };
1139 
1141 } // namespace csf
1142 } // namespace test
1143 } // 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:755
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:1078
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:1027
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::compare
int compare(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:553
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
ripple::Validations::getTrustedForLedger
std::vector< WrappedValidationType > getTrustedForLedger(ID const &ledgerID)
Get trusted full validations for a specific ledger.
Definition: Validations.h:1055
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::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:988
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:1121
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:1005
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:702
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:787
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:919
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
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:859
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