rippled
Loading...
Searching...
No Matches
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 <xrpl/basics/CountedObject.h>
24#include <xrpl/basics/LocalValue.h>
25#include <xrpl/basics/Number.h>
26#include <xrpl/beast/utility/instrumentation.h>
27#include <xrpl/protocol/Asset.h>
28#include <xrpl/protocol/IOUAmount.h>
29#include <xrpl/protocol/Issue.h>
30#include <xrpl/protocol/MPTAmount.h>
31#include <xrpl/protocol/SField.h>
32#include <xrpl/protocol/STBase.h>
33#include <xrpl/protocol/Serializer.h>
34#include <xrpl/protocol/XRPAmount.h>
35#include <xrpl/protocol/json_get_or_throw.h>
36
37namespace ripple {
38
39// Internal form:
40// 1: If amount is zero, then value is zero and offset is -100
41// 2: Otherwise:
42// legal offset range is -96 to +80 inclusive
43// value range is 10^15 to (10^16 - 1) inclusive
44// amount = value * [10 ^ offset]
45
46// Wire form:
47// High 8 bits are (offset+142), legal range is, 80 to 22 inclusive
48// Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive
49class STAmount final : public STBase, public CountedObject<STAmount>
50{
51public:
53 using exponent_type = int;
55
56private:
61
62public:
64
65 static int const cMinOffset = -96;
66 static int const cMaxOffset = 80;
67
68 // Maximum native value supported by the code
69 static std::uint64_t const cMinValue = 1000000000000000ull;
70 static std::uint64_t const cMaxValue = 9999999999999999ull;
71 static std::uint64_t const cMaxNative = 9000000000000000000ull;
72
73 // Max native value on network.
74 static std::uint64_t const cMaxNativeN = 100000000000000000ull;
75 static std::uint64_t const cIssuedCurrency = 0x8000000000000000ull;
76 static std::uint64_t const cPositive = 0x4000000000000000ull;
77 static std::uint64_t const cMPToken = 0x2000000000000000ull;
79
80 static std::uint64_t const uRateOne;
81
82 //--------------------------------------------------------------------------
83 STAmount(SerialIter& sit, SField const& name);
84
85 struct unchecked
86 {
87 explicit unchecked() = default;
88 };
89
90 // Do not call canonicalize
91 template <AssetType A>
93 SField const& name,
94 A const& asset,
97 bool negative,
98 unchecked);
99
100 template <AssetType A>
101 STAmount(
102 A const& asset,
105 bool negative,
106 unchecked);
107
108 // Call canonicalize
109 template <AssetType A>
110 STAmount(
111 SField const& name,
112 A const& asset,
115 bool negative = false);
116
117 STAmount(SField const& name, std::int64_t mantissa);
118
119 STAmount(
120 SField const& name,
122 bool negative = false);
123
124 explicit STAmount(std::uint64_t mantissa = 0, bool negative = false);
125
126 explicit STAmount(SField const& name, STAmount const& amt);
127
128 template <AssetType A>
130 A const& asset,
132 int exponent = 0,
133 bool negative = false)
134 : mAsset(asset)
138 {
139 canonicalize();
140 }
141
142 // VFALCO Is this needed when we have the previous signature?
143 template <AssetType A>
144 STAmount(
145 A const& asset,
147 int exponent = 0,
148 bool negative = false);
149
150 template <AssetType A>
151 STAmount(A const& asset, std::int64_t mantissa, int exponent = 0);
152
153 template <AssetType A>
154 STAmount(A const& asset, int mantissa, int exponent = 0);
155
156 template <AssetType A>
157 STAmount(A const& asset, Number const& number)
158 : STAmount(asset, number.mantissa(), number.exponent())
159 {
160 }
161
162 // Legacy support for new-style amounts
163 STAmount(IOUAmount const& amount, Issue const& issue);
164 STAmount(XRPAmount const& amount);
165 STAmount(MPTAmount const& amount, MPTIssue const& mptIssue);
166 operator Number() const;
167
168 //--------------------------------------------------------------------------
169 //
170 // Observers
171 //
172 //--------------------------------------------------------------------------
173
174 int
175 exponent() const noexcept;
176
177 bool
178 native() const noexcept;
179
180 template <ValidIssueType TIss>
181 constexpr bool
182 holds() const noexcept;
183
184 bool
185 negative() const noexcept;
186
187 std::uint64_t
188 mantissa() const noexcept;
189
190 Asset const&
191 asset() const;
192
193 template <ValidIssueType TIss>
194 constexpr TIss const&
195 get() const;
196
197 Issue const&
198 issue() const;
199
200 // These three are deprecated
201 Currency const&
202 getCurrency() const;
203
204 AccountID const&
205 getIssuer() const;
206
207 int
208 signum() const noexcept;
209
212 zeroed() const;
213
214 void
215 setJson(Json::Value&) const;
216
217 STAmount const&
218 value() const noexcept;
219
220 //--------------------------------------------------------------------------
221 //
222 // Operators
223 //
224 //--------------------------------------------------------------------------
225
226 explicit
227 operator bool() const noexcept;
228
229 STAmount&
230 operator+=(STAmount const&);
231 STAmount&
232 operator-=(STAmount const&);
233
234 STAmount& operator=(beast::Zero);
235
236 STAmount&
237 operator=(XRPAmount const& amount);
238
239 STAmount&
240 operator=(Number const&);
241
242 //--------------------------------------------------------------------------
243 //
244 // Modification
245 //
246 //--------------------------------------------------------------------------
247
248 void
249 negate();
250
251 void
252 clear();
253
254 // Zero while copying currency and issuer.
255 void
256 clear(Asset const& asset);
257
258 void
259 setIssuer(AccountID const& uIssuer);
260
262 void
263 setIssue(Asset const& asset);
264
265 //--------------------------------------------------------------------------
266 //
267 // STBase
268 //
269 //--------------------------------------------------------------------------
270
272 getSType() const override;
273
274 std::string
275 getFullText() const override;
276
277 std::string
278 getText() const override;
279
280 Json::Value getJson(JsonOptions = JsonOptions::none) const override;
281
282 void
283 add(Serializer& s) const override;
284
285 bool
286 isEquivalent(STBase const& t) const override;
287
288 bool
289 isDefault() const override;
290
292 xrp() const;
294 iou() const;
296 mpt() const;
297
298private:
299 static std::unique_ptr<STAmount>
300 construct(SerialIter&, SField const& name);
301
302 void
303 set(std::int64_t v);
304 void
305 canonicalize();
306
307 STBase*
308 copy(std::size_t n, void* buf) const override;
309 STBase*
310 move(std::size_t n, void* buf) override;
311
312 STAmount&
313 operator=(IOUAmount const& iou);
314
315 friend class detail::STVar;
316
317 friend STAmount
318 operator+(STAmount const& v1, STAmount const& v2);
319};
320
321template <AssetType A>
323 SField const& name,
324 A const& asset,
327 bool negative,
328 unchecked)
329 : STBase(name)
330 , mAsset(asset)
334{
335}
336
337template <AssetType A>
347
348template <AssetType A>
350 SField const& name,
351 A const& asset,
352 std::uint64_t mantissa,
353 int exponent,
354 bool negative)
355 : STBase(name)
356 , mAsset(asset)
357 , mValue(mantissa)
358 , mOffset(exponent)
359 , mIsNegative(negative)
360{
361 // mValue is uint64, but needs to fit in the range of int64
362 XRPL_ASSERT(
364 "ripple::STAmount::STAmount(SField, A, std::uint64_t, int, bool) : "
365 "maximum mantissa input");
366 canonicalize();
367}
368
369template <AssetType A>
370STAmount::STAmount(A const& asset, std::int64_t mantissa, int exponent)
371 : mAsset(asset), mOffset(exponent)
372{
373 set(mantissa);
374 canonicalize();
375}
376
377template <AssetType A>
379 A const& asset,
380 std::uint32_t mantissa,
381 int exponent,
382 bool negative)
383 : STAmount(asset, safe_cast<std::uint64_t>(mantissa), exponent, negative)
384{
385}
386
387template <AssetType A>
388STAmount::STAmount(A const& asset, int mantissa, int exponent)
389 : STAmount(asset, safe_cast<std::int64_t>(mantissa), exponent)
390{
391}
392
393// Legacy support for new-style amounts
394inline STAmount::STAmount(IOUAmount const& amount, Issue const& issue)
395 : mAsset(issue)
396 , mOffset(amount.exponent())
397 , mIsNegative(amount < beast::zero)
398{
399 if (mIsNegative)
400 mValue = unsafe_cast<std::uint64_t>(-amount.mantissa());
401 else
402 mValue = unsafe_cast<std::uint64_t>(amount.mantissa());
403
404 canonicalize();
405}
406
407inline STAmount::STAmount(MPTAmount const& amount, MPTIssue const& mptIssue)
408 : mAsset(mptIssue), mOffset(0), mIsNegative(amount < beast::zero)
409{
410 if (mIsNegative)
411 mValue = unsafe_cast<std::uint64_t>(-amount.value());
412 else
413 mValue = unsafe_cast<std::uint64_t>(amount.value());
414
415 canonicalize();
416}
417
418//------------------------------------------------------------------------------
419//
420// Creation
421//
422//------------------------------------------------------------------------------
423
424// VFALCO TODO The parameter type should be Quality not uint64_t
427
429amountFromString(Asset const& asset, std::string const& amount);
430
432amountFromJson(SField const& name, Json::Value const& v);
433
434bool
435amountFromJsonNoThrow(STAmount& result, Json::Value const& jvSource);
436
437// IOUAmount and XRPAmount define toSTAmount, defining this
438// trivial conversion here makes writing generic code easier
439inline STAmount const&
441{
442 return a;
443}
444
445//------------------------------------------------------------------------------
446//
447// Observers
448//
449//------------------------------------------------------------------------------
450
451inline int
452STAmount::exponent() const noexcept
453{
454 return mOffset;
455}
456
457inline bool
458STAmount::native() const noexcept
459{
460 return mAsset.native();
461}
462
463template <ValidIssueType TIss>
464constexpr bool
465STAmount::holds() const noexcept
466{
467 return mAsset.holds<TIss>();
468}
469
470inline bool
471STAmount::negative() const noexcept
472{
473 return mIsNegative;
474}
475
476inline std::uint64_t
477STAmount::mantissa() const noexcept
478{
479 return mValue;
480}
481
482inline Asset const&
484{
485 return mAsset;
486}
487
488template <ValidIssueType TIss>
489constexpr TIss const&
491{
492 return mAsset.get<TIss>();
493}
494
495inline Issue const&
497{
498 return get<Issue>();
499}
500
501inline Currency const&
503{
504 return mAsset.get<Issue>().currency;
505}
506
507inline AccountID const&
509{
510 return mAsset.getIssuer();
511}
512
513inline int
514STAmount::signum() const noexcept
515{
516 return mValue ? (mIsNegative ? -1 : 1) : 0;
517}
518
519inline STAmount
521{
522 return STAmount(mAsset);
523}
524
525inline STAmount::operator bool() const noexcept
526{
527 return *this != beast::zero;
528}
529
530inline STAmount::operator Number() const
531{
532 if (native())
533 return xrp();
534 if (mAsset.holds<MPTIssue>())
535 return mpt();
536 return iou();
537}
538
539inline STAmount&
541{
542 clear();
543 return *this;
544}
545
546inline STAmount&
548{
549 *this = STAmount(amount);
550 return *this;
551}
552
553inline STAmount&
555{
556 mIsNegative = number.mantissa() < 0;
557 mValue = mIsNegative ? -number.mantissa() : number.mantissa();
558 mOffset = number.exponent();
559 canonicalize();
560 return *this;
561}
562
563inline void
565{
566 if (*this != beast::zero)
568}
569
570inline void
572{
573 // The -100 is used to allow 0 to sort less than a small positive values
574 // which have a negative exponent.
575 mOffset = native() ? 0 : -100;
576 mValue = 0;
577 mIsNegative = false;
578}
579
580inline void
582{
584 clear();
585}
586
587inline void
589{
590 mAsset.get<Issue>().account = uIssuer;
591}
592
593inline STAmount const&
594STAmount::value() const noexcept
595{
596 return *this;
597}
598
599inline bool
600isLegalNet(STAmount const& value)
601{
602 return !value.native() || (value.mantissa() <= STAmount::cMaxNativeN);
603}
604
605//------------------------------------------------------------------------------
606//
607// Operators
608//
609//------------------------------------------------------------------------------
610
611bool
612operator==(STAmount const& lhs, STAmount const& rhs);
613bool
614operator<(STAmount const& lhs, STAmount const& rhs);
615
616inline bool
617operator!=(STAmount const& lhs, STAmount const& rhs)
618{
619 return !(lhs == rhs);
620}
621
622inline bool
623operator>(STAmount const& lhs, STAmount const& rhs)
624{
625 return rhs < lhs;
626}
627
628inline bool
629operator<=(STAmount const& lhs, STAmount const& rhs)
630{
631 return !(rhs < lhs);
632}
633
634inline bool
635operator>=(STAmount const& lhs, STAmount const& rhs)
636{
637 return !(lhs < rhs);
638}
639
640STAmount
641operator-(STAmount const& value);
642
643//------------------------------------------------------------------------------
644//
645// Arithmetic
646//
647//------------------------------------------------------------------------------
648
649STAmount
650operator+(STAmount const& v1, STAmount const& v2);
651STAmount
652operator-(STAmount const& v1, STAmount const& v2);
653
654STAmount
655divide(STAmount const& v1, STAmount const& v2, Asset const& asset);
656
657STAmount
658multiply(STAmount const& v1, STAmount const& v2, Asset const& asset);
659
660// multiply rounding result in specified direction
661STAmount
663 STAmount const& v1,
664 STAmount const& v2,
665 Asset const& asset,
666 bool roundUp);
667
668// multiply following the rounding directions more precisely.
669STAmount
671 STAmount const& v1,
672 STAmount const& v2,
673 Asset const& asset,
674 bool roundUp);
675
676// divide rounding result in specified direction
677STAmount
679 STAmount const& v1,
680 STAmount const& v2,
681 Asset const& asset,
682 bool roundUp);
683
684// divide following the rounding directions more precisely.
685STAmount
687 STAmount const& v1,
688 STAmount const& v2,
689 Asset const& asset,
690 bool roundUp);
691
692// Someone is offering X for Y, what is the rate?
693// Rate: smaller is better, the taker wants the most out: in/out
694// VFALCO TODO Return a Quality object
696getRate(STAmount const& offerOut, STAmount const& offerIn);
697
698//------------------------------------------------------------------------------
699
700inline bool
701isXRP(STAmount const& amount)
702{
703 return amount.native();
704}
705
706bool
707canAdd(STAmount const& amt1, STAmount const& amt2);
708
709bool
710canSubtract(STAmount const& amt1, STAmount const& amt2);
711
712} // namespace ripple
713
714//------------------------------------------------------------------------------
715namespace Json {
716template <>
717inline ripple::STAmount
718getOrThrow(Json::Value const& v, ripple::SField const& field)
719{
720 using namespace ripple;
721 Json::StaticString const& key = field.getJsonName();
722 if (!v.isMember(key))
723 Throw<JsonMissingKeyError>(key);
724 Json::Value const& inner = v[key];
725 return amountFromJson(field, inner);
726}
727} // namespace Json
728#endif
Lightweight wrapper to tag static string.
Definition json_value.h:63
Represents a JSON value.
Definition json_value.h:149
bool isMember(char const *key) const
Return true if the object has a member named key.
bool native() const
Definition Asset.h:101
constexpr TIss const & get() const
AccountID const & getIssuer() const
Definition Asset.cpp:36
constexpr bool holds() const
Definition Asset.h:132
Tracks the number of instances of an object.
Floating point representation of amounts with high dynamic range.
Definition IOUAmount.h:46
std::int64_t mantissa() const noexcept
Definition IOUAmount.h:178
A currency issued by an account.
Definition Issue.h:33
constexpr value_type value() const
Returns the underlying value.
Definition MPTAmount.h:133
constexpr int exponent() const noexcept
Definition Number.h:236
constexpr rep mantissa() const noexcept
Definition Number.h:230
Identifies fields.
Definition SField.h:146
constexpr bool holds() const noexcept
Definition STAmount.h:465
IOUAmount iou() const
Definition STAmount.cpp:299
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STAmount.cpp:772
static std::uint64_t const cMaxNativeN
Definition STAmount.h:74
STAmount & operator=(beast::Zero)
Definition STAmount.h:540
int exponent() const noexcept
Definition STAmount.h:452
STBase * move(std::size_t n, void *buf) override
Definition STAmount.cpp:272
Asset const & asset() const
Definition STAmount.h:483
static std::uint64_t const cPositive
Definition STAmount.h:76
constexpr TIss const & get() const
void setIssuer(AccountID const &uIssuer)
Definition STAmount.h:588
static int const cMaxOffset
Definition STAmount.h:66
static int const cMinOffset
Definition STAmount.h:65
Currency const & getCurrency() const
Definition STAmount.h:502
friend class detail::STVar
Definition STAmount.h:315
static std::uint64_t const cMinValue
Definition STAmount.h:69
static std::unique_ptr< STAmount > construct(SerialIter &, SField const &name)
Definition STAmount.cpp:260
void setIssue(Asset const &asset)
Set the Issue for this amount.
Definition STAmount.cpp:448
XRPAmount xrp() const
Definition STAmount.cpp:283
void setJson(Json::Value &) const
Definition STAmount.cpp:643
bool isDefault() const override
Definition STAmount.cpp:826
void add(Serializer &s) const override
Definition STAmount.cpp:780
static std::uint64_t const cIssuedCurrency
Definition STAmount.h:75
static std::uint64_t const cMPToken
Definition STAmount.h:77
SerializedTypeID getSType() const override
Definition STAmount.cpp:667
mantissa_type mValue
Definition STAmount.h:58
int signum() const noexcept
Definition STAmount.h:514
static std::uint64_t const cMaxValue
Definition STAmount.h:70
STAmount const & value() const noexcept
Definition STAmount.h:594
std::string getText() const override
Definition STAmount.cpp:683
bool negative() const noexcept
Definition STAmount.h:471
AccountID const & getIssuer() const
Definition STAmount.h:508
bool isEquivalent(STBase const &t) const override
Definition STAmount.cpp:819
STAmount(A const &asset, std::uint64_t mantissa=0, int exponent=0, bool negative=false)
Definition STAmount.h:129
STBase * copy(std::size_t n, void *buf) const override
Definition STAmount.cpp:266
MPTAmount mpt() const
Definition STAmount.cpp:314
static std::uint64_t const cValueMask
Definition STAmount.h:78
exponent_type mOffset
Definition STAmount.h:59
Issue const & issue() const
Definition STAmount.h:496
static std::uint64_t const cMaxNative
Definition STAmount.h:71
STAmount(A const &asset, Number const &number)
Definition STAmount.h:157
void set(std::int64_t v)
Definition STAmount.cpp:967
std::uint64_t mantissa() const noexcept
Definition STAmount.h:477
std::string getFullText() const override
Definition STAmount.cpp:673
STAmount(SerialIter &sit, SField const &name)
Definition STAmount.cpp:120
bool native() const noexcept
Definition STAmount.h:458
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
Definition STAmount.h:520
static std::uint64_t const uRateOne
Definition STAmount.h:80
A type which can be exported to a well known binary format.
Definition STBase.h:135
JSON (JavaScript Object Notation).
Definition json_errors.h:25
ripple::AccountID getOrThrow(Json::Value const &v, ripple::SField const &field)
Definition AccountID.h:131
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
bool operator<=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:629
STAmount divide(STAmount const &amount, Rate const &rate)
Definition Rate2.cpp:93
bool isXRP(AccountID const &c)
Definition AccountID.h:90
bool operator!=(Buffer const &lhs, Buffer const &rhs) noexcept
Definition Buffer.h:232
bool canSubtract(STAmount const &amt1, STAmount const &amt2)
Determines if it is safe to subtract one STAmount from another.
Definition STAmount.cpp:585
STAmount divRoundStrict(STAmount const &v1, STAmount const &v2, Asset const &asset, bool roundUp)
STAmount amountFromJson(SField const &name, Json::Value const &v)
bool canAdd(STAmount const &amt1, STAmount const &amt2)
Safely checks if two STAmount values can be added without overflow, underflow, or precision loss.
Definition STAmount.cpp:505
bool isLegalNet(STAmount const &value)
Definition STAmount.h:600
SerializedTypeID
Definition SField.h:110
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > safe_cast(Src s) noexcept
Definition safe_cast.h:41
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
STAmount amountFromQuality(std::uint64_t rate)
Definition STAmount.cpp:984
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition Rate2.cpp:53
std::uint64_t getRate(STAmount const &offerOut, STAmount const &offerIn)
Definition STAmount.cpp:463
bool operator>(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:623
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
bool operator<(Slice const &lhs, Slice const &rhs) noexcept
Definition Slice.h:223
STAmount divRound(STAmount const &v1, STAmount const &v2, Asset const &asset, bool roundUp)
Number operator-(Number const &x, Number const &y)
Definition Number.h:300
STAmount amountFromString(Asset const &asset, std::string const &amount)
Definition STAmount.cpp:996
STAmount mulRound(STAmount const &v1, STAmount const &v2, Asset const &asset, bool roundUp)
constexpr base_uint< Bits, Tag > operator+(base_uint< Bits, Tag > const &a, base_uint< Bits, Tag > const &b)
Definition base_uint.h:622
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
Definition base_uint.h:585
STAmount mulRoundStrict(STAmount const &v1, STAmount const &v2, Asset const &asset, bool roundUp)
bool operator>=(STAmount const &lhs, STAmount const &rhs)
Definition STAmount.h:635
STL namespace.
Zero allows classes to offer efficient comparisons to zero.
Definition Zero.h:43
Note, should be treated as flags that can be | and &.
Definition STBase.h:37