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 =
47 !r || (r->enabled(featureSingleAssetVault) || r->enabled(featureLendingProtocol));
48 // If enableLargeNumbers is true, then useRulesGuards must also return true.
49 // However, the reverse is not true. Other amendments can cause the rules guard to be used,
50 // even though large numbers are _not_ used.
51 XRPL_ASSERT(
52 !r || !enableLargeNumbers || useRulesGuards(*r),
53 "setCurrentTransactionRules : rule decisions match");
54
55 if (enableLargeNumbers)
56 {
57 static_assert(
59 if (!r || r->enabled(fixCleanup3_3_0))
60 {
62 }
63 if (r->enabled(fixCleanup3_2_0))
64 {
66 }
68 }
70 }();
72
73 *getCurrentTransactionRulesRef() = std::move(r);
74}
75
76bool
77useRulesGuards(Rules const& rules)
78{
79 // The list of amendments used here - to decide whether to create a RulesGuard - must be a
80 // superset of the list used to determine "enableLargeNumbers" in setCurrentTransactionRules.
81 // Additional amendments can be added if desired.
82 //
83 // As soon as any one of these amendments is retired, this whole function can be removed, along
84 // with createGuards, and any other callers, and the first set of guards can be created directly
85 // at the call site, without using optional.
86 return rules.enabled(featureSingleAssetVault) || rules.enabled(featureLendingProtocol) ||
87 rules.enabled(fixCleanup3_2_0) || rules.enabled(fixCleanup3_3_0);
88}
89
90void
92 Rules const& rules,
95{
96 if (useRulesGuards(rules))
97 {
98 // raii classes for the current ledger rules. If the rules are set, the MantissaRange will
99 // be updated, too.
100 rulesGuard.emplace(rules);
101 }
102 else
103 {
104 // Without those features enabled, always use the old number rules.
106 }
107}
108
110{
111private:
115
116public:
120
124 STVector256 const& amendments)
126 {
127 set_.reserve(amendments.size());
128 set_.insert(amendments.begin(), amendments.end());
129 }
130
132 presets() const
133 {
134 return presets_;
135 }
136
137 [[nodiscard]] bool
138 enabled(uint256 const& feature) const
139 {
140 if (presets_.contains(feature))
141 return true;
142 return set_.contains(feature);
143 }
144
145 bool
146 operator==(Impl const& other) const
147 {
148 if (!digest_ && !other.digest_)
149 return true;
150 if (!digest_ || !other.digest_)
151 return false;
152 XRPL_ASSERT(
153 presets_ == other.presets_,
154 "xrpl::Rules::Impl::operator==(Impl) const : input presets do "
155 "match");
156 return *digest_ == *other.digest_;
157 }
158};
159
164
168 STVector256 const& amendments)
169 : impl_(std::make_shared<Impl>(presets, digest, amendments))
170{
171}
172
175{
176 return impl_->presets();
177}
178
179bool
180Rules::enabled(uint256 const& feature) const
181{
182 XRPL_ASSERT(impl_, "xrpl::Rules::enabled : initialized");
183
184 return impl_->enabled(feature);
185}
186
187bool
188Rules::operator==(Rules const& other) const
189{
190 XRPL_ASSERT(impl_ && other.impl_, "xrpl::Rules::operator==(Rules) const : both initialized");
191 if (impl_.get() == other.impl_.get())
192 return true;
193 return *impl_ == *other.impl_;
194}
195
196bool
197isFeatureEnabled(uint256 const& feature, bool resultIfNoRules)
198{
199 auto const& rules = getCurrentTransactionRules();
200 if (!rules)
201 return resultIfNoRules;
202 return rules->enabled(feature);
203}
204
205bool
207{
208 return isFeatureEnabled(feature, false);
209}
210
211} // namespace xrpl
static void setMantissaScale(MantissaRange::MantissaScale scale)
Changes which mantissa scale is used for normalization.
bool operator==(Impl const &other) const
Definition Rules.cpp:146
Impl(std::unordered_set< uint256, beast::Uhash<> > const &presets)
Definition Rules.cpp:117
bool enabled(uint256 const &feature) const
Definition Rules.cpp:138
std::unordered_set< uint256, beast::Uhash<> > const & presets() const
Definition Rules.cpp:132
std::unordered_set< uint256, beast::Uhash<> > const & presets_
Definition Rules.cpp:114
Impl(std::unordered_set< uint256, beast::Uhash<> > const &presets, std::optional< uint256 > const &digest, STVector256 const &amendments)
Definition Rules.cpp:121
std::unordered_set< uint256, HardenedHash<> > set_
Definition Rules.cpp:112
std::optional< uint256 > digest_
Definition Rules.cpp:113
Rules controlling protocol behavior.
Definition Rules.h:40
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:180
std::unordered_set< uint256, beast::Uhash<> > const & presets() const
Definition Rules.cpp:174
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:188
T emplace(T... args)
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool isFeatureEnabled(uint256 const &feature, bool resultIfNoRules)
Check whether a feature is enabled in the current ledger rules.
Definition Rules.cpp:197
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:77
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:37
void createGuards(Rules const &rules, std::optional< CurrentTransactionRulesGuard > &rulesGuard, std::optional< NumberMantissaScaleGuard > &mantissaScaleGuard)
Definition Rules.cpp:91
std::optional< Rules > const & getCurrentTransactionRules()
Definition Rules.cpp:30
void setCurrentTransactionRules(std::optional< Rules > r)
Definition Rules.cpp:36
BaseUInt< 256 > uint256
Definition base_uint.h:580