rippled
Validations.h
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 #ifndef RIPPLE_CONSENSUS_VALIDATIONS_H_INCLUDED
21 #define RIPPLE_CONSENSUS_VALIDATIONS_H_INCLUDED
22 
23 #include <ripple/basics/Log.h>
24 #include <ripple/basics/UnorderedContainers.h>
25 #include <ripple/basics/chrono.h>
26 #include <ripple/beast/container/aged_container_utility.h>
27 #include <ripple/beast/container/aged_unordered_map.h>
28 #include <ripple/consensus/LedgerTrie.h>
29 #include <ripple/protocol/PublicKey.h>
30 #include <boost/optional.hpp>
31 #include <mutex>
32 #include <utility>
33 #include <vector>
34 
35 namespace ripple {
36 
44 {
45  explicit ValidationParms() = default;
46 
54 
62 
69 
77 
87 };
88 
95 template <class Seq>
97 {
98  using time_point = std::chrono::steady_clock::time_point;
99  Seq seq_{0};
101 
102 public:
115  bool
116  operator()(time_point now, Seq s, ValidationParms const& p)
117  {
118  if (now > (when_ + p.validationSET_EXPIRES))
119  seq_ = Seq{0};
120  if (s <= seq_)
121  return false;
122  seq_ = s;
123  when_ = now;
124  return true;
125  }
126 
127  Seq
128  largest() const
129  {
130  return seq_;
131  }
132 };
144 inline bool
146  ValidationParms const& p,
148  NetClock::time_point signTime,
149  NetClock::time_point seenTime)
150 {
151  // Because this can be called on untrusted, possibly
152  // malicious validations, we do our math in a way
153  // that avoids any chance of overflowing or underflowing
154  // the signing time.
155 
156  return (signTime > (now - p.validationCURRENT_EARLY)) &&
157  (signTime < (now + p.validationCURRENT_WALL)) &&
158  ((seenTime == NetClock::time_point{}) ||
159  (seenTime < (now + p.validationCURRENT_LOCAL)));
160 }
161 
164 enum class ValStatus {
166  current,
168  stale,
170  badSeq,
172  multiple,
175 };
176 
177 inline std::string
179 {
180  switch (m)
181  {
182  case ValStatus::current:
183  return "current";
184  case ValStatus::stale:
185  return "stale";
186  case ValStatus::badSeq:
187  return "badSeq";
188  case ValStatus::multiple:
189  return "multiple";
191  return "conflicting";
192  default:
193  return "unknown";
194  }
195 }
196 
283 template <class Adaptor>
284 class Validations
285 {
286  using Mutex = typename Adaptor::Mutex;
287  using Validation = typename Adaptor::Validation;
288  using Ledger = typename Adaptor::Ledger;
289  using ID = typename Ledger::ID;
290  using Seq = typename Ledger::Seq;
291  using NodeID = typename Validation::NodeID;
292  using NodeKey = typename Validation::NodeKey;
293 
295  std::result_of_t<decltype (&Validation::unwrap)(Validation)>>;
296 
297  // Manages concurrent access to members
298  mutable Mutex mutex_;
299 
300  // Validations from currently listed and trusted nodes (partial and full)
302 
303  // Used to enforce the largest validation invariant for the local node
305 
306  // Sequence of the largest validation received from each node
308 
311  ID,
316 
317  // Partial and full validations indexed by sequence
319  Seq,
324 
325  // Sequence of the earliest validation to keep from expire
326  boost::optional<Seq> toKeep_;
327 
328  // Represents the ancestry of validated ledgers
330 
331  // Last (validated) ledger successfully acquired. If in this map, it is
332  // accounted for in the trie.
334 
335  // Set of ledgers being acquired from the network
337 
338  // Parameters to determine validation staleness
340 
341  // Adaptor instance
342  // Is NOT managed by the mutex_ above
343  Adaptor adaptor_;
344 
345 private:
346  // Remove support of a validated ledger
347  void
349  std::lock_guard<Mutex> const&,
350  NodeID const& nodeID,
351  Validation const& val)
352  {
353  {
354  auto it =
355  acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
356  if (it != acquiring_.end())
357  {
358  it->second.erase(nodeID);
359  if (it->second.empty())
360  acquiring_.erase(it);
361  }
362  }
363  {
364  auto it = lastLedger_.find(nodeID);
365  if (it != lastLedger_.end() && it->second.id() == val.ledgerID())
366  {
367  trie_.remove(it->second);
368  lastLedger_.erase(nodeID);
369  }
370  }
371  }
372 
373  // Check if any pending acquire ledger requests are complete
374  void
376  {
377  for (auto it = acquiring_.begin(); it != acquiring_.end();)
378  {
379  if (boost::optional<Ledger> ledger =
380  adaptor_.acquire(it->first.second))
381  {
382  for (NodeID const& nodeID : it->second)
383  updateTrie(lock, nodeID, *ledger);
384 
385  it = acquiring_.erase(it);
386  }
387  else
388  ++it;
389  }
390  }
391 
392  // Update the trie to reflect a new validated ledger
393  void
395  std::lock_guard<Mutex> const&,
396  NodeID const& nodeID,
397  Ledger ledger)
398  {
399  auto const [it, inserted] = lastLedger_.emplace(nodeID, ledger);
400  if (!inserted)
401  {
402  trie_.remove(it->second);
403  it->second = ledger;
404  }
405  trie_.insert(ledger);
406  }
407 
421  void
423  std::lock_guard<Mutex> const& lock,
424  NodeID const& nodeID,
425  Validation const& val,
426  boost::optional<std::pair<Seq, ID>> prior)
427  {
428  assert(val.trusted());
429 
430  // Clear any prior acquiring ledger for this node
431  if (prior)
432  {
433  auto it = acquiring_.find(*prior);
434  if (it != acquiring_.end())
435  {
436  it->second.erase(nodeID);
437  if (it->second.empty())
438  acquiring_.erase(it);
439  }
440  }
441 
442  checkAcquired(lock);
443 
444  std::pair<Seq, ID> valPair{val.seq(), val.ledgerID()};
445  auto it = acquiring_.find(valPair);
446  if (it != acquiring_.end())
447  {
448  it->second.insert(nodeID);
449  }
450  else
451  {
452  if (boost::optional<Ledger> ledger =
453  adaptor_.acquire(val.ledgerID()))
454  updateTrie(lock, nodeID, *ledger);
455  else
456  acquiring_[valPair].insert(nodeID);
457  }
458  }
459 
472  template <class F>
473  auto
474  withTrie(std::lock_guard<Mutex> const& lock, F&& f)
475  {
476  // Call current to flush any stale validations
477  current(
478  lock, [](auto) {}, [](auto, auto) {});
479  checkAcquired(lock);
480  return f(trie_);
481  }
482 
499  template <class Pre, class F>
500  void
501  current(std::lock_guard<Mutex> const& lock, Pre&& pre, F&& f)
502  {
503  NetClock::time_point t = adaptor_.now();
504  pre(current_.size());
505  auto it = current_.begin();
506  while (it != current_.end())
507  {
508  // Check for staleness
509  if (!isCurrent(
510  parms_, t, it->second.signTime(), it->second.seenTime()))
511  {
512  removeTrie(lock, it->first, it->second);
513  it = current_.erase(it);
514  }
515  else
516  {
517  auto cit = typename decltype(current_)::const_iterator{it};
518  // contains a live record
519  f(cit->first, cit->second);
520  ++it;
521  }
522  }
523  }
524 
537  template <class Pre, class F>
538  void
540  std::lock_guard<Mutex> const&,
541  ID const& ledgerID,
542  Pre&& pre,
543  F&& f)
544  {
545  auto it = byLedger_.find(ledgerID);
546  if (it != byLedger_.end())
547  {
548  // Update set time since it is being used
549  byLedger_.touch(it);
550  pre(it->second.size());
551  for (auto const& [key, val] : it->second)
552  f(key, val);
553  }
554  }
555 
556 public:
563  template <class... Ts>
565  ValidationParms const& p,
567  Ts&&... ts)
568  : byLedger_(c)
569  , bySequence_(c)
570  , parms_(p)
571  , adaptor_(std::forward<Ts>(ts)...)
572  {
573  }
574 
577  Adaptor const&
578  adaptor() const
579  {
580  return adaptor_;
581  }
582 
585  ValidationParms const&
586  parms() const
587  {
588  return parms_;
589  }
590 
598  bool
600  {
601  std::lock_guard lock{mutex_};
602  return localSeqEnforcer_(byLedger_.clock().now(), s, parms_);
603  }
604 
613  ValStatus
614  add(NodeID const& nodeID, Validation const& val)
615  {
616  if (!isCurrent(parms_, adaptor_.now(), val.signTime(), val.seenTime()))
617  return ValStatus::stale;
618 
619  {
620  std::lock_guard lock{mutex_};
621 
622  // Check that validation sequence is greater than any non-expired
623  // validations sequence from that validator; if it's not, perform
624  // additional work to detect Byzantine validations
625  auto const now = byLedger_.clock().now();
626 
627  auto const [seqit, seqinserted] =
628  bySequence_[val.seq()].emplace(nodeID, val);
629 
630  if (!seqinserted)
631  {
632  // Check if the entry we're already tracking was signed
633  // long enough ago that we can disregard it.
634  auto const diff =
635  std::max(seqit->second.signTime(), val.signTime()) -
636  std::min(seqit->second.signTime(), val.signTime());
637 
639  val.signTime() > seqit->second.signTime())
640  seqit->second = val;
641  }
642 
643  // Enforce monotonically increasing sequences for validations
644  // by a given node:
645  if (auto& enf = seqEnforcers_[nodeID]; !enf(now, val.seq(), parms_))
646  {
647  // If the validation is for the same sequence as one we are
648  // tracking, check it closely:
649  if (seqit->second.seq() == val.seq())
650  {
651  // Two validations for the same sequence but for different
652  // ledgers. This could be the result of misconfiguration
653  // but it can also mean a Byzantine validator.
654  if (seqit->second.ledgerID() != val.ledgerID())
655  return ValStatus::conflicting;
656 
657  // Two validations for the same sequence but with different
658  // cookies. This is probably accidental misconfiguration.
659  if (seqit->second.cookie() != val.cookie())
660  return ValStatus::multiple;
661  }
662 
663  return ValStatus::badSeq;
664  }
665 
666  byLedger_[val.ledgerID()].insert_or_assign(nodeID, val);
667 
668  auto const [it, inserted] = current_.emplace(nodeID, val);
669  if (!inserted)
670  {
671  // Replace existing only if this one is newer
672  Validation& oldVal = it->second;
673  if (val.signTime() > oldVal.signTime())
674  {
675  std::pair<Seq, ID> old(oldVal.seq(), oldVal.ledgerID());
676  it->second = val;
677  if (val.trusted())
678  updateTrie(lock, nodeID, val, old);
679  }
680  else
681  return ValStatus::stale;
682  }
683  else if (val.trusted())
684  {
685  updateTrie(lock, nodeID, val, boost::none);
686  }
687  }
688 
689  return ValStatus::current;
690  }
691 
696  void
697  setSeqToKeep(Seq const& s)
698  {
699  std::lock_guard lock{mutex_};
700  toKeep_ = s;
701  }
702 
708  void
710  {
711  std::lock_guard lock{mutex_};
712  if (toKeep_)
713  {
714  for (auto i = byLedger_.begin(); i != byLedger_.end(); ++i)
715  {
716  auto const& validationMap = i->second;
717  if (!validationMap.empty() &&
718  validationMap.begin()->second.seq() >= toKeep_)
719  {
720  byLedger_.touch(i);
721  }
722  }
723 
724  for (auto i = bySequence_.begin(); i != bySequence_.end(); ++i)
725  {
726  if (i->first >= toKeep_)
727  {
728  bySequence_.touch(i);
729  }
730  }
731  }
732 
735  }
736 
746  void
747  trustChanged(hash_set<NodeID> const& added, hash_set<NodeID> const& removed)
748  {
749  std::lock_guard lock{mutex_};
750 
751  for (auto& [nodeId, validation] : current_)
752  {
753  if (added.find(nodeId) != added.end())
754  {
755  validation.setTrusted();
756  updateTrie(lock, nodeId, validation, boost::none);
757  }
758  else if (removed.find(nodeId) != removed.end())
759  {
760  validation.setUntrusted();
761  removeTrie(lock, nodeId, validation);
762  }
763  }
764 
765  for (auto& [_, validationMap] : byLedger_)
766  {
767  (void)_;
768  for (auto& [nodeId, validation] : validationMap)
769  {
770  if (added.find(nodeId) != added.end())
771  {
772  validation.setTrusted();
773  }
774  else if (removed.find(nodeId) != removed.end())
775  {
776  validation.setUntrusted();
777  }
778  }
779  }
780  }
781 
783  getJsonTrie() const
784  {
785  std::lock_guard lock{mutex_};
786  return trie_.getJson();
787  }
788 
801  boost::optional<std::pair<Seq, ID>>
802  getPreferred(Ledger const& curr)
803  {
804  std::lock_guard lock{mutex_};
805  boost::optional<SpanTip<Ledger>> preferred =
806  withTrie(lock, [this](LedgerTrie<Ledger>& trie) {
807  return trie.getPreferred(localSeqEnforcer_.largest());
808  });
809  // No trusted validations to determine branch
810  if (!preferred)
811  {
812  // fall back to majority over acquiring ledgers
813  auto it = std::max_element(
814  acquiring_.begin(),
815  acquiring_.end(),
816  [](auto const& a, auto const& b) {
817  std::pair<Seq, ID> const& aKey = a.first;
818  typename hash_set<NodeID>::size_type const& aSize =
819  a.second.size();
820  std::pair<Seq, ID> const& bKey = b.first;
821  typename hash_set<NodeID>::size_type const& bSize =
822  b.second.size();
823  // order by number of trusted peers validating that ledger
824  // break ties with ledger ID
825  return std::tie(aSize, aKey.second) <
826  std::tie(bSize, bKey.second);
827  });
828  if (it != acquiring_.end())
829  return it->first;
830  return boost::none;
831  }
832 
833  // If we are the parent of the preferred ledger, stick with our
834  // current ledger since we might be about to generate it
835  if (preferred->seq == curr.seq() + Seq{1} &&
836  preferred->ancestor(curr.seq()) == curr.id())
837  return std::make_pair(curr.seq(), curr.id());
838 
839  // A ledger ahead of us is preferred regardless of whether it is
840  // a descendant of our working ledger or it is on a different chain
841  if (preferred->seq > curr.seq())
842  return std::make_pair(preferred->seq, preferred->id);
843 
844  // Only switch to earlier or same sequence number
845  // if it is a different chain.
846  if (curr[preferred->seq] != preferred->id)
847  return std::make_pair(preferred->seq, preferred->id);
848 
849  // Stick with current ledger
850  return std::make_pair(curr.seq(), curr.id());
851  }
852 
862  ID
863  getPreferred(Ledger const& curr, Seq minValidSeq)
864  {
865  boost::optional<std::pair<Seq, ID>> preferred = getPreferred(curr);
866  if (preferred && preferred->first >= minValidSeq)
867  return preferred->second;
868  return curr.id();
869  }
870 
887  ID
889  Ledger const& lcl,
890  Seq minSeq,
891  hash_map<ID, std::uint32_t> const& peerCounts)
892  {
893  boost::optional<std::pair<Seq, ID>> preferred = getPreferred(lcl);
894 
895  // Trusted validations exist, but stick with local preferred ledger if
896  // preferred is in the past
897  if (preferred)
898  return (preferred->first >= minSeq) ? preferred->second : lcl.id();
899 
900  // Otherwise, rely on peer ledgers
901  auto it = std::max_element(
902  peerCounts.begin(), peerCounts.end(), [](auto& a, auto& b) {
903  // Prefer larger counts, then larger ids on ties
904  // (max_element expects this to return true if a < b)
905  return std::tie(a.second, a.first) <
906  std::tie(b.second, b.first);
907  });
908 
909  if (it != peerCounts.end())
910  return it->first;
911  return lcl.id();
912  }
913 
926  getNodesAfter(Ledger const& ledger, ID const& ledgerID)
927  {
928  std::lock_guard lock{mutex_};
929 
930  // Use trie if ledger is the right one
931  if (ledger.id() == ledgerID)
932  return withTrie(lock, [&ledger](LedgerTrie<Ledger>& trie) {
933  return trie.branchSupport(ledger) - trie.tipSupport(ledger);
934  });
935 
936  // Count parent ledgers as fallback
937  return std::count_if(
938  lastLedger_.begin(),
939  lastLedger_.end(),
940  [&ledgerID](auto const& it) {
941  auto const& curr = it.second;
942  return curr.seq() > Seq{0} &&
943  curr[curr.seq() - Seq{1}] == ledgerID;
944  });
945  }
946 
953  {
955  std::lock_guard lock{mutex_};
956  current(
957  lock,
958  [&](std::size_t numValidations) { ret.reserve(numValidations); },
959  [&](NodeID const&, Validation const& v) {
960  if (v.trusted() && v.full())
961  ret.push_back(v.unwrap());
962  });
963  return ret;
964  }
965 
970  auto
972  {
973  hash_set<NodeID> ret;
974  std::lock_guard lock{mutex_};
975  current(
976  lock,
977  [&](std::size_t numValidations) { ret.reserve(numValidations); },
978  [&](NodeID const& nid, Validation const&) { ret.insert(nid); });
979 
980  return ret;
981  }
982 
989  numTrustedForLedger(ID const& ledgerID)
990  {
991  std::size_t count = 0;
992  std::lock_guard lock{mutex_};
993  byLedger(
994  lock,
995  ledgerID,
996  [&](std::size_t) {}, // nothing to reserve
997  [&](NodeID const&, Validation const& v) {
998  if (v.trusted() && v.full())
999  ++count;
1000  });
1001  return count;
1002  }
1003 
1010  getTrustedForLedger(ID const& ledgerID)
1011  {
1013  std::lock_guard lock{mutex_};
1014  byLedger(
1015  lock,
1016  ledgerID,
1017  [&](std::size_t numValidations) { res.reserve(numValidations); },
1018  [&](NodeID const&, Validation const& v) {
1019  if (v.trusted() && v.full())
1020  res.emplace_back(v.unwrap());
1021  });
1022 
1023  return res;
1024  }
1025 
1033  fees(ID const& ledgerID, std::uint32_t baseFee)
1034  {
1036  std::lock_guard lock{mutex_};
1037  byLedger(
1038  lock,
1039  ledgerID,
1040  [&](std::size_t numValidations) { res.reserve(numValidations); },
1041  [&](NodeID const&, Validation const& v) {
1042  if (v.trusted() && v.full())
1043  {
1044  boost::optional<std::uint32_t> loadFee = v.loadFee();
1045  if (loadFee)
1046  res.push_back(*loadFee);
1047  else
1048  res.push_back(baseFee);
1049  }
1050  });
1051  return res;
1052  }
1053 
1056  void
1058  {
1059  std::lock_guard lock{mutex_};
1060  current_.clear();
1061  }
1062 
1078  std::size_t
1079  laggards(Seq const seq, hash_set<NodeKey>& trustedKeys)
1080  {
1081  std::size_t laggards = 0;
1082 
1083  current(
1084  std::lock_guard{mutex_},
1085  [](std::size_t) {},
1086  [&](NodeID const&, Validation const& v) {
1087  if (adaptor_.now() <
1088  v.seenTime() + parms_.validationFRESHNESS &&
1089  trustedKeys.find(v.key()) != trustedKeys.end())
1090  {
1091  trustedKeys.erase(v.key());
1092  if (seq > v.seq())
1093  ++laggards;
1094  }
1095  });
1096 
1097  return laggards;
1098  }
1099 };
1100 
1101 } // namespace ripple
1102 #endif
ripple::Validations::expire
void expire()
Expire old validation sets.
Definition: Validations.h:709
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::Seq
typename Ledger::Seq Seq
Definition: Validations.h:290
std::max_element
T max_element(T... args)
ripple::LedgerTrie::branchSupport
std::uint32_t branchSupport(Ledger const &ledger) const
Return the count of branch support for the specific ledger.
Definition: LedgerTrie.h:604
std::chrono::steady_clock
ripple::LedgerTrie::getPreferred
boost::optional< SpanTip< Ledger > > getPreferred(Seq const largestIssued) const
Return the preferred ledger ID.
Definition: LedgerTrie.h:678
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::Validation
typename ripple::test::csf::Peer::ValAdaptor ::Validation Validation
Definition: Validations.h:287
ripple::Validations::seqEnforcers_
hash_map< NodeID, SeqEnforcer< Seq > > seqEnforcers_
Definition: Validations.h:307
ripple::Dir::const_iterator
Definition: Directory.h:49
ripple::SeqEnforcer
Enforce validation increasing sequence requirement.
Definition: Validations.h:96
std::string
STL class.
utility
ripple::Validations::laggards
std::size_t laggards(Seq const seq, hash_set< NodeKey > &trustedKeys)
Return quantity of lagging proposers, and remove online proposers for purposes of evaluating whether ...
Definition: Validations.h:1079
std::unordered_set
STL class.
std::pair< Seq, ID >
std::vector::reserve
T reserve(T... args)
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
ripple::Validations::lastLedger_
hash_map< NodeID, Ledger > lastLedger_
Definition: Validations.h:333
ripple::Validations::Validations
Validations(ValidationParms const &p, beast::abstract_clock< std::chrono::steady_clock > &c, Ts &&... ts)
Constructor.
Definition: Validations.h:564
vector
std::unordered_set::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::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::seconds
ripple::Validations::trie_
LedgerTrie< Ledger > trie_
Definition: Validations.h:329
ripple::Validations::bySequence_
beast::aged_unordered_map< Seq, hash_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> > bySequence_
Definition: Validations.h:323
ripple::LedgerTrie::tipSupport
std::uint32_t tipSupport(Ledger const &ledger) const
Return count of tip support for the specific ledger.
Definition: LedgerTrie.h:590
ripple::Validations::withTrie
auto withTrie(std::lock_guard< Mutex > const &lock, F &&f)
Use the trie for a calculation.
Definition: Validations.h:474
ripple::Validations::current
void current(std::lock_guard< Mutex > const &lock, Pre &&pre, F &&f)
Iterate current validations.
Definition: Validations.h:501
ripple::Validations::byLedger
void byLedger(std::lock_guard< Mutex > const &, ID const &ledgerID, Pre &&pre, F &&f)
Iterate the set of validations associated with a given ledger id.
Definition: Validations.h:539
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::Validations::setSeqToKeep
void setSeqToKeep(Seq const &s)
Set the smallest sequence number of validations to keep from expire.
Definition: Validations.h:697
std::lock_guard
STL class.
ripple::SBoxCmp::diff
@ diff
ripple::Validations::byLedger_
beast::aged_unordered_map< ID, hash_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> > byLedger_
Validations from listed nodes, indexed by ledger id (partial and full)
Definition: Validations.h:315
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:45
ripple::Validations::checkAcquired
void checkAcquired(std::lock_guard< Mutex > const &lock)
Definition: Validations.h:375
ripple::Validations::parms
ValidationParms const & parms() const
Return the validation timing parameters.
Definition: Validations.h:586
ripple::Validations::getJsonTrie
Json::Value getJsonTrie() const
Definition: Validations.h:783
ripple::Validations::updateTrie
void updateTrie(std::lock_guard< Mutex > const &lock, NodeID const &nodeID, Validation const &val, boost::optional< std::pair< Seq, ID >> prior)
Process a new validation.
Definition: Validations.h:422
ripple::SeqEnforcer::largest
Seq largest() const
Definition: Validations.h:128
std::vector::push_back
T push_back(T... args)
ripple::ValStatus::badSeq
@ badSeq
A validation violates the increasing seq requirement.
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::Validations::mutex_
Mutex mutex_
Definition: Validations.h:298
ripple::Validations::add
ValStatus add(NodeID const &nodeID, Validation const &val)
Add a new validation.
Definition: Validations.h:614
ripple::Validations::adaptor_
Adaptor adaptor_
Definition: Validations.h:343
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::Mutex
typename ripple::test::csf::Peer::ValAdaptor ::Mutex Mutex
Definition: Validations.h:286
ripple::SeqEnforcer::time_point
std::chrono::steady_clock::time_point time_point
Definition: Validations.h:98
ripple::Validations::acquiring_
hash_map< std::pair< Seq, ID >, hash_set< NodeID > > acquiring_
Definition: Validations.h:336
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::NodeKey
typename Validation::NodeKey NodeKey
Definition: Validations.h:292
ripple::isCurrent
bool isCurrent(ValidationParms const &p, NetClock::time_point now, NetClock::time_point signTime, NetClock::time_point seenTime)
Whether a validation is still current.
Definition: Validations.h:145
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::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::SeqEnforcer::when_
time_point when_
Definition: Validations.h:100
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::NodeID
typename Validation::NodeID NodeID
Definition: Validations.h:291
std::chrono::time_point
ripple::ValStatus::multiple
@ multiple
Multiple validations for the same ledger from multiple validators.
std::unordered_set::erase
T erase(T... args)
ripple::ValStatus::stale
@ stale
Not current or was older than current from this node.
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
ripple::Validations::canValidateSeq
bool canValidateSeq(Seq const s)
Return whether the local node can issue a validation for the given sequence number.
Definition: Validations.h:599
ripple::HashPrefix::validation
@ validation
validation for signing
beast::expire
std::enable_if< is_aged_container< AgedContainer >::value, std::size_t >::type expire(AgedContainer &c, std::chrono::duration< Rep, Period > const &age)
Expire aged container items past the specified age.
Definition: aged_container_utility.h:33
ripple::Validations::toKeep_
boost::optional< Seq > toKeep_
Definition: Validations.h:326
std::uint32_t
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::SeqEnforcer::operator()
bool operator()(time_point now, Seq s, ValidationParms const &p)
Try advancing the largest observed validation ledger sequence.
Definition: Validations.h:116
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 >
ripple::Validations::getPreferred
ID getPreferred(Ledger const &curr, Seq minValidSeq)
Get the ID of the preferred working ledger that exceeds a minimum valid ledger sequence number.
Definition: Validations.h:863
ripple::Validations::flush
void flush()
Flush all current validations.
Definition: Validations.h:1057
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::ID
typename Ledger::ID ID
Definition: Validations.h:289
std::min
T min(T... args)
std::decay_t
ripple::Validations::updateTrie
void updateTrie(std::lock_guard< Mutex > const &, NodeID const &nodeID, Ledger ledger)
Definition: Validations.h:394
ripple::ValStatus::conflicting
@ conflicting
Multiple validations for different ledgers by a single validator.
ripple::Validations::localSeqEnforcer_
SeqEnforcer< Seq > localSeqEnforcer_
Definition: Validations.h:304
beast::detail::aged_unordered_container
Associative container where each element is also indexed by time.
Definition: aged_unordered_container.h:85
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::LedgerTrie
Ancestry trie of ledgers.
Definition: LedgerTrie.h:347
ripple::ValidationParms::validationFRESHNESS
std::chrono::seconds validationFRESHNESS
How long we consider a validation fresh.
Definition: Validations.h:86
std::unordered_map::begin
T begin(T... args)
std
STL namespace.
std::unordered_set::insert
T insert(T... args)
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::Validations::parms_
const ValidationParms parms_
Definition: Validations.h:339
std::result_of_t
std::count_if
T count_if(T... args)
mutex
std::size_t
std::make_pair
T make_pair(T... args)
std::unordered_set::end
T end(T... args)
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::Ledger
typename ripple::test::csf::Peer::ValAdaptor ::Ledger Ledger
Definition: Validations.h:288
beast::uhash<>
ripple::Validations::getCurrentNodeIDs
auto getCurrentNodeIDs() -> hash_set< NodeID >
Get the set of node ids associated with current validations.
Definition: Validations.h:971
ripple::ValidationParms::ValidationParms
ValidationParms()=default
std::max
T max(T... args)
ripple::Validations::removeTrie
void removeTrie(std::lock_guard< Mutex > const &, NodeID const &nodeID, Validation const &val)
Definition: Validations.h:348
ripple::Validations::adaptor
Adaptor const & adaptor() const
Return the adaptor instance.
Definition: Validations.h:578
ripple::ValidationParms
Timing parameters to control validation staleness and expiration.
Definition: Validations.h:43
std::unordered_map
STL class.
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::SeqEnforcer::seq_
Seq seq_
Definition: Validations.h:99
ripple::Validations::currentTrusted
std::vector< WrappedValidationType > currentTrusted()
Get the currently trusted full validations.
Definition: Validations.h:952
ripple::Validations::current_
hash_map< NodeID, Validation > current_
Definition: Validations.h:301