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{
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 
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  {
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::badSeq == harness.add(n.validate(ledgerAB)));
308  // Cannot send the same partial validation sequence
309  BEAST_EXPECT(ValStatus::badSeq == harness.add(n.partial(ledgerAB)));
310 
311  // Now trusts the newest ledger too
312  harness.clock().advance(1s);
313  BEAST_EXPECT(
314  ValStatus::current == harness.add(n.validate(ledgerABC)));
315  BEAST_EXPECT(
316  harness.vals().numTrustedForLedger(ledgerAB.id()) == 1);
317  BEAST_EXPECT(
318  harness.vals().numTrustedForLedger(ledgerABC.id()) == 1);
319 
320  // Processing validations out of order should ignore the older
321  // validation
322  harness.clock().advance(2s);
323  auto const valABCDE = n.validate(ledgerABCDE);
324 
325  harness.clock().advance(4s);
326  auto const valABCD = n.validate(ledgerABCD);
327 
328  BEAST_EXPECT(ValStatus::current == harness.add(valABCD));
329 
330  BEAST_EXPECT(ValStatus::stale == harness.add(valABCDE));
331  }
332 
333  {
334  // Process validations out of order with shifted times
335 
336  TestHarness harness(h.oracle);
337  Node n = harness.makeNode();
338 
339  // Establish a new current validation
340  BEAST_EXPECT(
341  ValStatus::current == harness.add(n.validate(ledgerA)));
342 
343  // Process a validation that has "later" seq but early sign time
344  BEAST_EXPECT(
346  harness.add(n.validate(ledgerAB, -1s, -1s)));
347 
348  // Process a validation that has a later seq and later sign
349  // time
350  BEAST_EXPECT(
352  harness.add(n.validate(ledgerABC, 1s, 1s)));
353  }
354 
355  {
356  // Test stale on arrival validations
357  TestHarness harness(h.oracle);
358  Node n = harness.makeNode();
359 
360  BEAST_EXPECT(
362  harness.add(n.validate(
363  ledgerA, -harness.parms().validationCURRENT_EARLY, 0s)));
364 
365  BEAST_EXPECT(
367  harness.add(n.validate(
368  ledgerA, harness.parms().validationCURRENT_WALL, 0s)));
369 
370  BEAST_EXPECT(
372  harness.add(n.validate(
373  ledgerA, 0s, harness.parms().validationCURRENT_LOCAL)));
374  }
375 
376  {
377  // Test that full or partials cannot be sent for older sequence
378  // numbers, unless time-out has happened
379  for (bool doFull : {true, false})
380  {
381  TestHarness harness(h.oracle);
382  Node n = harness.makeNode();
383 
384  auto process = [&](Ledger& lgr) {
385  if (doFull)
386  return harness.add(n.validate(lgr));
387  return harness.add(n.partial(lgr));
388  };
389 
390  BEAST_EXPECT(ValStatus::current == process(ledgerABC));
391  harness.clock().advance(1s);
392  BEAST_EXPECT(ledgerAB.seq() < ledgerABC.seq());
393  BEAST_EXPECT(ValStatus::badSeq == process(ledgerAB));
394 
395  // If we advance far enough for AB to expire, we can fully
396  // validate or partially validate that sequence number again
397  BEAST_EXPECT(ValStatus::badSeq == process(ledgerAZ));
398  harness.clock().advance(
399  harness.parms().validationSET_EXPIRES + 1ms);
400  BEAST_EXPECT(ValStatus::current == process(ledgerAZ));
401  }
402  }
403  }
404 
405  void
407  {
408  testcase("Stale validation");
409  // Verify validation becomes stale based solely on time passing, but
410  // use different functions to trigger the check for staleness
411 
413  Ledger ledgerA = h["a"];
414  Ledger ledgerAB = h["ab"];
415 
416  using Trigger = std::function<void(TestValidations&)>;
417 
418  std::vector<Trigger> triggers = {
419  [&](TestValidations& vals) { vals.currentTrusted(); },
420  [&](TestValidations& vals) { vals.getCurrentNodeIDs(); },
421  [&](TestValidations& vals) { vals.getPreferred(genesisLedger); },
422  [&](TestValidations& vals) {
423  vals.getNodesAfter(ledgerA, ledgerA.id());
424  }};
425  for (Trigger trigger : triggers)
426  {
427  TestHarness harness(h.oracle);
428  Node n = harness.makeNode();
429 
430  BEAST_EXPECT(
431  ValStatus::current == harness.add(n.validate(ledgerAB)));
432  trigger(harness.vals());
433  BEAST_EXPECT(
434  harness.vals().getNodesAfter(ledgerA, ledgerA.id()) == 1);
435  BEAST_EXPECT(
436  harness.vals().getPreferred(genesisLedger) ==
437  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
438  harness.clock().advance(harness.parms().validationCURRENT_LOCAL);
439 
440  // trigger check for stale
441  trigger(harness.vals());
442 
443  BEAST_EXPECT(
444  harness.vals().getNodesAfter(ledgerA, ledgerA.id()) == 0);
445  BEAST_EXPECT(
446  harness.vals().getPreferred(genesisLedger) == boost::none);
447  }
448  }
449 
450  void
452  {
453  // Test getting number of nodes working on a validation descending
454  // a prescribed one. This count should only be for trusted nodes, but
455  // includes partial and full validations
456 
457  using namespace std::chrono_literals;
458  testcase("Get nodes after");
459 
461  Ledger ledgerA = h["a"];
462  Ledger ledgerAB = h["ab"];
463  Ledger ledgerABC = h["abc"];
464  Ledger ledgerAD = h["ad"];
465 
466  TestHarness harness(h.oracle);
467  Node a = harness.makeNode(), b = harness.makeNode(),
468  c = harness.makeNode(), d = harness.makeNode();
469  c.untrust();
470 
471  // first round a,b,c agree, d has is partial
472  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
473  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
474  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerA)));
475  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerA)));
476 
477  for (Ledger const& ledger : {ledgerA, ledgerAB, ledgerABC, ledgerAD})
478  BEAST_EXPECT(
479  harness.vals().getNodesAfter(ledger, ledger.id()) == 0);
480 
481  harness.clock().advance(5s);
482 
483  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerAB)));
484  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerABC)));
485  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerAB)));
486  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerABC)));
487 
488  BEAST_EXPECT(harness.vals().getNodesAfter(ledgerA, ledgerA.id()) == 3);
489  BEAST_EXPECT(
490  harness.vals().getNodesAfter(ledgerAB, ledgerAB.id()) == 2);
491  BEAST_EXPECT(
492  harness.vals().getNodesAfter(ledgerABC, ledgerABC.id()) == 0);
493  BEAST_EXPECT(
494  harness.vals().getNodesAfter(ledgerAD, ledgerAD.id()) == 0);
495 
496  // If given a ledger inconsistent with the id, is still able to check
497  // using slower method
498  BEAST_EXPECT(harness.vals().getNodesAfter(ledgerAD, ledgerA.id()) == 1);
499  BEAST_EXPECT(
500  harness.vals().getNodesAfter(ledgerAD, ledgerAB.id()) == 2);
501  }
502 
503  void
505  {
506  using namespace std::chrono_literals;
507  testcase("Current trusted validations");
508 
510  Ledger ledgerA = h["a"];
511  Ledger ledgerB = h["b"];
512  Ledger ledgerAC = h["ac"];
513 
514  TestHarness harness(h.oracle);
515  Node a = harness.makeNode(), b = harness.makeNode();
516  b.untrust();
517 
518  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
519  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerB)));
520 
521  // Only a is trusted
522  BEAST_EXPECT(harness.vals().currentTrusted().size() == 1);
523  BEAST_EXPECT(
524  harness.vals().currentTrusted()[0].ledgerID() == ledgerA.id());
525  BEAST_EXPECT(harness.vals().currentTrusted()[0].seq() == ledgerA.seq());
526 
527  harness.clock().advance(3s);
528 
529  for (auto const& node : {a, b})
530  BEAST_EXPECT(
531  ValStatus::current == harness.add(node.validate(ledgerAC)));
532 
533  // New validation for a
534  BEAST_EXPECT(harness.vals().currentTrusted().size() == 1);
535  BEAST_EXPECT(
536  harness.vals().currentTrusted()[0].ledgerID() == ledgerAC.id());
537  BEAST_EXPECT(
538  harness.vals().currentTrusted()[0].seq() == ledgerAC.seq());
539 
540  // Pass enough time for it to go stale
541  harness.clock().advance(harness.parms().validationCURRENT_LOCAL);
542  BEAST_EXPECT(harness.vals().currentTrusted().empty());
543  }
544 
545  void
547  {
548  using namespace std::chrono_literals;
549  testcase("Current public keys");
550 
552  Ledger ledgerA = h["a"];
553  Ledger ledgerAC = h["ac"];
554 
555  TestHarness harness(h.oracle);
556  Node a = harness.makeNode(), b = harness.makeNode();
557  b.untrust();
558 
559  for (auto const& node : {a, b})
560  BEAST_EXPECT(
561  ValStatus::current == harness.add(node.validate(ledgerA)));
562 
563  {
564  hash_set<PeerID> const expectedKeys = {a.nodeID(), b.nodeID()};
565  BEAST_EXPECT(harness.vals().getCurrentNodeIDs() == expectedKeys);
566  }
567 
568  harness.clock().advance(3s);
569 
570  // Change keys and issue partials
571  a.advanceKey();
572  b.advanceKey();
573 
574  for (auto const& node : {a, b})
575  BEAST_EXPECT(
576  ValStatus::current == harness.add(node.partial(ledgerAC)));
577 
578  {
579  hash_set<PeerID> const expectedKeys = {a.nodeID(), b.nodeID()};
580  BEAST_EXPECT(harness.vals().getCurrentNodeIDs() == expectedKeys);
581  }
582 
583  // Pass enough time for them to go stale
584  harness.clock().advance(harness.parms().validationCURRENT_LOCAL);
585  BEAST_EXPECT(harness.vals().getCurrentNodeIDs().empty());
586  }
587 
588  void
590  {
591  // Test the Validations functions that calculate a value by ledger ID
592  using namespace std::chrono_literals;
593  testcase("By ledger functions");
594 
595  // Several Validations functions return a set of values associated
596  // with trusted ledgers sharing the same ledger ID. The tests below
597  // exercise this logic by saving the set of trusted Validations, and
598  // verifying that the Validations member functions all calculate the
599  // proper transformation of the available ledgers.
600 
602  TestHarness harness(h.oracle);
603 
604  Node a = harness.makeNode(), b = harness.makeNode(),
605  c = harness.makeNode(), d = harness.makeNode(),
606  e = harness.makeNode();
607 
608  c.untrust();
609  // Mix of load fees
610  a.setLoadFee(12);
611  b.setLoadFee(1);
612  c.setLoadFee(12);
613  e.setLoadFee(12);
614 
616 
617  //----------------------------------------------------------------------
618  // checkers
619  auto sorted = [](auto vec) {
620  std::sort(vec.begin(), vec.end());
621  return vec;
622  };
623  auto compare = [&]() {
624  for (auto& it : trustedValidations)
625  {
626  auto const& id = it.first;
627  auto const& expectedValidations = it.second;
628 
629  BEAST_EXPECT(
630  harness.vals().numTrustedForLedger(id) ==
631  expectedValidations.size());
632  BEAST_EXPECT(
633  sorted(harness.vals().getTrustedForLedger(id)) ==
634  sorted(expectedValidations));
635 
636  std::uint32_t baseFee = 0;
637  std::vector<uint32_t> expectedFees;
638  for (auto const& val : expectedValidations)
639  {
640  expectedFees.push_back(val.loadFee().value_or(baseFee));
641  }
642 
643  BEAST_EXPECT(
644  sorted(harness.vals().fees(id, baseFee)) ==
645  sorted(expectedFees));
646  }
647  };
648 
649  //----------------------------------------------------------------------
650  Ledger ledgerA = h["a"];
651  Ledger ledgerB = h["b"];
652  Ledger ledgerAC = h["ac"];
653 
654  // Add a dummy ID to cover unknown ledger identifiers
655  trustedValidations[Ledger::ID{100}] = {};
656 
657  // first round a,b,c agree
658  for (auto const& node : {a, b, c})
659  {
660  auto const val = node.validate(ledgerA);
661  BEAST_EXPECT(ValStatus::current == harness.add(val));
662  if (val.trusted())
663  trustedValidations[val.ledgerID()].emplace_back(val);
664  }
665  // d disagrees
666  {
667  auto const val = d.validate(ledgerB);
668  BEAST_EXPECT(ValStatus::current == harness.add(val));
669  trustedValidations[val.ledgerID()].emplace_back(val);
670  }
671  // e only issues partials
672  {
673  BEAST_EXPECT(ValStatus::current == harness.add(e.partial(ledgerA)));
674  }
675 
676  harness.clock().advance(5s);
677  // second round, a,b,c move to ledger 2
678  for (auto const& node : {a, b, c})
679  {
680  auto const val = node.validate(ledgerAC);
681  BEAST_EXPECT(ValStatus::current == harness.add(val));
682  if (val.trusted())
683  trustedValidations[val.ledgerID()].emplace_back(val);
684  }
685  // d now thinks ledger 1, but cannot re-issue a previously used seq
686  {
687  BEAST_EXPECT(ValStatus::badSeq == harness.add(d.partial(ledgerA)));
688  }
689  // e only issues partials
690  {
691  BEAST_EXPECT(
692  ValStatus::current == harness.add(e.partial(ledgerAC)));
693  }
694 
695  compare();
696  }
697 
698  void
700  {
701  // Verify expiring clears out validations stored by ledger
702  testcase("Expire validations");
704  TestHarness harness(h.oracle);
705  Node a = harness.makeNode();
706 
707  Ledger ledgerA = h["a"];
708 
709  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
710  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()));
711  harness.clock().advance(harness.parms().validationSET_EXPIRES);
712  harness.vals().expire();
713  BEAST_EXPECT(!harness.vals().numTrustedForLedger(ledgerA.id()));
714  }
715 
716  void
718  {
719  // Test final flush of validations
720  using namespace std::chrono_literals;
721  testcase("Flush validations");
722 
724  TestHarness harness(h.oracle);
725  Node a = harness.makeNode(), b = harness.makeNode(),
726  c = harness.makeNode();
727  c.untrust();
728 
729  Ledger ledgerA = h["a"];
730  Ledger ledgerAB = h["ab"];
731 
733  for (auto const& node : {a, b, c})
734  {
735  auto const val = node.validate(ledgerA);
736  BEAST_EXPECT(ValStatus::current == harness.add(val));
737  expected.emplace(node.nodeID(), val);
738  }
739 
740  // Send in a new validation for a, saving the new one into the expected
741  // map after setting the proper prior ledger ID it replaced
742  harness.clock().advance(1s);
743  auto newVal = a.validate(ledgerAB);
744  BEAST_EXPECT(ValStatus::current == harness.add(newVal));
745  expected.find(a.nodeID())->second = newVal;
746  }
747 
748  void
750  {
751  using namespace std::chrono_literals;
752  testcase("Preferred Ledger");
753 
755  TestHarness harness(h.oracle);
756  Node a = harness.makeNode(), b = harness.makeNode(),
757  c = harness.makeNode(), d = harness.makeNode();
758  c.untrust();
759 
760  Ledger ledgerA = h["a"];
761  Ledger ledgerB = h["b"];
762  Ledger ledgerAC = h["ac"];
763  Ledger ledgerACD = h["acd"];
764 
765  using Seq = Ledger::Seq;
766  using ID = Ledger::ID;
767 
768  auto pref = [](Ledger ledger) {
769  return std::make_pair(ledger.seq(), ledger.id());
770  };
771 
772  // Empty (no ledgers)
773  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == boost::none);
774 
775  // Single ledger
776  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerB)));
777  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
778  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
779 
780  // Minimum valid sequence
781  BEAST_EXPECT(
782  harness.vals().getPreferred(ledgerA, Seq{10}) == ledgerA.id());
783 
784  // Untrusted doesn't impact preferred ledger
785  // (ledgerB has tie-break over ledgerA)
786  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
787  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerA)));
788  BEAST_EXPECT(ledgerB.id() > ledgerA.id());
789  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
790  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
791 
792  // Partial does break ties
793  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerA)));
794  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
795  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerA));
796 
797  harness.clock().advance(5s);
798 
799  // Parent of preferred-> stick with ledger
800  for (auto const& node : {a, b, c, d})
801  BEAST_EXPECT(
802  ValStatus::current == harness.add(node.validate(ledgerAC)));
803  // Parent of preferred stays put
804  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
805  // Earlier different chain, switch
806  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerAC));
807  // Later on chain, stays where it is
808  BEAST_EXPECT(harness.vals().getPreferred(ledgerACD) == pref(ledgerACD));
809 
810  // Any later grandchild or different chain is preferred
811  harness.clock().advance(5s);
812  for (auto const& node : {a, b, c, d})
813  BEAST_EXPECT(
814  ValStatus::current == harness.add(node.validate(ledgerACD)));
815  for (auto const& ledger : {ledgerA, ledgerB, ledgerACD})
816  BEAST_EXPECT(
817  harness.vals().getPreferred(ledger) == pref(ledgerACD));
818  }
819 
820  void
822  {
823  using namespace std::chrono_literals;
824  testcase("Get preferred LCL");
825 
827  TestHarness harness(h.oracle);
828  Node a = harness.makeNode();
829 
830  Ledger ledgerA = h["a"];
831  Ledger ledgerB = h["b"];
832  Ledger ledgerC = h["c"];
833 
834  using ID = Ledger::ID;
835  using Seq = Ledger::Seq;
836 
837  hash_map<ID, std::uint32_t> peerCounts;
838 
839  // No trusted validations or counts sticks with current ledger
840  BEAST_EXPECT(
841  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
842  ledgerA.id());
843 
844  ++peerCounts[ledgerB.id()];
845 
846  // No trusted validations, rely on peer counts
847  BEAST_EXPECT(
848  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
849  ledgerB.id());
850 
851  ++peerCounts[ledgerC.id()];
852  // No trusted validations, tied peers goes with larger ID
853  BEAST_EXPECT(ledgerC.id() > ledgerB.id());
854 
855  BEAST_EXPECT(
856  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
857  ledgerC.id());
858 
859  peerCounts[ledgerC.id()] += 1000;
860 
861  // Single trusted always wins over peer counts
862  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
863  BEAST_EXPECT(
864  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
865  ledgerA.id());
866  BEAST_EXPECT(
867  harness.vals().getPreferredLCL(ledgerB, Seq{0}, peerCounts) ==
868  ledgerA.id());
869  BEAST_EXPECT(
870  harness.vals().getPreferredLCL(ledgerC, Seq{0}, peerCounts) ==
871  ledgerA.id());
872 
873  // Stick with current ledger if trusted validation ledger has too old
874  // of a sequence
875  BEAST_EXPECT(
876  harness.vals().getPreferredLCL(ledgerB, Seq{2}, peerCounts) ==
877  ledgerB.id());
878  }
879 
880  void
882  {
883  using namespace std::chrono_literals;
884  testcase("Acquire validated ledger");
885 
887  TestHarness harness(h.oracle);
888  Node a = harness.makeNode();
889  Node b = harness.makeNode();
890 
891  using ID = Ledger::ID;
892  using Seq = Ledger::Seq;
893 
894  // Validate the ledger before it is actually available
895  Validation val = a.validate(ID{2}, Seq{2}, 0s, 0s, true);
896 
897  BEAST_EXPECT(ValStatus::current == harness.add(val));
898  // Validation is available
899  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{2}) == 1);
900  // but ledger based data is not
901  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 0);
902  // Initial preferred branch falls back to the ledger we are trying to
903  // acquire
904  BEAST_EXPECT(
905  harness.vals().getPreferred(genesisLedger) ==
906  std::make_pair(Seq{2}, ID{2}));
907 
908  // After adding another unavailable validation, the preferred ledger
909  // breaks ties via higher ID
910  BEAST_EXPECT(
912  harness.add(b.validate(ID{3}, Seq{2}, 0s, 0s, true)));
913  BEAST_EXPECT(
914  harness.vals().getPreferred(genesisLedger) ==
915  std::make_pair(Seq{2}, ID{3}));
916 
917  // Create the ledger
918  Ledger ledgerAB = h["ab"];
919  // Now it should be available
920  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 1);
921 
922  // Create a validation that is not available
923  harness.clock().advance(5s);
924  Validation val2 = a.validate(ID{4}, Seq{4}, 0s, 0s, true);
925  BEAST_EXPECT(ValStatus::current == harness.add(val2));
926  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 1);
927  BEAST_EXPECT(
928  harness.vals().getPreferred(genesisLedger) ==
929  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
930 
931  // Another node requesting that ledger still doesn't change things
932  Validation val3 = b.validate(ID{4}, Seq{4}, 0s, 0s, true);
933  BEAST_EXPECT(ValStatus::current == harness.add(val3));
934  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 2);
935  BEAST_EXPECT(
936  harness.vals().getPreferred(genesisLedger) ==
937  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
938 
939  // Switch to validation that is available
940  harness.clock().advance(5s);
941  Ledger ledgerABCDE = h["abcde"];
942  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerABCDE)));
943  BEAST_EXPECT(ValStatus::current == harness.add(b.partial(ledgerABCDE)));
944  BEAST_EXPECT(
945  harness.vals().getPreferred(genesisLedger) ==
946  std::make_pair(ledgerABCDE.seq(), ledgerABCDE.id()));
947  }
948 
949  void
951  {
952  testcase("NumTrustedForLedger");
954  TestHarness harness(h.oracle);
955  Node a = harness.makeNode();
956  Node b = harness.makeNode();
957  Ledger ledgerA = h["a"];
958 
959  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerA)));
960  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 0);
961 
962  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
963  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
964  }
965 
966  void
968  {
969  testcase("SeqEnforcer");
970  using Seq = Ledger::Seq;
971  using namespace std::chrono;
972 
974  SeqEnforcer<Seq> enforcer;
975 
976  ValidationParms p;
977 
978  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
979  BEAST_EXPECT(enforcer(clock.now(), Seq{10}, p));
980  BEAST_EXPECT(!enforcer(clock.now(), Seq{5}, p));
981  BEAST_EXPECT(!enforcer(clock.now(), Seq{9}, p));
982  clock.advance(p.validationSET_EXPIRES - 1ms);
983  BEAST_EXPECT(!enforcer(clock.now(), Seq{1}, p));
984  clock.advance(2ms);
985  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
986  }
987 
988  void
990  {
991  testcase("TrustChanged");
992  using namespace std::chrono;
993 
994  auto checker = [this](
995  TestValidations& vals,
996  hash_set<PeerID> const& listed,
997  std::vector<Validation> const& trustedVals) {
998  Ledger::ID testID = trustedVals.empty() ? this->genesisLedger.id()
999  : trustedVals[0].ledgerID();
1000  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1001  BEAST_EXPECT(vals.getCurrentNodeIDs() == listed);
1002  BEAST_EXPECT(
1003  vals.getNodesAfter(this->genesisLedger, genesisLedger.id()) ==
1004  trustedVals.size());
1005  if (trustedVals.empty())
1006  BEAST_EXPECT(
1007  vals.getPreferred(this->genesisLedger) == boost::none);
1008  else
1009  BEAST_EXPECT(
1010  vals.getPreferred(this->genesisLedger)->second == testID);
1011  BEAST_EXPECT(vals.getTrustedForLedger(testID) == trustedVals);
1012  BEAST_EXPECT(
1013  vals.numTrustedForLedger(testID) == trustedVals.size());
1014  };
1015 
1016  {
1017  // Trusted to untrusted
1019  TestHarness harness(h.oracle);
1020  Node a = harness.makeNode();
1021  Ledger ledgerAB = h["ab"];
1022  Validation v = a.validate(ledgerAB);
1023  BEAST_EXPECT(ValStatus::current == harness.add(v));
1024 
1025  hash_set<PeerID> listed({a.nodeID()});
1026  std::vector<Validation> trustedVals({v});
1027  checker(harness.vals(), listed, trustedVals);
1028 
1029  trustedVals.clear();
1030  harness.vals().trustChanged({}, {a.nodeID()});
1031  checker(harness.vals(), listed, trustedVals);
1032  }
1033 
1034  {
1035  // Untrusted to trusted
1037  TestHarness harness(h.oracle);
1038  Node a = harness.makeNode();
1039  a.untrust();
1040  Ledger ledgerAB = h["ab"];
1041  Validation v = a.validate(ledgerAB);
1042  BEAST_EXPECT(ValStatus::current == harness.add(v));
1043 
1044  hash_set<PeerID> listed({a.nodeID()});
1045  std::vector<Validation> trustedVals;
1046  checker(harness.vals(), listed, trustedVals);
1047 
1048  trustedVals.push_back(v);
1049  harness.vals().trustChanged({a.nodeID()}, {});
1050  checker(harness.vals(), listed, trustedVals);
1051  }
1052 
1053  {
1054  // Trusted but not acquired -> untrusted
1056  TestHarness harness(h.oracle);
1057  Node a = harness.makeNode();
1058  Validation v =
1059  a.validate(Ledger::ID{2}, Ledger::Seq{2}, 0s, 0s, true);
1060  BEAST_EXPECT(ValStatus::current == harness.add(v));
1061 
1062  hash_set<PeerID> listed({a.nodeID()});
1063  std::vector<Validation> trustedVals({v});
1064  auto& vals = harness.vals();
1065  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1066  BEAST_EXPECT(
1067  vals.getPreferred(genesisLedger)->second == v.ledgerID());
1068  BEAST_EXPECT(
1069  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1070 
1071  trustedVals.clear();
1072  harness.vals().trustChanged({}, {a.nodeID()});
1073  // make acquiring ledger available
1074  h["ab"];
1075  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1076  BEAST_EXPECT(vals.getPreferred(genesisLedger) == boost::none);
1077  BEAST_EXPECT(
1078  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1079  }
1080  }
1081 
1082  void
1083  run() override
1084  {
1086  testOnStale();
1091  testExpire();
1092  testFlush();
1097  testSeqEnforcer();
1098  testTrustChanged();
1099  }
1100 };
1101 
1103 } // namespace csf
1104 } // namespace test
1105 } // namespace ripple
ripple::Validations::expire
void expire()
Expire old validation sets.
Definition: Validations.h:638
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:406
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:504
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:129
ripple::test::csf::Validations_test::testFlush
void testFlush()
Definition: Validations_test.cpp:717
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:940
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:654
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:795
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:228
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:57
ripple::test::csf::Ledger::seq
Seq seq() const
Definition: ledgers.h:172
std::function
ripple::test::csf::Validations_test::testGetNodesAfter
void testGetNodesAfter()
Definition: Validations_test.cpp:451
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:68
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:320
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:709
ripple::test::csf::Validations_test::testTrustChanged
void testTrustChanged()
Definition: Validations_test.cpp:989
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:592
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:497
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:833
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:896
ripple::test::csf::LedgerOracle
Oracle maintaining unique ledgers for a simulation.
Definition: ledgers.h:243
ripple::test::csf::LedgerHistoryHelper::oracle
LedgerOracle oracle
Definition: ledgers.h:322
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:546
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:137
ripple::Validations::getTrustedForLedger
std::vector< WrappedValidationType > getTrustedForLedger(ID const &ledgerID)
Get trusted full validations for a specific ledger.
Definition: Validations.h:917
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:589
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:166
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:950
ripple::test::csf::Validation
Validation of a specific ledger by a specific Peer.
Definition: Validation.h:46
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:66
ripple::test::csf::Validations_test::run
void run() override
Definition: Validations_test.cpp:1083
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:63
ripple::test::csf::Validations_test::testSeqEnforcer
void testSeqEnforcer()
Definition: Validations_test.cpp:967
ripple::test::csf::Validation::ledgerID
Ledger::ID ledgerID() const
Definition: Validation.h:84
ripple::Validations
Maintains current and recent ledger validations.
Definition: Application.h:90
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:699
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:878
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:749
beast::manual_clock< std::chrono::steady_clock >
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:881
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: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:54
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:821
ripple::Validations::currentTrusted
std::vector< WrappedValidationType > currentTrusted()
Get the currently trusted full validations.
Definition: Validations.h:859
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:180