20#ifndef RIPPLE_CONSENSUS_VALIDATIONS_H_INCLUDED 
   21#define RIPPLE_CONSENSUS_VALIDATIONS_H_INCLUDED 
   23#include <xrpld/consensus/LedgerTrie.h> 
   25#include <xrpl/basics/Log.h> 
   26#include <xrpl/basics/UnorderedContainers.h> 
   27#include <xrpl/basics/chrono.h> 
   28#include <xrpl/beast/container/aged_container_utility.h> 
   29#include <xrpl/beast/container/aged_unordered_map.h> 
   30#include <xrpl/protocol/PublicKey.h> 
  196            return "conflicting";
 
 
  288template <
class Adaptor>
 
  291    using Mutex = 
typename Adaptor::Mutex;
 
  294    using ID = 
typename Ledger::ID;
 
  295    using Seq = 
typename Ledger::Seq;
 
  296    using NodeID = 
typename Validation::NodeID;
 
  368                it->second.erase(nodeID);
 
  369                if (it->second.empty())
 
  375            if (it != 
lastLedger_.end() && it->second.id() == val.ledgerID())
 
  377                trie_.remove(it->second);
 
 
  392                for (
NodeID const& nodeID : it->second)
 
 
  409        auto const [it, inserted] = 
lastLedger_.emplace(nodeID, ledger);
 
  412            trie_.remove(it->second);
 
  415        trie_.insert(ledger);
 
 
  440            "ripple::Validations::updateTrie : trusted input validation");
 
  448                it->second.erase(nodeID);
 
  449                if (it->second.empty())
 
  460            it->
second.insert(nodeID);
 
 
  488        current(lock, [](
auto) {}, [](
auto, 
auto) {});
 
 
  509    template <
class Pre, 
class F>
 
  520                    parms_, t, it->second.signTime(), it->second.seenTime()))
 
  529                f(cit->first, cit->second);
 
 
  547    template <
class Pre, 
class F>
 
  560            pre(it->second.size());
 
  561            for (
auto const& [key, val] : it->second)
 
 
  573    template <
class... Ts>
 
  635            auto const now = 
byLedger_.clock().now();
 
  637            auto const [seqit, seqinserted] =
 
  645                    std::max(seqit->second.signTime(), val.signTime()) -
 
  646                    std::min(seqit->second.signTime(), val.signTime());
 
  649                    val.signTime() > seqit->second.signTime())
 
  659                if (seqit->second.seq() == val.seq())
 
  664                    if (seqit->second.ledgerID() != val.ledgerID())
 
  671                    if (seqit->second.signTime() != val.signTime())
 
  676                    if (seqit->second.cookie() != val.cookie())
 
  683            byLedger_[val.ledgerID()].insert_or_assign(nodeID, val);
 
  685            auto const [it, inserted] = 
current_.emplace(nodeID, val);
 
  690                if (val.signTime() > oldVal.signTime())
 
  700            else if (val.trusted())
 
 
  720            low < high, 
"ripple::Validations::setSeqToKeep : valid inputs");
 
 
  739                static std::chrono::steady_clock::time_point refreshTime;
 
  740                if (
auto const now = 
byLedger_.clock().now();
 
  750                        auto const& validationMap = i->second;
 
  751                        if (!validationMap.empty())
 
  754                                validationMap.begin()->second.seq();
 
  755                            if (
toKeep_->low_ <= seq && seq < toKeep_->high_)
 
  765                        if (
toKeep_->low_ <= i->first &&
 
  778            << 
"Validations sets sweep lock duration " 
  779            << std::chrono::duration_cast<std::chrono::milliseconds>(
 
 
  801            if (added.
find(nodeId) != added.
end())
 
  806            else if (removed.
find(nodeId) != removed.
end())
 
  813        for (
auto& [_, validationMap] : 
byLedger_)
 
  816            for (
auto& [nodeId, 
validation] : validationMap)
 
  818                if (added.
find(nodeId) != added.
end())
 
  822                else if (removed.
find(nodeId) != removed.
end())
 
 
  834        return trie_.getJson();
 
 
  864                [](
auto const& a, 
auto const& b) {
 
  865                    std::pair<Seq, ID> const& aKey = a.first;
 
  866                    typename hash_set<NodeID>::size_type const& aSize =
 
  868                    std::pair<Seq, ID> const& bKey = b.first;
 
  869                    typename hash_set<NodeID>::size_type const& bSize =
 
  873                    return std::tie(aSize, aKey.second) <
 
  874                        std::tie(bSize, bKey.second);
 
  883        if (preferred->seq == curr.seq() + 
Seq{1} &&
 
  884            preferred->ancestor(curr.seq()) == curr.id())
 
  889        if (preferred->seq > curr.seq())
 
  894        if (curr[preferred->seq] != preferred->id)
 
 
  914        if (preferred && preferred->first >= minValidSeq)
 
  915            return preferred->second;
 
 
  946            return (preferred->first >= minSeq) ? preferred->second : lcl.id();
 
  950            peerCounts.
begin(), peerCounts.
end(), [](
auto& a, 
auto& b) {
 
  953                return std::tie(a.second, a.first) <
 
  954                    std::tie(b.second, b.first);
 
  957        if (it != peerCounts.
end())
 
 
  979        if (ledger.id() == ledgerID)
 
  988            [&ledgerID](
auto const& it) {
 
  989                auto const& curr = it.second;
 
  990                return curr.seq() > Seq{0} &&
 
  991                    curr[curr.seq() - 
Seq{1}] == ledgerID;
 
 
 1008                if (v.trusted() && v.full())
 
 
 1046                if (v.trusted() && v.full())
 
 
 1068                if (v.trusted() && v.full() && v.seq() == seq)
 
 
 1091                if (v.trusted() && v.full())
 
 
 1136                if (adaptor_.now() <
 
 1137                        v.seenTime() + parms_.validationFRESHNESS &&
 
 1138                    trustedKeys.
find(v.key()) != trustedKeys.
end())
 
 1140                    trustedKeys.
erase(v.key());
 
 
 1153        return current_.size();
 
 
 1160        return seqEnforcers_.size();
 
 
 1167        return byLedger_.size();
 
 
 1174        return bySequence_.size();
 
 
 
A generic endpoint for log messages.
 
Abstract interface to a clock.
 
Associative container where each element is also indexed by time.
 
Ancestry trie of ledgers.
 
std::uint32_t tipSupport(Ledger const &ledger) const
Return count of tip support for the specific ledger.
 
std::optional< SpanTip< Ledger > > getPreferred(Seq const largestIssued) const
Return the preferred ledger ID.
 
std::uint32_t branchSupport(Ledger const &ledger) const
Return the count of branch support for the specific ledger.
 
Enforce validation increasing sequence requirement.
 
bool operator()(time_point now, Seq s, ValidationParms const &p)
Try advancing the largest observed validation ledger sequence.
 
std::chrono::steady_clock::time_point time_point
 
Maintains current and recent ledger validations.
 
void current(std::lock_guard< Mutex > const &lock, Pre &&pre, F &&f)
Iterate current validations.
 
std::size_t sizeOfByLedgerCache() const
 
auto withTrie(std::lock_guard< Mutex > const &lock, F &&f)
Use the trie for a calculation.
 
hash_map< NodeID, Ledger > lastLedger_
 
std::optional< std::pair< Seq, ID > > getPreferred(Ledger const &curr)
Return the sequence number and ID of the preferred working ledger.
 
typename Adaptor::Mutex Mutex
 
typename Adaptor::Validation Validation
 
Adaptor const & adaptor() const
Return the adaptor instance.
 
Validations(ValidationParms const &p, beast::abstract_clock< std::chrono::steady_clock > &c, Ts &&... ts)
Constructor.
 
void removeTrie(std::lock_guard< Mutex > const &, NodeID const &nodeID, Validation const &val)
 
std::size_t sizeOfCurrentCache() const
 
hash_map< NodeID, SeqEnforcer< Seq > > seqEnforcers_
 
Json::Value getJsonTrie() const
 
typename Validation::NodeKey NodeKey
 
SeqEnforcer< Seq > localSeqEnforcer_
 
std::size_t numTrustedForLedger(ID const &ledgerID)
Count the number of trusted full validations for the given ledger.
 
hash_map< std::pair< Seq, ID >, hash_set< NodeID > > acquiring_
 
typename Validation::NodeID NodeID
 
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 ...
 
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)
 
hash_map< NodeID, Validation > current_
 
void updateTrie(std::lock_guard< Mutex > const &, NodeID const &nodeID, Ledger ledger)
 
void flush()
Flush all current validations.
 
LedgerTrie< Ledger > trie_
 
ValidationParms const & parms() const
Return the validation timing parameters.
 
auto getCurrentNodeIDs() -> hash_set< NodeID >
Get the set of node ids associated with current validations.
 
std::optional< KeepRange > toKeep_
 
ValidationParms const parms_
 
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.
 
std::vector< WrappedValidationType > getTrustedForLedger(ID const &ledgerID, Seq const &seq)
Get trusted full validations for a specific ledger.
 
typename Adaptor::Ledger Ledger
 
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.
 
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.
 
std::size_t sizeOfSeqEnforcersCache() const
 
beast::aged_unordered_map< Seq, hash_map< NodeID, Validation >, std::chrono::steady_clock, beast::uhash<> > bySequence_
 
void trustChanged(hash_set< NodeID > const &added, hash_set< NodeID > const &removed)
Update trust status of validations.
 
std::vector< WrappedValidationType > currentTrusted()
Get the currently trusted full validations.
 
ID getPreferred(Ledger const &curr, Seq minValidSeq)
Get the ID of the preferred working ledger that exceeds a minimum valid ledger sequence number.
 
std::size_t sizeOfBySequenceCache() const
 
void checkAcquired(std::lock_guard< Mutex > const &lock)
 
void setSeqToKeep(Seq const &low, Seq const &high)
Set the range [low, high) of validations to keep from expire.
 
bool canValidateSeq(Seq const s)
Return whether the local node can issue a validation for the given sequence number.
 
ValStatus add(NodeID const &nodeID, Validation const &val)
Add a new validation.
 
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.
 
void expire(beast::Journal &j)
Expire old validation sets.
 
std::vector< std::uint32_t > fees(ID const &ledgerID, std::uint32_t baseFee)
Returns fees reported by trusted full validators in the given ledger.
 
T emplace_back(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.
 
bool isCurrent(ValidationParms const &p, NetClock::time_point now, NetClock::time_point signTime, NetClock::time_point seenTime)
Whether a validation is still current.
 
ValStatus
Status of validation we received.
 
@ 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
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
@ validation
validation for signing
 
Timing parameters to control validation staleness and expiration.
 
std::chrono::seconds validationCURRENT_LOCAL
Duration a validation remains current after first observed.
 
std::chrono::seconds validationFRESHNESS
How long we consider a validation fresh.
 
ValidationParms()=default
 
std::chrono::seconds validationSET_EXPIRES
Duration a set of validations for a given ledger hash remain valid.
 
std::chrono::seconds validationCURRENT_WALL
The number of seconds a validation remains current after its ledger's close time.
 
std::chrono::seconds validationCURRENT_EARLY
Duration pre-close in which validations are acceptable.