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 const int cMinOffset = -96;
66 static const int cMaxOffset = 80;
67
68 // Maximum native value supported by the code
69 static const std::uint64_t cMinValue = 1000000000000000ull;
70 static const std::uint64_t cMaxValue = 9999999999999999ull;
71 static const std::uint64_t cMaxNative = 9000000000000000000ull;
72
73 // Max native value on network.
74 static const std::uint64_t cMaxNativeN = 100000000000000000ull;
75 static const std::uint64_t cIssuedCurrency = 0x8000000000000000ull;
76 static const std::uint64_t cPositive = 0x4000000000000000ull;
77 static const std::uint64_t 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 // Legacy support for new-style amounts
157 STAmount(IOUAmount const& amount, Issue const& issue);
158 STAmount(XRPAmount const& amount);
159 STAmount(MPTAmount const& amount, MPTIssue const& mptIssue);
160 operator Number() const;
161
162 //--------------------------------------------------------------------------
163 //
164 // Observers
165 //
166 //--------------------------------------------------------------------------
167
168 int
169 exponent() const noexcept;
170
171 bool
172 native() const noexcept;
173
174 template <ValidIssueType TIss>
175 constexpr bool
176 holds() const noexcept;
177
178 bool
179 negative() const noexcept;
180
181 std::uint64_t
182 mantissa() const noexcept;
183
184 Asset const&
185 asset() const;
186
187 template <ValidIssueType TIss>
188 constexpr TIss const&
189 get() const;
190
191 Issue const&
192 issue() const;
193
194 // These three are deprecated
195 Currency const&
196 getCurrency() const;
197
198 AccountID const&
199 getIssuer() const;
200
201 int
202 signum() const noexcept;
203
206 zeroed() const;
207
208 void
209 setJson(Json::Value&) const;
210
211 STAmount const&
212 value() const noexcept;
213
214 //--------------------------------------------------------------------------
215 //
216 // Operators
217 //
218 //--------------------------------------------------------------------------
219
220 explicit
221 operator bool() const noexcept;
222
223 STAmount&
224 operator+=(STAmount const&);
225 STAmount&
226 operator-=(STAmount const&);
227
228 STAmount& operator=(beast::Zero);
229
230 STAmount&
231 operator=(XRPAmount const& amount);
232
233 //--------------------------------------------------------------------------
234 //
235 // Modification
236 //
237 //--------------------------------------------------------------------------
238
239 void
240 negate();
241
242 void
243 clear();
244
245 // Zero while copying currency and issuer.
246 void
247 clear(Asset const& asset);
248
249 void
250 setIssuer(AccountID const& uIssuer);
251
253 void
254 setIssue(Asset const& asset);
255
256 //--------------------------------------------------------------------------
257 //
258 // STBase
259 //
260 //--------------------------------------------------------------------------
261
263 getSType() const override;
264
265 std::string
266 getFullText() const override;
267
268 std::string
269 getText() const override;
270
271 Json::Value getJson(JsonOptions) const override;
272
273 void
274 add(Serializer& s) const override;
275
276 bool
277 isEquivalent(const STBase& t) const override;
278
279 bool
280 isDefault() const override;
281
283 xrp() const;
285 iou() const;
287 mpt() const;
288
289private:
290 static std::unique_ptr<STAmount>
291 construct(SerialIter&, SField const& name);
292
293 void
294 set(std::int64_t v);
295 void
296 canonicalize();
297
298 STBase*
299 copy(std::size_t n, void* buf) const override;
300 STBase*
301 move(std::size_t n, void* buf) override;
302
303 STAmount&
304 operator=(IOUAmount const& iou);
305
306 friend class detail::STVar;
307
308 friend STAmount
309 operator+(STAmount const& v1, STAmount const& v2);
310};
311
312template <AssetType A>
314 SField const& name,
315 A const& asset,
318 bool negative,
319 unchecked)
320 : STBase(name)
321 , mAsset(asset)
325{
326}
327
328template <AssetType A>
330 A const& asset,
333 bool negative,
334 unchecked)
336{
337}
338
339template <AssetType A>
341 SField const& name,
342 A const& asset,
343 std::uint64_t mantissa,
344 int exponent,
345 bool negative)
346 : STBase(name)
347 , mAsset(asset)
348 , mValue(mantissa)
349 , mOffset(exponent)
350 , mIsNegative(negative)
351{
352 // mValue is uint64, but needs to fit in the range of int64
353 XRPL_ASSERT(
355 "ripple::STAmount::STAmount(SField, A, std::uint64_t, int, bool) : "
356 "maximum mantissa input");
357 canonicalize();
358}
359
360template <AssetType A>
361STAmount::STAmount(A const& asset, std::int64_t mantissa, int exponent)
362 : mAsset(asset), mOffset(exponent)
363{
364 set(mantissa);
365 canonicalize();
366}
367
368template <AssetType A>
370 A const& asset,
371 std::uint32_t mantissa,
372 int exponent,
373 bool negative)
374 : STAmount(asset, safe_cast<std::uint64_t>(mantissa), exponent, negative)
375{
376}
377
378template <AssetType A>
379STAmount::STAmount(A const& asset, int mantissa, int exponent)
380 : STAmount(asset, safe_cast<std::int64_t>(mantissa), exponent)
381{
382}
383
384// Legacy support for new-style amounts
385inline STAmount::STAmount(IOUAmount const& amount, Issue const& issue)
386 : mAsset(issue)
387 , mOffset(amount.exponent())
388 , mIsNegative(amount < beast::zero)
389{
390 if (mIsNegative)
391 mValue = unsafe_cast<std::uint64_t>(-amount.mantissa());
392 else
393 mValue = unsafe_cast<std::uint64_t>(amount.mantissa());
394
395 canonicalize();
396}
397
398inline STAmount::STAmount(MPTAmount const& amount, MPTIssue const& mptIssue)
399 : mAsset(mptIssue), mOffset(0), mIsNegative(amount < beast::zero)
400{
401 if (mIsNegative)
402 mValue = unsafe_cast<std::uint64_t>(-amount.value());
403 else
404 mValue = unsafe_cast<std::uint64_t>(amount.value());
405
406 canonicalize();
407}
408
409//------------------------------------------------------------------------------
410//
411// Creation
412//
413//------------------------------------------------------------------------------
414
415// VFALCO TODO The parameter type should be Quality not uint64_t
418
420amountFromString(Asset const& issue, std::string const& amount);
421
423amountFromJson(SField const& name, Json::Value const& v);
424
425bool
426amountFromJsonNoThrow(STAmount& result, Json::Value const& jvSource);
427
428// IOUAmount and XRPAmount define toSTAmount, defining this
429// trivial conversion here makes writing generic code easier
430inline STAmount const&
432{
433 return a;
434}
435
436//------------------------------------------------------------------------------
437//
438// Observers
439//
440//------------------------------------------------------------------------------
441
442inline int
443STAmount::exponent() const noexcept
444{
445 return mOffset;
446}
447
448inline bool
449STAmount::native() const noexcept
450{
451 return mAsset.native();
452}
453
454template <ValidIssueType TIss>
455constexpr bool
456STAmount::holds() const noexcept
457{
458 return mAsset.holds<TIss>();
459}
460
461inline bool
462STAmount::negative() const noexcept
463{
464 return mIsNegative;
465}
466
467inline std::uint64_t
468STAmount::mantissa() const noexcept
469{
470 return mValue;
471}
472
473inline Asset const&
475{
476 return mAsset;
477}
478
479template <ValidIssueType TIss>
480constexpr TIss const&
482{
483 return mAsset.get<TIss>();
484}
485
486inline Issue const&
488{
489 return get<Issue>();
490}
491
492inline Currency const&
494{
495 return mAsset.get<Issue>().currency;
496}
497
498inline AccountID const&
500{
501 return mAsset.getIssuer();
502}
503
504inline int
505STAmount::signum() const noexcept
506{
507 return mValue ? (mIsNegative ? -1 : 1) : 0;
508}
509
510inline STAmount
512{
513 return STAmount(mAsset);
514}
515
516inline STAmount::operator bool() const noexcept
517{
518 return *this != beast::zero;
519}
520
521inline STAmount::operator Number() const
522{
523 if (native())
524 return xrp();
525 if (mAsset.holds<MPTIssue>())
526 return mpt();
527 return iou();
528}
529
530inline STAmount&
532{
533 clear();
534 return *this;
535}
536
537inline STAmount&
539{
540 *this = STAmount(amount);
541 return *this;
542}
543
544inline void
546{
547 if (*this != beast::zero)
549}
550
551inline void
553{
554 // The -100 is used to allow 0 to sort less than a small positive values
555 // which have a negative exponent.
556 mOffset = native() ? 0 : -100;
557 mValue = 0;
558 mIsNegative = false;
559}
560
561inline void
563{
565 clear();
566}
567
568inline void
570{
571 mAsset.get<Issue>().account = uIssuer;
572}
573
574inline STAmount const&
575STAmount::value() const noexcept
576{
577 return *this;
578}
579
580inline bool
581isLegalNet(STAmount const& value)
582{
583 return !value.native() || (value.mantissa() <= STAmount::cMaxNativeN);
584}
585
586//------------------------------------------------------------------------------
587//
588// Operators
589//
590//------------------------------------------------------------------------------
591
592bool
593operator==(STAmount const& lhs, STAmount const& rhs);
594bool
595operator<(STAmount const& lhs, STAmount const& rhs);
596
597inline bool
598operator!=(STAmount const& lhs, STAmount const& rhs)
599{
600 return !(lhs == rhs);
601}
602
603inline bool
604operator>(STAmount const& lhs, STAmount const& rhs)
605{
606 return rhs < lhs;
607}
608
609inline bool
610operator<=(STAmount const& lhs, STAmount const& rhs)
611{
612 return !(rhs < lhs);
613}
614
615inline bool
616operator>=(STAmount const& lhs, STAmount const& rhs)
617{
618 return !(lhs < rhs);
619}
620
621STAmount
622operator-(STAmount const& value);
623
624//------------------------------------------------------------------------------
625//
626// Arithmetic
627//
628//------------------------------------------------------------------------------
629
630STAmount
631operator+(STAmount const& v1, STAmount const& v2);
632STAmount
633operator-(STAmount const& v1, STAmount const& v2);
634
635STAmount
636divide(STAmount const& v1, STAmount const& v2, Asset const& asset);
637
638STAmount
639multiply(STAmount const& v1, STAmount const& v2, Asset const& asset);
640
641// multiply rounding result in specified direction
642STAmount
644 STAmount const& v1,
645 STAmount const& v2,
646 Asset const& asset,
647 bool roundUp);
648
649// multiply following the rounding directions more precisely.
650STAmount
652 STAmount const& v1,
653 STAmount const& v2,
654 Asset const& asset,
655 bool roundUp);
656
657// divide rounding result in specified direction
658STAmount
660 STAmount const& v1,
661 STAmount const& v2,
662 Asset const& asset,
663 bool roundUp);
664
665// divide following the rounding directions more precisely.
666STAmount
668 STAmount const& v1,
669 STAmount const& v2,
670 Asset const& asset,
671 bool roundUp);
672
673// Someone is offering X for Y, what is the rate?
674// Rate: smaller is better, the taker wants the most out: in/out
675// VFALCO TODO Return a Quality object
677getRate(STAmount const& offerOut, STAmount const& offerIn);
678
679//------------------------------------------------------------------------------
680
681inline bool
682isXRP(STAmount const& amount)
683{
684 return amount.native();
685}
686
687// Since `canonicalize` does not have access to a ledger, this is needed to put
688// the low-level routine stAmountCanonicalize on an amendment switch. Only
689// transactions need to use this switchover. Outside of a transaction it's safe
690// to unconditionally use the new behavior.
691
692bool
694
695void
697
702{
703public:
705 {
707 }
708
710 {
712 }
713
714private:
715 bool saved_;
716};
717
718} // namespace ripple
719
720//------------------------------------------------------------------------------
721namespace Json {
722template <>
723inline ripple::STAmount
724getOrThrow(Json::Value const& v, ripple::SField const& field)
725{
726 using namespace ripple;
727 Json::StaticString const& key = field.getJsonName();
728 if (!v.isMember(key))
729 Throw<JsonMissingKeyError>(key);
730 Json::Value const& inner = v[key];
731 return amountFromJson(field, inner);
732}
733} // namespace Json
734#endif
Lightweight wrapper to tag static string.
Definition: json_value.h:62
Represents a JSON value.
Definition: json_value.h:148
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:949
bool native() const
Definition: Asset.h:96
constexpr TIss const & get() const
AccountID const & getIssuer() const
Definition: Asset.cpp:35
constexpr bool holds() const
Definition: Asset.h:119
Tracks the number of instances of an object.
Floating point representation of amounts with high dynamic range.
Definition: IOUAmount.h:47
std::int64_t mantissa() const noexcept
Definition: IOUAmount.h:173
A currency issued by an account.
Definition: Issue.h:36
constexpr value_type value() const
Returns the underlying value.
Definition: MPTAmount.h:136
Identifies fields.
Definition: SField.h:144
RAII class to set and restore the STAmount canonicalize switchover.
Definition: STAmount.h:702
STAmountSO(bool v)
Definition: STAmount.h:704
constexpr bool holds() const noexcept
Definition: STAmount.h:456
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:636
IOUAmount iou() const
Definition: STAmount.cpp:320
static const std::uint64_t cIssuedCurrency
Definition: STAmount.h:75
void canonicalize()
Definition: STAmount.cpp:714
bool mIsNegative
Definition: STAmount.h:60
STAmount & operator=(beast::Zero)
Definition: STAmount.h:531
int exponent() const noexcept
Definition: STAmount.h:443
STBase * move(std::size_t n, void *buf) override
Definition: STAmount.cpp:294
Asset const & asset() const
Definition: STAmount.h:474
constexpr TIss const & get() const
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:569
Currency const & getCurrency() const
Definition: STAmount.h:493
friend class detail::STVar
Definition: STAmount.h:306
static const std::uint64_t cMaxNative
Definition: STAmount.h:71
static std::unique_ptr< STAmount > construct(SerialIter &, SField const &name)
Definition: STAmount.cpp:282
void setIssue(Asset const &asset)
Set the Issue for this amount.
Definition: STAmount.cpp:468
XRPAmount xrp() const
Definition: STAmount.cpp:305
void setJson(Json::Value &) const
Definition: STAmount.cpp:507
bool isDefault() const override
Definition: STAmount.cpp:690
void add(Serializer &s) const override
Definition: STAmount.cpp:644
static const int cMaxOffset
Definition: STAmount.h:66
SerializedTypeID getSType() const override
Definition: STAmount.cpp:531
mantissa_type mValue
Definition: STAmount.h:58
int signum() const noexcept
Definition: STAmount.h:505
STAmount const & value() const noexcept
Definition: STAmount.h:575
std::string getText() const override
Definition: STAmount.cpp:547
bool negative() const noexcept
Definition: STAmount.h:462
AccountID const & getIssuer() const
Definition: STAmount.h:499
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:288
static const std::uint64_t cPositive
Definition: STAmount.h:76
MPTAmount mpt() const
Definition: STAmount.cpp:335
exponent_type mOffset
Definition: STAmount.h:59
Issue const & issue() const
Definition: STAmount.h:487
static const std::uint64_t cMinValue
Definition: STAmount.h:69
static const std::uint64_t cMPToken
Definition: STAmount.h:77
static const int cMinOffset
Definition: STAmount.h:65
bool isEquivalent(const STBase &t) const override
Definition: STAmount.cpp:683
void set(std::int64_t v)
Definition: STAmount.cpp:837
std::uint64_t mantissa() const noexcept
Definition: STAmount.h:468
static const std::uint64_t cValueMask
Definition: STAmount.h:78
static const std::uint64_t cMaxNativeN
Definition: STAmount.h:74
std::string getFullText() const override
Definition: STAmount.cpp:537
STAmount(SerialIter &sit, SField const &name)
Definition: STAmount.cpp:142
bool native() const noexcept
Definition: STAmount.h:449
static const std::uint64_t cMaxValue
Definition: STAmount.h:70
STAmount zeroed() const
Returns a zero value with the same issuer and currency.
Definition: STAmount.h:511
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:126
JSON (JavaScript Object Notation).
Definition: json_errors.h:25
ripple::AccountID getOrThrow(Json::Value const &v, ripple::SField const &field)
Definition: AccountID.h:132
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
STAmount amountFromString(Asset const &issue, std::string const &amount)
Definition: STAmount.cpp:866
bool operator<=(STAmount const &lhs, STAmount const &rhs)
Definition: STAmount.h:610
STAmount divide(STAmount const &amount, Rate const &rate)
Definition: Rate2.cpp:93
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
bool operator!=(Buffer const &lhs, Buffer const &rhs) noexcept
Definition: Buffer.h:231
STAmount divRoundStrict(STAmount const &v1, STAmount const &v2, Asset const &asset, bool roundUp)
Definition: STAmount.cpp:1659
STAmount amountFromJson(SField const &name, Json::Value const &v)
Definition: STAmount.cpp:932
bool isLegalNet(STAmount const &value)
Definition: STAmount.h:581
SerializedTypeID
Definition: SField.h:108
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:42
STAmount toSTAmount(IOUAmount const &iou, Issue const &iss)
STAmount amountFromQuality(std::uint64_t rate)
Definition: STAmount.cpp:854
bool getSTAmountCanonicalizeSwitchover()
Definition: STAmount.cpp:82
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:483
bool operator>(STAmount const &lhs, STAmount const &rhs)
Definition: STAmount.h:604
bool amountFromJsonNoThrow(STAmount &result, Json::Value const &jvSource)
Definition: STAmount.cpp:1061
bool operator<(Slice const &lhs, Slice const &rhs) noexcept
Definition: Slice.h:223
void setSTAmountCanonicalizeSwitchover(bool v)
Definition: STAmount.cpp:88
STAmount divRound(STAmount const &v1, STAmount const &v2, Asset const &asset, bool roundUp)
Definition: STAmount.cpp:1649
Number operator-(Number const &x, Number const &y)
Definition: Number.h:282
STAmount mulRound(STAmount const &v1, STAmount const &v2, Asset const &asset, bool roundUp)
Definition: STAmount.cpp:1542
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)
Definition: STAmount.cpp:1553
bool operator>=(STAmount const &lhs, STAmount const &rhs)
Definition: STAmount.h:616
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:38