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  STBase*
148  copy(std::size_t n, void* buf) const override
149  {
150  return emplace(n, buf, *this);
151  }
152 
153  STBase*
154  move(std::size_t n, void* buf) override
155  {
156  return emplace(n, buf, std::move(*this));
157  }
158 
159  //--------------------------------------------------------------------------
160 
161 private:
163  construct(SerialIter&, SField const& name);
164 
165  void
166  set(std::int64_t v);
167  void
168  canonicalize();
169 
170 public:
171  //--------------------------------------------------------------------------
172  //
173  // Observers
174  //
175  //--------------------------------------------------------------------------
176 
177  int
178  exponent() const noexcept
179  {
180  return mOffset;
181  }
182  bool
183  native() const noexcept
184  {
185  return mIsNative;
186  }
187  bool
188  negative() const noexcept
189  {
190  return mIsNegative;
191  }
193  mantissa() const noexcept
194  {
195  return mValue;
196  }
197  Issue const&
198  issue() const
199  {
200  return mIssue;
201  }
202 
203  // These three are deprecated
204  Currency const&
205  getCurrency() const
206  {
207  return mIssue.currency;
208  }
209  AccountID const&
210  getIssuer() const
211  {
212  return mIssue.account;
213  }
214 
215  int
216  signum() const noexcept
217  {
218  return mValue ? (mIsNegative ? -1 : 1) : 0;
219  }
220 
222  STAmount
223  zeroed() const
224  {
225  return STAmount(mIssue);
226  }
227 
228  void
229  setJson(Json::Value&) const;
230 
231  STAmount const&
232  value() const noexcept
233  {
234  return *this;
235  }
236 
237  //--------------------------------------------------------------------------
238  //
239  // Operators
240  //
241  //--------------------------------------------------------------------------
242 
243  explicit operator bool() const noexcept
244  {
245  return *this != beast::zero;
246  }
247 
248  STAmount&
249  operator+=(STAmount const&);
250  STAmount&
251  operator-=(STAmount const&);
252 
254  {
255  clear();
256  return *this;
257  }
258 
259  STAmount&
260  operator=(XRPAmount const& amount)
261  {
262  *this = STAmount(amount);
263  return *this;
264  }
265 
266  //--------------------------------------------------------------------------
267  //
268  // Modification
269  //
270  //--------------------------------------------------------------------------
271 
272  void
274  {
275  if (*this != beast::zero)
277  }
278 
279  void
281  {
282  // The -100 is used to allow 0 to sort less than a small positive values
283  // which have a negative exponent.
284  mOffset = mIsNative ? 0 : -100;
285  mValue = 0;
286  mIsNegative = false;
287  }
288 
289  // Zero while copying currency and issuer.
290  void
291  clear(STAmount const& saTmpl)
292  {
293  clear(saTmpl.mIssue);
294  }
295 
296  void
297  clear(Issue const& issue)
298  {
299  setIssue(issue);
300  clear();
301  }
302 
303  void
304  setIssuer(AccountID const& uIssuer)
305  {
306  mIssue.account = uIssuer;
307  setIssue(mIssue);
308  }
309 
311  void
312  setIssue(Issue const& issue);
313 
314  //--------------------------------------------------------------------------
315  //
316  // STBase
317  //
318  //--------------------------------------------------------------------------
319 
321  getSType() const override
322  {
323  return STI_AMOUNT;
324  }
325 
327  getFullText() const override;
328 
330  getText() const override;
331 
332  Json::Value getJson(JsonOptions) const override;
333 
334  void
335  add(Serializer& s) const override;
336 
337  bool
338  isEquivalent(const STBase& t) const override;
339 
340  bool
341  isDefault() const override
342  {
343  return (mValue == 0) && mIsNative;
344  }
345 
346  XRPAmount
347  xrp() const;
348  IOUAmount
349  iou() const;
350 };
351 
352 //------------------------------------------------------------------------------
353 //
354 // Creation
355 //
356 //------------------------------------------------------------------------------
357 
358 // VFALCO TODO The parameter type should be Quality not uint64_t
359 STAmount
361 
362 STAmount
363 amountFromString(Issue const& issue, std::string const& amount);
364 
365 STAmount
366 amountFromJson(SField const& name, Json::Value const& v);
367 
368 bool
369 amountFromJsonNoThrow(STAmount& result, Json::Value const& jvSource);
370 
371 // IOUAmount and XRPAmount define toSTAmount, defining this
372 // trivial conversion here makes writing generic code easier
373 inline STAmount const&
375 {
376  return a;
377 }
378 
379 //------------------------------------------------------------------------------
380 //
381 // Observers
382 //
383 //------------------------------------------------------------------------------
384 
385 inline bool
386 isLegalNet(STAmount const& value)
387 {
388  return !value.native() || (value.mantissa() <= STAmount::cMaxNativeN);
389 }
390 
391 //------------------------------------------------------------------------------
392 //
393 // Operators
394 //
395 //------------------------------------------------------------------------------
396 
397 bool
398 operator==(STAmount const& lhs, STAmount const& rhs);
399 bool
400 operator<(STAmount const& lhs, STAmount const& rhs);
401 
402 inline bool
403 operator!=(STAmount const& lhs, STAmount const& rhs)
404 {
405  return !(lhs == rhs);
406 }
407 
408 inline bool
409 operator>(STAmount const& lhs, STAmount const& rhs)
410 {
411  return rhs < lhs;
412 }
413 
414 inline bool
415 operator<=(STAmount const& lhs, STAmount const& rhs)
416 {
417  return !(rhs < lhs);
418 }
419 
420 inline bool
421 operator>=(STAmount const& lhs, STAmount const& rhs)
422 {
423  return !(lhs < rhs);
424 }
425 
426 STAmount
427 operator-(STAmount const& value);
428 
429 //------------------------------------------------------------------------------
430 //
431 // Arithmetic
432 //
433 //------------------------------------------------------------------------------
434 
435 STAmount
436 operator+(STAmount const& v1, STAmount const& v2);
437 STAmount
438 operator-(STAmount const& v1, STAmount const& v2);
439 
440 STAmount
441 divide(STAmount const& v1, STAmount const& v2, Issue const& issue);
442 
443 STAmount
444 multiply(STAmount const& v1, STAmount const& v2, Issue const& issue);
445 
446 // multiply, or divide rounding result in specified direction
447 STAmount
448 mulRound(
449  STAmount const& v1,
450  STAmount const& v2,
451  Issue const& issue,
452  bool roundUp);
453 
454 STAmount
455 divRound(
456  STAmount const& v1,
457  STAmount const& v2,
458  Issue const& issue,
459  bool roundUp);
460 
461 // Someone is offering X for Y, what is the rate?
462 // Rate: smaller is better, the taker wants the most out: in/out
463 // VFALCO TODO Return a Quality object
465 getRate(STAmount const& offerOut, STAmount const& offerIn);
466 
467 //------------------------------------------------------------------------------
468 
469 inline bool
470 isXRP(STAmount const& amount)
471 {
472  return isXRP(amount.issue().currency);
473 }
474 
475 // Since `canonicalize` does not have access to a ledger, this is needed to put
476 // the low-level routine stAmountCanonicalize on an amendment switch. Only
477 // transactions need to use this switchover. Outside of a transaction it's safe
478 // to unconditionally use the new behavior.
480 
485 {
486 public:
488  {
490  }
491 
493  {
495  }
496 
497 private:
498  bool saved_;
499 };
500 
501 } // namespace ripple
502 
503 #endif
ripple::STAmount::mIsNative
bool mIsNative
Definition: STAmount.h:54
ripple::STAmount::clear
void clear(STAmount const &saTmpl)
Definition: STAmount.h:291
ripple::STAmount::negate
void negate()
Definition: STAmount.h:273
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:951
ripple::STAmountSO
RAII class to set and restore the STAmount canonicalize switchover.
Definition: STAmount.h:484
ripple::STAmount::move
STBase * move(std::size_t n, void *buf) override
Definition: STAmount.h:154
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
std::string
STL class.
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:752
ripple::JsonOptions
JsonOptions
Definition: STBase.h:34
ripple::STAmount::clear
void clear()
Definition: STAmount.h:280
ripple::STAmount::mantissa
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:193
ripple::STAmountSO::~STAmountSO
~STAmountSO()
Definition: STAmount.h:492
std::pair
ripple::operator>=
bool operator>=(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:571
ripple::STI_AMOUNT
@ STI_AMOUNT
Definition: SField.h:64
ripple::STAmount::getText
std::string getText() const override
Definition: STAmount.cpp:512
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:596
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:216
ripple::STAmount::cMinOffset
static const int cMinOffset
Definition: STAmount.h:60
ripple::isLegalNet
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:386
ripple::operator-
STAmount operator-(STAmount const &v1, STAmount const &v2)
Definition: STAmount.cpp:416
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::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:304
ripple::STAmount::zeroed
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
Definition: STAmount.h:223
ripple::STAmount::operator=
STAmount & operator=(XRPAmount const &amount)
Definition: STAmount.h:260
ripple::STAmount::iou
IOUAmount iou() const
Definition: STAmount.cpp:316
ripple::STAmount::operator-=
STAmount & operator-=(STAmount const &)
Definition: STAmount.cpp:344
ripple::STAmount::xrp
XRPAmount xrp() const
Definition: STAmount.cpp:301
ripple::operator==
bool operator==(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:159
ripple::mulRound
STAmount mulRound(STAmount const &v1, STAmount const &v2, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1219
ripple::STAmount::copy
STBase * copy(std::size_t n, void *buf) const override
Definition: STAmount.h:148
ripple::getRate
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
Definition: STAmount.cpp:442
ripple::divide
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:77
ripple::STBase::emplace
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition: STBase.h:149
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:75
ripple::STAmount::getFullText
std::string getFullText() const override
Definition: STAmount.cpp:489
ripple::STAmount::exponent
int exponent() const noexcept
Definition: STAmount.h:178
ripple::operator<=
bool operator<=(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition: base_uint.h:557
ripple::STAmount::mIssue
Issue mIssue
Definition: STAmount.h:51
ripple::STAmount::setJson
void setJson(Json::Value &) const
Definition: STAmount.cpp:464
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::STAmount::clear
void clear(Issue const &issue)
Definition: STAmount.h:297
ripple::divRound
STAmount divRound(STAmount const &num, STAmount const &den, Issue const &issue, bool roundUp)
Definition: STAmount.cpp:1305
ripple::STAmount::unchecked::unchecked
unchecked()=default
ripple::toSTAmount
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
Definition: AmountConversions.h:30
ripple::operator!=
bool operator!=(Manifest const &lhs, Manifest const &rhs)
Definition: Manifest.h:169
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:846
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:426
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:769
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:205
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:210
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:635
ripple::STAmount::native
bool native() const noexcept
Definition: STAmount.h:183
ripple::STAmount::operator+=
STAmount & operator+=(STAmount const &)
Definition: STAmount.cpp:337
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:781
ripple::STAmount::isDefault
bool isDefault() const override
Definition: STAmount.h:341
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:62
ripple::STAmount::issue
Issue const & issue() const
Definition: STAmount.h:198
ripple::STAmount::canonicalize
void canonicalize()
Definition: STAmount.cpp:660
ripple::STAmount::add
void add(Serializer &s) const override
Definition: STAmount.cpp:604
ripple::STAmount::value
STAmount const & value() const noexcept
Definition: STAmount.h:232
ripple::STAmount::negative
bool negative() const noexcept
Definition: STAmount.h:188
ripple::STAmount::exponent_type
int exponent_type
Definition: STAmount.h:47
std::size_t
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:479
std::unique_ptr
STL class.
ripple::STAmount::mOffset
exponent_type mOffset
Definition: STAmount.h:53
ripple::STAmountSO::saved_
bool saved_
Definition: STAmount.h:498
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.h:321
ripple::Issue::account
AccountID account
Definition: Issue.h:38
ripple::STAmount::cMaxValue
static const std::uint64_t cMaxValue
Definition: STAmount.h:65
ripple::STAmount::operator=
STAmount & operator=(beast::Zero)
Definition: STAmount.h:253
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::STAmountSO::STAmountSO
STAmountSO(bool v)
Definition: STAmount.h:487
ripple::XRPAmount
Definition: XRPAmount.h:46