20#include <xrpl/basics/Slice.h> 
   21#include <xrpl/basics/base_uint.h> 
   22#include <xrpl/basics/contract.h> 
   23#include <xrpl/beast/utility/instrumentation.h> 
   24#include <xrpl/protocol/Feature.h> 
   25#include <xrpl/protocol/digest.h> 
   27#include <boost/container_hash/hash.hpp> 
   28#include <boost/multi_index/hashed_index.hpp> 
   29#include <boost/multi_index/indexed_by.hpp> 
   30#include <boost/multi_index/member.hpp> 
   31#include <boost/multi_index/random_access_index.hpp> 
   32#include <boost/multi_index/tag.hpp> 
   33#include <boost/multi_index_container.hpp> 
   47    using namespace boost;
 
   48    for (
auto const& n : feature)
 
   49        hash_combine(seed, n);
 
 
   84class FeatureCollections
 
   93            : name(name_), feature(feature_)
 
  112    template <
class tag, 
typename Type, Type Feature::*PtrToMember>
 
  113    using feature_hashed_unique = boost::multi_index::hashed_unique<
 
  114        boost::multi_index::tag<tag>,
 
  115        boost::multi_index::member<Feature, Type, PtrToMember>>;
 
  118    using feature_indexing = boost::multi_index::indexed_by<
 
  119        boost::multi_index::random_access<
 
  120            boost::multi_index::tag<Feature::byIndex>>,
 
  121        feature_hashed_unique<Feature::byFeature, uint256, &Feature::feature>,
 
  122        feature_hashed_unique<Feature::byName, std::string, &Feature::name>>;
 
  126    boost::multi_index::multi_index_container<Feature, feature_indexing>
 
  138    getByIndex(
size_t i)
 const 
  140        if (i >= features.size())
 
  142        auto const& sequence = features.get<Feature::byIndex>();
 
  146    getIndex(Feature 
const& feature)
 const 
  148        auto const& sequence = features.get<Feature::byIndex>();
 
  149        auto const it_to = sequence.iterator_to(feature);
 
  150        return it_to - sequence.begin();
 
  153    getByFeature(
uint256 const& feature)
 const 
  155        auto const& feature_index = features.get<Feature::byFeature>();
 
  156        auto const feature_it = feature_index.find(feature);
 
  157        return feature_it == feature_index.end() ? nullptr : &*feature_it;
 
  162        auto const& name_index = features.get<Feature::byName>();
 
  163        auto const name_it = name_index.find(name);
 
  164        return name_it == name_index.end() ? nullptr : &*name_it;
 
  168    FeatureCollections();
 
  225FeatureCollections::FeatureCollections()
 
  231FeatureCollections::getRegisteredFeature(
std::string const& name)
 const 
  235        "ripple::FeatureCollections::getRegisteredFeature : startup completed");
 
  236    Feature 
const* feature = getByName(name);
 
  238        return feature->feature;
 
  243check(
bool condition, 
char const* logicErrorMessage)
 
  250FeatureCollections::registerFeature(
 
  255    check(!readOnly, 
"Attempting to register a feature after startup.");
 
  258        "Invalid feature parameters. Must be supported to be up-voted.");
 
  259    Feature 
const* i = getByName(name);
 
  264            "More features defined than allocated.");
 
  268        features.emplace_back(name, f);
 
  270        auto const getAmendmentSupport = [=]() {
 
  276        all.emplace(name, getAmendmentSupport());
 
  278        if (support == Supported::yes)
 
  280            supported.emplace(name, vote);
 
  288            upVotes + downVotes == supported.size(),
 
  289            "Feature counting logic broke");
 
  291            supported.size() <= features.size(),
 
  292            "More supported features than defined features");
 
  294            features.size() == 
all.size(),
 
  295            "The 'all' features list is populated incorrectly");
 
  305FeatureCollections::registrationIsDone()
 
  312FeatureCollections::featureToBitsetIndex(
uint256 const& f)
 const 
  316        "ripple::FeatureCollections::featureToBitsetIndex : startup completed");
 
  318    Feature 
const* feature = getByFeature(f);
 
  322    return getIndex(*feature);
 
  326FeatureCollections::bitsetIndexToFeature(
size_t i)
 const 
  330        "ripple::FeatureCollections::bitsetIndexToFeature : startup completed");
 
  331    Feature 
const& feature = getByIndex(i);
 
  332    return feature.feature;
 
  336FeatureCollections::featureToName(
uint256 const& f)
 const 
  340        "ripple::FeatureCollections::featureToName : startup completed");
 
  341    Feature 
const* feature = getByFeature(f);
 
  342    return feature ? feature->name : 
to_string(f);
 
  345static FeatureCollections featureCollections;
 
  353    return featureCollections.allAmendments();
 
 
  362    return featureCollections.supportedAmendments();
 
 
  369    return featureCollections.numDownVotedAmendments();
 
 
  376    return featureCollections.numUpVotedAmendments();
 
 
  384    return featureCollections.getRegisteredFeature(name);
 
 
  390    return featureCollections.registerFeature(name, support, vote);
 
 
  405    return featureCollections.registrationIsDone();
 
 
  411    return featureCollections.featureToBitsetIndex(f);
 
 
  417    return featureCollections.bitsetIndexToFeature(i);
 
 
  423    return featureCollections.featureToName(f);
 
 
  429#pragma push_macro("XRPL_FEATURE") 
  431#pragma push_macro("XRPL_FIX") 
  433#pragma push_macro("XRPL_RETIRE") 
  436#define XRPL_FEATURE(name, supported, vote) \ 
  437    uint256 const feature##name = registerFeature(#name, supported, vote); 
  438#define XRPL_FIX(name, supported, vote) \ 
  439    uint256 const fix##name = registerFeature("fix" #name, supported, vote); 
  442#define XRPL_RETIRE(name)                                       \ 
  443    [[deprecated("The referenced amendment has been retired")]] \ 
  445    uint256 const retired##name = retireFeature(#name); 
  448#include <xrpl/protocol/detail/features.macro> 
  451#pragma pop_macro("XRPL_RETIRE") 
  453#pragma pop_macro("XRPL_FIX") 
  455#pragma pop_macro("XRPL_FEATURE") 
  463    featureCollections.registrationIsDone();
 
void check(bool condition, std::string const &message)
 
static constexpr std::size_t numFeatures
 
std::size_t numUpVotedAmendments()
Amendments that this server will vote for by default.
 
std::size_t numDownVotedAmendments()
Amendments that this server won't vote for by default.
 
std::map< std::string, VoteBehavior > const & supportedAmendments()
Amendments that this server supports and the default voting behavior.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
uint256 bitsetIndexToFeature(size_t i)
 
uint256 registerFeature(std::string const &name, Supported support, VoteBehavior vote)
 
size_t featureToBitsetIndex(uint256 const &f)
 
std::map< std::string, AmendmentSupport > const & allAmendments()
All amendments libxrpl knows about.
 
std::size_t hash_value(ripple::uint256 const &feature)
 
uint256 retireFeature(std::string const &name)
 
std::string featureToName(uint256 const &f)
 
std::optional< uint256 > getRegisteredFeature(std::string const &name)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
bool registrationIsDone()
Tell FeatureCollections when registration is complete.
 
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
 
static bool const readOnlySet
 
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.