#include // Do not remove. Forces Rules.h to stay first, to verify it can compile // without any hidden dependencies #include #include #include #include #include #include #include #include #include #include #include #include namespace xrpl { namespace { // Use a static inside a function to help prevent order-of-initialization issues LocalValue>& getCurrentTransactionRulesRef() { static LocalValue> r; return r; } } // namespace std::optional const& getCurrentTransactionRules() { return *getCurrentTransactionRulesRef(); } void setCurrentTransactionRules(std::optional r) { // Make global changes associated with the rules before the value is moved. // Push the appropriate setting, instead of having the class pull every time // the value is needed. That could get expensive fast. bool enableLargeNumbers = !r || (r->enabled(featureSingleAssetVault) || r->enabled(featureLendingProtocol)); Number::setMantissaScale(enableLargeNumbers ? MantissaRange::large : MantissaRange::small); *getCurrentTransactionRulesRef() = std::move(r); } class Rules::Impl { private: std::unordered_set> set_; std::optional digest_; std::unordered_set> const& presets_; public: explicit Impl(std::unordered_set> const& presets) : presets_(presets) { } Impl( std::unordered_set> const& presets, std::optional const& digest, STVector256 const& amendments) : digest_(digest), presets_(presets) { set_.reserve(amendments.size()); set_.insert(amendments.begin(), amendments.end()); } std::unordered_set> const& presets() const { return presets_; } bool enabled(uint256 const& feature) const { if (presets_.count(feature) > 0) return true; return set_.count(feature) > 0; } bool operator==(Impl const& other) const { if (!digest_ && !other.digest_) return true; if (!digest_ || !other.digest_) return false; XRPL_ASSERT( presets_ == other.presets_, "xrpl::Rules::Impl::operator==(Impl) const : input presets do " "match"); return *digest_ == *other.digest_; } }; Rules::Rules(std::unordered_set> const& presets) : impl_(std::make_shared(presets)) { } Rules::Rules( std::unordered_set> const& presets, std::optional const& digest, STVector256 const& amendments) : impl_(std::make_shared(presets, digest, amendments)) { } std::unordered_set> const& Rules::presets() const { return impl_->presets(); } bool Rules::enabled(uint256 const& feature) const { XRPL_ASSERT(impl_, "xrpl::Rules::enabled : initialized"); return impl_->enabled(feature); } bool Rules::operator==(Rules const& other) const { XRPL_ASSERT(impl_ && other.impl_, "xrpl::Rules::operator==(Rules) const : both initialized"); if (impl_.get() == other.impl_.get()) return true; return *impl_ == *other.impl_; } bool Rules::operator!=(Rules const& other) const { return !(*this == other); } bool isFeatureEnabled(uint256 const& feature) { auto const& rules = getCurrentTransactionRules(); return rules && rules->enabled(feature); } } // namespace xrpl