xrpld
Loading...
Searching...
No Matches
Quality_test.cpp
1#include <xrpl/beast/unit_test/suite.h>
2#include <xrpl/beast/utility/Zero.h>
3#include <xrpl/protocol/AccountID.h>
4#include <xrpl/protocol/Issue.h>
5#include <xrpl/protocol/Quality.h>
6#include <xrpl/protocol/STAmount.h>
7#include <xrpl/protocol/UintTypes.h>
8
9#include <cstdint>
10#include <type_traits>
11
12namespace xrpl {
13
15{
16public:
17 // Create a raw, non-integral amount from mantissa and exponent
18 STAmount static raw(std::uint64_t mantissa, int exponent)
19 {
20 return STAmount(Issue{Currency(3), AccountID(3)}, mantissa, exponent);
21 }
22
23 template <class Integer>
24 static STAmount
25 amount(Integer integer)
27 {
28 static_assert(std::is_integral_v<Integer>);
29 return STAmount(integer, false);
30 }
31
32 template <class Integer>
33 static STAmount
34 amount(Integer integer)
36 {
37 static_assert(std::is_integral_v<Integer>);
38 if (integer < 0)
39 return STAmount(-integer, true);
40 return STAmount(integer, false);
41 }
42
43 template <class In, class Out>
44 static Amounts
45 amounts(In in, Out out)
46 {
47 return Amounts(amount(in), amount(out));
48 }
49
50 template <class In1, class Out1, class Int, class In2, class Out2>
51 void
52 ceilIn(Quality const& q, In1 in, Out1 out, Int limit, In2 inExpected, Out2 outExpected)
53 {
54 auto expectResult(amounts(inExpected, outExpected));
55 auto actualResult(q.ceilIn(amounts(in, out), amount(limit)));
56
57 BEAST_EXPECT(actualResult == expectResult);
58 }
59
60 template <class In1, class Out1, class Int, class In2, class Out2>
61 void
62 ceilOut(Quality const& q, In1 in, Out1 out, Int limit, In2 inExpected, Out2 outExpected)
63 {
64 auto const expectResult(amounts(inExpected, outExpected));
65 auto const actualResult(q.ceilOut(amounts(in, out), amount(limit)));
66
67 BEAST_EXPECT(actualResult == expectResult);
68 }
69
70 void
72 {
73 testcase("ceil_in");
74
75 {
76 // 1 in, 1 out:
77 Quality const q(Amounts(amount(1), amount(1)));
78
79 ceilIn(
80 q,
81 1,
82 1, // 1 in, 1 out
83 1, // limit: 1
84 1,
85 1); // 1 in, 1 out
86
87 ceilIn(
88 q,
89 10,
90 10, // 10 in, 10 out
91 5, // limit: 5
92 5,
93 5); // 5 in, 5 out
94
95 ceilIn(
96 q,
97 5,
98 5, // 5 in, 5 out
99 10, // limit: 10
100 5,
101 5); // 5 in, 5 out
102 }
103
104 {
105 // 1 in, 2 out:
106 Quality const q(Amounts(amount(1), amount(2)));
107
108 ceilIn(
109 q,
110 40,
111 80, // 40 in, 80 out
112 40, // limit: 40
113 40,
114 80); // 40 in, 20 out
115
116 ceilIn(
117 q,
118 40,
119 80, // 40 in, 80 out
120 20, // limit: 20
121 20,
122 40); // 20 in, 40 out
123
124 ceilIn(
125 q,
126 40,
127 80, // 40 in, 80 out
128 60, // limit: 60
129 40,
130 80); // 40 in, 80 out
131 }
132
133 {
134 // 2 in, 1 out:
135 Quality const q(Amounts(amount(2), amount(1)));
136
137 ceilIn(
138 q,
139 40,
140 20, // 40 in, 20 out
141 20, // limit: 20
142 20,
143 10); // 20 in, 10 out
144
145 ceilIn(
146 q,
147 40,
148 20, // 40 in, 20 out
149 40, // limit: 40
150 40,
151 20); // 40 in, 20 out
152
153 ceilIn(
154 q,
155 40,
156 20, // 40 in, 20 out
157 50, // limit: 40
158 40,
159 20); // 40 in, 20 out
160 }
161 }
162
163 void
165 {
166 testcase("ceil_out");
167
168 {
169 // 1 in, 1 out:
170 Quality const q(Amounts(amount(1), amount(1)));
171
172 ceilOut(
173 q,
174 1,
175 1, // 1 in, 1 out
176 1, // limit 1
177 1,
178 1); // 1 in, 1 out
179
180 ceilOut(
181 q,
182 10,
183 10, // 10 in, 10 out
184 5, // limit 5
185 5,
186 5); // 5 in, 5 out
187
188 ceilOut(
189 q,
190 10,
191 10, // 10 in, 10 out
192 20, // limit 20
193 10,
194 10); // 10 in, 10 out
195 }
196
197 {
198 // 1 in, 2 out:
199 Quality const q(Amounts(amount(1), amount(2)));
200
201 ceilOut(
202 q,
203 40,
204 80, // 40 in, 80 out
205 40, // limit 40
206 20,
207 40); // 20 in, 40 out
208
209 ceilOut(
210 q,
211 40,
212 80, // 40 in, 80 out
213 80, // limit 80
214 40,
215 80); // 40 in, 80 out
216
217 ceilOut(
218 q,
219 40,
220 80, // 40 in, 80 out
221 100, // limit 100
222 40,
223 80); // 40 in, 80 out
224 }
225
226 {
227 // 2 in, 1 out:
228 Quality const q(Amounts(amount(2), amount(1)));
229
230 ceilOut(
231 q,
232 40,
233 20, // 40 in, 20 out
234 20, // limit 20
235 40,
236 20); // 40 in, 20 out
237
238 ceilOut(
239 q,
240 40,
241 20, // 40 in, 20 out
242 40, // limit 40
243 40,
244 20); // 40 in, 20 out
245
246 ceilOut(
247 q,
248 40,
249 20, // 40 in, 20 out
250 10, // limit 10
251 20,
252 10); // 20 in, 10 out
253 }
254 }
255
256 void
258 {
259 testcase("raw");
260
261 {
262 Quality const q(0x5d048191fb9130daull); // 126836389.7680090
263 Amounts const value(
264 amount(349469768), // 349.469768 XRP
265 raw(2755280000000000ull, -15)); // 2.75528
266 STAmount const limit(raw(4131113916555555, -16)); // .4131113916555555
267 Amounts const result(q.ceilOut(value, limit));
268 BEAST_EXPECT(result.in != beast::kZero);
269 }
270 }
271
272 void
274 {
275 testcase("round");
276
277 Quality const q(0x59148191fb913522ull); // 57719.63525051682
278 BEAST_EXPECT(q.round(3).rate().getText() == "57800");
279 BEAST_EXPECT(q.round(4).rate().getText() == "57720");
280 BEAST_EXPECT(q.round(5).rate().getText() == "57720");
281 BEAST_EXPECT(q.round(6).rate().getText() == "57719.7");
282 BEAST_EXPECT(q.round(7).rate().getText() == "57719.64");
283 BEAST_EXPECT(q.round(8).rate().getText() == "57719.636");
284 BEAST_EXPECT(q.round(9).rate().getText() == "57719.6353");
285 BEAST_EXPECT(q.round(10).rate().getText() == "57719.63526");
286 BEAST_EXPECT(q.round(11).rate().getText() == "57719.635251");
287 BEAST_EXPECT(q.round(12).rate().getText() == "57719.6352506");
288 BEAST_EXPECT(q.round(13).rate().getText() == "57719.63525052");
289 BEAST_EXPECT(q.round(14).rate().getText() == "57719.635250517");
290 BEAST_EXPECT(q.round(15).rate().getText() == "57719.6352505169");
291 BEAST_EXPECT(q.round(16).rate().getText() == "57719.63525051682");
292 }
293
294 void
296 {
297 testcase("comparisons");
298
299 STAmount const amount1(noIssue(), 231);
300 STAmount const amount2(noIssue(), 462);
301 STAmount const amount3(noIssue(), 924);
302
303 Quality const q11(Amounts(amount1, amount1));
304 Quality const q12(Amounts(amount1, amount2));
305 Quality const q13(Amounts(amount1, amount3));
306 Quality const q21(Amounts(amount2, amount1));
307 Quality const q31(Amounts(amount3, amount1));
308
309 BEAST_EXPECT(q11 == q11);
310 BEAST_EXPECT(q11 < q12);
311 BEAST_EXPECT(q12 < q13);
312 BEAST_EXPECT(q31 < q21);
313 BEAST_EXPECT(q21 < q11);
314 BEAST_EXPECT(q11 >= q11);
315 BEAST_EXPECT(q12 >= q11);
316 BEAST_EXPECT(q13 >= q12);
317 BEAST_EXPECT(q21 >= q31);
318 BEAST_EXPECT(q11 >= q21);
319 BEAST_EXPECT(q12 > q11);
320 BEAST_EXPECT(q13 > q12);
321 BEAST_EXPECT(q21 > q31);
322 BEAST_EXPECT(q11 > q21);
323 BEAST_EXPECT(q11 <= q11);
324 BEAST_EXPECT(q11 <= q12);
325 BEAST_EXPECT(q12 <= q13);
326 BEAST_EXPECT(q31 <= q21);
327 BEAST_EXPECT(q21 <= q11);
328 BEAST_EXPECT(q31 != q21);
329 }
330
331 void
333 {
334 testcase("composition");
335
336 STAmount const amount1(noIssue(), 231);
337 STAmount const amount2(noIssue(), 462);
338 STAmount const amount3(noIssue(), 924);
339
340 Quality const q11(Amounts(amount1, amount1));
341 Quality const q12(Amounts(amount1, amount2));
342 Quality const q13(Amounts(amount1, amount3));
343 Quality const q21(Amounts(amount2, amount1));
344 Quality const q31(Amounts(amount3, amount1));
345
346 BEAST_EXPECT(composedQuality(q12, q21) == q11);
347
348 Quality const q1331(composedQuality(q13, q31));
349 Quality const q3113(composedQuality(q31, q13));
350
351 BEAST_EXPECT(q1331 == q3113);
352 BEAST_EXPECT(q1331 == q11);
353 }
354
355 void
357 {
358 testcase("operations");
359
360 Quality const q11(Amounts(STAmount(noIssue(), 731), STAmount(noIssue(), 731)));
361
362 Quality qa(q11);
363 Quality qb(q11);
364
365 BEAST_EXPECT(qa == qb);
366 BEAST_EXPECT(++qa != q11);
367 BEAST_EXPECT(qa != qb);
368 BEAST_EXPECT(--qb != q11);
369 BEAST_EXPECT(qa != qb);
370 BEAST_EXPECT(qb < qa);
371 BEAST_EXPECT(qb++ < qa);
372 BEAST_EXPECT(qb++ < qa);
373 BEAST_EXPECT(qb++ == qa);
374 BEAST_EXPECT(qa < qb);
375 }
376 void
377 run() override
378 {
382 testCeilIn();
383 testCeilOut();
384 testRaw();
385 testRound();
386 }
387};
388
390
391} // namespace xrpl
A testsuite class.
Definition suite.h:52
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:155
A currency issued by an account.
Definition Issue.h:18
static STAmount amount(Integer integer)
static STAmount raw(std::uint64_t mantissa, int exponent)
static STAmount amount(Integer integer)
void ceilOut(Quality const &q, In1 in, Out1 out, Int limit, In2 inExpected, Out2 outExpected)
void run() override
Runs the suite.
void ceilIn(Quality const &q, In1 in, Out1 out, Int limit, In2 inExpected, Out2 outExpected)
static Amounts amounts(In in, Out out)
Represents the logical ratio of output currency to input currency.
Definition Quality.h:90
STAmount rate() const
Returns the quality as STAmount.
Definition Quality.h:162
Quality round(int tickSize) const
Returns the quality rounded up to the specified number of decimal digits.
Definition Quality.cpp:134
Amounts ceilOut(Amounts const &amount, STAmount const &limit) const
Returns the scaled amount with out capped.
Definition Quality.cpp:102
Amounts ceilIn(Amounts const &amount, STAmount const &limit) const
Returns the scaled amount with in capped.
Definition Quality.cpp:73
std::string getText() const override
Definition STAmount.cpp:646
T is_integral_v
T is_signed_v
constexpr Zero kZero
Definition Zero.h:30
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
TAmounts< STAmount, STAmount > Amounts
Definition Quality.h:69
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:42
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition Issue.h:118
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, xrpl)
Quality composedQuality(Quality const &lhs, Quality const &rhs)
Calculate the quality of a two-hop path given the two hops.
Definition Quality.cpp:114