xrpld
Loading...
Searching...
No Matches
Rules.cpp
1#include <xrpl/protocol/Rules.h>
2
3#include <xrpl/basics/LocalValue.h>
4#include <xrpl/basics/Number.h>
5#include <xrpl/basics/base_uint.h>
6#include <xrpl/basics/hardened_hash.h>
7#include <xrpl/beast/hash/uhash.h>
8#include <xrpl/beast/utility/instrumentation.h>
9#include <xrpl/protocol/Feature.h>
10#include <xrpl/protocol/STVector256.h>
11
12#include <memory>
13#include <optional>
14#include <unordered_set>
15#include <utility>
16
17namespace xrpl {
18
19namespace {
20// Use a static inside a function to help prevent order-of-initialization issues
22getCurrentTransactionRulesRef()
23{
25 return kR;
26}
27} // namespace
28
29std::optional<Rules> const&
31{
32 return *getCurrentTransactionRulesRef();
33}
34
35void
37{
38 // Make global changes associated with the rules before the value is moved.
39 // Push the appropriate setting, instead of having the class pull every time
40 // the value is needed. That could get expensive fast.
41
42 // Declare the range this way to keep clang-tidy from complaining
43 auto const range = [&r]() {
44 // If any new conditions with new amendments are added to "enableLargeNumbers", those
45 // amendments must also be added to useRulesGuards.
46 bool const enableLargeNumbers = !r ||
47 (r->enabled(featureSingleAssetVault) || r->enabled(featureLendingProtocol) ||
48 r->enabled(featureMPTokensV2));
49 // If enableLargeNumbers is true, then useRulesGuards must also return true.
50 // However, the reverse is not true. Other amendments can cause the rules guard to be used,
51 // even though large numbers are _not_ used.
52 XRPL_ASSERT(
53 !r || !enableLargeNumbers || useRulesGuards(*r),
54 "setCurrentTransactionRules : rule decisions match");
55
56 if (enableLargeNumbers)
57 {
58 static_assert(
60 if (!r || r->enabled(fixCleanup3_3_0))
61 {
63 }
64 if (r->enabled(fixCleanup3_2_0))
65 {
67 }
69 }
71 }();
73
74 *getCurrentTransactionRulesRef() = std::move(r);
75}
76
77bool
78useRulesGuards(Rules const& rules)
79{
80 // The list of amendments used here - to decide whether to create a RulesGuard - must be a
81 // superset of the list used to determine "enableLargeNumbers" in setCurrentTransactionRules.
82 // Additional amendments can be added if desired.
83 //
84 // As soon as any one of these amendments is retired, this whole function can be removed, along
85 // with createGuards, and any other callers, and the first set of guards can be created directly
86 // at the call site, without using optional.
87 return rules.enabled(featureSingleAssetVault) || rules.enabled(featureLendingProtocol) ||
88 rules.enabled(fixCleanup3_2_0) || rules.enabled(fixCleanup3_3_0) ||
89 rules.enabled(featureMPTokensV2);
90}
91
92void
94 Rules const& rules,
97{
98 if (useRulesGuards(rules))
99 {
100 // raii classes for the current ledger rules. If the rules are set, the MantissaRange will
101 // be updated, too.
102 rulesGuard.emplace(rules);
103 }
104 else
105 {
106 // Without those features enabled, always use the old number rules.
108 }
109}
110
112{
113private:
117
118public:
122
126 STVector256 const& amendments)
128 {
129 set_.reserve(amendments.size());
130 set_.insert(amendments.begin(), amendments.end());
131 }
132
134 presets() const
135 {
136 return presets_;
137 }
138
139 [[nodiscard]] bool
140 enabled(UInt256 const& feature) const
141 {
142 if (presets_.contains(feature))
143 return true;
144 return set_.contains(feature);
145 }
146
147 bool
148 operator==(Impl const& other) const
149 {
150 if (!digest_ && !other.digest_)
151 return true;
152 if (!digest_ || !other.digest_)
153 return false;
154 XRPL_ASSERT(
155 presets_ == other.presets_,
156 "xrpl::Rules::Impl::operator==(Impl) const : input presets do "
157 "match");
158 return *digest_ == *other.digest_;
159 }
160};
161
166
170 STVector256 const& amendments)
171 : impl_(std::make_shared<Impl>(presets, digest, amendments))
172{
173}
174
177{
178 return impl_->presets();
179}
180
181bool
182Rules::enabled(UInt256 const& feature) const
183{
184 XRPL_ASSERT(impl_, "xrpl::Rules::enabled : initialized");
185
186 return impl_->enabled(feature);
187}
188
189bool
190Rules::operator==(Rules const& other) const
191{
192 XRPL_ASSERT(impl_ && other.impl_, "xrpl::Rules::operator==(Rules) const : both initialized");
193 if (impl_.get() == other.impl_.get())
194 return true;
195 return *impl_ == *other.impl_;
196}
197
198bool
199isFeatureEnabled(UInt256 const& feature, bool resultIfNoRules)
200{
201 auto const& rules = getCurrentTransactionRules();
202 if (!rules)
203 return resultIfNoRules;
204 return rules->enabled(feature);
205}
206
207bool
209{
210 return isFeatureEnabled(feature, false);
211}
212
213} // namespace xrpl
static void setMantissaScale(MantissaRange::MantissaScale scale)
Changes which mantissa scale is used for normalization.
std::unordered_set< UInt256, beast::Uhash<> > const & presets() const
Definition Rules.cpp:134
std::unordered_set< UInt256, beast::Uhash<> > const & presets_
Definition Rules.cpp:116
bool operator==(Impl const &other) const
Definition Rules.cpp:148
Impl(std::unordered_set< UInt256, beast::Uhash<> > const &presets, std::optional< UInt256 > const &digest, STVector256 const &amendments)
Definition Rules.cpp:123
std::unordered_set< UInt256, HardenedHash<> > set_
Definition Rules.cpp:114
Impl(std::unordered_set< UInt256, beast::Uhash<> > const &presets)
Definition Rules.cpp:119
bool enabled(UInt256 const &feature) const
Definition Rules.cpp:140
std::optional< UInt256 > digest_
Definition Rules.cpp:115
Rules controlling protocol behavior.
Definition Rules.h:40
Rules(Rules const &)=default
Rules()=delete
std::shared_ptr< Impl const > impl_
Definition Rules.h:46
bool operator==(Rules const &) const
Returns true if two rule sets are identical.
Definition Rules.cpp:190
std::unordered_set< UInt256, beast::Uhash<> > const & presets() const
Definition Rules.cpp:176
bool enabled(UInt256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:182
T emplace(T... args)
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition tokens.cpp:140
bool useRulesGuards(Rules const &rules)
Definition Rules.cpp:78
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:37
bool isFeatureEnabled(UInt256 const &feature, bool resultIfNoRules)
Check whether a feature is enabled in the current ledger rules.
Definition Rules.cpp:199
void createGuards(Rules const &rules, std::optional< CurrentTransactionRulesGuard > &rulesGuard, std::optional< NumberMantissaScaleGuard > &mantissaScaleGuard)
Definition Rules.cpp:93
std::optional< Rules > const & getCurrentTransactionRules()
Definition Rules.cpp:30
BaseUInt< 256 > UInt256
Definition base_uint.h:580
void setCurrentTransactionRules(std::optional< Rules > r)
Definition Rules.cpp:36