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  unexpected(
310  c != Currency(from_hex_text<Currency>(cur)),
311  "check custom currency");
312  }
313 
314  //--------------------------------------------------------------------------
315 
316  void
318  {
319  testcase("custom currency");
320  STAmount zeroSt(noIssue()), one(noIssue(), 1), hundred(noIssue(), 100);
321  unexpected(serializeAndDeserialize(zeroSt) != zeroSt, "STAmount fail");
322  unexpected(serializeAndDeserialize(one) != one, "STAmount fail");
323  unexpected(
324  serializeAndDeserialize(hundred) != hundred, "STAmount fail");
325  unexpected(zeroSt.native(), "STAmount fail");
326  unexpected(hundred.native(), "STAmount fail");
327  unexpected(zeroSt != beast::zero, "STAmount fail");
328  unexpected(one == beast::zero, "STAmount fail");
329  unexpected(hundred == beast::zero, "STAmount fail");
330  unexpected((zeroSt < zeroSt), "STAmount fail");
331  unexpected(!(zeroSt < one), "STAmount fail");
332  unexpected(!(zeroSt < hundred), "STAmount fail");
333  unexpected((one < zeroSt), "STAmount fail");
334  unexpected((one < one), "STAmount fail");
335  unexpected(!(one < hundred), "STAmount fail");
336  unexpected((hundred < zeroSt), "STAmount fail");
337  unexpected((hundred < one), "STAmount fail");
338  unexpected((hundred < hundred), "STAmount fail");
339  unexpected((zeroSt > zeroSt), "STAmount fail");
340  unexpected((zeroSt > one), "STAmount fail");
341  unexpected((zeroSt > hundred), "STAmount fail");
342  unexpected(!(one > zeroSt), "STAmount fail");
343  unexpected((one > one), "STAmount fail");
344  unexpected((one > hundred), "STAmount fail");
345  unexpected(!(hundred > zeroSt), "STAmount fail");
346  unexpected(!(hundred > one), "STAmount fail");
347  unexpected((hundred > hundred), "STAmount fail");
348  unexpected(!(zeroSt <= zeroSt), "STAmount fail");
349  unexpected(!(zeroSt <= one), "STAmount fail");
350  unexpected(!(zeroSt <= hundred), "STAmount fail");
351  unexpected((one <= zeroSt), "STAmount fail");
352  unexpected(!(one <= one), "STAmount fail");
353  unexpected(!(one <= hundred), "STAmount fail");
354  unexpected((hundred <= zeroSt), "STAmount fail");
355  unexpected((hundred <= one), "STAmount fail");
356  unexpected(!(hundred <= hundred), "STAmount fail");
357  unexpected(!(zeroSt >= zeroSt), "STAmount fail");
358  unexpected((zeroSt >= one), "STAmount fail");
359  unexpected((zeroSt >= hundred), "STAmount fail");
360  unexpected(!(one >= zeroSt), "STAmount fail");
361  unexpected(!(one >= one), "STAmount fail");
362  unexpected((one >= hundred), "STAmount fail");
363  unexpected(!(hundred >= zeroSt), "STAmount fail");
364  unexpected(!(hundred >= one), "STAmount fail");
365  unexpected(!(hundred >= hundred), "STAmount fail");
366  unexpected(!(zeroSt == zeroSt), "STAmount fail");
367  unexpected((zeroSt == one), "STAmount fail");
368  unexpected((zeroSt == hundred), "STAmount fail");
369  unexpected((one == zeroSt), "STAmount fail");
370  unexpected(!(one == one), "STAmount fail");
371  unexpected((one == hundred), "STAmount fail");
372  unexpected((hundred == zeroSt), "STAmount fail");
373  unexpected((hundred == one), "STAmount fail");
374  unexpected(!(hundred == hundred), "STAmount fail");
375  unexpected((zeroSt != zeroSt), "STAmount fail");
376  unexpected(!(zeroSt != one), "STAmount fail");
377  unexpected(!(zeroSt != hundred), "STAmount fail");
378  unexpected(!(one != zeroSt), "STAmount fail");
379  unexpected((one != one), "STAmount fail");
380  unexpected(!(one != hundred), "STAmount fail");
381  unexpected(!(hundred != zeroSt), "STAmount fail");
382  unexpected(!(hundred != one), "STAmount fail");
383  unexpected((hundred != hundred), "STAmount fail");
384  unexpected(STAmount(noIssue()).getText() != "0", "STAmount fail");
385  unexpected(STAmount(noIssue(), 31).getText() != "31", "STAmount fail");
386  unexpected(
387  STAmount(noIssue(), 31, 1).getText() != "310", "STAmount fail");
388  unexpected(
389  STAmount(noIssue(), 31, -1).getText() != "3.1", "STAmount fail");
390  unexpected(
391  STAmount(noIssue(), 31, -2).getText() != "0.31", "STAmount fail");
392  unexpected(
393  multiply(STAmount(noIssue(), 20), STAmount(3), noIssue())
394  .getText() != "60",
395  "STAmount multiply fail 1");
396  unexpected(
397  multiply(STAmount(noIssue(), 20), STAmount(3), xrpIssue())
398  .getText() != "60",
399  "STAmount multiply fail 2");
400  unexpected(
401  multiply(STAmount(20), STAmount(3), noIssue()).getText() != "60",
402  "STAmount multiply fail 3");
403  unexpected(
404  multiply(STAmount(20), STAmount(3), xrpIssue()).getText() != "60",
405  "STAmount multiply fail 4");
406 
407  if (divide(STAmount(noIssue(), 60), STAmount(3), noIssue()).getText() !=
408  "20")
409  {
410  log << "60/3 = "
411  << divide(STAmount(noIssue(), 60), STAmount(3), noIssue())
412  .getText();
413  fail("STAmount divide fail");
414  }
415  else
416  {
417  pass();
418  }
419 
420  unexpected(
421  divide(STAmount(noIssue(), 60), STAmount(3), xrpIssue())
422  .getText() != "20",
423  "STAmount divide fail");
424 
425  unexpected(
426  divide(STAmount(noIssue(), 60), STAmount(noIssue(), 3), noIssue())
427  .getText() != "20",
428  "STAmount divide fail");
429 
430  unexpected(
431  divide(STAmount(noIssue(), 60), STAmount(noIssue(), 3), xrpIssue())
432  .getText() != "20",
433  "STAmount divide fail");
434 
435  STAmount a1(noIssue(), 60), a2(noIssue(), 10, -1);
436 
437  unexpected(
438  divide(a2, a1, noIssue()) != amountFromQuality(getRate(a1, a2)),
439  "STAmount setRate(getRate) fail");
440 
441  unexpected(
442  divide(a1, a2, noIssue()) != amountFromQuality(getRate(a2, a1)),
443  "STAmount setRate(getRate) fail");
444  }
445 
446  //--------------------------------------------------------------------------
447 
448  void
450  {
451  testcase("arithmetic");
452 
453  // Test currency multiplication and division operations such as
454  // convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed,
455  // and getNeeded
456 
457  unexpected(
458  getRate(STAmount(1), STAmount(10)) !=
459  (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
460  "STAmount getRate fail 1");
461 
462  unexpected(
463  getRate(STAmount(10), STAmount(1)) !=
464  (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
465  "STAmount getRate fail 2");
466 
467  unexpected(
468  getRate(STAmount(noIssue(), 1), STAmount(noIssue(), 10)) !=
469  (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
470  "STAmount getRate fail 3");
471 
472  unexpected(
473  getRate(STAmount(noIssue(), 10), STAmount(noIssue(), 1)) !=
474  (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
475  "STAmount getRate fail 4");
476 
477  unexpected(
478  getRate(STAmount(noIssue(), 1), STAmount(10)) !=
479  (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
480  "STAmount getRate fail 5");
481 
482  unexpected(
483  getRate(STAmount(noIssue(), 10), STAmount(1)) !=
484  (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
485  "STAmount getRate fail 6");
486 
487  unexpected(
488  getRate(STAmount(1), STAmount(noIssue(), 10)) !=
489  (((100ull - 14) << (64 - 8)) | 1000000000000000ull),
490  "STAmount getRate fail 7");
491 
492  unexpected(
493  getRate(STAmount(10), STAmount(noIssue(), 1)) !=
494  (((100ull - 16) << (64 - 8)) | 1000000000000000ull),
495  "STAmount getRate fail 8");
496 
497  roundTest(1, 3, 3);
498  roundTest(2, 3, 9);
499  roundTest(1, 7, 21);
500  roundTest(1, 2, 4);
501  roundTest(3, 9, 18);
502  roundTest(7, 11, 44);
503 
504  for (int i = 0; i <= 100000; ++i)
505  {
506  mulTest(rand_int(10000000), rand_int(10000000));
507  }
508  }
509 
510  //--------------------------------------------------------------------------
511 
512  void
514  {
515  testcase("underflow");
516 
517  STAmount bigNative(STAmount::cMaxNative / 2);
518  STAmount bigValue(
519  noIssue(),
522  STAmount smallValue(
523  noIssue(),
526  STAmount zeroSt(noIssue(), 0);
527 
528  STAmount smallXsmall = multiply(smallValue, smallValue, noIssue());
529 
530  BEAST_EXPECT(smallXsmall == beast::zero);
531 
532  STAmount bigDsmall = divide(smallValue, bigValue, noIssue());
533 
534  BEAST_EXPECT(bigDsmall == beast::zero);
535 
536  BEAST_EXPECT(bigDsmall == beast::zero);
537 
538  bigDsmall = divide(smallValue, bigValue, xrpIssue());
539 
540  BEAST_EXPECT(bigDsmall == beast::zero);
541 
542  bigDsmall = divide(smallValue, bigNative, xrpIssue());
543 
544  BEAST_EXPECT(bigDsmall == beast::zero);
545 
546  // very bad offer
547  std::uint64_t r = getRate(smallValue, bigValue);
548 
549  BEAST_EXPECT(r == 0);
550 
551  // very good offer
552  r = getRate(bigValue, smallValue);
553 
554  BEAST_EXPECT(r == 0);
555  }
556 
557  //--------------------------------------------------------------------------
558 
559  void
561  {
562  // VFALCO TODO There are no actual tests here, just printed output?
563  // Change this to actually do something.
564 
565 #if 0
566  beginTestCase ("rounding ");
567 
568  std::uint64_t value = 25000000000000000ull;
569  int offset = -14;
570  canonicalizeRound (false, value, offset, true);
571 
572  STAmount one (noIssue(), 1);
573  STAmount two (noIssue(), 2);
574  STAmount three (noIssue(), 3);
575 
576  STAmount oneThird1 = divRound (one, three, noIssue(), false);
577  STAmount oneThird2 = divide (one, three, noIssue());
578  STAmount oneThird3 = divRound (one, three, noIssue(), true);
579  log << oneThird1;
580  log << oneThird2;
581  log << oneThird3;
582 
583  STAmount twoThird1 = divRound (two, three, noIssue(), false);
584  STAmount twoThird2 = divide (two, three, noIssue());
585  STAmount twoThird3 = divRound (two, three, noIssue(), true);
586  log << twoThird1;
587  log << twoThird2;
588  log << twoThird3;
589 
590  STAmount oneA = mulRound (oneThird1, three, noIssue(), false);
591  STAmount oneB = multiply (oneThird2, three, noIssue());
592  STAmount oneC = mulRound (oneThird3, three, noIssue(), true);
593  log << oneA;
594  log << oneB;
595  log << oneC;
596 
597  STAmount fourThirdsB = twoThird2 + twoThird2;
598  log << fourThirdsA;
599  log << fourThirdsB;
600  log << fourThirdsC;
601 
602  STAmount dripTest1 = mulRound (twoThird2, two, xrpIssue (), false);
603  STAmount dripTest2 = multiply (twoThird2, two, xrpIssue ());
604  STAmount dripTest3 = mulRound (twoThird2, two, xrpIssue (), true);
605  log << dripTest1;
606  log << dripTest2;
607  log << dripTest3;
608 #endif
609  }
610 
611  void
613  {
614  testcase("STAmount to XRPAmount conversions");
615 
616  Issue const usd{Currency(0x5553440000000000), AccountID(0x4985601)};
617  Issue const xrp{xrpIssue()};
618 
619  for (std::uint64_t drops = 100000000000000000; drops != 1;
620  drops = drops / 10)
621  {
622  auto const t = amountFromString(xrp, std::to_string(drops));
623  auto const s = t.xrp();
624  BEAST_EXPECT(s.drops() == drops);
625  BEAST_EXPECT(t == STAmount(XRPAmount(drops)));
626  BEAST_EXPECT(s == XRPAmount(drops));
627  }
628 
629  try
630  {
631  auto const t = amountFromString(usd, "136500");
632  fail(to_string(t.xrp()));
633  }
634  catch (std::logic_error const&)
635  {
636  pass();
637  }
638  catch (std::exception const&)
639  {
640  fail("wrong exception");
641  }
642  }
643 
644  void
646  {
647  testcase("STAmount to IOUAmount conversions");
648 
649  Issue const usd{Currency(0x5553440000000000), AccountID(0x4985601)};
650  Issue const xrp{xrpIssue()};
651 
652  for (std::uint64_t dollars = 10000000000; dollars != 1;
653  dollars = dollars / 10)
654  {
655  auto const t = amountFromString(usd, std::to_string(dollars));
656  auto const s = t.iou();
657  BEAST_EXPECT(t == STAmount(s, usd));
658  BEAST_EXPECT(s.mantissa() == t.mantissa());
659  BEAST_EXPECT(s.exponent() == t.exponent());
660  }
661 
662  try
663  {
664  auto const t = amountFromString(xrp, "136500");
665  fail(to_string(t.iou()));
666  }
667  catch (std::logic_error const&)
668  {
669  pass();
670  }
671  catch (std::exception const&)
672  {
673  fail("wrong exception");
674  }
675  }
676 
677  //--------------------------------------------------------------------------
678 
679  void
680  run() override
681  {
682  testSetValue();
685  testArithmetic();
686  testUnderflow();
687  testRounding();
688  testConvertXRP();
689  testConvertIOU();
690  }
691 };
692 
693 BEAST_DEFINE_TESTSUITE(STAmount, ripple_data, ripple);
694 
695 } // 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:612
std::string
STL class.
ripple::STAmount::cMinValue
static const std::uint64_t cMinValue
Definition: STAmount.h:63
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:332
ripple::STAmount_test::testCustomCurrency
void testCustomCurrency()
Definition: STAmount_test.cpp:317
ripple::STAmount::mantissa
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:192
ripple::STAmount_test
Definition: STAmount_test.cpp:27
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:510
ripple::STAmount::cMaxNative
static const std::uint64_t cMaxNative
Definition: STAmount.h:65
ripple::Issue::currency
Currency currency
Definition: Issue.h:37
ripple::STAmount::cMinOffset
static const int cMinOffset
Definition: STAmount.h:59
ripple::noIssue
Issue const & noIssue()
Returns an asset specifier that represents no account and currency.
Definition: Issue.h:105
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:42
ripple::mulRound
STAmount mulRound(STAmount const &v1, STAmount const &v2, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1199
ripple::getRate
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
Definition: STAmount.cpp:440
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:77
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:487
ripple::STAmount::exponent
int exponent() const noexcept
Definition: STAmount.h:177
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:1285
std::to_string
T to_string(T... args)
ripple::STAmount
Definition: STAmount.h:42
ripple::STAmount_test::testRounding
void testRounding()
Definition: STAmount_test.cpp:560
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:513
ripple::SerialIter
Definition: Serializer.h:308
std::logic_error
STL class.
std::uint64_t
ripple::canonicalizeRound
static void canonicalizeRound(bool native, std::uint64_t &value, int &offset)
Definition: STAmount.cpp:1164
ripple::amountFromQuality
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:749
ripple::multiply
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:38
ripple::Serializer
Definition: Serializer.h:39
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:182
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:761
ripple::STAmount_test::run
void run() override
Definition: STAmount_test.cpp:680
ripple::STAmount::unchecked
Definition: STAmount.h:77
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:197
ripple::STAmount::add
void add(Serializer &s) const override
Definition: STAmount.cpp:602
ripple::STAmount::negative
bool negative() const noexcept
Definition: STAmount.h:187
ripple::xrpIssue
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition: Issue.h:97
ripple::STAmount_test::testConvertIOU
void testConvertIOU()
Definition: STAmount_test.cpp:645
ripple::STAmount::cMaxOffset
static const int cMaxOffset
Definition: STAmount.h:60
ripple::STAmount_test::testArithmetic
void testArithmetic()
Definition: STAmount_test.cpp:449
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:64
ripple::XRPAmount
Definition: XRPAmount.h:46