rippled
STAmount.h
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 #ifndef RIPPLE_PROTOCOL_STAMOUNT_H_INCLUDED
21 #define RIPPLE_PROTOCOL_STAMOUNT_H_INCLUDED
22 
23 #include <ripple/basics/CountedObject.h>
24 #include <ripple/basics/IOUAmount.h>
25 #include <ripple/basics/LocalValue.h>
26 #include <ripple/basics/Number.h>
27 #include <ripple/basics/XRPAmount.h>
28 #include <ripple/protocol/Issue.h>
29 #include <ripple/protocol/SField.h>
30 #include <ripple/protocol/STBase.h>
31 #include <ripple/protocol/Serializer.h>
32 
33 namespace ripple {
34 
35 // Internal form:
36 // 1: If amount is zero, then value is zero and offset is -100
37 // 2: Otherwise:
38 // legal offset range is -96 to +80 inclusive
39 // value range is 10^15 to (10^16 - 1) inclusive
40 // amount = value * [10 ^ offset]
41 
42 // Wire form:
43 // High 8 bits are (offset+142), legal range is, 80 to 22 inclusive
44 // Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive
45 class STAmount final : public STBase, public CountedObject<STAmount>
46 {
47 public:
49  using exponent_type = int;
51 
52 private:
56  bool mIsNative; // A shorthand for isXRP(mIssue).
58 
59 public:
61 
62  static const int cMinOffset = -96;
63  static const int cMaxOffset = 80;
64 
65  // Maximum native value supported by the code
66  static const std::uint64_t cMinValue = 1000000000000000ull;
67  static const std::uint64_t cMaxValue = 9999999999999999ull;
68  static const std::uint64_t cMaxNative = 9000000000000000000ull;
69 
70  // Max native value on network.
71  static const std::uint64_t cMaxNativeN = 100000000000000000ull;
72  static const std::uint64_t cNotNative = 0x8000000000000000ull;
73  static const std::uint64_t cPosNative = 0x4000000000000000ull;
74 
75  static std::uint64_t const uRateOne;
76 
77  //--------------------------------------------------------------------------
78  STAmount(SerialIter& sit, SField const& name);
79 
80  struct unchecked
81  {
82  explicit unchecked() = default;
83  };
84 
85  // Do not call canonicalize
86  STAmount(
87  SField const& name,
88  Issue const& issue,
91  bool native,
92  bool negative,
93  unchecked);
94 
95  STAmount(
96  Issue const& issue,
99  bool native,
100  bool negative,
101  unchecked);
102 
103  // Call canonicalize
104  STAmount(
105  SField const& name,
106  Issue const& issue,
109  bool native,
110  bool negative);
111 
112  STAmount(SField const& name, std::int64_t mantissa);
113 
114  STAmount(
115  SField const& name,
117  bool negative = false);
118 
119  STAmount(
120  SField const& name,
121  Issue const& issue,
123  int exponent = 0,
124  bool negative = false);
125 
126  explicit STAmount(std::uint64_t mantissa = 0, bool negative = false);
127 
128  STAmount(
129  Issue const& issue,
131  int exponent = 0,
132  bool negative = false);
133 
134  // VFALCO Is this needed when we have the previous signature?
135  STAmount(
136  Issue const& issue,
138  int exponent = 0,
139  bool negative = false);
140 
141  STAmount(Issue const& issue, std::int64_t mantissa, int exponent = 0);
142 
143  STAmount(Issue const& issue, int mantissa, int exponent = 0);
144 
145  // Legacy support for new-style amounts
146  STAmount(IOUAmount const& amount, Issue const& issue);
147  STAmount(XRPAmount const& amount);
148  operator Number() const;
149 
150  //--------------------------------------------------------------------------
151  //
152  // Observers
153  //
154  //--------------------------------------------------------------------------
155 
156  int
157  exponent() const noexcept;
158 
159  bool
160  native() const noexcept;
161 
162  bool
163  negative() const noexcept;
164 
165  std::uint64_t
166  mantissa() const noexcept;
167 
168  Issue const&
169  issue() const;
170 
171  // These three are deprecated
172  Currency const&
173  getCurrency() const;
174 
175  AccountID const&
176  getIssuer() const;
177 
178  int
179  signum() const noexcept;
180 
182  STAmount
183  zeroed() const;
184 
185  void
186  setJson(Json::Value&) const;
187 
188  STAmount const&
189  value() const noexcept;
190 
191  //--------------------------------------------------------------------------
192  //
193  // Operators
194  //
195  //--------------------------------------------------------------------------
196 
197  explicit operator bool() const noexcept;
198 
199  STAmount&
200  operator+=(STAmount const&);
201  STAmount&
202  operator-=(STAmount const&);
203 
204  STAmount& operator=(beast::Zero);
205 
206  STAmount&
207  operator=(XRPAmount const& amount);
208 
209  //--------------------------------------------------------------------------
210  //
211  // Modification
212  //
213  //--------------------------------------------------------------------------
214 
215  void
216  negate();
217 
218  void
219  clear();
220 
221  // Zero while copying currency and issuer.
222  void
223  clear(STAmount const& saTmpl);
224 
225  void
226  clear(Issue const& issue);
227 
228  void
229  setIssuer(AccountID const& uIssuer);
230 
232  void
233  setIssue(Issue const& issue);
234 
235  //--------------------------------------------------------------------------
236  //
237  // STBase
238  //
239  //--------------------------------------------------------------------------
240 
242  getSType() const override;
243 
244  std::string
245  getFullText() const override;
246 
247  std::string
248  getText() const override;
249 
250  Json::Value getJson(JsonOptions) const override;
251 
252  void
253  add(Serializer& s) const override;
254 
255  bool
256  isEquivalent(const STBase& t) const override;
257 
258  bool
259  isDefault() const override;
260 
261  XRPAmount
262  xrp() const;
263  IOUAmount
264  iou() const;
265 
266 private:
267  static std::unique_ptr<STAmount>
268  construct(SerialIter&, SField const& name);
269 
270  void
271  set(std::int64_t v);
272  void
273  canonicalize();
274 
275  STBase*
276  copy(std::size_t n, void* buf) const override;
277  STBase*
278  move(std::size_t n, void* buf) override;
279 
280  STAmount&
281  operator=(IOUAmount const& iou);
282 
283  friend class detail::STVar;
284 
285  friend STAmount
286  operator+(STAmount const& v1, STAmount const& v2);
287 };
288 
289 //------------------------------------------------------------------------------
290 //
291 // Creation
292 //
293 //------------------------------------------------------------------------------
294 
295 // VFALCO TODO The parameter type should be Quality not uint64_t
296 STAmount
297 amountFromQuality(std::uint64_t rate);
298 
299 STAmount
300 amountFromString(Issue const& issue, std::string const& amount);
301 
302 STAmount
303 amountFromJson(SField const& name, Json::Value const& v);
304 
305 bool
306 amountFromJsonNoThrow(STAmount& result, Json::Value const& jvSource);
307 
308 // IOUAmount and XRPAmount define toSTAmount, defining this
309 // trivial conversion here makes writing generic code easier
310 inline STAmount const&
312 {
313  return a;
314 }
315 
316 //------------------------------------------------------------------------------
317 //
318 // Observers
319 //
320 //------------------------------------------------------------------------------
321 
322 inline int
323 STAmount::exponent() const noexcept
324 {
325  return mOffset;
326 }
327 
328 inline bool
329 STAmount::native() const noexcept
330 {
331  return mIsNative;
332 }
333 
334 inline bool
335 STAmount::negative() const noexcept
336 {
337  return mIsNegative;
338 }
339 
340 inline std::uint64_t
341 STAmount::mantissa() const noexcept
342 {
343  return mValue;
344 }
345 
346 inline Issue const&
348 {
349  return mIssue;
350 }
351 
352 inline Currency const&
354 {
355  return mIssue.currency;
356 }
357 
358 inline AccountID const&
360 {
361  return mIssue.account;
362 }
363 
364 inline int
365 STAmount::signum() const noexcept
366 {
367  return mValue ? (mIsNegative ? -1 : 1) : 0;
368 }
369 
370 inline STAmount
372 {
373  return STAmount(mIssue);
374 }
375 
376 inline STAmount::operator bool() const noexcept
377 {
378  return *this != beast::zero;
379 }
380 
381 inline STAmount::operator Number() const
382 {
383  if (mIsNative)
384  return xrp();
385  return iou();
386 }
387 
389 {
390  clear();
391  return *this;
392 }
393 
394 inline STAmount&
396 {
397  *this = STAmount(amount);
398  return *this;
399 }
400 
401 inline void
403 {
404  if (*this != beast::zero)
406 }
407 
408 inline void
410 {
411  // The -100 is used to allow 0 to sort less than a small positive values
412  // which have a negative exponent.
413  mOffset = mIsNative ? 0 : -100;
414  mValue = 0;
415  mIsNegative = false;
416 }
417 
418 // Zero while copying currency and issuer.
419 inline void
420 STAmount::clear(STAmount const& saTmpl)
421 {
422  clear(saTmpl.mIssue);
423 }
424 
425 inline void
427 {
428  setIssue(issue);
429  clear();
430 }
431 
432 inline void
434 {
435  mIssue.account = uIssuer;
436  setIssue(mIssue);
437 }
438 
439 inline STAmount const&
440 STAmount::value() const noexcept
441 {
442  return *this;
443 }
444 
445 inline bool
447 {
448  return !value.native() || (value.mantissa() <= STAmount::cMaxNativeN);
449 }
450 
451 //------------------------------------------------------------------------------
452 //
453 // Operators
454 //
455 //------------------------------------------------------------------------------
456 
457 bool
458 operator==(STAmount const& lhs, STAmount const& rhs);
459 bool
460 operator<(STAmount const& lhs, STAmount const& rhs);
461 
462 inline bool
463 operator!=(STAmount const& lhs, STAmount const& rhs)
464 {
465  return !(lhs == rhs);
466 }
467 
468 inline bool
469 operator>(STAmount const& lhs, STAmount const& rhs)
470 {
471  return rhs < lhs;
472 }
473 
474 inline bool
475 operator<=(STAmount const& lhs, STAmount const& rhs)
476 {
477  return !(rhs < lhs);
478 }
479 
480 inline bool
481 operator>=(STAmount const& lhs, STAmount const& rhs)
482 {
483  return !(lhs < rhs);
484 }
485 
486 STAmount
487 operator-(STAmount const& value);
488 
489 //------------------------------------------------------------------------------
490 //
491 // Arithmetic
492 //
493 //------------------------------------------------------------------------------
494 
495 STAmount
496 operator+(STAmount const& v1, STAmount const& v2);
497 STAmount
498 operator-(STAmount const& v1, STAmount const& v2);
499 
500 STAmount
501 divide(STAmount const& v1, STAmount const& v2, Issue const& issue);
502 
503 STAmount
504 multiply(STAmount const& v1, STAmount const& v2, Issue const& issue);
505 
506 // multiply, or divide rounding result in specified direction
507 STAmount
508 mulRound(
509  STAmount const& v1,
510  STAmount const& v2,
511  Issue const& issue,
512  bool roundUp);
513 
514 STAmount
515 divRound(
516  STAmount const& v1,
517  STAmount const& v2,
518  Issue const& issue,
519  bool roundUp);
520 
521 // Someone is offering X for Y, what is the rate?
522 // Rate: smaller is better, the taker wants the most out: in/out
523 // VFALCO TODO Return a Quality object
525 getRate(STAmount const& offerOut, STAmount const& offerIn);
526 
527 //------------------------------------------------------------------------------
528 
529 inline bool
530 isXRP(STAmount const& amount)
531 {
532  return isXRP(amount.issue().currency);
533 }
534 
535 // Since `canonicalize` does not have access to a ledger, this is needed to put
536 // the low-level routine stAmountCanonicalize on an amendment switch. Only
537 // transactions need to use this switchover. Outside of a transaction it's safe
538 // to unconditionally use the new behavior.
539 
540 bool
542 
543 void
545 
550 {
551 public:
552  explicit STAmountSO(bool v) : saved_(getSTAmountCanonicalizeSwitchover())
553  {
555  }
556 
558  {
560  }
561 
562 private:
563  bool saved_;
564 };
565 
566 } // namespace ripple
567 
568 #endif
ripple::STAmount::mIsNative
bool mIsNative
Definition: STAmount.h:56
ripple::STAmount::move
STBase * move(std::size_t n, void *buf) override
Definition: STAmount.cpp:323
ripple::STAmount::negate
void negate()
Definition: STAmount.h:402
ripple::STAmount::copy
STBase * copy(std::size_t n, void *buf) const override
Definition: STAmount.cpp:317
ripple::amountFromJsonNoThrow
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
Definition: STAmount.cpp:1034
ripple::STAmountSO
RAII class to set and restore the STAmount canonicalize switchover.
Definition: STAmount.h:549
ripple::CountedObject
Tracks the number of instances of an object.
Definition: CountedObject.h:124
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
ripple::STAmount::cMinValue
static const std::uint64_t cMinValue
Definition: STAmount.h:66
ripple::STAmount::set
void set(std::int64_t v)
Definition: STAmount.cpp:835
ripple::JsonOptions
JsonOptions
Definition: STBase.h:34
ripple::STAmount::clear
void clear()
Definition: STAmount.h:409
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::STAmountSO::~STAmountSO
~STAmountSO()
Definition: STAmount.h:557
std::pair
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:571
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:655
ripple::SerializedTypeID
SerializedTypeID
Definition: SField.h:52
ripple::operator-
Number operator-(Number const &x, Number const &y)
Definition: Number.h:277
ripple::STAmount::cMaxNative
static const std::uint64_t cMaxNative
Definition: STAmount.h:68
ripple::STAmount::mValue
mantissa_type mValue
Definition: STAmount.h:54
ripple::Issue::currency
Currency currency
Definition: Issue.h:37
ripple::STAmount::signum
int signum() const noexcept
Definition: STAmount.h:365
ripple::STAmount::cMinOffset
static const int cMinOffset
Definition: STAmount.h:62
ripple::isLegalNet
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:446
ripple::STAmount::cNotNative
static const std::uint64_t cNotNative
Definition: STAmount.h:72
ripple::IOUAmount
Floating point representation of amounts with high dynamic range.
Definition: IOUAmount.h:43
ripple::STAmount::operator=
STAmount & operator=(beast::Zero)
Definition: STAmount.h:388
ripple::STAmount::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:433
ripple::STAmount::zeroed
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
Definition: STAmount.h:371
ripple::STAmount::iou
IOUAmount iou() const
Definition: STAmount.cpp:349
ripple::STAmount::operator+
friend STAmount operator+(STAmount const &v1, STAmount const &v2)
Definition: STAmount.cpp:397
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:334
ripple::mulRound
STAmount mulRound(STAmount const &v1, STAmount const &v2, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1305
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:359
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::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
Json
JSON (JavaScript Object Notation).
Definition: json_reader.cpp:27
ripple::operator<=
bool operator<=(STAmount const &lhs, STAmount const &rhs)
Definition: STAmount.h:475
ripple::STAmount::mIssue
Issue mIssue
Definition: STAmount.h:53
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:517
ripple::Number
Definition: Number.h:36
ripple::STAmount::STAmount
STAmount(SerialIter &sit, SField const &name)
Definition: STAmount.cpp:88
ripple::operator>
bool operator>(STAmount const &lhs, STAmount const &rhs)
Definition: STAmount.h:469
ripple::setSTAmountCanonicalizeSwitchover
void setSTAmountCanonicalizeSwitchover(bool v)
Definition: STAmount.cpp:55
ripple::operator<
bool operator<(CanonicalTXSet::Key const &lhs, CanonicalTXSet::Key const &rhs)
Definition: CanonicalTXSet.cpp:25
ripple::divRound
STAmount divRound(STAmount const &num, STAmount const &den, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1391
ripple::STAmount::unchecked::unchecked
unchecked()=default
ripple::toSTAmount
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
Definition: AmountConversions.h:30
ripple::STAmount::value
STAmount const & value() const noexcept
Definition: STAmount.h:440
ripple::operator>=
bool operator>=(STAmount const &lhs, STAmount const &rhs)
Definition: STAmount.h:481
beast::Zero
Zero allows classes to offer efficient comparisons to zero.
Definition: Zero.h:42
ripple::STAmount
Definition: STAmount.h:45
ripple::getSTAmountCanonicalizeSwitchover
bool getSTAmountCanonicalizeSwitchover()
Definition: STAmount.cpp:49
ripple::amountFromJson
STAmount amountFromJson(SField const &name, Json::Value const &v)
Definition: STAmount.cpp:929
ripple::isXRP
bool isXRP(AccountID const &c)
Definition: AccountID.h:89
ripple::SerialIter
Definition: Serializer.h:310
std::uint64_t
ripple::STAmount::setIssue
void setIssue(Issue const &issue)
Set the Issue for this amount and update mIsNative.
Definition: STAmount.cpp:479
ripple::STAmount::construct
static std::unique_ptr< STAmount > construct(SerialIter &, SField const &name)
Definition: STAmount.cpp:311
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::STAmount::isEquivalent
bool isEquivalent(const STBase &t) const override
Definition: STAmount.cpp:694
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:329
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::STAmount::mIsNegative
bool mIsNegative
Definition: STAmount.h:57
ripple::amountFromString
STAmount amountFromString(Issue const &issue, std::string const &amount)
Definition: STAmount.cpp:864
ripple::STAmount::isDefault
bool isDefault() const override
Definition: STAmount.cpp:701
ripple::STAmount::unchecked
Definition: STAmount.h:80
ripple::SField
Identifies fields.
Definition: SField.h:112
ripple::STBase
A type which can be exported to a well known binary format.
Definition: STBase.h:66
ripple::STBase::operator!=
bool operator!=(const STBase &t) const
Definition: STBase.cpp:51
std
STL namespace.
ripple::STAmount::canonicalize
void canonicalize()
Definition: STAmount.cpp:725
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::STBase::operator==
bool operator==(const STBase &t) const
Definition: STBase.cpp:45
ripple::STAmount::exponent_type
int exponent_type
Definition: STAmount.h:49
ripple::STAmount::cMaxNativeN
static const std::uint64_t cMaxNativeN
Definition: STAmount.h:71
ripple::STAmount::cMaxOffset
static const int cMaxOffset
Definition: STAmount.h:63
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:353
ripple::STAmount::mOffset
exponent_type mOffset
Definition: STAmount.h:55
ripple::STAmountSO::saved_
bool saved_
Definition: STAmount.h:563
ripple::STAmount::cPosNative
static const std::uint64_t cPosNative
Definition: STAmount.h:73
ripple::STAmount::uRateOne
static const std::uint64_t uRateOne
Definition: STAmount.h:75
ripple::STAmount::getSType
SerializedTypeID getSType() const override
Definition: STAmount.cpp:542
ripple::Issue::account
AccountID account
Definition: Issue.h:38
ripple::STAmount::cMaxValue
static const std::uint64_t cMaxValue
Definition: STAmount.h:67
ripple::STAmountSO::STAmountSO
STAmountSO(bool v)
Definition: STAmount.h:552
ripple::XRPAmount
Definition: XRPAmount.h:46
beast
Definition: base_uint.h:641