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