rippled
STAmount_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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 
20 #include <ripple/basics/Log.h>
21 #include <ripple/basics/random.h>
22 #include <ripple/beast/unit_test.h>
23 #include <ripple/protocol/STAmount.h>
24 
25 namespace ripple {
26 
27 class STAmount_test : public beast::unit_test::suite
28 {
29 public:
30  static STAmount
32  {
33  Serializer ser;
34  s.add(ser);
35 
36  SerialIter sit(ser.slice());
37  return STAmount(sit, sfGeneric);
38  }
39 
40  //--------------------------------------------------------------------------
41  STAmount
42  roundSelf(STAmount const& amount)
43  {
44  if (amount.native())
45  return amount;
46 
47  std::uint64_t mantissa = amount.mantissa();
48  std::uint64_t valueDigits = mantissa % 1000000000;
49 
50  if (valueDigits == 1)
51  {
52  mantissa--;
53 
54  if (mantissa < STAmount::cMinValue)
55  return {
56  amount.issue(),
57  mantissa,
58  amount.exponent(),
59  amount.negative()};
60 
61  return {
62  amount.issue(),
63  mantissa,
64  amount.exponent(),
65  amount.native(),
66  amount.negative(),
68  }
69 
70  if (valueDigits == 999999999)
71  {
72  mantissa++;
73 
74  if (mantissa > STAmount::cMaxValue)
75  return {
76  amount.issue(),
77  mantissa,
78  amount.exponent(),
79  amount.negative()};
80 
81  return {
82  amount.issue(),
83  mantissa,
84  amount.exponent(),
85  amount.native(),
86  amount.negative(),
88  }
89 
90  return amount;
91  }
92 
93  void
94  roundTest(int n, int d, int m)
95  {
96  // check STAmount rounding
97  STAmount num(noIssue(), n);
98  STAmount den(noIssue(), d);
99  STAmount mul(noIssue(), m);
100  STAmount quot = divide(STAmount(n), STAmount(d), noIssue());
101  STAmount res = roundSelf(multiply(quot, mul, noIssue()));
102 
103  BEAST_EXPECT(!res.native());
104 
105  STAmount cmp(noIssue(), (n * m) / d);
106 
107  BEAST_EXPECT(!cmp.native());
108 
109  BEAST_EXPECT(cmp.issue().currency == res.issue().currency);
110 
111  if (res != cmp)
112  {
113  log << "(" << num.getText() << "/" << den.getText() << ") X "
114  << mul.getText() << " = " << res.getText() << " not "
115  << cmp.getText();
116  fail("Rounding");
117  return;
118  }
119  }
120 
121  void
122  mulTest(int a, int b)
123  {
124  STAmount aa(noIssue(), a);
125  STAmount bb(noIssue(), b);
126  STAmount prod1(multiply(aa, bb, noIssue()));
127 
128  BEAST_EXPECT(!prod1.native());
129 
130  STAmount prod2(
131  noIssue(),
132  static_cast<std::uint64_t>(a) * static_cast<std::uint64_t>(b));
133 
134  if (prod1 != prod2)
135  {
136  log << "nn(" << aa.getFullText() << " * " << bb.getFullText()
137  << ") = " << prod1.getFullText() << " not "
138  << prod2.getFullText();
139  fail("Multiplication result is not exact");
140  }
141  }
142 
143  //--------------------------------------------------------------------------
144 
145  void
147  std::string const& value,
148  Issue const& issue,
149  bool success = true)
150  {
151  try
152  {
153  STAmount const amount = amountFromString(issue, value);
154  BEAST_EXPECT(amount.getText() == value);
155  }
156  catch (std::exception const&)
157  {
158  BEAST_EXPECT(!success);
159  }
160  }
161 
162  void
164  {
165  {
166  testcase("set value (native)");
167 
168  Issue const xrp(xrpIssue());
169 
170  // fractional XRP (i.e. drops)
171  testSetValue("1", xrp);
172  testSetValue("22", xrp);
173  testSetValue("333", xrp);
174  testSetValue("4444", xrp);
175  testSetValue("55555", xrp);
176  testSetValue("666666", xrp);
177 
178  // 1 XRP up to 100 billion, in powers of 10 (in drops)
179  testSetValue("1000000", xrp);
180  testSetValue("10000000", xrp);
181  testSetValue("100000000", xrp);
182  testSetValue("1000000000", xrp);
183  testSetValue("10000000000", xrp);
184  testSetValue("100000000000", xrp);
185  testSetValue("1000000000000", xrp);
186  testSetValue("10000000000000", xrp);
187  testSetValue("100000000000000", xrp);
188  testSetValue("1000000000000000", xrp);
189  testSetValue("10000000000000000", xrp);
190  testSetValue("100000000000000000", xrp);
191 
192  // Invalid native values:
193  testSetValue("1.1", xrp, false);
194  testSetValue("100000000000000001", xrp, false);
195  testSetValue("1000000000000000000", xrp, false);
196  }
197 
198  {
199  testcase("set value (iou)");
200 
201  Issue const usd(Currency(0x5553440000000000), AccountID(0x4985601));
202 
203  testSetValue("1", usd);
204  testSetValue("10", usd);
205  testSetValue("100", usd);
206  testSetValue("1000", usd);
207  testSetValue("10000", usd);
208  testSetValue("100000", usd);
209  testSetValue("1000000", usd);
210  testSetValue("10000000", usd);
211  testSetValue("100000000", usd);
212  testSetValue("1000000000", usd);
213  testSetValue("10000000000", usd);
214 
215  testSetValue("1234567.1", usd);
216  testSetValue("1234567.12", usd);
217  testSetValue("1234567.123", usd);
218  testSetValue("1234567.1234", usd);
219  testSetValue("1234567.12345", usd);
220  testSetValue("1234567.123456", usd);
221  testSetValue("1234567.1234567", usd);
222  testSetValue("1234567.12345678", usd);
223  testSetValue("1234567.123456789", usd);
224  }
225  }
226 
227  //--------------------------------------------------------------------------
228 
229  void
231  {
232  testcase("native currency");
233  STAmount zeroSt, one(1), hundred(100);
234  // VFALCO NOTE Why repeat "STAmount fail" so many times??
235  unexpected(serializeAndDeserialize(zeroSt) != zeroSt, "STAmount fail");
236  unexpected(serializeAndDeserialize(one) != one, "STAmount fail");
237  unexpected(
238  serializeAndDeserialize(hundred) != hundred, "STAmount fail");
239  unexpected(!zeroSt.native(), "STAmount fail");
240  unexpected(!hundred.native(), "STAmount fail");
241  unexpected(zeroSt != beast::zero, "STAmount fail");
242  unexpected(one == beast::zero, "STAmount fail");
243  unexpected(hundred == beast::zero, "STAmount fail");
244  unexpected((zeroSt < zeroSt), "STAmount fail");
245  unexpected(!(zeroSt < one), "STAmount fail");
246  unexpected(!(zeroSt < hundred), "STAmount fail");
247  unexpected((one < zeroSt), "STAmount fail");
248  unexpected((one < one), "STAmount fail");
249  unexpected(!(one < hundred), "STAmount fail");
250  unexpected((hundred < zeroSt), "STAmount fail");
251  unexpected((hundred < one), "STAmount fail");
252  unexpected((hundred < hundred), "STAmount fail");
253  unexpected((zeroSt > zeroSt), "STAmount fail");
254  unexpected((zeroSt > one), "STAmount fail");
255  unexpected((zeroSt > hundred), "STAmount fail");
256  unexpected(!(one > zeroSt), "STAmount fail");
257  unexpected((one > one), "STAmount fail");
258  unexpected((one > hundred), "STAmount fail");
259  unexpected(!(hundred > zeroSt), "STAmount fail");
260  unexpected(!(hundred > one), "STAmount fail");
261  unexpected((hundred > hundred), "STAmount fail");
262  unexpected(!(zeroSt <= zeroSt), "STAmount fail");
263  unexpected(!(zeroSt <= one), "STAmount fail");
264  unexpected(!(zeroSt <= hundred), "STAmount fail");
265  unexpected((one <= zeroSt), "STAmount fail");
266  unexpected(!(one <= one), "STAmount fail");
267  unexpected(!(one <= hundred), "STAmount fail");
268  unexpected((hundred <= zeroSt), "STAmount fail");
269  unexpected((hundred <= one), "STAmount fail");
270  unexpected(!(hundred <= hundred), "STAmount fail");
271  unexpected(!(zeroSt >= zeroSt), "STAmount fail");
272  unexpected((zeroSt >= one), "STAmount fail");
273  unexpected((zeroSt >= hundred), "STAmount fail");
274  unexpected(!(one >= zeroSt), "STAmount fail");
275  unexpected(!(one >= one), "STAmount fail");
276  unexpected((one >= hundred), "STAmount fail");
277  unexpected(!(hundred >= zeroSt), "STAmount fail");
278  unexpected(!(hundred >= one), "STAmount fail");
279  unexpected(!(hundred >= hundred), "STAmount fail");
280  unexpected(!(zeroSt == zeroSt), "STAmount fail");
281  unexpected((zeroSt == one), "STAmount fail");
282  unexpected((zeroSt == hundred), "STAmount fail");
283  unexpected((one == zeroSt), "STAmount fail");
284  unexpected(!(one == one), "STAmount fail");
285  unexpected((one == hundred), "STAmount fail");
286  unexpected((hundred == zeroSt), "STAmount fail");
287  unexpected((hundred == one), "STAmount fail");
288  unexpected(!(hundred == hundred), "STAmount fail");
289  unexpected((zeroSt != zeroSt), "STAmount fail");
290  unexpected(!(zeroSt != one), "STAmount fail");
291  unexpected(!(zeroSt != hundred), "STAmount fail");
292  unexpected(!(one != zeroSt), "STAmount fail");
293  unexpected((one != one), "STAmount fail");
294  unexpected(!(one != hundred), "STAmount fail");
295  unexpected(!(hundred != zeroSt), "STAmount fail");
296  unexpected(!(hundred != one), "STAmount fail");
297  unexpected((hundred != hundred), "STAmount fail");
298  unexpected(STAmount().getText() != "0", "STAmount fail");
299  unexpected(STAmount(31).getText() != "31", "STAmount fail");
300  unexpected(STAmount(310).getText() != "310", "STAmount fail");
301  unexpected(to_string(Currency()) != "XRP", "cHC(XRP)");
302  Currency c;
303  unexpected(!to_currency(c, "USD"), "create USD currency");
304  unexpected(to_string(c) != "USD", "check USD currency");
305 
306  const std::string cur = "015841551A748AD2C1F76FF6ECB0CCCD00000000";
307  unexpected(!to_currency(c, cur), "create custom currency");
308  unexpected(to_string(c) != cur, "check custom currency");
309  }
310 
311  //--------------------------------------------------------------------------
312 
313  void
315  {
316  testcase("custom currency");
317  STAmount zeroSt(noIssue()), one(noIssue(), 1), hundred(noIssue(), 100);
318  unexpected(serializeAndDeserialize(zeroSt) != zeroSt, "STAmount fail");
319  unexpected(serializeAndDeserialize(one) != one, "STAmount fail");
320  unexpected(
321  serializeAndDeserialize(hundred) != hundred, "STAmount fail");
322  unexpected(zeroSt.native(), "STAmount fail");
323  unexpected(hundred.native(), "STAmount fail");
324  unexpected(zeroSt != beast::zero, "STAmount fail");
325  unexpected(one == beast::zero, "STAmount fail");
326  unexpected(hundred == beast::zero, "STAmount fail");
327  unexpected((zeroSt < zeroSt), "STAmount fail");
328  unexpected(!(zeroSt < one), "STAmount fail");
329  unexpected(!(zeroSt < hundred), "STAmount fail");
330  unexpected((one < zeroSt), "STAmount fail");
331  unexpected((one < one), "STAmount fail");
332  unexpected(!(one < hundred), "STAmount fail");
333  unexpected((hundred < zeroSt), "STAmount fail");
334  unexpected((hundred < one), "STAmount fail");
335  unexpected((hundred < hundred), "STAmount fail");
336  unexpected((zeroSt > zeroSt), "STAmount fail");
337  unexpected((zeroSt > one), "STAmount fail");
338  unexpected((zeroSt > hundred), "STAmount fail");
339  unexpected(!(one > zeroSt), "STAmount fail");
340  unexpected((one > one), "STAmount fail");
341  unexpected((one > hundred), "STAmount fail");
342  unexpected(!(hundred > zeroSt), "STAmount fail");
343  unexpected(!(hundred > one), "STAmount fail");
344  unexpected((hundred > hundred), "STAmount fail");
345  unexpected(!(zeroSt <= zeroSt), "STAmount fail");
346  unexpected(!(zeroSt <= one), "STAmount fail");
347  unexpected(!(zeroSt <= hundred), "STAmount fail");
348  unexpected((one <= zeroSt), "STAmount fail");
349  unexpected(!(one <= one), "STAmount fail");
350  unexpected(!(one <= hundred), "STAmount fail");
351  unexpected((hundred <= zeroSt), "STAmount fail");
352  unexpected((hundred <= one), "STAmount fail");
353  unexpected(!(hundred <= hundred), "STAmount fail");
354  unexpected(!(zeroSt >= zeroSt), "STAmount fail");
355  unexpected((zeroSt >= one), "STAmount fail");
356  unexpected((zeroSt >= hundred), "STAmount fail");
357  unexpected(!(one >= zeroSt), "STAmount fail");
358  unexpected(!(one >= one), "STAmount fail");
359  unexpected((one >= hundred), "STAmount fail");
360  unexpected(!(hundred >= zeroSt), "STAmount fail");
361  unexpected(!(hundred >= one), "STAmount fail");
362  unexpected(!(hundred >= hundred), "STAmount fail");
363  unexpected(!(zeroSt == zeroSt), "STAmount fail");
364  unexpected((zeroSt == one), "STAmount fail");
365  unexpected((zeroSt == hundred), "STAmount fail");
366  unexpected((one == zeroSt), "STAmount fail");
367  unexpected(!(one == one), "STAmount fail");
368  unexpected((one == hundred), "STAmount fail");
369  unexpected((hundred == zeroSt), "STAmount fail");
370  unexpected((hundred == one), "STAmount fail");
371  unexpected(!(hundred == hundred), "STAmount fail");
372  unexpected((zeroSt != zeroSt), "STAmount fail");
373  unexpected(!(zeroSt != one), "STAmount fail");
374  unexpected(!(zeroSt != hundred), "STAmount fail");
375  unexpected(!(one != zeroSt), "STAmount fail");
376  unexpected((one != one), "STAmount fail");
377  unexpected(!(one != hundred), "STAmount fail");
378  unexpected(!(hundred != zeroSt), "STAmount fail");
379  unexpected(!(hundred != one), "STAmount fail");
380  unexpected((hundred != hundred), "STAmount fail");
381  unexpected(STAmount(noIssue()).getText() != "0", "STAmount fail");
382  unexpected(STAmount(noIssue(), 31).getText() != "31", "STAmount fail");
383  unexpected(
384  STAmount(noIssue(), 31, 1).getText() != "310", "STAmount fail");
385  unexpected(
386  STAmount(noIssue(), 31, -1).getText() != "3.1", "STAmount fail");
387  unexpected(
388  STAmount(noIssue(), 31, -2).getText() != "0.31", "STAmount fail");
389  unexpected(
390  multiply(STAmount(noIssue(), 20), STAmount(3), noIssue())
391  .getText() != "60",
392  "STAmount multiply fail 1");
393  unexpected(
394  multiply(STAmount(noIssue(), 20), STAmount(3), xrpIssue())
395  .getText() != "60",
396  "STAmount multiply fail 2");
397  unexpected(
398  multiply(STAmount(20), STAmount(3), noIssue()).getText() != "60",
399  "STAmount multiply fail 3");
400  unexpected(
401  multiply(STAmount(20), STAmount(3), xrpIssue()).getText() != "60",
402  "STAmount multiply fail 4");
403 
404  if (divide(STAmount(noIssue(), 60), STAmount(3), noIssue()).getText() !=
405  "20")
406  {
407  log << "60/3 = "
408  << divide(STAmount(noIssue(), 60), STAmount(3), noIssue())
409  .getText();
410  fail("STAmount divide fail");
411  }
412  else
413  {
414  pass();
415  }
416 
417  unexpected(
418  divide(STAmount(noIssue(), 60), STAmount(3), xrpIssue())
419  .getText() != "20",
420  "STAmount divide fail");
421 
422  unexpected(
423  divide(STAmount(noIssue(), 60), STAmount(noIssue(), 3), noIssue())
424  .getText() != "20",
425  "STAmount divide fail");
426 
427  unexpected(
428  divide(STAmount(noIssue(), 60), STAmount(noIssue(), 3), xrpIssue())
429  .getText() != "20",
430  "STAmount divide fail");
431 
432  STAmount a1(noIssue(), 60), a2(noIssue(), 10, -1);
433 
434  unexpected(
435  divide(a2, a1, noIssue()) != amountFromQuality(getRate(a1, a2)),
436  "STAmount setRate(getRate) fail");
437 
438  unexpected(
439  divide(a1, a2, noIssue()) != amountFromQuality(getRate(a2, a1)),
440  "STAmount setRate(getRate) fail");
441  }
442 
443  //--------------------------------------------------------------------------
444 
445  void
447  {
448  testcase("arithmetic");
449 
450  // Test currency multiplication and division operations such as
451  // convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed,
452  // and getNeeded
453 
454  unexpected(
455  getRate(STAmount(1), STAmount(10)) !=
456  (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
457  "STAmount getRate fail 1");
458 
459  unexpected(
460  getRate(STAmount(10), STAmount(1)) !=
461  (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
462  "STAmount getRate fail 2");
463 
464  unexpected(
465  getRate(STAmount(noIssue(), 1), STAmount(noIssue(), 10)) !=
466  (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
467  "STAmount getRate fail 3");
468 
469  unexpected(
470  getRate(STAmount(noIssue(), 10), STAmount(noIssue(), 1)) !=
471  (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
472  "STAmount getRate fail 4");
473 
474  unexpected(
475  getRate(STAmount(noIssue(), 1), STAmount(10)) !=
476  (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
477  "STAmount getRate fail 5");
478 
479  unexpected(
480  getRate(STAmount(noIssue(), 10), STAmount(1)) !=
481  (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
482  "STAmount getRate fail 6");
483 
484  unexpected(
485  getRate(STAmount(1), STAmount(noIssue(), 10)) !=
486  (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
487  "STAmount getRate fail 7");
488 
489  unexpected(
490  getRate(STAmount(10), STAmount(noIssue(), 1)) !=
491  (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
492  "STAmount getRate fail 8");
493 
494  roundTest(1, 3, 3);
495  roundTest(2, 3, 9);
496  roundTest(1, 7, 21);
497  roundTest(1, 2, 4);
498  roundTest(3, 9, 18);
499  roundTest(7, 11, 44);
500 
501  for (int i = 0; i <= 100000; ++i)
502  {
503  mulTest(rand_int(10000000), rand_int(10000000));
504  }
505  }
506 
507  //--------------------------------------------------------------------------
508 
509  void
511  {
512  testcase("underflow");
513 
514  STAmount bigNative(STAmount::cMaxNative / 2);
515  STAmount bigValue(
516  noIssue(),
519  STAmount smallValue(
520  noIssue(),
523  STAmount zeroSt(noIssue(), 0);
524 
525  STAmount smallXsmall = multiply(smallValue, smallValue, noIssue());
526 
527  BEAST_EXPECT(smallXsmall == beast::zero);
528 
529  STAmount bigDsmall = divide(smallValue, bigValue, noIssue());
530 
531  BEAST_EXPECT(bigDsmall == beast::zero);
532 
533  BEAST_EXPECT(bigDsmall == beast::zero);
534 
535  bigDsmall = divide(smallValue, bigValue, xrpIssue());
536 
537  BEAST_EXPECT(bigDsmall == beast::zero);
538 
539  bigDsmall = divide(smallValue, bigNative, xrpIssue());
540 
541  BEAST_EXPECT(bigDsmall == beast::zero);
542 
543  // very bad offer
544  std::uint64_t r = getRate(smallValue, bigValue);
545 
546  BEAST_EXPECT(r == 0);
547 
548  // very good offer
549  r = getRate(bigValue, smallValue);
550 
551  BEAST_EXPECT(r == 0);
552  }
553 
554  //--------------------------------------------------------------------------
555 
556  void
558  {
559  // VFALCO TODO There are no actual tests here, just printed output?
560  // Change this to actually do something.
561 
562 #if 0
563  beginTestCase ("rounding ");
564 
565  std::uint64_t value = 25000000000000000ull;
566  int offset = -14;
567  canonicalizeRound (false, value, offset, true);
568 
569  STAmount one (noIssue(), 1);
570  STAmount two (noIssue(), 2);
571  STAmount three (noIssue(), 3);
572 
573  STAmount oneThird1 = divRound (one, three, noIssue(), false);
574  STAmount oneThird2 = divide (one, three, noIssue());
575  STAmount oneThird3 = divRound (one, three, noIssue(), true);
576  log << oneThird1;
577  log << oneThird2;
578  log << oneThird3;
579 
580  STAmount twoThird1 = divRound (two, three, noIssue(), false);
581  STAmount twoThird2 = divide (two, three, noIssue());
582  STAmount twoThird3 = divRound (two, three, noIssue(), true);
583  log << twoThird1;
584  log << twoThird2;
585  log << twoThird3;
586 
587  STAmount oneA = mulRound (oneThird1, three, noIssue(), false);
588  STAmount oneB = multiply (oneThird2, three, noIssue());
589  STAmount oneC = mulRound (oneThird3, three, noIssue(), true);
590  log << oneA;
591  log << oneB;
592  log << oneC;
593 
594  STAmount fourThirdsB = twoThird2 + twoThird2;
595  log << fourThirdsA;
596  log << fourThirdsB;
597  log << fourThirdsC;
598 
599  STAmount dripTest1 = mulRound (twoThird2, two, xrpIssue (), false);
600  STAmount dripTest2 = multiply (twoThird2, two, xrpIssue ());
601  STAmount dripTest3 = mulRound (twoThird2, two, xrpIssue (), true);
602  log << dripTest1;
603  log << dripTest2;
604  log << dripTest3;
605 #endif
606  }
607 
608  void
610  {
611  testcase("STAmount to XRPAmount conversions");
612 
613  Issue const usd{Currency(0x5553440000000000), AccountID(0x4985601)};
614  Issue const xrp{xrpIssue()};
615 
616  for (std::uint64_t drops = 100000000000000000; drops != 1;
617  drops = drops / 10)
618  {
619  auto const t = amountFromString(xrp, std::to_string(drops));
620  auto const s = t.xrp();
621  BEAST_EXPECT(s.drops() == drops);
622  BEAST_EXPECT(t == STAmount(XRPAmount(drops)));
623  BEAST_EXPECT(s == XRPAmount(drops));
624  }
625 
626  try
627  {
628  auto const t = amountFromString(usd, "136500");
629  fail(to_string(t.xrp()));
630  }
631  catch (std::logic_error const&)
632  {
633  pass();
634  }
635  catch (std::exception const&)
636  {
637  fail("wrong exception");
638  }
639  }
640 
641  void
643  {
644  testcase("STAmount to IOUAmount conversions");
645 
646  Issue const usd{Currency(0x5553440000000000), AccountID(0x4985601)};
647  Issue const xrp{xrpIssue()};
648 
649  for (std::uint64_t dollars = 10000000000; dollars != 1;
650  dollars = dollars / 10)
651  {
652  auto const t = amountFromString(usd, std::to_string(dollars));
653  auto const s = t.iou();
654  BEAST_EXPECT(t == STAmount(s, usd));
655  BEAST_EXPECT(s.mantissa() == t.mantissa());
656  BEAST_EXPECT(s.exponent() == t.exponent());
657  }
658 
659  try
660  {
661  auto const t = amountFromString(xrp, "136500");
662  fail(to_string(t.iou()));
663  }
664  catch (std::logic_error const&)
665  {
666  pass();
667  }
668  catch (std::exception const&)
669  {
670  fail("wrong exception");
671  }
672  }
673 
674  //--------------------------------------------------------------------------
675 
676  void
677  run() override
678  {
679  testSetValue();
682  testArithmetic();
683  testUnderflow();
684  testRounding();
685  testConvertXRP();
686  testConvertIOU();
687  }
688 };
689 
690 BEAST_DEFINE_TESTSUITE(STAmount, ripple_data, ripple);
691 
692 } // namespace ripple
ripple::STAmount_test::roundSelf
STAmount roundSelf(STAmount const &amount)
Definition: STAmount_test.cpp:42
ripple::STAmount_test::roundTest
void roundTest(int n, int d, int m)
Definition: STAmount_test.cpp:94
ripple::to_currency
bool to_currency(Currency &currency, std::string const &code)
Tries to convert a string to a Currency, returns true on success.
Definition: UintTypes.cpp:80
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
ripple::STAmount_test::testConvertXRP
void testConvertXRP()
Definition: STAmount_test.cpp:609
std::string
STL class.
ripple::STAmount::cMinValue
static const std::uint64_t cMinValue
Definition: STAmount.h:66
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
std::exception
STL class.
ripple::STAmount_test::testSetValue
void testSetValue(std::string const &value, Issue const &issue, bool success=true)
Definition: STAmount_test.cpp:146
ripple::sfGeneric
const SField sfGeneric(access, 0)
Definition: SField.h:327
ripple::STAmount_test::testCustomCurrency
void testCustomCurrency()
Definition: STAmount_test.cpp:314
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:347
ripple::STAmount::mantissa
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:341
ripple::STAmount_test
Definition: STAmount_test.cpp:27
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:571
ripple::STAmount::cMaxNative
static const std::uint64_t cMaxNative
Definition: STAmount.h:68
ripple::Issue::currency
Currency currency
Definition: Issue.h:37
ripple::STAmount::cMinOffset
static const int cMinOffset
Definition: STAmount.h:62
ripple::noIssue
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition: Issue.h:103
ripple::mulRound
STAmount mulRound(STAmount const &v1, STAmount const &v2, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1305
ripple::getRate
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
Definition: STAmount.cpp:495
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:86
ripple::STAmount_test::mulTest
void mulTest(int a, int b)
Definition: STAmount_test.cpp:122
ripple::base_uint< 160, detail::CurrencyTag >
ripple::STAmount::getFullText
std::string getFullText() const override
Definition: STAmount.cpp:548
ripple::STAmount::exponent
int exponent() const noexcept
Definition: STAmount.h:323
ripple::rand_int
std::enable_if_t< std::is_integral< Integral >::value &&detail::is_engine< Engine >::value, Integral > rand_int(Engine &engine, Integral min, Integral max)
Return a uniformly distributed random integer.
Definition: ripple/basics/random.h:115
ripple::divRound
STAmount divRound(STAmount const &num, STAmount const &den, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1391
std::to_string
T to_string(T... args)
ripple::STAmount
Definition: STAmount.h:45
ripple::STAmount_test::testRounding
void testRounding()
Definition: STAmount_test.cpp:557
ripple::Serializer::slice
Slice slice() const noexcept
Definition: Serializer.h:63
ripple::STAmount_test::testNativeCurrency
void testNativeCurrency()
Definition: STAmount_test.cpp:230
ripple::STAmount_test::serializeAndDeserialize
static STAmount serializeAndDeserialize(STAmount const &s)
Definition: STAmount_test.cpp:31
ripple::STAmount_test::testUnderflow
void testUnderflow()
Definition: STAmount_test.cpp:510
ripple::SerialIter
Definition: Serializer.h:310
std::logic_error
STL class.
std::uint64_t
ripple::canonicalizeRound
static void canonicalizeRound(bool native, std::uint64_t &value, int &offset)
Definition: STAmount.cpp:1270
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:852
ripple::multiply
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:47
ripple::Serializer
Definition: Serializer.h:39
ripple::one
constexpr Number one
Definition: Number.cpp:169
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:329
ripple::Currency
base_uint< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition: UintTypes.h:56
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::amountFromString
STAmount amountFromString(Issue const &issue, std::string const &amount)
Definition: STAmount.cpp:864
ripple::STAmount_test::run
void run() override
Definition: STAmount_test.cpp:677
ripple::STAmount::unchecked
Definition: STAmount.h:80
ripple::STAmount::add
void add(Serializer &s) const override
Definition: STAmount.cpp:663
ripple::STAmount::negative
bool negative() const noexcept
Definition: STAmount.h:335
ripple::xrpIssue
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition: Issue.h:95
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::STAmount_test::testConvertIOU
void testConvertIOU()
Definition: STAmount_test.cpp:642
ripple::STAmount::cMaxOffset
static const int cMaxOffset
Definition: STAmount.h:63
ripple::STAmount_test::testArithmetic
void testArithmetic()
Definition: STAmount_test.cpp:446
ripple::STAmount_test::testSetValue
void testSetValue()
Definition: STAmount_test.cpp:163
ripple::AccountID
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition: AccountID.h:47
ripple::STAmount::cMaxValue
static const std::uint64_t cMaxValue
Definition: STAmount.h:67
ripple::XRPAmount
Definition: XRPAmount.h:46