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  using FeeLevel32 = FeeLevel<std::uint32_t>;
34 
35  {
36  XRPAmount x{100};
37  BEAST_EXPECT(x.drops() == 100);
38  BEAST_EXPECT(
39  (std::is_same_v<decltype(x)::unit_type, feeunit::dropTag>));
40  auto y = 4u * x;
41  BEAST_EXPECT(y.value() == 400);
42  BEAST_EXPECT(
43  (std::is_same_v<decltype(y)::unit_type, feeunit::dropTag>));
44 
45  auto z = 4 * y;
46  BEAST_EXPECT(z.value() == 1600);
47  BEAST_EXPECT(
48  (std::is_same_v<decltype(z)::unit_type, feeunit::dropTag>));
49 
50  FeeLevel32 f{10};
51  FeeLevel32 baseFee{100};
52 
53  auto drops = mulDiv(baseFee, x, f).second;
54 
55  BEAST_EXPECT(drops.value() == 1000);
56  BEAST_EXPECT(
57  (std::is_same_v<decltype(drops)::unit_type, feeunit::dropTag>));
58  BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
59  }
60  {
61  XRPAmount x{100};
62  BEAST_EXPECT(x.value() == 100);
63  BEAST_EXPECT(
64  (std::is_same_v<decltype(x)::unit_type, feeunit::dropTag>));
65  auto y = 4u * x;
66  BEAST_EXPECT(y.value() == 400);
67  BEAST_EXPECT(
68  (std::is_same_v<decltype(y)::unit_type, feeunit::dropTag>));
69 
70  FeeLevel64 f{10};
71  FeeLevel64 baseFee{100};
72 
73  auto drops = mulDiv(baseFee, x, f).second;
74 
75  BEAST_EXPECT(drops.value() == 1000);
76  BEAST_EXPECT(
77  (std::is_same_v<decltype(drops)::unit_type, feeunit::dropTag>));
78  BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
79  }
80  {
81  FeeLevel64 x{1024};
82  BEAST_EXPECT(x.value() == 1024);
83  BEAST_EXPECT(
84  (std::is_same_v<decltype(x)::unit_type, feeunit::feelevelTag>));
85  std::uint64_t m = 4;
86  auto y = m * x;
87  BEAST_EXPECT(y.value() == 4096);
88  BEAST_EXPECT(
89  (std::is_same_v<decltype(y)::unit_type, feeunit::feelevelTag>));
90 
91  XRPAmount basefee{10};
92  FeeLevel64 referencefee{256};
93 
94  auto drops = mulDiv(x, basefee, referencefee).second;
95 
96  BEAST_EXPECT(drops.value() == 40);
97  BEAST_EXPECT(
98  (std::is_same_v<decltype(drops)::unit_type, feeunit::dropTag>));
99  BEAST_EXPECT((std::is_same_v<decltype(drops), XRPAmount>));
100  }
101  }
102 
103  void
105  {
106  // Json value functionality
107  using FeeLevel32 = FeeLevel<std::uint32_t>;
108 
109  {
111  auto y = x.jsonClipped();
112  BEAST_EXPECT(y.type() == Json::uintValue);
113  BEAST_EXPECT(y == Json::Value{x.fee()});
114  }
115 
116  {
118  auto y = x.jsonClipped();
119  BEAST_EXPECT(y.type() == Json::uintValue);
120  BEAST_EXPECT(y == Json::Value{x.fee()});
121  }
122 
123  {
125  auto y = x.jsonClipped();
126  BEAST_EXPECT(y.type() == Json::uintValue);
127  BEAST_EXPECT(
129  }
130 
131  {
133  auto y = x.jsonClipped();
134  BEAST_EXPECT(y.type() == Json::uintValue);
135  BEAST_EXPECT(y == Json::Value{0});
136  }
137 
138  {
140  auto y = x.jsonClipped();
141  BEAST_EXPECT(y.type() == Json::realValue);
142  BEAST_EXPECT(y == Json::Value{std::numeric_limits<double>::max()});
143  }
144 
145  {
147  auto y = x.jsonClipped();
148  BEAST_EXPECT(y.type() == Json::realValue);
149  BEAST_EXPECT(y == Json::Value{std::numeric_limits<double>::min()});
150  }
151 
152  {
154  auto y = x.jsonClipped();
155  BEAST_EXPECT(y.type() == Json::intValue);
156  BEAST_EXPECT(
158  }
159 
160  {
162  auto y = x.jsonClipped();
163  BEAST_EXPECT(y.type() == Json::intValue);
164  BEAST_EXPECT(
166  }
167  }
168 
169  void
171  {
172  // Explicitly test every defined function for the TaggedFee class
173  // since some of them are templated, but not used anywhere else.
174  using FeeLevel32 = FeeLevel<std::uint32_t>;
175 
176  {
177  auto make = [&](auto x) -> FeeLevel64 { return x; };
178  auto explicitmake = [&](auto x) -> FeeLevel64 {
179  return FeeLevel64{x};
180  };
181 
182  FeeLevel64 defaulted;
183  (void)defaulted;
184  FeeLevel64 test{0};
185  BEAST_EXPECT(test.fee() == 0);
186 
187  test = explicitmake(beast::zero);
188  BEAST_EXPECT(test.fee() == 0);
189 
190  test = beast::zero;
191  BEAST_EXPECT(test.fee() == 0);
192 
193  test = explicitmake(100u);
194  BEAST_EXPECT(test.fee() == 100);
195 
196  FeeLevel64 const targetSame{200u};
197  FeeLevel32 const targetOther{300u};
198  test = make(targetSame);
199  BEAST_EXPECT(test.fee() == 200);
200  BEAST_EXPECT(test == targetSame);
201  BEAST_EXPECT(test < FeeLevel64{1000});
202  BEAST_EXPECT(test > FeeLevel64{100});
203  test = make(targetOther);
204  BEAST_EXPECT(test.fee() == 300);
205  BEAST_EXPECT(test == targetOther);
206 
207  test = std::uint64_t(200);
208  BEAST_EXPECT(test.fee() == 200);
209  test = std::uint32_t(300);
210  BEAST_EXPECT(test.fee() == 300);
211 
212  test = targetSame;
213  BEAST_EXPECT(test.fee() == 200);
214  test = targetOther.fee();
215  BEAST_EXPECT(test.fee() == 300);
216  BEAST_EXPECT(test == targetOther);
217 
218  test = targetSame * 2;
219  BEAST_EXPECT(test.fee() == 400);
220  test = 3 * targetSame;
221  BEAST_EXPECT(test.fee() == 600);
222  test = targetSame / 10;
223  BEAST_EXPECT(test.fee() == 20);
224 
225  test += targetSame;
226  BEAST_EXPECT(test.fee() == 220);
227 
228  test -= targetSame;
229  BEAST_EXPECT(test.fee() == 20);
230 
231  test++;
232  BEAST_EXPECT(test.fee() == 21);
233  ++test;
234  BEAST_EXPECT(test.fee() == 22);
235  test--;
236  BEAST_EXPECT(test.fee() == 21);
237  --test;
238  BEAST_EXPECT(test.fee() == 20);
239 
240  test *= 5;
241  BEAST_EXPECT(test.fee() == 100);
242  test /= 2;
243  BEAST_EXPECT(test.fee() == 50);
244  test %= 13;
245  BEAST_EXPECT(test.fee() == 11);
246 
247  /*
248  // illegal with unsigned
249  test = -test;
250  BEAST_EXPECT(test.fee() == -11);
251  BEAST_EXPECT(test.signum() == -1);
252  BEAST_EXPECT(to_string(test) == "-11");
253  */
254 
255  BEAST_EXPECT(test);
256  test = 0;
257  BEAST_EXPECT(!test);
258  BEAST_EXPECT(test.signum() == 0);
259  test = targetSame;
260  BEAST_EXPECT(test.signum() == 1);
261  BEAST_EXPECT(to_string(test) == "200");
262  }
263  {
264  auto make = [&](auto x) -> FeeLevelDouble { return x; };
265  auto explicitmake = [&](auto x) -> FeeLevelDouble {
266  return FeeLevelDouble{x};
267  };
268 
269  FeeLevelDouble defaulted;
270  (void)defaulted;
271  FeeLevelDouble test{0};
272  BEAST_EXPECT(test.fee() == 0);
273 
274  test = explicitmake(beast::zero);
275  BEAST_EXPECT(test.fee() == 0);
276 
277  test = beast::zero;
278  BEAST_EXPECT(test.fee() == 0);
279 
280  test = explicitmake(100.0);
281  BEAST_EXPECT(test.fee() == 100);
282 
283  FeeLevelDouble const targetSame{200.0};
284  FeeLevel64 const targetOther{300};
285  test = make(targetSame);
286  BEAST_EXPECT(test.fee() == 200);
287  BEAST_EXPECT(test == targetSame);
288  BEAST_EXPECT(test < FeeLevelDouble{1000.0});
289  BEAST_EXPECT(test > FeeLevelDouble{100.0});
290  test = targetOther.fee();
291  BEAST_EXPECT(test.fee() == 300);
292  BEAST_EXPECT(test == targetOther);
293 
294  test = 200.0;
295  BEAST_EXPECT(test.fee() == 200);
296  test = std::uint64_t(300);
297  BEAST_EXPECT(test.fee() == 300);
298 
299  test = targetSame;
300  BEAST_EXPECT(test.fee() == 200);
301 
302  test = targetSame * 2;
303  BEAST_EXPECT(test.fee() == 400);
304  test = 3 * targetSame;
305  BEAST_EXPECT(test.fee() == 600);
306  test = targetSame / 10;
307  BEAST_EXPECT(test.fee() == 20);
308 
309  test += targetSame;
310  BEAST_EXPECT(test.fee() == 220);
311 
312  test -= targetSame;
313  BEAST_EXPECT(test.fee() == 20);
314 
315  test++;
316  BEAST_EXPECT(test.fee() == 21);
317  ++test;
318  BEAST_EXPECT(test.fee() == 22);
319  test--;
320  BEAST_EXPECT(test.fee() == 21);
321  --test;
322  BEAST_EXPECT(test.fee() == 20);
323 
324  test *= 5;
325  BEAST_EXPECT(test.fee() == 100);
326  test /= 2;
327  BEAST_EXPECT(test.fee() == 50);
328  /* illegal with floating
329  test %= 13;
330  BEAST_EXPECT(test.fee() == 11);
331  */
332 
333  // legal with signed
334  test = -test;
335  BEAST_EXPECT(test.fee() == -50);
336  BEAST_EXPECT(test.signum() == -1);
337  BEAST_EXPECT(to_string(test) == "-50.000000");
338 
339  BEAST_EXPECT(test);
340  test = 0;
341  BEAST_EXPECT(!test);
342  BEAST_EXPECT(test.signum() == 0);
343  test = targetSame;
344  BEAST_EXPECT(test.signum() == 1);
345  BEAST_EXPECT(to_string(test) == "200.000000");
346  }
347  }
348 
349 public:
350  void
351  run() override
352  {
353  BEAST_EXPECT(INITIAL_XRP.drops() == 100'000'000'000'000'000);
354  BEAST_EXPECT(INITIAL_XRP == XRPAmount{100'000'000'000'000'000});
355 
356  testTypes();
357  testJson();
358  testFunctions();
359  }
360 };
361 
362 BEAST_DEFINE_TESTSUITE(feeunits, ripple_basics, ripple);
363 
364 } // namespace test
365 } // namespace ripple
std::is_same_v
T is_same_v
ripple::test::feeunits_test::testFunctions
void testFunctions()
Definition: FeeUnits_test.cpp:170
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:104
Json::intValue
@ intValue
signed integer value
Definition: json_value.h:37
ripple::test::feeunits_test::run
void run() override
Definition: FeeUnits_test.cpp:351
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:468
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