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::conflicting == 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  // and attempting it should generate a conflict.
687  {
688  BEAST_EXPECT(
689  ValStatus::conflicting == harness.add(d.partial(ledgerA)));
690  }
691  // e only issues partials
692  {
693  BEAST_EXPECT(
694  ValStatus::current == harness.add(e.partial(ledgerAC)));
695  }
696 
697  compare();
698  }
699 
700  void
702  {
703  // Verify expiring clears out validations stored by ledger
704  testcase("Expire validations");
706  TestHarness harness(h.oracle);
707  Node a = harness.makeNode();
708 
709  Ledger ledgerA = h["a"];
710  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
711  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()));
712 
713  // Keep the validation from expire
714  harness.clock().advance(harness.parms().validationSET_EXPIRES);
715  harness.vals().setSeqToKeep(ledgerA.seq());
716  harness.vals().expire();
717  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()));
718 
719  // Allow the validation to expire
720  harness.clock().advance(harness.parms().validationSET_EXPIRES);
721  harness.vals().setSeqToKeep(++ledgerA.seq());
722  harness.vals().expire();
723  BEAST_EXPECT(!harness.vals().numTrustedForLedger(ledgerA.id()));
724  }
725 
726  void
728  {
729  // Test final flush of validations
730  using namespace std::chrono_literals;
731  testcase("Flush validations");
732 
734  TestHarness harness(h.oracle);
735  Node a = harness.makeNode(), b = harness.makeNode(),
736  c = harness.makeNode();
737  c.untrust();
738 
739  Ledger ledgerA = h["a"];
740  Ledger ledgerAB = h["ab"];
741 
743  for (auto const& node : {a, b, c})
744  {
745  auto const val = node.validate(ledgerA);
746  BEAST_EXPECT(ValStatus::current == harness.add(val));
747  expected.emplace(node.nodeID(), val);
748  }
749 
750  // Send in a new validation for a, saving the new one into the expected
751  // map after setting the proper prior ledger ID it replaced
752  harness.clock().advance(1s);
753  auto newVal = a.validate(ledgerAB);
754  BEAST_EXPECT(ValStatus::current == harness.add(newVal));
755  expected.find(a.nodeID())->second = newVal;
756  }
757 
758  void
760  {
761  using namespace std::chrono_literals;
762  testcase("Preferred Ledger");
763 
765  TestHarness harness(h.oracle);
766  Node a = harness.makeNode(), b = harness.makeNode(),
767  c = harness.makeNode(), d = harness.makeNode();
768  c.untrust();
769 
770  Ledger ledgerA = h["a"];
771  Ledger ledgerB = h["b"];
772  Ledger ledgerAC = h["ac"];
773  Ledger ledgerACD = h["acd"];
774 
775  using Seq = Ledger::Seq;
776  using ID = Ledger::ID;
777 
778  auto pref = [](Ledger ledger) {
779  return std::make_pair(ledger.seq(), ledger.id());
780  };
781 
782  // Empty (no ledgers)
783  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == boost::none);
784 
785  // Single ledger
786  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerB)));
787  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
788  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
789 
790  // Minimum valid sequence
791  BEAST_EXPECT(
792  harness.vals().getPreferred(ledgerA, Seq{10}) == ledgerA.id());
793 
794  // Untrusted doesn't impact preferred ledger
795  // (ledgerB has tie-break over ledgerA)
796  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
797  BEAST_EXPECT(ValStatus::current == harness.add(c.validate(ledgerA)));
798  BEAST_EXPECT(ledgerB.id() > ledgerA.id());
799  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerB));
800  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerB));
801 
802  // Partial does break ties
803  BEAST_EXPECT(ValStatus::current == harness.add(d.partial(ledgerA)));
804  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
805  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerA));
806 
807  harness.clock().advance(5s);
808 
809  // Parent of preferred-> stick with ledger
810  for (auto const& node : {a, b, c, d})
811  BEAST_EXPECT(
812  ValStatus::current == harness.add(node.validate(ledgerAC)));
813  // Parent of preferred stays put
814  BEAST_EXPECT(harness.vals().getPreferred(ledgerA) == pref(ledgerA));
815  // Earlier different chain, switch
816  BEAST_EXPECT(harness.vals().getPreferred(ledgerB) == pref(ledgerAC));
817  // Later on chain, stays where it is
818  BEAST_EXPECT(harness.vals().getPreferred(ledgerACD) == pref(ledgerACD));
819 
820  // Any later grandchild or different chain is preferred
821  harness.clock().advance(5s);
822  for (auto const& node : {a, b, c, d})
823  BEAST_EXPECT(
824  ValStatus::current == harness.add(node.validate(ledgerACD)));
825  for (auto const& ledger : {ledgerA, ledgerB, ledgerACD})
826  BEAST_EXPECT(
827  harness.vals().getPreferred(ledger) == pref(ledgerACD));
828  }
829 
830  void
832  {
833  using namespace std::chrono_literals;
834  testcase("Get preferred LCL");
835 
837  TestHarness harness(h.oracle);
838  Node a = harness.makeNode();
839 
840  Ledger ledgerA = h["a"];
841  Ledger ledgerB = h["b"];
842  Ledger ledgerC = h["c"];
843 
844  using ID = Ledger::ID;
845  using Seq = Ledger::Seq;
846 
847  hash_map<ID, std::uint32_t> peerCounts;
848 
849  // No trusted validations or counts sticks with current ledger
850  BEAST_EXPECT(
851  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
852  ledgerA.id());
853 
854  ++peerCounts[ledgerB.id()];
855 
856  // No trusted validations, rely on peer counts
857  BEAST_EXPECT(
858  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
859  ledgerB.id());
860 
861  ++peerCounts[ledgerC.id()];
862  // No trusted validations, tied peers goes with larger ID
863  BEAST_EXPECT(ledgerC.id() > ledgerB.id());
864 
865  BEAST_EXPECT(
866  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
867  ledgerC.id());
868 
869  peerCounts[ledgerC.id()] += 1000;
870 
871  // Single trusted always wins over peer counts
872  BEAST_EXPECT(ValStatus::current == harness.add(a.validate(ledgerA)));
873  BEAST_EXPECT(
874  harness.vals().getPreferredLCL(ledgerA, Seq{0}, peerCounts) ==
875  ledgerA.id());
876  BEAST_EXPECT(
877  harness.vals().getPreferredLCL(ledgerB, Seq{0}, peerCounts) ==
878  ledgerA.id());
879  BEAST_EXPECT(
880  harness.vals().getPreferredLCL(ledgerC, Seq{0}, peerCounts) ==
881  ledgerA.id());
882 
883  // Stick with current ledger if trusted validation ledger has too old
884  // of a sequence
885  BEAST_EXPECT(
886  harness.vals().getPreferredLCL(ledgerB, Seq{2}, peerCounts) ==
887  ledgerB.id());
888  }
889 
890  void
892  {
893  using namespace std::chrono_literals;
894  testcase("Acquire validated ledger");
895 
897  TestHarness harness(h.oracle);
898  Node a = harness.makeNode();
899  Node b = harness.makeNode();
900 
901  using ID = Ledger::ID;
902  using Seq = Ledger::Seq;
903 
904  // Validate the ledger before it is actually available
905  Validation val = a.validate(ID{2}, Seq{2}, 0s, 0s, true);
906 
907  BEAST_EXPECT(ValStatus::current == harness.add(val));
908  // Validation is available
909  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{2}) == 1);
910  // but ledger based data is not
911  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 0);
912  // Initial preferred branch falls back to the ledger we are trying to
913  // acquire
914  BEAST_EXPECT(
915  harness.vals().getPreferred(genesisLedger) ==
916  std::make_pair(Seq{2}, ID{2}));
917 
918  // After adding another unavailable validation, the preferred ledger
919  // breaks ties via higher ID
920  BEAST_EXPECT(
922  harness.add(b.validate(ID{3}, Seq{2}, 0s, 0s, true)));
923  BEAST_EXPECT(
924  harness.vals().getPreferred(genesisLedger) ==
925  std::make_pair(Seq{2}, ID{3}));
926 
927  // Create the ledger
928  Ledger ledgerAB = h["ab"];
929  // Now it should be available
930  BEAST_EXPECT(harness.vals().getNodesAfter(genesisLedger, ID{0}) == 1);
931 
932  // Create a validation that is not available
933  harness.clock().advance(5s);
934  Validation val2 = a.validate(ID{4}, Seq{4}, 0s, 0s, true);
935  BEAST_EXPECT(ValStatus::current == harness.add(val2));
936  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 1);
937  BEAST_EXPECT(
938  harness.vals().getPreferred(genesisLedger) ==
939  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
940 
941  // Another node requesting that ledger still doesn't change things
942  Validation val3 = b.validate(ID{4}, Seq{4}, 0s, 0s, true);
943  BEAST_EXPECT(ValStatus::current == harness.add(val3));
944  BEAST_EXPECT(harness.vals().numTrustedForLedger(ID{4}) == 2);
945  BEAST_EXPECT(
946  harness.vals().getPreferred(genesisLedger) ==
947  std::make_pair(ledgerAB.seq(), ledgerAB.id()));
948 
949  // Switch to validation that is available
950  harness.clock().advance(5s);
951  Ledger ledgerABCDE = h["abcde"];
952  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerABCDE)));
953  BEAST_EXPECT(ValStatus::current == harness.add(b.partial(ledgerABCDE)));
954  BEAST_EXPECT(
955  harness.vals().getPreferred(genesisLedger) ==
956  std::make_pair(ledgerABCDE.seq(), ledgerABCDE.id()));
957  }
958 
959  void
961  {
962  testcase("NumTrustedForLedger");
964  TestHarness harness(h.oracle);
965  Node a = harness.makeNode();
966  Node b = harness.makeNode();
967  Ledger ledgerA = h["a"];
968 
969  BEAST_EXPECT(ValStatus::current == harness.add(a.partial(ledgerA)));
970  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 0);
971 
972  BEAST_EXPECT(ValStatus::current == harness.add(b.validate(ledgerA)));
973  BEAST_EXPECT(harness.vals().numTrustedForLedger(ledgerA.id()) == 1);
974  }
975 
976  void
978  {
979  testcase("SeqEnforcer");
980  using Seq = Ledger::Seq;
981  using namespace std::chrono;
982 
984  SeqEnforcer<Seq> enforcer;
985 
986  ValidationParms p;
987 
988  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
989  BEAST_EXPECT(enforcer(clock.now(), Seq{10}, p));
990  BEAST_EXPECT(!enforcer(clock.now(), Seq{5}, p));
991  BEAST_EXPECT(!enforcer(clock.now(), Seq{9}, p));
992  clock.advance(p.validationSET_EXPIRES - 1ms);
993  BEAST_EXPECT(!enforcer(clock.now(), Seq{1}, p));
994  clock.advance(2ms);
995  BEAST_EXPECT(enforcer(clock.now(), Seq{1}, p));
996  }
997 
998  void
1000  {
1001  testcase("TrustChanged");
1002  using namespace std::chrono;
1003 
1004  auto checker = [this](
1005  TestValidations& vals,
1006  hash_set<PeerID> const& listed,
1007  std::vector<Validation> const& trustedVals) {
1008  Ledger::ID testID = trustedVals.empty() ? this->genesisLedger.id()
1009  : trustedVals[0].ledgerID();
1010  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1011  BEAST_EXPECT(vals.getCurrentNodeIDs() == listed);
1012  BEAST_EXPECT(
1013  vals.getNodesAfter(this->genesisLedger, genesisLedger.id()) ==
1014  trustedVals.size());
1015  if (trustedVals.empty())
1016  BEAST_EXPECT(
1017  vals.getPreferred(this->genesisLedger) == boost::none);
1018  else
1019  BEAST_EXPECT(
1020  vals.getPreferred(this->genesisLedger)->second == testID);
1021  BEAST_EXPECT(vals.getTrustedForLedger(testID) == trustedVals);
1022  BEAST_EXPECT(
1023  vals.numTrustedForLedger(testID) == trustedVals.size());
1024  };
1025 
1026  {
1027  // Trusted to untrusted
1029  TestHarness harness(h.oracle);
1030  Node a = harness.makeNode();
1031  Ledger ledgerAB = h["ab"];
1032  Validation v = a.validate(ledgerAB);
1033  BEAST_EXPECT(ValStatus::current == harness.add(v));
1034 
1035  hash_set<PeerID> listed({a.nodeID()});
1036  std::vector<Validation> trustedVals({v});
1037  checker(harness.vals(), listed, trustedVals);
1038 
1039  trustedVals.clear();
1040  harness.vals().trustChanged({}, {a.nodeID()});
1041  checker(harness.vals(), listed, trustedVals);
1042  }
1043 
1044  {
1045  // Untrusted to trusted
1047  TestHarness harness(h.oracle);
1048  Node a = harness.makeNode();
1049  a.untrust();
1050  Ledger ledgerAB = h["ab"];
1051  Validation v = a.validate(ledgerAB);
1052  BEAST_EXPECT(ValStatus::current == harness.add(v));
1053 
1054  hash_set<PeerID> listed({a.nodeID()});
1055  std::vector<Validation> trustedVals;
1056  checker(harness.vals(), listed, trustedVals);
1057 
1058  trustedVals.push_back(v);
1059  harness.vals().trustChanged({a.nodeID()}, {});
1060  checker(harness.vals(), listed, trustedVals);
1061  }
1062 
1063  {
1064  // Trusted but not acquired -> untrusted
1066  TestHarness harness(h.oracle);
1067  Node a = harness.makeNode();
1068  Validation v =
1069  a.validate(Ledger::ID{2}, Ledger::Seq{2}, 0s, 0s, true);
1070  BEAST_EXPECT(ValStatus::current == harness.add(v));
1071 
1072  hash_set<PeerID> listed({a.nodeID()});
1073  std::vector<Validation> trustedVals({v});
1074  auto& vals = harness.vals();
1075  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1076  BEAST_EXPECT(
1077  vals.getPreferred(genesisLedger)->second == v.ledgerID());
1078  BEAST_EXPECT(
1079  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1080 
1081  trustedVals.clear();
1082  harness.vals().trustChanged({}, {a.nodeID()});
1083  // make acquiring ledger available
1084  h["ab"];
1085  BEAST_EXPECT(vals.currentTrusted() == trustedVals);
1086  BEAST_EXPECT(vals.getPreferred(genesisLedger) == boost::none);
1087  BEAST_EXPECT(
1088  vals.getNodesAfter(genesisLedger, genesisLedger.id()) == 0);
1089  }
1090  }
1091 
1092  void
1093  run() override
1094  {
1096  testOnStale();
1101  testExpire();
1102  testFlush();
1107  testSeqEnforcer();
1108  testTrustChanged();
1109  }
1110 };
1111 
1113 } // namespace csf
1114 } // namespace test
1115 } // namespace ripple
ripple::Validations::expire
void expire()
Expire old validation sets.
Definition: Validations.h:709
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:727
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:1033
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:747
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:888
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::Validations::setSeqToKeep
void setSeqToKeep(Seq const &s)
Set the smallest sequence number of validations to keep from expire.
Definition: Validations.h:697
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:117
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:802
ripple::test::csf::Validations_test::testTrustChanged
void testTrustChanged()
Definition: Validations_test.cpp:999
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:614
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:461
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:926
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:989
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:1010
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::ValStatus::conflicting
@ conflicting
Multiple validations for different ledgers by a single validator.
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:960
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:1093
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:977
ripple::test::csf::Validation::ledgerID
Ledger::ID ledgerID() const
Definition: Validation.h:87
ripple::Validations
Maintains current and recent ledger validations.
Definition: Application.h:97
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:701
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:971
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:759
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:891
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:831
ripple::Validations::currentTrusted
std::vector< WrappedValidationType > currentTrusted()
Get the currently trusted full validations.
Definition: Validations.h:952
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