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 <mutex>
31 #include <optional>
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 };
133 
145 inline bool
147  ValidationParms const& p,
149  NetClock::time_point signTime,
150  NetClock::time_point seenTime)
151 {
152  // Because this can be called on untrusted, possibly
153  // malicious validations, we do our math in a way
154  // that avoids any chance of overflowing or underflowing
155  // the signing time. All of the expressions below are
156  // promoted from unsigned 32 bit to signed 64 bit prior
157  // to computation.
158 
159  return (signTime > (now - p.validationCURRENT_EARLY)) &&
160  (signTime < (now + p.validationCURRENT_WALL)) &&
161  ((seenTime == NetClock::time_point{}) ||
162  (seenTime < (now + p.validationCURRENT_LOCAL)));
163 }
164 
166 enum class ValStatus {
168  current,
170  stale,
172  badSeq,
174  multiple,
177 };
178 
179 inline std::string
181 {
182  switch (m)
183  {
184  case ValStatus::current:
185  return "current";
186  case ValStatus::stale:
187  return "stale";
188  case ValStatus::badSeq:
189  return "badSeq";
190  case ValStatus::multiple:
191  return "multiple";
193  return "conflicting";
194  default:
195  return "unknown";
196  }
197 }
198 
285 template <class Adaptor>
286 class Validations
287 {
288  using Mutex = typename Adaptor::Mutex;
289  using Validation = typename Adaptor::Validation;
290  using Ledger = typename Adaptor::Ledger;
291  using ID = typename Ledger::ID;
292  using Seq = typename Ledger::Seq;
293  using NodeID = typename Validation::NodeID;
294  using NodeKey = typename Validation::NodeKey;
295 
297  std::result_of_t<decltype (&Validation::unwrap)(Validation)>>;
298 
299  // Manages concurrent access to members
300  mutable Mutex mutex_;
301 
302  // Validations from currently listed and trusted nodes (partial and full)
304 
305  // Used to enforce the largest validation invariant for the local node
307 
308  // Sequence of the largest validation received from each node
310 
313  ID,
318 
319  // Partial and full validations indexed by sequence
321  Seq,
326 
327  // A range [low_, high_) of validations to keep from expire
328  struct KeepRange
329  {
332  };
334 
335  // Represents the ancestry of validated ledgers
337 
338  // Last (validated) ledger successfully acquired. If in this map, it is
339  // accounted for in the trie.
341 
342  // Set of ledgers being acquired from the network
344 
345  // Parameters to determine validation staleness
347 
348  // Adaptor instance
349  // Is NOT managed by the mutex_ above
350  Adaptor adaptor_;
351 
352 private:
353  // Remove support of a validated ledger
354  void
356  std::lock_guard<Mutex> const&,
357  NodeID const& nodeID,
358  Validation const& val)
359  {
360  {
361  auto it =
362  acquiring_.find(std::make_pair(val.seq(), val.ledgerID()));
363  if (it != acquiring_.end())
364  {
365  it->second.erase(nodeID);
366  if (it->second.empty())
367  acquiring_.erase(it);
368  }
369  }
370  {
371  auto it = lastLedger_.find(nodeID);
372  if (it != lastLedger_.end() && it->second.id() == val.ledgerID())
373  {
374  trie_.remove(it->second);
375  lastLedger_.erase(nodeID);
376  }
377  }
378  }
379 
380  // Check if any pending acquire ledger requests are complete
381  void
383  {
384  for (auto it = acquiring_.begin(); it != acquiring_.end();)
385  {
386  if (std::optional<Ledger> ledger =
387  adaptor_.acquire(it->first.second))
388  {
389  for (NodeID const& nodeID : it->second)
390  updateTrie(lock, nodeID, *ledger);
391 
392  it = acquiring_.erase(it);
393  }
394  else
395  ++it;
396  }
397  }
398 
399  // Update the trie to reflect a new validated ledger
400  void
402  std::lock_guard<Mutex> const&,
403  NodeID const& nodeID,
404  Ledger ledger)
405  {
406  auto const [it, inserted] = lastLedger_.emplace(nodeID, ledger);
407  if (!inserted)
408  {
409  trie_.remove(it->second);
410  it->second = ledger;
411  }
412  trie_.insert(ledger);
413  }
414 
428  void
430  std::lock_guard<Mutex> const& lock,
431  NodeID const& nodeID,
432  Validation const& val,
434  {
435  assert(val.trusted());
436 
437  // Clear any prior acquiring ledger for this node
438  if (prior)
439  {
440  auto it = acquiring_.find(*prior);
441  if (it != acquiring_.end())
442  {
443  it->second.erase(nodeID);
444  if (it->second.empty())
445  acquiring_.erase(it);
446  }
447  }
448 
449  checkAcquired(lock);
450 
451  std::pair<Seq, ID> valPair{val.seq(), val.ledgerID()};
452  auto it = acquiring_.find(valPair);
453  if (it != acquiring_.end())
454  {
455  it->second.insert(nodeID);
456  }
457  else
458  {
459  if (std::optional<Ledger> ledger = adaptor_.acquire(val.ledgerID()))
460  updateTrie(lock, nodeID, *ledger);
461  else
462  acquiring_[valPair].insert(nodeID);
463  }
464  }
465 
478  template <class F>
479  auto
480  withTrie(std::lock_guard<Mutex> const& lock, F&& f)
481  {
482  // Call current to flush any stale validations
483  current(
484  lock, [](auto) {}, [](auto, auto) {});
485  checkAcquired(lock);
486  return f(trie_);
487  }
488 
505  template <class Pre, class F>
506  void
507  current(std::lock_guard<Mutex> const& lock, Pre&& pre, F&& f)
508  {
509  NetClock::time_point t = adaptor_.now();
510  pre(current_.size());
511  auto it = current_.begin();
512  while (it != current_.end())
513  {
514  // Check for staleness
515  if (!isCurrent(
516  parms_, t, it->second.signTime(), it->second.seenTime()))
517  {
518  removeTrie(lock, it->first, it->second);
519  it = current_.erase(it);
520  }
521  else
522  {
523  auto cit = typename decltype(current_)::const_iterator{it};
524  // contains a live record
525  f(cit->first, cit->second);
526  ++it;
527  }
528  }
529  }
530 
543  template <class Pre, class F>
544  void
546  std::lock_guard<Mutex> const&,
547  ID const& ledgerID,
548  Pre&& pre,
549  F&& f)
550  {
551  auto it = byLedger_.find(ledgerID);
552  if (it != byLedger_.end())
553  {
554  // Update set time since it is being used
555  byLedger_.touch(it);
556  pre(it->second.size());
557  for (auto const& [key, val] : it->second)
558  f(key, val);
559  }
560  }
561 
562 public:
569  template <class... Ts>
571  ValidationParms const& p,
573  Ts&&... ts)
574  : byLedger_(c)
575  , bySequence_(c)
576  , parms_(p)
577  , adaptor_(std::forward<Ts>(ts)...)
578  {
579  }
580 
583  Adaptor const&
584  adaptor() const
585  {
586  return adaptor_;
587  }
588 
591  ValidationParms const&
592  parms() const
593  {
594  return parms_;
595  }
596 
604  bool
606  {
607  std::lock_guard lock{mutex_};
608  return localSeqEnforcer_(byLedger_.clock().now(), s, parms_);
609  }
610 
619  ValStatus
620  add(NodeID const& nodeID, Validation const& val)
621  {
622  if (!isCurrent(parms_, adaptor_.now(), val.signTime(), val.seenTime()))
623  return ValStatus::stale;
624 
625  {
626  std::lock_guard lock{mutex_};
627 
628  // Check that validation sequence is greater than any non-expired
629  // validations sequence from that validator; if it's not, perform
630  // additional work to detect Byzantine validations
631  auto const now = byLedger_.clock().now();
632 
633  auto const [seqit, seqinserted] =
634  bySequence_[val.seq()].emplace(nodeID, val);
635 
636  if (!seqinserted)
637  {
638  // Check if the entry we're already tracking was signed
639  // long enough ago that we can disregard it.
640  auto const diff =
641  std::max(seqit->second.signTime(), val.signTime()) -
642  std::min(seqit->second.signTime(), val.signTime());
643 
644  if (diff > parms_.validationCURRENT_WALL &&
645  val.signTime() > seqit->second.signTime())
646  seqit->second = val;
647  }
648 
649  // Enforce monotonically increasing sequences for validations
650  // by a given node, and run the active Byzantine detector:
651  if (auto& enf = seqEnforcers_[nodeID]; !enf(now, val.seq(), parms_))
652  {
653  // If the validation is for the same sequence as one we are
654  // tracking, check it closely:
655  if (seqit->second.seq() == val.seq())
656  {
657  // Two validations for the same sequence but for different
658  // ledgers. This could be the result of misconfiguration
659  // but it can also mean a Byzantine validator.
660  if (seqit->second.ledgerID() != val.ledgerID())
661  return ValStatus::conflicting;
662 
663  // Two validations for the same sequence and for the same
664  // ledger with different sign times. This could be the
665  // result of a misconfiguration but it can also mean a
666  // Byzantine validator.
667  if (seqit->second.signTime() != val.signTime())
668  return ValStatus::conflicting;
669 
670  // Two validations for the same sequence but with different
671  // cookies. This is probably accidental misconfiguration.
672  if (seqit->second.cookie() != val.cookie())
673  return ValStatus::multiple;
674  }
675 
676  return ValStatus::badSeq;
677  }
678 
679  byLedger_[val.ledgerID()].insert_or_assign(nodeID, val);
680 
681  auto const [it, inserted] = current_.emplace(nodeID, val);
682  if (!inserted)
683  {
684  // Replace existing only if this one is newer
685  Validation& oldVal = it->second;
686  if (val.signTime() > oldVal.signTime())
687  {
688  std::pair<Seq, ID> old(oldVal.seq(), oldVal.ledgerID());
689  it->second = val;
690  if (val.trusted())
691  updateTrie(lock, nodeID, val, old);
692  }
693  else
694  return ValStatus::stale;
695  }
696  else if (val.trusted())
697  {
698  updateTrie(lock, nodeID, val, std::nullopt);
699  }
700  }
701 
702  return ValStatus::current;
703  }
704 
711  void
712  setSeqToKeep(Seq const& low, Seq const& high)
713  {
714  std::lock_guard lock{mutex_};
715  assert(low < high);
716  toKeep_ = {low, high};
717  }
718 
724  void
726  {
727  auto const start = std::chrono::steady_clock::now();
728  {
729  std::lock_guard lock{mutex_};
730  if (toKeep_)
731  {
732  // We only need to refresh the keep range when it's just about
733  // to expire. Track the next time we need to refresh.
734  static std::chrono::steady_clock::time_point refreshTime;
735  if (auto const now = byLedger_.clock().now();
736  refreshTime <= now)
737  {
738  // The next refresh time is shortly before the expiration
739  // time from now.
740  refreshTime = now + parms_.validationSET_EXPIRES -
742 
743  for (auto i = byLedger_.begin(); i != byLedger_.end(); ++i)
744  {
745  auto const& validationMap = i->second;
746  if (!validationMap.empty())
747  {
748  auto const seq =
749  validationMap.begin()->second.seq();
750  if (toKeep_->low_ <= seq && seq < toKeep_->high_)
751  {
752  byLedger_.touch(i);
753  }
754  }
755  }
756 
757  for (auto i = bySequence_.begin(); i != bySequence_.end();
758  ++i)
759  {
760  if (toKeep_->low_ <= i->first &&
761  i->first < toKeep_->high_)
762  {
763  bySequence_.touch(i);
764  }
765  }
766  }
767  }
768 
771  }
772  JLOG(j.debug())
773  << "Validations sets sweep lock duration "
774  << std::chrono::duration_cast<std::chrono::milliseconds>(
776  .count()
777  << "ms";
778  }
779 
789  void
790  trustChanged(hash_set<NodeID> const& added, hash_set<NodeID> const& removed)
791  {
792  std::lock_guard lock{mutex_};
793 
794  for (auto& [nodeId, validation] : current_)
795  {
796  if (added.find(nodeId) != added.end())
797  {
798  validation.setTrusted();
799  updateTrie(lock, nodeId, validation, std::nullopt);
800  }
801  else if (removed.find(nodeId) != removed.end())
802  {
803  validation.setUntrusted();
804  removeTrie(lock, nodeId, validation);
805  }
806  }
807 
808  for (auto& [_, validationMap] : byLedger_)
809  {
810  (void)_;
811  for (auto& [nodeId, validation] : validationMap)
812  {
813  if (added.find(nodeId) != added.end())
814  {
815  validation.setTrusted();
816  }
817  else if (removed.find(nodeId) != removed.end())
818  {
819  validation.setUntrusted();
820  }
821  }
822  }
823  }
824 
826  getJsonTrie() const
827  {
828  std::lock_guard lock{mutex_};
829  return trie_.getJson();
830  }
831 
845  getPreferred(Ledger const& curr)
846  {
847  std::lock_guard lock{mutex_};
848  std::optional<SpanTip<Ledger>> preferred =
849  withTrie(lock, [this](LedgerTrie<Ledger>& trie) {
850  return trie.getPreferred(localSeqEnforcer_.largest());
851  });
852  // No trusted validations to determine branch
853  if (!preferred)
854  {
855  // fall back to majority over acquiring ledgers
856  auto it = std::max_element(
857  acquiring_.begin(),
858  acquiring_.end(),
859  [](auto const& a, auto const& b) {
860  std::pair<Seq, ID> const& aKey = a.first;
861  typename hash_set<NodeID>::size_type const& aSize =
862  a.second.size();
863  std::pair<Seq, ID> const& bKey = b.first;
864  typename hash_set<NodeID>::size_type const& bSize =
865  b.second.size();
866  // order by number of trusted peers validating that ledger
867  // break ties with ledger ID
868  return std::tie(aSize, aKey.second) <
869  std::tie(bSize, bKey.second);
870  });
871  if (it != acquiring_.end())
872  return it->first;
873  return std::nullopt;
874  }
875 
876  // If we are the parent of the preferred ledger, stick with our
877  // current ledger since we might be about to generate it
878  if (preferred->seq == curr.seq() + Seq{1} &&
879  preferred->ancestor(curr.seq()) == curr.id())
880  return std::make_pair(curr.seq(), curr.id());
881 
882  // A ledger ahead of us is preferred regardless of whether it is
883  // a descendant of our working ledger or it is on a different chain
884  if (preferred->seq > curr.seq())
885  return std::make_pair(preferred->seq, preferred->id);
886 
887  // Only switch to earlier or same sequence number
888  // if it is a different chain.
889  if (curr[preferred->seq] != preferred->id)
890  return std::make_pair(preferred->seq, preferred->id);
891 
892  // Stick with current ledger
893  return std::make_pair(curr.seq(), curr.id());
894  }
895 
905  ID
906  getPreferred(Ledger const& curr, Seq minValidSeq)
907  {
909  if (preferred && preferred->first >= minValidSeq)
910  return preferred->second;
911  return curr.id();
912  }
913 
930  ID
932  Ledger const& lcl,
933  Seq minSeq,
934  hash_map<ID, std::uint32_t> const& peerCounts)
935  {
937 
938  // Trusted validations exist, but stick with local preferred ledger if
939  // preferred is in the past
940  if (preferred)
941  return (preferred->first >= minSeq) ? preferred->second : lcl.id();
942 
943  // Otherwise, rely on peer ledgers
944  auto it = std::max_element(
945  peerCounts.begin(), peerCounts.end(), [](auto& a, auto& b) {
946  // Prefer larger counts, then larger ids on ties
947  // (max_element expects this to return true if a < b)
948  return std::tie(a.second, a.first) <
949  std::tie(b.second, b.first);
950  });
951 
952  if (it != peerCounts.end())
953  return it->first;
954  return lcl.id();
955  }
956 
969  getNodesAfter(Ledger const& ledger, ID const& ledgerID)
970  {
971  std::lock_guard lock{mutex_};
972 
973  // Use trie if ledger is the right one
974  if (ledger.id() == ledgerID)
975  return withTrie(lock, [&ledger](LedgerTrie<Ledger>& trie) {
976  return trie.branchSupport(ledger) - trie.tipSupport(ledger);
977  });
978 
979  // Count parent ledgers as fallback
980  return std::count_if(
981  lastLedger_.begin(),
982  lastLedger_.end(),
983  [&ledgerID](auto const& it) {
984  auto const& curr = it.second;
985  return curr.seq() > Seq{0} &&
986  curr[curr.seq() - Seq{1}] == ledgerID;
987  });
988  }
989 
996  {
998  std::lock_guard lock{mutex_};
999  current(
1000  lock,
1001  [&](std::size_t numValidations) { ret.reserve(numValidations); },
1002  [&](NodeID const&, Validation const& v) {
1003  if (v.trusted() && v.full())
1004  ret.push_back(v.unwrap());
1005  });
1006  return ret;
1007  }
1008 
1013  auto
1015  {
1016  hash_set<NodeID> ret;
1017  std::lock_guard lock{mutex_};
1018  current(
1019  lock,
1020  [&](std::size_t numValidations) { ret.reserve(numValidations); },
1021  [&](NodeID const& nid, Validation const&) { ret.insert(nid); });
1022 
1023  return ret;
1024  }
1025 
1031  std::size_t
1032  numTrustedForLedger(ID const& ledgerID)
1033  {
1034  std::size_t count = 0;
1035  std::lock_guard lock{mutex_};
1036  byLedger(
1037  lock,
1038  ledgerID,
1039  [&](std::size_t) {}, // nothing to reserve
1040  [&](NodeID const&, Validation const& v) {
1041  if (v.trusted() && v.full())
1042  ++count;
1043  });
1044  return count;
1045  }
1046 
1053  getTrustedForLedger(ID const& ledgerID)
1054  {
1056  std::lock_guard lock{mutex_};
1057  byLedger(
1058  lock,
1059  ledgerID,
1060  [&](std::size_t numValidations) { res.reserve(numValidations); },
1061  [&](NodeID const&, Validation const& v) {
1062  if (v.trusted() && v.full())
1063  res.emplace_back(v.unwrap());
1064  });
1065 
1066  return res;
1067  }
1068 
1076  fees(ID const& ledgerID, std::uint32_t baseFee)
1077  {
1079  std::lock_guard lock{mutex_};
1080  byLedger(
1081  lock,
1082  ledgerID,
1083  [&](std::size_t numValidations) { res.reserve(numValidations); },
1084  [&](NodeID const&, Validation const& v) {
1085  if (v.trusted() && v.full())
1086  {
1087  std::optional<std::uint32_t> loadFee = v.loadFee();
1088  if (loadFee)
1089  res.push_back(*loadFee);
1090  else
1091  res.push_back(baseFee);
1092  }
1093  });
1094  return res;
1095  }
1096 
1099  void
1101  {
1102  std::lock_guard lock{mutex_};
1103  current_.clear();
1104  }
1105 
1121  std::size_t
1122  laggards(Seq const seq, hash_set<NodeKey>& trustedKeys)
1123  {
1124  std::size_t laggards = 0;
1125 
1126  current(
1127  std::lock_guard{mutex_},
1128  [](std::size_t) {},
1129  [&](NodeID const&, Validation const& v) {
1130  if (adaptor_.now() <
1131  v.seenTime() + parms_.validationFRESHNESS &&
1132  trustedKeys.find(v.key()) != trustedKeys.end())
1133  {
1134  trustedKeys.erase(v.key());
1135  if (seq > v.seq())
1136  ++laggards;
1137  }
1138  });
1139 
1140  return laggards;
1141  }
1142 };
1143 
1144 } // namespace ripple
1145 #endif
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::Seq
typename Ledger::Seq Seq
Definition: Validations.h:292
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::Validations< ripple::test::csf::Peer::ValAdaptor >::Validation
typename ripple::test::csf::Peer::ValAdaptor ::Validation Validation
Definition: Validations.h:289
ripple::Validations::KeepRange::low_
Seq low_
Definition: Validations.h:330
ripple::Validations::seqEnforcers_
hash_map< NodeID, SeqEnforcer< Seq > > seqEnforcers_
Definition: Validations.h:309
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:1122
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:1076
ripple::Validations::lastLedger_
hash_map< NodeID, Ledger > lastLedger_
Definition: Validations.h:340
ripple::Validations::Validations
Validations(ValidationParms const &p, beast::abstract_clock< std::chrono::steady_clock > &c, Ts &&... ts)
Constructor.
Definition: Validations.h:570
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:790
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:931
std::chrono::seconds
ripple::Validations::trie_
LedgerTrie< Ledger > trie_
Definition: Validations.h:336
ripple::Validations::bySequence_
beast::aged_unordered_map< Seq, hash_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> > bySequence_
Definition: Validations.h:325
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:480
ripple::Validations::current
void current(std::lock_guard< Mutex > const &lock, Pre &&pre, F &&f)
Iterate current validations.
Definition: Validations.h:507
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:545
ripple::ValStatus
ValStatus
Status of validation we received.
Definition: Validations.h:166
ripple::ValidationParms::validationCURRENT_EARLY
std::chrono::seconds validationCURRENT_EARLY
Duration pre-close in which validations are acceptable.
Definition: Validations.h:68
ripple::Validations::toKeep_
std::optional< KeepRange > toKeep_
Definition: Validations.h:333
std::lock_guard
STL class.
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:317
ripple::Validations::checkAcquired
void checkAcquired(std::lock_guard< Mutex > const &lock)
Definition: Validations.h:382
ripple::Validations::parms
ValidationParms const & parms() const
Return the validation timing parameters.
Definition: Validations.h:592
ripple::Validations::getJsonTrie
Json::Value getJsonTrie() const
Definition: Validations.h:826
ripple::SeqEnforcer::largest
Seq largest() const
Definition: Validations.h:128
ripple::Validations::KeepRange
Definition: Validations.h:328
std::vector::push_back
T push_back(T... args)
ripple::ValStatus::badSeq
@ badSeq
A validation violates the increasing seq requirement.
ripple::LedgerTrie::getPreferred
std::optional< SpanTip< Ledger > > getPreferred(Seq const largestIssued) const
Return the preferred ledger ID.
Definition: LedgerTrie.h:678
ripple::Validations::mutex_
Mutex mutex_
Definition: Validations.h:300
ripple::Validations::add
ValStatus add(NodeID const &nodeID, Validation const &val)
Add a new validation.
Definition: Validations.h:620
ripple::Validations::adaptor_
Adaptor adaptor_
Definition: Validations.h:350
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::Mutex
typename ripple::test::csf::Peer::ValAdaptor ::Mutex Mutex
Definition: Validations.h:288
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:343
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::NodeKey
typename Validation::NodeKey NodeKey
Definition: Validations.h:294
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:146
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:969
ripple::Validations::numTrustedForLedger
std::size_t numTrustedForLedger(ID const &ledgerID)
Count the number of trusted full validations for the given ledger.
Definition: Validations.h:1032
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:293
std::chrono::time_point
ripple::ValStatus::multiple
@ multiple
Multiple validations by a validator for the same ledger.
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:605
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
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
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:1053
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:906
ripple::Validations::flush
void flush()
Flush all current validations.
Definition: Validations.h:1100
ripple::Validations< ripple::test::csf::Peer::ValAdaptor >::ID
typename Ledger::ID ID
Definition: Validations.h:291
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:401
ripple::ValStatus::conflicting
@ conflicting
Multiple validations by a validator for different ledgers.
ripple::Validations::localSeqEnforcer_
SeqEnforcer< Seq > localSeqEnforcer_
Definition: Validations.h:306
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::Validations::updateTrie
void updateTrie(std::lock_guard< Mutex > const &lock, NodeID const &nodeID, Validation const &val, std::optional< std::pair< Seq, ID >> prior)
Process a new validation.
Definition: Validations.h:429
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::setSeqToKeep
void setSeqToKeep(Seq const &low, Seq const &high)
Set the range [low, high) of validations to keep from expire.
Definition: Validations.h:712
ripple::Validations::parms_
const ValidationParms parms_
Definition: Validations.h:346
std::result_of_t
std::count_if
T count_if(T... args)
ripple::Validations::getPreferred
std::optional< std::pair< Seq, ID > > getPreferred(Ledger const &curr)
Return the sequence number and ID of the preferred working ledger.
Definition: Validations.h:845
optional
mutex
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
std::size_t
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:38
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:290
beast::uhash<>
ripple::Validations::getCurrentNodeIDs
auto getCurrentNodeIDs() -> hash_set< NodeID >
Get the set of node ids associated with current validations.
Definition: Validations.h:1014
ripple::ValidationParms::ValidationParms
ValidationParms()=default
std::max
T max(T... args)
ripple::Validations::expire
void expire(beast::Journal &j)
Expire old validation sets.
Definition: Validations.h:725
ripple::Validations::removeTrie
void removeTrie(std::lock_guard< Mutex > const &, NodeID const &nodeID, Validation const &val)
Definition: Validations.h:355
ripple::Validations::adaptor
Adaptor const & adaptor() const
Return the adaptor instance.
Definition: Validations.h:584
ripple::Validations::KeepRange::high_
Seq high_
Definition: Validations.h:331
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:995
ripple::Validations::current_
hash_map< NodeID, Validation > current_
Definition: Validations.h:303
std::chrono::steady_clock::now
T now(T... args)