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 <test/csf/Validation.h>
25 
26 #include <memory>
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;
58  boost::optional<std::uint32_t> loadFee_;
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{id,
123  seq,
124  now() + signOffset,
125  now() + seenOffset,
126  currKey(),
127  nodeID_,
128  full,
129  loadFee_};
130  if (trusted_)
131  v.setTrusted();
132  return v;
133  }
134 
135  Validation
137  Ledger ledger,
138  NetClock::duration signOffset,
139  NetClock::duration seenOffset) const
140  {
141  return validate(
142  ledger.id(), ledger.seq(), signOffset, seenOffset, true);
143  }
144 
145  Validation
146  validate(Ledger ledger) const
147  {
148  return validate(
149  ledger.id(),
150  ledger.seq(),
153  true);
154  }
155 
156  Validation
157  partial(Ledger ledger) const
158  {
159  return validate(
160  ledger.id(),
161  ledger.seq(),
164  false);
165  }
166  };
167 
168  // Generic Validations adaptor
169  class Adaptor
170  {
173 
174  public:
175  // Non-locking mutex to avoid locks in generic Validations
176  struct Mutex
177  {
178  void
180  {
181  }
182 
183  void
185  {
186  }
187  };
188 
191 
193  : c_{c}, oracle_{o}
194  {
195  }
196 
198  now() const
199  {
200  return toNetClock(c_);
201  }
202 
203  boost::optional<Ledger>
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  : tv_(p_, clock_, clock_, o)
225  {
226  }
227 
228  ValStatus
229  add(Validation const& v)
230  {
231  return tv_.add(v.nodeID(), v);
232  }
233 
236  {
237  return tv_;
238  }
239 
240  Node
242  {
243  return Node(nextNodeId_++, clock_);
244  }
245 
247  parms() const
248  {
249  return p_;
250  }
251 
252  auto&
254  {
255  return clock_;
256  }
257  };
258 
260 
261  void
263  {
264  using namespace std::chrono_literals;
265 
266  testcase("Add validation");
268  Ledger ledgerA = h["a"];
269  Ledger ledgerAB = h["ab"];
270  Ledger ledgerAZ = h["az"];
271  Ledger ledgerABC = h["abc"];
272  Ledger ledgerABCD = h["abcd"];
273  Ledger ledgerABCDE = h["abcde"];
274 
275  {
276  TestHarness harness(h.oracle);
277  Node n = harness.makeNode();
278 
279  auto const v = n.validate(ledgerA);
280 
281  // Add a current validation
282  BEAST_EXPECT(ValStatus::current == harness.add(v));
283 
284  // Re-adding violates the increasing seq requirement for full
285  // validations
286  BEAST_EXPECT(ValStatus::badSeq == harness.add(v));
287 
288  harness.clock().advance(1s);
289 
290  BEAST_EXPECT(
291  ValStatus::current == harness.add(n.validate(ledgerAB)));
292 
293  // Test the node changing signing key
294 
295  // Confirm old ledger on hand, but not new ledger
296  BEAST_EXPECT(
297  harness.vals().numTrustedForLedger(ledgerAB.id()) == 1);
298  BEAST_EXPECT(
299  harness.vals().numTrustedForLedger(ledgerABC.id()) == 0);
300 
301  // Rotate signing keys
302  n.advanceKey();
303 
304  harness.clock().advance(1s);
305 
306  // Cannot re-do the same full validation sequence
307  BEAST_EXPECT(
308  ValStatus::badSeq == harness.add(n.validate(ledgerAB)));
309  // Cannot send the same partial validation sequence
310  BEAST_EXPECT(ValStatus::badSeq == 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::badSeq == 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) == boost::none);
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  {
688  BEAST_EXPECT(ValStatus::badSeq == harness.add(d.partial(ledgerA)));
689  }
690  // e only issues partials
691  {
692  BEAST_EXPECT(
693  ValStatus::current == harness.add(e.partial(ledgerAC)));
694  }
695 
696  compare();
697  }
698 
699  void
701  {
702  // Verify expiring clears out validations stored by ledger
703  testcase("Expire validations");
705  TestHarness harness(h.oracle);
706  Node a = harness.makeNode();
707 
708  Ledger ledgerA = h["a"];
709 
710  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
711  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()));
712  harness.clock().advance(harness.parms().validationSET_EXPIRES);
713  harness.vals().expire();
714  BEAST_EXPECT(!harness.vals().numTrustedForLedger(ledgerA.id()));
715  }
716 
717  void
719  {
720  // Test final flush of validations
721  using namespace std::chrono_literals;
722  testcase("Flush validations");
723 
725  TestHarness harness(h.oracle);
726  Node a = harness.makeNode(), b = harness.makeNode(),
727  c = harness.makeNode();
728  c.untrust();
729 
730  Ledger ledgerA = h["a"];
731  Ledger ledgerAB = h["ab"];
732 
734  for (auto const& node : {a, b, c})
735  {
736  auto const val = node.validate(ledgerA);
737  BEAST_EXPECT(ValStatus::current == harness.add(val));
738  expected.emplace(node.nodeID(), val);
739  }
740 
741  // Send in a new validation for a, saving the new one into the expected
742  // map after setting the proper prior ledger ID it replaced
743  harness.clock().advance(1s);
744  auto newVal = a.validate(ledgerAB);
745  BEAST_EXPECT(ValStatus::current == harness.add(newVal));
746  expected.find(a.nodeID())->second = newVal;
747  }
748 
749  void
751  {
752  using namespace std::chrono_literals;
753  testcase("Preferred Ledger");
754 
756  TestHarness harness(h.oracle);
757  Node a = harness.makeNode(), b = harness.makeNode(),
758  c = harness.makeNode(), d = harness.makeNode();
759  c.untrust();
760 
761  Ledger ledgerA = h["a"];
762  Ledger ledgerB = h["b"];
763  Ledger ledgerAC = h["ac"];
764  Ledger ledgerACD = h["acd"];
765 
766  using Seq = Ledger::Seq;
767  using ID = Ledger::ID;
768 
769  auto pref = [](Ledger ledger) {
770  return std::make_pair(ledger.seq(), ledger.id());
771  };
772 
773  // Empty (no ledgers)
774  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == boost::none);
775 
776  // Single ledger
777  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerB)));
778  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
779  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
780 
781  // Minimum valid sequence
782  BEAST_EXPECT(
783  harness.vals().getPreferred(ledgerA, Seq{10}) == ledgerA.id());
784 
785  // Untrusted doesn't impact preferred ledger
786  // (ledgerB has tie-break over ledgerA)
787  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
788  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerA)));
789  BEAST_EXPECT(ledgerB.id() > ledgerA.id());
790  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
791  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
792 
793  // Partial does break ties
794  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerA)));
795  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
796  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerA));
797 
798  harness.clock().advance(5s);
799 
800  // Parent of preferred-> stick with ledger
801  for (auto const& node : {a, b, c, d})
802  BEAST_EXPECT(
803  ValStatus::current == harness.add(node.validate(ledgerAC)));
804  // Parent of preferred stays put
805  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
806  // Earlier different chain, switch
807  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerAC));
808  // Later on chain, stays where it is
809  BEAST_EXPECT(harness.vals().getPreferred(ledgerACD) == pref(ledgerACD));
810 
811  // Any later grandchild or different chain is preferred
812  harness.clock().advance(5s);
813  for (auto const& node : {a, b, c, d})
814  BEAST_EXPECT(
815  ValStatus::current == harness.add(node.validate(ledgerACD)));
816  for (auto const& ledger : {ledgerA, ledgerB, ledgerACD})
817  BEAST_EXPECT(
818  harness.vals().getPreferred(ledger) == pref(ledgerACD));
819  }
820 
821  void
823  {
824  using namespace std::chrono_literals;
825  testcase("Get preferred LCL");
826 
828  TestHarness harness(h.oracle);
829  Node a = harness.makeNode();
830 
831  Ledger ledgerA = h["a"];
832  Ledger ledgerB = h["b"];
833  Ledger ledgerC = h["c"];
834 
835  using ID = Ledger::ID;
836  using Seq = Ledger::Seq;
837 
838  hash_map<ID, std::uint32_t> peerCounts;
839 
840  // No trusted validations or counts sticks with current ledger
841  BEAST_EXPECT(
842  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
843  ledgerA.id());
844 
845  ++peerCounts[ledgerB.id()];
846 
847  // No trusted validations, rely on peer counts
848  BEAST_EXPECT(
849  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
850  ledgerB.id());
851 
852  ++peerCounts[ledgerC.id()];
853  // No trusted validations, tied peers goes with larger ID
854  BEAST_EXPECT(ledgerC.id() > ledgerB.id());
855 
856  BEAST_EXPECT(
857  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
858  ledgerC.id());
859 
860  peerCounts[ledgerC.id()] += 1000;
861 
862  // Single trusted always wins over peer counts
863  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
864  BEAST_EXPECT(
865  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
866  ledgerA.id());
867  BEAST_EXPECT(
868  harness.vals().getPreferredLCL(ledgerB, Seq{0}, peerCounts) ==
869  ledgerA.id());
870  BEAST_EXPECT(
871  harness.vals().getPreferredLCL(ledgerC, Seq{0}, peerCounts) ==
872  ledgerA.id());
873 
874  // Stick with current ledger if trusted validation ledger has too old
875  // of a sequence
876  BEAST_EXPECT(
877  harness.vals().getPreferredLCL(ledgerB, Seq{2}, peerCounts) ==
878  ledgerB.id());
879  }
880 
881  void
883  {
884  using namespace std::chrono_literals;
885  testcase("Acquire validated ledger");
886 
888  TestHarness harness(h.oracle);
889  Node a = harness.makeNode();
890  Node b = harness.makeNode();
891 
892  using ID = Ledger::ID;
893  using Seq = Ledger::Seq;
894 
895  // Validate the ledger before it is actually available
896  Validation val = a.validate(ID{2}, Seq{2}, 0s, 0s, true);
897 
898  BEAST_EXPECT(ValStatus::current == harness.add(val));
899  // Validation is available
900  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{2}) == 1);
901  // but ledger based data is not
902  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 0);
903  // Initial preferred branch falls back to the ledger we are trying to
904  // acquire
905  BEAST_EXPECT(
906  harness.vals().getPreferred(genesisLedger) ==
907  std::make_pair(Seq{2}, ID{2}));
908 
909  // After adding another unavailable validation, the preferred ledger
910  // breaks ties via higher ID
911  BEAST_EXPECT(
913  harness.add(b.validate(ID{3}, Seq{2}, 0s, 0s, true)));
914  BEAST_EXPECT(
915  harness.vals().getPreferred(genesisLedger) ==
916  std::make_pair(Seq{2}, ID{3}));
917 
918  // Create the ledger
919  Ledger ledgerAB = h["ab"];
920  // Now it should be available
921  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 1);
922 
923  // Create a validation that is not available
924  harness.clock().advance(5s);
925  Validation val2 = a.validate(ID{4}, Seq{4}, 0s, 0s, true);
926  BEAST_EXPECT(ValStatus::current == harness.add(val2));
927  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 1);
928  BEAST_EXPECT(
929  harness.vals().getPreferred(genesisLedger) ==
930  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
931 
932  // Another node requesting that ledger still doesn't change things
933  Validation val3 = b.validate(ID{4}, Seq{4}, 0s, 0s, true);
934  BEAST_EXPECT(ValStatus::current == harness.add(val3));
935  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 2);
936  BEAST_EXPECT(
937  harness.vals().getPreferred(genesisLedger) ==
938  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
939 
940  // Switch to validation that is available
941  harness.clock().advance(5s);
942  Ledger ledgerABCDE = h["abcde"];
943  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerABCDE)));
944  BEAST_EXPECT(ValStatus::current == harness.add(b.partial(ledgerABCDE)));
945  BEAST_EXPECT(
946  harness.vals().getPreferred(genesisLedger) ==
947  std::make_pair(ledgerABCDE.seq(), ledgerABCDE.id()));
948  }
949 
950  void
952  {
953  testcase("NumTrustedForLedger");
955  TestHarness harness(h.oracle);
956  Node a = harness.makeNode();
957  Node b = harness.makeNode();
958  Ledger ledgerA = h["a"];
959 
960  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerA)));
961  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 0);
962 
963  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
964  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
965  }
966 
967  void
969  {
970  testcase("SeqEnforcer");
971  using Seq = Ledger::Seq;
972  using namespace std::chrono;
973 
975  SeqEnforcer<Seq> enforcer;
976 
977  ValidationParms p;
978 
979  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
980  BEAST_EXPECT(enforcer(clock.now(), Seq{10}, p));
981  BEAST_EXPECT(!enforcer(clock.now(), Seq{5}, p));
982  BEAST_EXPECT(!enforcer(clock.now(), Seq{9}, p));
983  clock.advance(p.validationSET_EXPIRES - 1ms);
984  BEAST_EXPECT(!enforcer(clock.now(), Seq{1}, p));
985  clock.advance(2ms);
986  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
987  }
988 
989  void
991  {
992  testcase("TrustChanged");
993  using namespace std::chrono;
994 
995  auto checker = [this](
996  TestValidations& vals,
997  hash_set<PeerID> const& listed,
998  std::vector<Validation> const& trustedVals) {
999  Ledger::ID testID = trustedVals.empty() ? this->genesisLedger.id()
1000  : trustedVals[0].ledgerID();
1001  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1002  BEAST_EXPECT(vals.getCurrentNodeIDs() == listed);
1003  BEAST_EXPECT(
1004  vals.getNodesAfter(this->genesisLedger, genesisLedger.id()) ==
1005  trustedVals.size());
1006  if (trustedVals.empty())
1007  BEAST_EXPECT(
1008  vals.getPreferred(this->genesisLedger) == boost::none);
1009  else
1010  BEAST_EXPECT(
1011  vals.getPreferred(this->genesisLedger)->second == testID);
1012  BEAST_EXPECT(vals.getTrustedForLedger(testID) == trustedVals);
1013  BEAST_EXPECT(
1014  vals.numTrustedForLedger(testID) == trustedVals.size());
1015  };
1016 
1017  {
1018  // Trusted to untrusted
1020  TestHarness harness(h.oracle);
1021  Node a = harness.makeNode();
1022  Ledger ledgerAB = h["ab"];
1023  Validation v = a.validate(ledgerAB);
1024  BEAST_EXPECT(ValStatus::current == harness.add(v));
1025 
1026  hash_set<PeerID> listed({a.nodeID()});
1027  std::vector<Validation> trustedVals({v});
1028  checker(harness.vals(), listed, trustedVals);
1029 
1030  trustedVals.clear();
1031  harness.vals().trustChanged({}, {a.nodeID()});
1032  checker(harness.vals(), listed, trustedVals);
1033  }
1034 
1035  {
1036  // Untrusted to trusted
1038  TestHarness harness(h.oracle);
1039  Node a = harness.makeNode();
1040  a.untrust();
1041  Ledger ledgerAB = h["ab"];
1042  Validation v = a.validate(ledgerAB);
1043  BEAST_EXPECT(ValStatus::current == harness.add(v));
1044 
1045  hash_set<PeerID> listed({a.nodeID()});
1046  std::vector<Validation> trustedVals;
1047  checker(harness.vals(), listed, trustedVals);
1048 
1049  trustedVals.push_back(v);
1050  harness.vals().trustChanged({a.nodeID()}, {});
1051  checker(harness.vals(), listed, trustedVals);
1052  }
1053 
1054  {
1055  // Trusted but not acquired -> untrusted
1057  TestHarness harness(h.oracle);
1058  Node a = harness.makeNode();
1059  Validation v =
1060  a.validate(Ledger::ID{2}, Ledger::Seq{2}, 0s, 0s, true);
1061  BEAST_EXPECT(ValStatus::current == harness.add(v));
1062 
1063  hash_set<PeerID> listed({a.nodeID()});
1064  std::vector<Validation> trustedVals({v});
1065  auto& vals = harness.vals();
1066  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1067  BEAST_EXPECT(
1068  vals.getPreferred(genesisLedger)->second == v.ledgerID());
1069  BEAST_EXPECT(
1070  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1071 
1072  trustedVals.clear();
1073  harness.vals().trustChanged({}, {a.nodeID()});
1074  // make acquiring ledger available
1075  h["ab"];
1076  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1077  BEAST_EXPECT(vals.getPreferred(genesisLedger) == boost::none);
1078  BEAST_EXPECT(
1079  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1080  }
1081  }
1082 
1083  void
1084  run() override
1085  {
1087  testOnStale();
1092  testExpire();
1093  testFlush();
1098  testSeqEnforcer();
1099  testTrustChanged();
1100  }
1101 };
1102 
1104 } // namespace csf
1105 } // namespace test
1106 } // namespace ripple
ripple::Validations::expire
void expire()
Expire old validation sets.
Definition: Validations.h:627
ripple::test::csf::Validations_test::TestHarness::parms
ValidationParms parms() const
Definition: Validations_test.cpp:247
ripple::test::csf::Validations_test::TestHarness
Definition: Validations_test.cpp:215
ripple::test::csf::Validations_test::Adaptor::Mutex
Definition: Validations_test.cpp:176
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:96
ripple::test::csf::LedgerOracle::lookup
boost::optional< Ledger > lookup(Ledger::ID const &id) const
Find the ledger with the given ID.
Definition: ledgers.cpp:130
ripple::test::csf::Validations_test::testFlush
void testFlush()
Definition: Validations_test.cpp:718
ripple::test::csf::Validations_test::Node::validate
Validation validate(Ledger ledger) const
Definition: Validations_test.cpp:146
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:929
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:643
ripple::test::csf::Validations_test::TestHarness::makeNode
Node makeNode()
Definition: Validations_test.cpp:241
ripple::test::csf::Validations_test::genesisLedger
const Ledger genesisLedger
Definition: Validations_test.cpp:259
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:784
std::chrono::duration
std::unordered_map::emplace
T emplace(T... args)
ripple::ValStatus
ValStatus
Status of newly received validation.
Definition: Validations.h:164
ripple::ValidationParms::validationCURRENT_EARLY
std::chrono::seconds validationCURRENT_EARLY
Duration pre-close in which validations are acceptable.
Definition: Validations.h:68
ripple::test::csf::Validations_test::TestHarness::add
ValStatus add(Validation const &v)
Definition: Validations_test.cpp:229
ripple::test::csf::Validations_test::Node::untrust
void untrust()
Definition: Validations_test.cpp:66
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:163
std::function
ripple::test::csf::Validations_test::testGetNodesAfter
void testGetNodesAfter()
Definition: Validations_test.cpp:452
ripple::test::csf::Validation::nodeID
PeerID nodeID() const
Definition: Validation.h:114
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:312
std::vector::push_back
T push_back(T... args)
ripple::ValStatus::badSeq
@ badSeq
A validation violates the increasing seq requirement.
ripple::test::csf::Validations_test::Node::nodeID
PeerID nodeID() const
Definition: Validations_test.cpp:84
ripple::Validations::getPreferred
boost::optional< std::pair< Seq, ID > > getPreferred(Ledger const &curr)
Return the sequence number and ID of the preferred working ledger.
Definition: Validations.h:698
ripple::test::csf::Validations_test::testTrustChanged
void testTrustChanged()
Definition: Validations_test.cpp:990
ripple::test::csf::Validations_test::Adaptor::c_
clock_type & c_
Definition: Validations_test.cpp:171
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:235
ripple::Validations::add
ValStatus add(NodeID const &nodeID, Validation const &val)
Add a new validation.
Definition: Validations.h:581
ripple::test::csf::Validations_test::Node::partial
Validation partial(Ledger ledger) const
Definition: Validations_test.cpp:157
ripple::test::csf::Validations_test::TestHarness::clock
auto & clock()
Definition: Validations_test.cpp:253
ripple::compare
int compare(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:439
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:822
ripple::test::csf::Validations_test::Node::loadFee_
boost::optional< std::uint32_t > loadFee_
Definition: Validations_test.cpp:58
ripple::Validations::numTrustedForLedger
std::size_t numTrustedForLedger(ID const &ledgerID)
Count the number of trusted full validations for the given ledger.
Definition: Validations.h:885
ripple::test::csf::LedgerOracle
Oracle maintaining unique ledgers for a simulation.
Definition: ledgers.h:235
ripple::test::csf::LedgerHistoryHelper::oracle
LedgerOracle oracle
Definition: ledgers.h:314
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:61
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:53
ripple::test::csf::Validations_test::Node::validate
Validation validate(Ledger ledger, NetClock::duration signOffset, NetClock::duration seenOffset) const
Definition: Validations_test.cpp:136
ripple::Validations::getTrustedForLedger
std::vector< WrappedValidationType > getTrustedForLedger(ID const &ledgerID)
Get trusted full validations for a specific ledger.
Definition: Validations.h:906
beast::abstract_clock< std::chrono::steady_clock >
memory
ripple::test::jtx::fee
Set the fee on a JTx.
Definition: fee.h:34
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::test::jtx::seq
Set the sequence number on a JTx.
Definition: seq.h:32
ripple::test::csf::Ledger::id
ID id() const
Definition: ledgers.h:157
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::test::csf::Validations_test::testNumTrustedForLedger
void testNumTrustedForLedger()
Definition: Validations_test.cpp:951
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:76
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:1084
ripple::test::csf::Validations_test::Adaptor
Definition: Validations_test.cpp:169
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:968
ripple::test::csf::Validation::ledgerID
Ledger::ID ledgerID() const
Definition: Validation.h:84
ripple::Validations
Maintains current and recent ledger validations.
Definition: Application.h:81
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:192
std::size_t
std::make_pair
T make_pair(T... args)
ripple::test::csf::Validations_test::testExpire
void testExpire()
Definition: Validations_test.cpp:700
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:867
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:750
beast::manual_clock< std::chrono::steady_clock >
ripple::test::csf::Validations_test::Adaptor::Mutex::unlock
void unlock()
Definition: Validations_test.cpp:184
ripple::test::csf::Validations_test::testAcquireValidatedLedger
void testAcquireValidatedLedger()
Definition: Validations_test.cpp:882
ripple::test::csf::Validations_test::testAddValidation
void testAddValidation()
Definition: Validations_test.cpp:262
ripple::ValidationParms
Timing parameters to control validation staleness and expiration.
Definition: Validations.h:43
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:53
ripple::test::csf::Validations_test::Adaptor::oracle_
LedgerOracle & oracle_
Definition: Validations_test.cpp:172
type_traits
ripple::test::csf::Validations_test::testGetPreferredLCL
void testGetPreferredLCL()
Definition: Validations_test.cpp:822
ripple::Validations::currentTrusted
std::vector< WrappedValidationType > currentTrusted()
Get the currently trusted full validations.
Definition: Validations.h:848
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
ripple::test::csf::Validations_test::Adaptor::acquire
boost::optional< Ledger > acquire(Ledger::ID const &id)
Definition: Validations_test.cpp:204
std::chrono
ripple::test::csf::Validations_test::Adaptor::Mutex::lock
void lock()
Definition: Validations_test.cpp:179