rippled
Loading...
Searching...
No Matches
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 <xrpld/consensus/LedgerTrie.h>
24#include <xrpl/basics/Log.h>
25#include <xrpl/basics/UnorderedContainers.h>
26#include <xrpl/basics/chrono.h>
27#include <xrpl/beast/container/aged_container_utility.h>
28#include <xrpl/beast/container/aged_unordered_map.h>
29#include <xrpl/protocol/PublicKey.h>
30
31#include <mutex>
32#include <optional>
33#include <type_traits>
34#include <utility>
35#include <vector>
36
37namespace ripple {
38
46{
47 explicit ValidationParms() = default;
48
56
64
71
79
89};
90
97template <class Seq>
99{
100 using time_point = std::chrono::steady_clock::time_point;
101 Seq seq_{0};
103
104public:
117 bool
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
147inline 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
168enum class ValStatus {
170 current,
172 stale,
174 badSeq,
176 multiple,
179};
180
181inline std::string
183{
184 switch (m)
185 {
187 return "current";
188 case ValStatus::stale:
189 return "stale";
191 return "badSeq";
193 return "multiple";
195 return "conflicting";
196 default:
197 return "unknown";
198 }
199}
200
287template <class Adaptor>
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
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
354private:
355 // Remove support of a validated ledger
356 void
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
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 XRPL_ASSERT(
438 val.trusted(),
439 "ripple::Validations::updateTrie : trusted input validation");
440
441 // Clear any prior acquiring ledger for this node
442 if (prior)
443 {
444 auto it = acquiring_.find(*prior);
445 if (it != acquiring_.end())
446 {
447 it->second.erase(nodeID);
448 if (it->second.empty())
449 acquiring_.erase(it);
450 }
451 }
452
453 checkAcquired(lock);
454
455 std::pair<Seq, ID> valPair{val.seq(), val.ledgerID()};
456 auto it = acquiring_.find(valPair);
457 if (it != acquiring_.end())
458 {
459 it->second.insert(nodeID);
460 }
461 else
462 {
463 if (std::optional<Ledger> ledger = adaptor_.acquire(val.ledgerID()))
464 updateTrie(lock, nodeID, *ledger);
465 else
466 acquiring_[valPair].insert(nodeID);
467 }
468 }
469
482 template <class F>
483 auto
485 {
486 // Call current to flush any stale validations
487 current(lock, [](auto) {}, [](auto, auto) {});
488 checkAcquired(lock);
489 return f(trie_);
490 }
491
508 template <class Pre, class F>
509 void
510 current(std::lock_guard<Mutex> const& lock, Pre&& pre, F&& f)
511 {
513 pre(current_.size());
514 auto it = current_.begin();
515 while (it != current_.end())
516 {
517 // Check for staleness
518 if (!isCurrent(
519 parms_, t, it->second.signTime(), it->second.seenTime()))
520 {
521 removeTrie(lock, it->first, it->second);
522 it = current_.erase(it);
523 }
524 else
525 {
526 auto cit = typename decltype(current_)::const_iterator{it};
527 // contains a live record
528 f(cit->first, cit->second);
529 ++it;
530 }
531 }
532 }
533
546 template <class Pre, class F>
547 void
550 ID const& ledgerID,
551 Pre&& pre,
552 F&& f)
553 {
554 auto it = byLedger_.find(ledgerID);
555 if (it != byLedger_.end())
556 {
557 // Update set time since it is being used
558 byLedger_.touch(it);
559 pre(it->second.size());
560 for (auto const& [key, val] : it->second)
561 f(key, val);
562 }
563 }
564
565public:
572 template <class... Ts>
574 ValidationParms const& p,
576 Ts&&... ts)
577 : byLedger_(c)
578 , bySequence_(c)
579 , parms_(p)
580 , adaptor_(std::forward<Ts>(ts)...)
581 {
582 }
583
586 Adaptor const&
587 adaptor() const
588 {
589 return adaptor_;
590 }
591
594 ValidationParms const&
595 parms() const
596 {
597 return parms_;
598 }
599
607 bool
609 {
611 return localSeqEnforcer_(byLedger_.clock().now(), s, parms_);
612 }
613
623 add(NodeID const& nodeID, Validation const& val)
624 {
625 if (!isCurrent(parms_, adaptor_.now(), val.signTime(), val.seenTime()))
626 return ValStatus::stale;
627
628 {
630
631 // Check that validation sequence is greater than any non-expired
632 // validations sequence from that validator; if it's not, perform
633 // additional work to detect Byzantine validations
634 auto const now = byLedger_.clock().now();
635
636 auto const [seqit, seqinserted] =
637 bySequence_[val.seq()].emplace(nodeID, val);
638
639 if (!seqinserted)
640 {
641 // Check if the entry we're already tracking was signed
642 // long enough ago that we can disregard it.
643 auto const diff =
644 std::max(seqit->second.signTime(), val.signTime()) -
645 std::min(seqit->second.signTime(), val.signTime());
646
647 if (diff > parms_.validationCURRENT_WALL &&
648 val.signTime() > seqit->second.signTime())
649 seqit->second = val;
650 }
651
652 // Enforce monotonically increasing sequences for validations
653 // by a given node, and run the active Byzantine detector:
654 if (auto& enf = seqEnforcers_[nodeID]; !enf(now, val.seq(), parms_))
655 {
656 // If the validation is for the same sequence as one we are
657 // tracking, check it closely:
658 if (seqit->second.seq() == val.seq())
659 {
660 // Two validations for the same sequence but for different
661 // ledgers. This could be the result of misconfiguration
662 // but it can also mean a Byzantine validator.
663 if (seqit->second.ledgerID() != val.ledgerID())
665
666 // Two validations for the same sequence and for the same
667 // ledger with different sign times. This could be the
668 // result of a misconfiguration but it can also mean a
669 // Byzantine validator.
670 if (seqit->second.signTime() != val.signTime())
672
673 // Two validations for the same sequence but with different
674 // cookies. This is probably accidental misconfiguration.
675 if (seqit->second.cookie() != val.cookie())
676 return ValStatus::multiple;
677 }
678
679 return ValStatus::badSeq;
680 }
681
682 byLedger_[val.ledgerID()].insert_or_assign(nodeID, val);
683
684 auto const [it, inserted] = current_.emplace(nodeID, val);
685 if (!inserted)
686 {
687 // Replace existing only if this one is newer
688 Validation& oldVal = it->second;
689 if (val.signTime() > oldVal.signTime())
690 {
691 std::pair<Seq, ID> old(oldVal.seq(), oldVal.ledgerID());
692 it->second = val;
693 if (val.trusted())
694 updateTrie(lock, nodeID, val, old);
695 }
696 else
697 return ValStatus::stale;
698 }
699 else if (val.trusted())
700 {
701 updateTrie(lock, nodeID, val, std::nullopt);
702 }
703 }
704
705 return ValStatus::current;
706 }
707
714 void
715 setSeqToKeep(Seq const& low, Seq const& high)
716 {
718 XRPL_ASSERT(
719 low < high, "ripple::Validations::setSeqToKeep : valid inputs");
720 toKeep_ = {low, high};
721 }
722
728 void
730 {
731 auto const start = std::chrono::steady_clock::now();
732 {
734 if (toKeep_)
735 {
736 // We only need to refresh the keep range when it's just about
737 // to expire. Track the next time we need to refresh.
738 static std::chrono::steady_clock::time_point refreshTime;
739 if (auto const now = byLedger_.clock().now();
740 refreshTime <= now)
741 {
742 // The next refresh time is shortly before the expiration
743 // time from now.
744 refreshTime = now + parms_.validationSET_EXPIRES -
746
747 for (auto i = byLedger_.begin(); i != byLedger_.end(); ++i)
748 {
749 auto const& validationMap = i->second;
750 if (!validationMap.empty())
751 {
752 auto const seq =
753 validationMap.begin()->second.seq();
754 if (toKeep_->low_ <= seq && seq < toKeep_->high_)
755 {
756 byLedger_.touch(i);
757 }
758 }
759 }
760
761 for (auto i = bySequence_.begin(); i != bySequence_.end();
762 ++i)
763 {
764 if (toKeep_->low_ <= i->first &&
765 i->first < toKeep_->high_)
766 {
767 bySequence_.touch(i);
768 }
769 }
770 }
771 }
772
775 }
776 JLOG(j.debug())
777 << "Validations sets sweep lock duration "
778 << std::chrono::duration_cast<std::chrono::milliseconds>(
780 .count()
781 << "ms";
782 }
783
793 void
794 trustChanged(hash_set<NodeID> const& added, hash_set<NodeID> const& removed)
795 {
797
798 for (auto& [nodeId, validation] : current_)
799 {
800 if (added.find(nodeId) != added.end())
801 {
802 validation.setTrusted();
803 updateTrie(lock, nodeId, validation, std::nullopt);
804 }
805 else if (removed.find(nodeId) != removed.end())
806 {
807 validation.setUntrusted();
808 removeTrie(lock, nodeId, validation);
809 }
810 }
811
812 for (auto& [_, validationMap] : byLedger_)
813 {
814 (void)_;
815 for (auto& [nodeId, validation] : validationMap)
816 {
817 if (added.find(nodeId) != added.end())
818 {
819 validation.setTrusted();
820 }
821 else if (removed.find(nodeId) != removed.end())
822 {
823 validation.setUntrusted();
824 }
825 }
826 }
827 }
828
831 {
833 return trie_.getJson();
834 }
835
849 getPreferred(Ledger const& curr)
850 {
853 withTrie(lock, [this](LedgerTrie<Ledger>& trie) {
854 return trie.getPreferred(localSeqEnforcer_.largest());
855 });
856 // No trusted validations to determine branch
857 if (!preferred)
858 {
859 // fall back to majority over acquiring ledgers
860 auto it = std::max_element(
861 acquiring_.begin(),
862 acquiring_.end(),
863 [](auto const& a, auto const& b) {
864 std::pair<Seq, ID> const& aKey = a.first;
865 typename hash_set<NodeID>::size_type const& aSize =
866 a.second.size();
867 std::pair<Seq, ID> const& bKey = b.first;
868 typename hash_set<NodeID>::size_type const& bSize =
869 b.second.size();
870 // order by number of trusted peers validating that ledger
871 // break ties with ledger ID
872 return std::tie(aSize, aKey.second) <
873 std::tie(bSize, bKey.second);
874 });
875 if (it != acquiring_.end())
876 return it->first;
877 return std::nullopt;
878 }
879
880 // If we are the parent of the preferred ledger, stick with our
881 // current ledger since we might be about to generate it
882 if (preferred->seq == curr.seq() + Seq{1} &&
883 preferred->ancestor(curr.seq()) == curr.id())
884 return std::make_pair(curr.seq(), curr.id());
885
886 // A ledger ahead of us is preferred regardless of whether it is
887 // a descendant of our working ledger or it is on a different chain
888 if (preferred->seq > curr.seq())
889 return std::make_pair(preferred->seq, preferred->id);
890
891 // Only switch to earlier or same sequence number
892 // if it is a different chain.
893 if (curr[preferred->seq] != preferred->id)
894 return std::make_pair(preferred->seq, preferred->id);
895
896 // Stick with current ledger
897 return std::make_pair(curr.seq(), curr.id());
898 }
899
909 ID
910 getPreferred(Ledger const& curr, Seq minValidSeq)
911 {
913 if (preferred && preferred->first >= minValidSeq)
914 return preferred->second;
915 return curr.id();
916 }
917
934 ID
936 Ledger const& lcl,
937 Seq minSeq,
938 hash_map<ID, std::uint32_t> const& peerCounts)
939 {
941
942 // Trusted validations exist, but stick with local preferred ledger if
943 // preferred is in the past
944 if (preferred)
945 return (preferred->first >= minSeq) ? preferred->second : lcl.id();
946
947 // Otherwise, rely on peer ledgers
948 auto it = std::max_element(
949 peerCounts.begin(), peerCounts.end(), [](auto& a, auto& b) {
950 // Prefer larger counts, then larger ids on ties
951 // (max_element expects this to return true if a < b)
952 return std::tie(a.second, a.first) <
953 std::tie(b.second, b.first);
954 });
955
956 if (it != peerCounts.end())
957 return it->first;
958 return lcl.id();
959 }
960
973 getNodesAfter(Ledger const& ledger, ID const& ledgerID)
974 {
976
977 // Use trie if ledger is the right one
978 if (ledger.id() == ledgerID)
979 return withTrie(lock, [&ledger](LedgerTrie<Ledger>& trie) {
980 return trie.branchSupport(ledger) - trie.tipSupport(ledger);
981 });
982
983 // Count parent ledgers as fallback
984 return std::count_if(
985 lastLedger_.begin(),
986 lastLedger_.end(),
987 [&ledgerID](auto const& it) {
988 auto const& curr = it.second;
989 return curr.seq() > Seq{0} &&
990 curr[curr.seq() - Seq{1}] == ledgerID;
991 });
992 }
993
1000 {
1002 std::lock_guard lock{mutex_};
1003 current(
1004 lock,
1005 [&](std::size_t numValidations) { ret.reserve(numValidations); },
1006 [&](NodeID const&, Validation const& v) {
1007 if (v.trusted() && v.full())
1008 ret.push_back(v.unwrap());
1009 });
1010 return ret;
1011 }
1012
1017 auto
1019 {
1020 hash_set<NodeID> ret;
1021 std::lock_guard lock{mutex_};
1022 current(
1023 lock,
1024 [&](std::size_t numValidations) { ret.reserve(numValidations); },
1025 [&](NodeID const& nid, Validation const&) { ret.insert(nid); });
1026
1027 return ret;
1028 }
1029
1036 numTrustedForLedger(ID const& ledgerID)
1037 {
1038 std::size_t count = 0;
1039 std::lock_guard lock{mutex_};
1040 byLedger(
1041 lock,
1042 ledgerID,
1043 [&](std::size_t) {}, // nothing to reserve
1044 [&](NodeID const&, Validation const& v) {
1045 if (v.trusted() && v.full())
1046 ++count;
1047 });
1048 return count;
1049 }
1050
1058 getTrustedForLedger(ID const& ledgerID, Seq const& seq)
1059 {
1061 std::lock_guard lock{mutex_};
1062 byLedger(
1063 lock,
1064 ledgerID,
1065 [&](std::size_t numValidations) { res.reserve(numValidations); },
1066 [&](NodeID const&, Validation const& v) {
1067 if (v.trusted() && v.full() && v.seq() == seq)
1068 res.emplace_back(v.unwrap());
1069 });
1070
1071 return res;
1072 }
1073
1081 fees(ID const& ledgerID, std::uint32_t baseFee)
1082 {
1084 std::lock_guard lock{mutex_};
1085 byLedger(
1086 lock,
1087 ledgerID,
1088 [&](std::size_t numValidations) { res.reserve(numValidations); },
1089 [&](NodeID const&, Validation const& v) {
1090 if (v.trusted() && v.full())
1091 {
1092 std::optional<std::uint32_t> loadFee = v.loadFee();
1093 if (loadFee)
1094 res.push_back(*loadFee);
1095 else
1096 res.push_back(baseFee);
1097 }
1098 });
1099 return res;
1100 }
1101
1104 void
1106 {
1107 std::lock_guard lock{mutex_};
1108 current_.clear();
1109 }
1110
1127 laggards(Seq const seq, hash_set<NodeKey>& trustedKeys)
1128 {
1129 std::size_t laggards = 0;
1130
1131 current(
1132 std::lock_guard{mutex_},
1133 [](std::size_t) {},
1134 [&](NodeID const&, Validation const& v) {
1135 if (adaptor_.now() <
1136 v.seenTime() + parms_.validationFRESHNESS &&
1137 trustedKeys.find(v.key()) != trustedKeys.end())
1138 {
1139 trustedKeys.erase(v.key());
1140 if (seq > v.seq())
1141 ++laggards;
1142 }
1143 });
1144
1145 return laggards;
1146 }
1147
1150 {
1151 std::lock_guard lock{mutex_};
1152 return current_.size();
1153 }
1154
1157 {
1158 std::lock_guard lock{mutex_};
1159 return seqEnforcers_.size();
1160 }
1161
1164 {
1165 std::lock_guard lock{mutex_};
1166 return byLedger_.size();
1167 }
1168
1171 {
1172 std::lock_guard lock{mutex_};
1173 return bySequence_.size();
1174 }
1175};
1176
1177} // namespace ripple
1178#endif
T begin(T... args)
Represents a JSON value.
Definition: json_value.h:147
A generic endpoint for log messages.
Definition: Journal.h:59
Stream debug() const
Definition: Journal.h:317
Abstract interface to a clock.
Associative container where each element is also indexed by time.
Ancestry trie of ledgers.
Definition: LedgerTrie.h:351
std::uint32_t tipSupport(Ledger const &ledger) const
Return count of tip support for the specific ledger.
Definition: LedgerTrie.h:597
std::optional< SpanTip< Ledger > > getPreferred(Seq const largestIssued) const
Return the preferred ledger ID.
Definition: LedgerTrie.h:685
std::uint32_t branchSupport(Ledger const &ledger) const
Return the count of branch support for the specific ledger.
Definition: LedgerTrie.h:611
Enforce validation increasing sequence requirement.
Definition: Validations.h:99
Seq largest() const
Definition: Validations.h:130
bool operator()(time_point now, Seq s, ValidationParms const &p)
Try advancing the largest observed validation ledger sequence.
Definition: Validations.h:118
std::chrono::steady_clock::time_point time_point
Definition: Validations.h:100
Maintains current and recent ledger validations.
Definition: Validations.h:289
void current(std::lock_guard< Mutex > const &lock, Pre &&pre, F &&f)
Iterate current validations.
Definition: Validations.h:510
std::size_t sizeOfByLedgerCache() const
Definition: Validations.h:1163
auto withTrie(std::lock_guard< Mutex > const &lock, F &&f)
Use the trie for a calculation.
Definition: Validations.h:484
hash_map< NodeID, Ledger > lastLedger_
Definition: Validations.h:342
std::optional< std::pair< Seq, ID > > getPreferred(Ledger const &curr)
Return the sequence number and ID of the preferred working ledger.
Definition: Validations.h:849
typename Ledger::Seq Seq
Definition: Validations.h:294
typename Adaptor::Mutex Mutex
Definition: Validations.h:290
typename Adaptor::Validation Validation
Definition: Validations.h:291
Adaptor const & adaptor() const
Return the adaptor instance.
Definition: Validations.h:587
Validations(ValidationParms const &p, beast::abstract_clock< std::chrono::steady_clock > &c, Ts &&... ts)
Constructor.
Definition: Validations.h:573
void removeTrie(std::lock_guard< Mutex > const &, NodeID const &nodeID, Validation const &val)
Definition: Validations.h:357
std::size_t sizeOfCurrentCache() const
Definition: Validations.h:1149
hash_map< NodeID, SeqEnforcer< Seq > > seqEnforcers_
Definition: Validations.h:311
Json::Value getJsonTrie() const
Definition: Validations.h:830
typename Validation::NodeKey NodeKey
Definition: Validations.h:296
SeqEnforcer< Seq > localSeqEnforcer_
Definition: Validations.h:308
std::size_t numTrustedForLedger(ID const &ledgerID)
Count the number of trusted full validations for the given ledger.
Definition: Validations.h:1036
hash_map< std::pair< Seq, ID >, hash_set< NodeID > > acquiring_
Definition: Validations.h:345
typename Validation::NodeID NodeID
Definition: Validations.h:295
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:1127
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
hash_map< NodeID, Validation > current_
Definition: Validations.h:305
void updateTrie(std::lock_guard< Mutex > const &, NodeID const &nodeID, Ledger ledger)
Definition: Validations.h:403
void flush()
Flush all current validations.
Definition: Validations.h:1105
LedgerTrie< Ledger > trie_
Definition: Validations.h:338
ValidationParms const & parms() const
Return the validation timing parameters.
Definition: Validations.h:595
auto getCurrentNodeIDs() -> hash_set< NodeID >
Get the set of node ids associated with current validations.
Definition: Validations.h:1018
std::optional< KeepRange > toKeep_
Definition: Validations.h:335
ValidationParms const parms_
Definition: Validations.h:348
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:973
std::vector< WrappedValidationType > getTrustedForLedger(ID const &ledgerID, Seq const &seq)
Get trusted full validations for a specific ledger.
Definition: Validations.h:1058
typename Adaptor::Ledger Ledger
Definition: Validations.h:292
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
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:935
std::size_t sizeOfSeqEnforcersCache() const
Definition: Validations.h:1156
beast::aged_unordered_map< Seq, hash_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> > bySequence_
Definition: Validations.h:327
void trustChanged(hash_set< NodeID > const &added, hash_set< NodeID > const &removed)
Update trust status of validations.
Definition: Validations.h:794
std::vector< WrappedValidationType > currentTrusted()
Get the currently trusted full validations.
Definition: Validations.h:999
typename Ledger::ID ID
Definition: Validations.h:293
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:910
std::size_t sizeOfBySequenceCache() const
Definition: Validations.h:1170
void checkAcquired(std::lock_guard< Mutex > const &lock)
Definition: Validations.h:384
void setSeqToKeep(Seq const &low, Seq const &high)
Set the range [low, high) of validations to keep from expire.
Definition: Validations.h:715
bool canValidateSeq(Seq const s)
Return whether the local node can issue a validation for the given sequence number.
Definition: Validations.h:608
ValStatus add(NodeID const &nodeID, Validation const &val)
Add a new validation.
Definition: Validations.h:623
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:548
void expire(beast::Journal &j)
Expire old validation sets.
Definition: Validations.h:729
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:1081
T count_if(T... args)
T emplace_back(T... args)
T end(T... args)
T erase(T... args)
T find(T... args)
T insert(T... args)
T make_pair(T... args)
T max_element(T... args)
T max(T... args)
T min(T... args)
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.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
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
ValStatus
Status of validation we received.
Definition: Validations.h:168
@ badSeq
A validation violates the increasing seq requirement.
@ stale
Not current or was older than current from this node.
@ current
This was a new validation and was added.
@ conflicting
Multiple validations by a validator for different ledgers.
@ multiple
Multiple validations by a validator for the same ledger.
@ stale
Sequence is too old.
Dir::const_iterator const_iterator
Definition: Dir.cpp:24
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:629
@ validation
validation for signing
STL namespace.
T push_back(T... args)
T reserve(T... args)
Timing parameters to control validation staleness and expiration.
Definition: Validations.h:46
std::chrono::seconds validationCURRENT_LOCAL
Duration a validation remains current after first observed.
Definition: Validations.h:63
std::chrono::seconds validationFRESHNESS
How long we consider a validation fresh.
Definition: Validations.h:88
std::chrono::seconds validationSET_EXPIRES
Duration a set of validations for a given ledger hash remain valid.
Definition: Validations.h:78
std::chrono::seconds validationCURRENT_WALL
The number of seconds a validation remains current after its ledger's close time.
Definition: Validations.h:55
std::chrono::seconds validationCURRENT_EARLY
Duration pre-close in which validations are acceptable.
Definition: Validations.h:70