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