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 
27 class feeunits_test : public beast::unit_test::suite
28 {
29 private:
30  void
32  {
33  {
34  XRPAmount x{100};
35  BEAST_EXPECT(x.drops() == 100);
36  BEAST_EXPECT(
37  (std::is_same_v<decltype(x)::unit_type, feeunit::dropTag>));
38  auto y = 4u * x;
39  BEAST_EXPECT(y.value() == 400);
40  BEAST_EXPECT(
41  (std::is_same_v<decltype(y)::unit_type, feeunit::dropTag>));
42 
43  auto z = 4 * y;
44  BEAST_EXPECT(z.value() == 1600);
45  BEAST_EXPECT(
46  (std::is_same_v<decltype(z)::unit_type, 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(
55  (std::is_same_v<decltype(drops)::unit_type, 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(
62  (std::is_same_v<decltype(x)::unit_type, feeunit::dropTag>));
63  auto y = 4u * x;
64  BEAST_EXPECT(y.value() == 400);
65  BEAST_EXPECT(
66  (std::is_same_v<decltype(y)::unit_type, 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(
75  (std::is_same_v<decltype(drops)::unit_type, 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(
82  (std::is_same_v<decltype(x)::unit_type, feeunit::feelevelTag>));
83  std::uint64_t m = 4;
84  auto y = m * x;
85  BEAST_EXPECT(y.value() == 4096);
86  BEAST_EXPECT(
87  (std::is_same_v<decltype(y)::unit_type, 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(
96  (std::is_same_v<decltype(drops)::unit_type, feeunit::dropTag>));
97  BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
98  }
99  }
100 
101  void
103  {
104  // Json value functionality
105  {
107  auto y = x.jsonClipped();
108  BEAST_EXPECT(y.type() == Json::uintValue);
109  BEAST_EXPECT(y == Json::Value{x.fee()});
110  }
111 
112  {
114  auto y = x.jsonClipped();
115  BEAST_EXPECT(y.type() == Json::uintValue);
116  BEAST_EXPECT(y == Json::Value{x.fee()});
117  }
118 
119  {
121  auto y = x.jsonClipped();
122  BEAST_EXPECT(y.type() == Json::uintValue);
123  BEAST_EXPECT(
125  }
126 
127  {
129  auto y = x.jsonClipped();
130  BEAST_EXPECT(y.type() == Json::uintValue);
131  BEAST_EXPECT(y == Json::Value{0});
132  }
133 
134  {
136  auto y = x.jsonClipped();
137  BEAST_EXPECT(y.type() == Json::realValue);
138  BEAST_EXPECT(y == Json::Value{std::numeric_limits<double>::max()});
139  }
140 
141  {
143  auto y = x.jsonClipped();
144  BEAST_EXPECT(y.type() == Json::realValue);
145  BEAST_EXPECT(y == Json::Value{std::numeric_limits<double>::min()});
146  }
147 
148  {
150  auto y = x.jsonClipped();
151  BEAST_EXPECT(y.type() == Json::intValue);
152  BEAST_EXPECT(
154  }
155 
156  {
158  auto y = x.jsonClipped();
159  BEAST_EXPECT(y.type() == Json::intValue);
160  BEAST_EXPECT(
162  }
163  }
164 
165  void
167  {
168  // Explicitly test every defined function for the TaggedFee class
169  // since some of them are templated, but not used anywhere else.
170  {
171  auto make = [&](auto x) -> FeeUnit64 { return x; };
172  auto explicitmake = [&](auto x) -> FeeUnit64 {
173  return FeeUnit64{x};
174  };
175 
176  FeeUnit64 defaulted;
177  (void)defaulted;
178  FeeUnit64 test{0};
179  BEAST_EXPECT(test.fee() == 0);
180 
181  test = explicitmake(beast::zero);
182  BEAST_EXPECT(test.fee() == 0);
183 
184  test = beast::zero;
185  BEAST_EXPECT(test.fee() == 0);
186 
187  test = explicitmake(100u);
188  BEAST_EXPECT(test.fee() == 100);
189 
190  FeeUnit64 const targetSame{200u};
191  FeeUnit32 const targetOther{300u};
192  test = make(targetSame);
193  BEAST_EXPECT(test.fee() == 200);
194  BEAST_EXPECT(test == targetSame);
195  BEAST_EXPECT(test < FeeUnit64{1000});
196  BEAST_EXPECT(test > FeeUnit64{100});
197  test = make(targetOther);
198  BEAST_EXPECT(test.fee() == 300);
199  BEAST_EXPECT(test == targetOther);
200 
201  test = std::uint64_t(200);
202  BEAST_EXPECT(test.fee() == 200);
203  test = std::uint32_t(300);
204  BEAST_EXPECT(test.fee() == 300);
205 
206  test = targetSame;
207  BEAST_EXPECT(test.fee() == 200);
208  test = targetOther.fee();
209  BEAST_EXPECT(test.fee() == 300);
210  BEAST_EXPECT(test == targetOther);
211 
212  test = targetSame * 2;
213  BEAST_EXPECT(test.fee() == 400);
214  test = 3 * targetSame;
215  BEAST_EXPECT(test.fee() == 600);
216  test = targetSame / 10;
217  BEAST_EXPECT(test.fee() == 20);
218 
219  test += targetSame;
220  BEAST_EXPECT(test.fee() == 220);
221 
222  test -= targetSame;
223  BEAST_EXPECT(test.fee() == 20);
224 
225  test++;
226  BEAST_EXPECT(test.fee() == 21);
227  ++test;
228  BEAST_EXPECT(test.fee() == 22);
229  test--;
230  BEAST_EXPECT(test.fee() == 21);
231  --test;
232  BEAST_EXPECT(test.fee() == 20);
233 
234  test *= 5;
235  BEAST_EXPECT(test.fee() == 100);
236  test /= 2;
237  BEAST_EXPECT(test.fee() == 50);
238  test %= 13;
239  BEAST_EXPECT(test.fee() == 11);
240 
241  /*
242  // illegal with unsigned
243  test = -test;
244  BEAST_EXPECT(test.fee() == -11);
245  BEAST_EXPECT(test.signum() == -1);
246  BEAST_EXPECT(to_string(test) == "-11");
247  */
248 
249  BEAST_EXPECT(test);
250  test = 0;
251  BEAST_EXPECT(!test);
252  BEAST_EXPECT(test.signum() == 0);
253  test = targetSame;
254  BEAST_EXPECT(test.signum() == 1);
255  BEAST_EXPECT(to_string(test) == "200");
256  }
257  {
258  auto make = [&](auto x) -> FeeLevelDouble { 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
345  run() override
346  {
347  BEAST_EXPECT(INITIAL_XRP.drops() == 100'000'000'000'000'000);
348  BEAST_EXPECT(INITIAL_XRP == XRPAmount{100'000'000'000'000'000});
349 
350  testTypes();
351  testJson();
352  testFunctions();
353  }
354 };
355 
356 BEAST_DEFINE_TESTSUITE(feeunits, ripple_basics, ripple);
357 
358 } // namespace test
359 } // namespace ripple
std::is_same_v
T is_same_v
ripple::test::feeunits_test::testFunctions
void testFunctions()
Definition: FeeUnits_test.cpp:166
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:241
ripple::XRPAmount::drops
constexpr value_type drops() const
Returns the number of drops.
Definition: XRPAmount.h:172
ripple::test::feeunits_test::testTypes
void testTypes()
Definition: FeeUnits_test.cpp:31
Json::realValue
@ realValue
double value
Definition: json_value.h:39
ripple::INITIAL_XRP
constexpr XRPAmount INITIAL_XRP
Configure the native currency.
Definition: SystemParameters.h:43
Json::uintValue
@ uintValue
unsigned integer value
Definition: json_value.h:38
std::uint64_t
ripple::feeunit::TaggedFee
Definition: FeeUnits.h:70
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:102
Json::intValue
@ intValue
signed integer value
Definition: json_value.h:37
ripple::test::feeunits_test::run
void run() override
Definition: FeeUnits_test.cpp:345
ripple::test::jtx::PrettyAmount::value
STAmount const & value() const
Definition: amount.h:124
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::mulDiv
std::pair< bool, Dest > mulDiv(Source1 value, Dest mul, Source2 div)
Definition: FeeUnits.h:473
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:145
ripple::XRPAmount
Definition: XRPAmount.h:46