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