rippled
FeeUnits_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2019 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 
19 #include <ripple/basics/FeeUnits.h>
20 #include <ripple/beast/unit_test.h>
21 #include <ripple/protocol/SystemParameters.h>
22 #include <type_traits>
23 
24 namespace ripple {
25 namespace test {
26 
28  : public beast::unit_test::suite
29 {
30 private:
31  void testTypes()
32  {
33  {
34  XRPAmount x{ 100 };
35  BEAST_EXPECT(x.drops() == 100);
36  BEAST_EXPECT((std::is_same_v<decltype(x)::unit_type,
37  feeunit::dropTag>));
38  auto y = 4u * x;
39  BEAST_EXPECT(y.value() == 400);
40  BEAST_EXPECT((std::is_same_v<decltype(y)::unit_type,
41  feeunit::dropTag>));
42 
43  auto z = 4 * y;
44  BEAST_EXPECT(z.value() == 1600);
45  BEAST_EXPECT((std::is_same_v<decltype(z)::unit_type,
46  feeunit::dropTag>));
47 
48  FeeUnit32 f{ 10 };
49  FeeUnit32 baseFee{ 100 };
50 
51  auto drops = mulDiv(baseFee, x, f).second;
52 
53  BEAST_EXPECT(drops.value() == 1000);
54  BEAST_EXPECT((std::is_same_v<decltype(drops)::unit_type,
55  feeunit::dropTag>));
56  BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
57  }
58  {
59  XRPAmount x{ 100 };
60  BEAST_EXPECT(x.value() == 100);
61  BEAST_EXPECT((std::is_same_v<decltype(x)::unit_type,
62  feeunit::dropTag>));
63  auto y = 4u * x;
64  BEAST_EXPECT(y.value() == 400);
65  BEAST_EXPECT((std::is_same_v<decltype(y)::unit_type,
66  feeunit::dropTag>));
67 
68  FeeUnit64 f{ 10 };
69  FeeUnit64 baseFee{ 100 };
70 
71  auto drops = mulDiv(baseFee, x, f).second;
72 
73  BEAST_EXPECT(drops.value() == 1000);
74  BEAST_EXPECT((std::is_same_v<decltype(drops)::unit_type,
75  feeunit::dropTag>));
76  BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
77  }
78  {
79  FeeLevel64 x{ 1024 };
80  BEAST_EXPECT(x.value() == 1024);
81  BEAST_EXPECT((std::is_same_v<decltype(x)::unit_type,
82  feeunit::feelevelTag>));
83  std::uint64_t m = 4;
84  auto y = m * x;
85  BEAST_EXPECT(y.value() == 4096);
86  BEAST_EXPECT((std::is_same_v<decltype(y)::unit_type,
87  feeunit::feelevelTag>));
88 
89  XRPAmount basefee{ 10 };
90  FeeLevel64 referencefee{ 256 };
91 
92  auto drops = mulDiv(x, basefee, referencefee).second;
93 
94  BEAST_EXPECT(drops.value() == 40);
95  BEAST_EXPECT((std::is_same_v<decltype(drops)::unit_type,
96  feeunit::dropTag>));
97  BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
98  }
99  }
100 
101  void testJson()
102  {
103  // Json value functionality
104  {
106  auto y = x.jsonClipped();
107  BEAST_EXPECT(y.type() == Json::uintValue);
108  BEAST_EXPECT(y == Json::Value{x.fee()});
109  }
110 
111  {
113  auto y = x.jsonClipped();
114  BEAST_EXPECT(y.type() == Json::uintValue);
115  BEAST_EXPECT(y == Json::Value{x.fee()});
116  }
117 
118  {
120  auto y = x.jsonClipped();
121  BEAST_EXPECT(y.type() == Json::uintValue);
122  BEAST_EXPECT(y ==
124  }
125 
126  {
128  auto y = x.jsonClipped();
129  BEAST_EXPECT(y.type() == Json::uintValue);
130  BEAST_EXPECT(y == Json::Value{0});
131  }
132 
133  {
135  auto y = x.jsonClipped();
136  BEAST_EXPECT(y.type() == Json::realValue);
137  BEAST_EXPECT(y == Json::Value{std::numeric_limits<double>::max()});
138  }
139 
140  {
142  auto y = x.jsonClipped();
143  BEAST_EXPECT(y.type() == Json::realValue);
144  BEAST_EXPECT(y == Json::Value{std::numeric_limits<double>::min()});
145  }
146 
147  {
149  auto y = x.jsonClipped();
150  BEAST_EXPECT(y.type() == Json::intValue);
151  BEAST_EXPECT(y ==
153  }
154 
155  {
157  auto y = x.jsonClipped();
158  BEAST_EXPECT(y.type() == Json::intValue);
159  BEAST_EXPECT(y ==
161  }
162  }
163 
165  {
166  // Explicitly test every defined function for the TaggedFee class
167  // since some of them are templated, but not used anywhere else.
168  {
169  auto make = [&](auto x) -> FeeUnit64 {
170  return x; };
171  auto explicitmake = [&](auto x) -> FeeUnit64 {
172  return FeeUnit64{ x };
173  };
174 
175  FeeUnit64 defaulted;
176  (void)defaulted;
177  FeeUnit64 test{ 0 };
178  BEAST_EXPECT(test.fee() == 0);
179 
180  test = explicitmake(beast::zero);
181  BEAST_EXPECT(test.fee() == 0);
182 
183  test = beast::zero;
184  BEAST_EXPECT(test.fee() == 0);
185 
186  test = explicitmake(100u);
187  BEAST_EXPECT(test.fee() == 100);
188 
189  FeeUnit64 const targetSame{ 200u };
190  FeeUnit32 const targetOther{ 300u };
191  test = make(targetSame);
192  BEAST_EXPECT(test.fee() == 200);
193  BEAST_EXPECT(test == targetSame);
194  BEAST_EXPECT(test < FeeUnit64{ 1000 });
195  BEAST_EXPECT(test > FeeUnit64{ 100 });
196  test = make(targetOther);
197  BEAST_EXPECT(test.fee() == 300);
198  BEAST_EXPECT(test == targetOther);
199 
200  test = std::uint64_t(200);
201  BEAST_EXPECT(test.fee() == 200);
202  test = std::uint32_t(300);
203  BEAST_EXPECT(test.fee() == 300);
204 
205  test = targetSame;
206  BEAST_EXPECT(test.fee() == 200);
207  test = targetOther.fee();
208  BEAST_EXPECT(test.fee() == 300);
209  BEAST_EXPECT(test == targetOther);
210 
211  test = targetSame * 2;
212  BEAST_EXPECT(test.fee() == 400);
213  test = 3 * targetSame;
214  BEAST_EXPECT(test.fee() == 600);
215  test = targetSame / 10;
216  BEAST_EXPECT(test.fee() == 20);
217 
218  test += targetSame;
219  BEAST_EXPECT(test.fee() == 220);
220 
221  test -= targetSame;
222  BEAST_EXPECT(test.fee() == 20);
223 
224  test++;
225  BEAST_EXPECT(test.fee() == 21);
226  ++test;
227  BEAST_EXPECT(test.fee() == 22);
228  test--;
229  BEAST_EXPECT(test.fee() == 21);
230  --test;
231  BEAST_EXPECT(test.fee() == 20);
232 
233  test *= 5;
234  BEAST_EXPECT(test.fee() == 100);
235  test /= 2;
236  BEAST_EXPECT(test.fee() == 50);
237  test %= 13;
238  BEAST_EXPECT(test.fee() == 11);
239 
240  /*
241  // illegal with unsigned
242  test = -test;
243  BEAST_EXPECT(test.fee() == -11);
244  BEAST_EXPECT(test.signum() == -1);
245  BEAST_EXPECT(to_string(test) == "-11");
246  */
247 
248  BEAST_EXPECT(test);
249  test = 0;
250  BEAST_EXPECT(!test);
251  BEAST_EXPECT(test.signum() == 0);
252  test = targetSame;
253  BEAST_EXPECT(test.signum() == 1);
254  BEAST_EXPECT(to_string(test) == "200");
255  }
256  {
257  auto make = [&](auto x) -> FeeLevelDouble {
258  return x; };
259  auto explicitmake = [&](auto x) -> FeeLevelDouble {
260  return FeeLevelDouble{ x };
261  };
262 
263  FeeLevelDouble defaulted;
264  (void)defaulted;
265  FeeLevelDouble test{ 0 };
266  BEAST_EXPECT(test.fee() == 0);
267 
268  test = explicitmake(beast::zero);
269  BEAST_EXPECT(test.fee() == 0);
270 
271  test = beast::zero;
272  BEAST_EXPECT(test.fee() == 0);
273 
274  test = explicitmake(100.0);
275  BEAST_EXPECT(test.fee() == 100);
276 
277  FeeLevelDouble const targetSame{ 200.0 };
278  FeeLevel64 const targetOther{ 300 };
279  test = make(targetSame);
280  BEAST_EXPECT(test.fee() == 200);
281  BEAST_EXPECT(test == targetSame);
282  BEAST_EXPECT(test < FeeLevelDouble{ 1000.0 });
283  BEAST_EXPECT(test > FeeLevelDouble{ 100.0 });
284  test = targetOther.fee();
285  BEAST_EXPECT(test.fee() == 300);
286  BEAST_EXPECT(test == targetOther);
287 
288  test = 200.0;
289  BEAST_EXPECT(test.fee() == 200);
290  test = std::uint64_t(300);
291  BEAST_EXPECT(test.fee() == 300);
292 
293  test = targetSame;
294  BEAST_EXPECT(test.fee() == 200);
295 
296  test = targetSame * 2;
297  BEAST_EXPECT(test.fee() == 400);
298  test = 3 * targetSame;
299  BEAST_EXPECT(test.fee() == 600);
300  test = targetSame / 10;
301  BEAST_EXPECT(test.fee() == 20);
302 
303  test += targetSame;
304  BEAST_EXPECT(test.fee() == 220);
305 
306  test -= targetSame;
307  BEAST_EXPECT(test.fee() == 20);
308 
309  test++;
310  BEAST_EXPECT(test.fee() == 21);
311  ++test;
312  BEAST_EXPECT(test.fee() == 22);
313  test--;
314  BEAST_EXPECT(test.fee() == 21);
315  --test;
316  BEAST_EXPECT(test.fee() == 20);
317 
318  test *= 5;
319  BEAST_EXPECT(test.fee() == 100);
320  test /= 2;
321  BEAST_EXPECT(test.fee() == 50);
322  /* illegal with floating
323  test %= 13;
324  BEAST_EXPECT(test.fee() == 11);
325  */
326 
327  // legal with signed
328  test = -test;
329  BEAST_EXPECT(test.fee() == -50);
330  BEAST_EXPECT(test.signum() == -1);
331  BEAST_EXPECT(to_string(test) == "-50.000000");
332 
333  BEAST_EXPECT(test);
334  test = 0;
335  BEAST_EXPECT(!test);
336  BEAST_EXPECT(test.signum() == 0);
337  test = targetSame;
338  BEAST_EXPECT(test.signum() == 1);
339  BEAST_EXPECT(to_string(test) == "200.000000");
340  }
341  }
342 
343 public:
344  void run() override
345  {
346  BEAST_EXPECT(INITIAL_XRP.drops() == 100'000'000'000'000'000);
347  BEAST_EXPECT(INITIAL_XRP == XRPAmount{100'000'000'000'000'000});
348 
349  testTypes();
350  testJson();
351  testFunctions();
352  }
353 };
354 
355 BEAST_DEFINE_TESTSUITE(feeunits,ripple_basics,ripple);
356 
357 } // test
358 } //ripple
std::is_same_v
T is_same_v
ripple::test::feeunits_test::testFunctions
void testFunctions()
Definition: FeeUnits_test.cpp:164
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::test::jtx::drops
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Definition: amount.h:261
ripple::XRPAmount::drops
constexpr value_type drops() const
Returns the number of drops.
Definition: XRPAmount.h:185
ripple::test::feeunits_test::testTypes
void testTypes()
Definition: FeeUnits_test.cpp:31
Json::realValue
@ realValue
double value
Definition: json_value.h:41
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::INITIAL_XRP
constexpr XRPAmount INITIAL_XRP
Configure the native currency.
Definition: SystemParameters.h:45
Json::uintValue
@ uintValue
unsigned integer value
Definition: json_value.h:40
std::uint64_t
ripple::feeunit::TaggedFee
Definition: FeeUnits.h:72
std::numeric_limits::min
T min(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::feeunits_test::testJson
void testJson()
Definition: FeeUnits_test.cpp:101
Json::intValue
@ intValue
signed integer value
Definition: json_value.h:39
ripple::test::feeunits_test::run
void run() override
Definition: FeeUnits_test.cpp:344
ripple::test::jtx::PrettyAmount::value
STAmount const & value() const
Definition: amount.h:125
ripple::mulDiv
std::pair< bool, Dest > mulDiv(Source1 value, Dest mul, Source2 div)
Definition: FeeUnits.h:487
std::numeric_limits::max
T max(T... args)
type_traits
ripple::test::feeunits_test
Definition: FeeUnits_test.cpp:27
Json::Value
Represents a JSON value.
Definition: json_value.h:141
ripple::XRPAmount
Definition: XRPAmount.h:46