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 const auto& sequence = features.get<Feature::byIndex>();
146 getIndex(Feature
const& feature)
const
148 const auto& 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 const auto& 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 const auto& 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,
const char* 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);
266 "More features defined than allocated. Adjust numFeatures in "
271 features.emplace_back(name, f);
273 auto const getAmendmentSupport = [=]() {
279 all.emplace(name, getAmendmentSupport());
281 if (support == Supported::yes)
283 supported.emplace(name, vote);
291 upVotes + downVotes == supported.size(),
292 "Feature counting logic broke");
294 supported.size() <= features.size(),
295 "More supported features than defined features");
297 features.size() ==
all.size(),
298 "The 'all' features list is populated incorrectly");
308FeatureCollections::registrationIsDone()
315FeatureCollections::featureToBitsetIndex(
uint256 const& f)
const
319 "ripple::FeatureCollections::featureToBitsetIndex : startup completed");
321 Feature
const* feature = getByFeature(f);
325 return getIndex(*feature);
329FeatureCollections::bitsetIndexToFeature(
size_t i)
const
333 "ripple::FeatureCollections::bitsetIndexToFeature : startup completed");
334 Feature
const& feature = getByIndex(i);
335 return feature.feature;
339FeatureCollections::featureToName(
uint256 const& f)
const
343 "ripple::FeatureCollections::featureToName : startup completed");
344 Feature
const* feature = getByFeature(f);
345 return feature ? feature->name :
to_string(f);
348static FeatureCollections featureCollections;
356 return featureCollections.allAmendments();
365 return featureCollections.supportedAmendments();
372 return featureCollections.numDownVotedAmendments();
379 return featureCollections.numUpVotedAmendments();
387 return featureCollections.getRegisteredFeature(name);
393 return featureCollections.registerFeature(name, support, vote);
408 return featureCollections.registrationIsDone();
414 return featureCollections.featureToBitsetIndex(f);
420 return featureCollections.bitsetIndexToFeature(i);
426 return featureCollections.featureToName(f);
432#pragma push_macro("XRPL_FEATURE")
434#pragma push_macro("XRPL_FIX")
437#define XRPL_FEATURE(name, supported, vote) \
438 uint256 const feature##name = registerFeature(#name, supported, vote);
439#define XRPL_FIX(name, supported, vote) \
440 uint256 const fix##name = registerFeature("fix" #name, supported, vote);
442#include <xrpl/protocol/detail/features.macro>
445#pragma pop_macro("XRPL_FIX")
447#pragma pop_macro("XRPL_FEATURE")
455[[deprecated(
"The referenced amendment has been retired"), maybe_unused]]
481 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 const retiredFeeEscalation
uint256 const retiredFix1528
uint256 const retiredFix1368
uint256 bitsetIndexToFeature(size_t i)
uint256 const retiredFix1512
static const bool readOnlySet
uint256 const retiredTrustSetAuth
uint256 registerFeature(std::string const &name, Supported support, VoteBehavior vote)
uint256 const retiredCryptoConditions
uint256 const retiredSortedDirectories
uint256 const retiredFix1523
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 const retiredFix1373
uint256 retireFeature(std::string const &name)
uint256 const retiredEscrow
std::string featureToName(uint256 const &f)
std::optional< uint256 > getRegisteredFeature(std::string const &name)
uint256 const retiredFix1201
std::string to_string(base_uint< Bits, Tag > const &a)
bool registrationIsDone()
Tell FeatureCollections when registration is complete.
uint256 const retiredMultiSign
uint256 const retiredTickSize
uint256 const retiredPayChan
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
uint256 const retiredEnforceInvariants
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.