xrpld
Loading...
Searching...
No Matches
Asset.h
1#pragma once
2
3#include <xrpl/basics/Number.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/json/json_value.h>
7#include <xrpl/protocol/AccountID.h>
8#include <xrpl/protocol/Concepts.h>
9#include <xrpl/protocol/Issue.h>
10#include <xrpl/protocol/MPTIssue.h>
11#include <xrpl/protocol/UintTypes.h>
12
13#include <compare>
14#include <ostream>
15#include <stdexcept>
16#include <string>
17#include <variant>
18
19namespace xrpl {
20
21class STAmount;
22
23template <typename T>
24 requires(
28{
29 using amount_type = T;
30};
31
32/* Used to check for an asset with either badCurrency()
33 * or MPT with 0 account.
34 */
36{
37};
38
39inline BadAsset const&
41{
42 static BadAsset const kA;
43 return kA;
44}
45
46/* Asset is an abstraction of three different issue types: XRP, IOU, MPT.
47 * For historical reasons, two issue types XRP and IOU are wrapped in Issue
48 * type. Many functions and classes there were first written for Issue
49 * have been rewritten for Asset.
50 */
51class Asset
52{
53public:
56 using AmtType =
58
59private:
61
62public:
63 Asset() = default;
64
69 Asset(Issue const& issue) : issue_(issue)
70 {
71 }
72
73 Asset(MPTIssue const& mptIssue) : issue_(mptIssue)
74 {
75 }
76
77 Asset(MPTID const& issuanceID) : issue_(MPTIssue{issuanceID})
78 {
79 }
80
81 [[nodiscard]] AccountID const&
82 getIssuer() const;
83
84 template <ValidIssueType TIss>
85 constexpr TIss const&
86 get() const;
87
88 template <ValidIssueType TIss>
89 TIss&
90 get();
91
92 template <ValidIssueType TIss>
93 [[nodiscard]] constexpr bool
94 holds() const;
95
96 [[nodiscard]] std::string
97 getText() const;
98
99 [[nodiscard]] constexpr value_type const&
100 value() const;
101
102 [[nodiscard]] constexpr token_type
103 token() const;
104
105 void
106 setJson(json::Value& jv) const;
107
109 operator()(Number const&) const;
110
111 [[nodiscard]] constexpr AmtType
112 getAmountType() const;
113
114 // Custom, generic visit implementation
115 template <typename... Visitors>
116 constexpr auto
117 visit(Visitors&&... visitors) const -> decltype(auto)
118 {
119 // Simple delegation to the reusable utility, passing the internal
120 // variant data.
121 return detail::visit(issue_, std::forward<Visitors>(visitors)...);
122 }
123
124 [[nodiscard]] constexpr bool
125 native() const
126 {
127 return visit(
128 [&](Issue const& issue) { return issue.native(); },
129 [&](MPTIssue const&) { return false; });
130 }
131
132 [[nodiscard]] bool
133 integral() const
134 {
135 return visit(
136 [&](Issue const& issue) { return issue.native(); },
137 [&](MPTIssue const&) { return true; });
138 }
139
140 friend constexpr bool
141 operator==(Asset const& lhs, Asset const& rhs);
142
143 friend constexpr std::weak_ordering
144 operator<=>(Asset const& lhs, Asset const& rhs);
145
146 friend constexpr bool
147 operator==(Currency const& lhs, Asset const& rhs);
148
149 // rhs is either badCurrency() or MPT issuer is 0
150 friend constexpr bool
151 operator==(BadAsset const& lhs, Asset const& rhs);
152
157 friend constexpr bool
158 equalTokens(Asset const& lhs, Asset const& rhs);
159};
160
161template <ValidIssueType TIss>
163
164template <ValidIssueType TIss>
166
167inline json::Value
168toJson(Asset const& asset)
169{
170 json::Value jv;
171 asset.setJson(jv);
172 return jv;
173}
174
175template <ValidIssueType TIss>
176constexpr bool
178{
180}
181
182template <ValidIssueType TIss>
183[[nodiscard]] constexpr TIss const&
185{
187 Throw<std::logic_error>("Asset is not a requested issue");
188 return std::get<TIss>(issue_);
189}
190
191template <ValidIssueType TIss>
192TIss&
194{
196 Throw<std::logic_error>("Asset is not a requested issue");
197 return std::get<TIss>(issue_);
198}
199
200constexpr Asset::value_type const&
202{
203 return issue_;
204}
205
206constexpr Asset::token_type
208{
209 return visit(
210 [&](Issue const& issue) -> Asset::token_type { return issue.currency; },
211 [&](MPTIssue const& issue) -> Asset::token_type { return issue.getMptID(); });
212}
213
214constexpr Asset::AmtType
216{
217 return visit(
218 [&](Issue const& issue) -> Asset::AmtType {
219 constexpr AmountType<XRPAmount> kXRP;
220 constexpr AmountType<IOUAmount> kIOU;
221 return native() ? AmtType(kXRP) : AmtType(kIOU);
222 },
223 [&](MPTIssue const& issue) -> Asset::AmtType {
224 constexpr AmountType<MPTAmount> kMPT;
225 return AmtType(kMPT);
226 });
227}
228
229constexpr bool
230operator==(Asset const& lhs, Asset const& rhs)
231{
232 return std::visit(
233 [&]<typename TLhs, typename TRhs>(TLhs const& issLhs, TRhs const& issRhs) {
234 if constexpr (std::is_same_v<TLhs, TRhs>)
235 {
236 return issLhs == issRhs;
237 }
238 else
239 {
240 return false;
241 }
242 },
243 lhs.issue_,
244 rhs.issue_);
245}
246
248operator<=>(Asset const& lhs, Asset const& rhs)
249{
250 return std::visit(
251 []<ValidIssueType TLhs, ValidIssueType TRhs>(TLhs const& lhs, TRhs const& rhs) {
252 if constexpr (std::is_same_v<TLhs, TRhs>)
253 {
254 return std::weak_ordering(lhs <=> rhs);
255 }
256 else if constexpr (kIsIssueV<TLhs> && kIsMptissueV<TRhs>)
257 {
258 return std::weak_ordering::greater;
259 }
260 else
261 {
262 return std::weak_ordering::less;
263 }
264 },
265 lhs.issue_,
266 rhs.issue_);
267}
268
269constexpr bool
270operator==(Currency const& lhs, Asset const& rhs)
271{
272 return rhs.visit(
273 [&](Issue const& issue) { return issue.currency == lhs; },
274 [](MPTIssue const& issue) { return false; });
275}
276
277constexpr bool
278operator==(BadAsset const&, Asset const& rhs)
279{
280 return rhs.visit(
281 [](Issue const& issue) -> bool { return badCurrency() == issue.currency; },
282 [](MPTIssue const& issue) -> bool { return issue.getIssuer() == xrpAccount(); });
283}
284
285constexpr bool
286equalTokens(Asset const& lhs, Asset const& rhs)
287{
288 return std::visit(
289 [&]<typename TLhs, typename TRhs>(TLhs const& issLhs, TRhs const& issRhs) {
291 {
292 return issLhs.currency == issRhs.currency;
293 }
295 {
296 return issLhs.getMptID() == issRhs.getMptID();
297 }
298 else
299 {
300 return false;
301 }
302 },
303 lhs.issue_,
304 rhs.issue_);
305}
306
307inline bool
308isXRP(Asset const& asset)
309{
310 return asset.native();
311}
312
314to_string(Asset const& asset);
315
316bool
317validJSONAsset(json::Value const& jv);
318
319Asset
320assetFromJson(json::Value const& jv);
321
322inline bool
323isConsistent(Asset const& asset)
324{
325 return asset.visit(
326 [](Issue const& issue) { return isConsistent(issue); },
327 [](MPTIssue const&) { return true; });
328}
329
330inline bool
331validAsset(Asset const& asset)
332{
333 return asset.visit(
334 [](Issue const& issue) { return isConsistent(issue) && issue.currency != badCurrency(); },
335 [](MPTIssue const& issue) { return issue.getIssuer() != xrpAccount(); });
336}
337
338template <class Hasher>
339void
340hash_append(Hasher& h, Asset const& r)
341{
342 using beast::hash_append;
343 r.visit(
344 [&](Issue const& issue) { hash_append(h, issue); },
345 [&](MPTIssue const& issue) { hash_append(h, issue); });
346}
347
349operator<<(std::ostream& os, Asset const& x);
350
351} // namespace xrpl
Represents a JSON value.
Definition json_value.h:117
void setJson(json::Value &jv) const
Definition Asset.cpp:33
constexpr auto visit(Visitors &&... visitors) const -> decltype(auto)
Definition Asset.h:117
std::variant< Currency, MPTID > token_type
Definition Asset.h:55
constexpr token_type token() const
Definition Asset.h:207
std::variant< AmountType< XRPAmount >, AmountType< IOUAmount >, AmountType< MPTAmount > > AmtType
Definition Asset.h:56
constexpr TIss const & get() const
constexpr bool native() const
Definition Asset.h:125
STAmount operator()(Number const &) const
Definition Asset.cpp:39
std::string getText() const
Definition Asset.cpp:27
constexpr AmtType getAmountType() const
Definition Asset.h:215
Asset(Issue const &issue)
Conversions to Asset are implicit and conversions to specific issue type are explicit.
Definition Asset.h:69
value_type issue_
Definition Asset.h:60
AccountID const & getIssuer() const
Definition Asset.cpp:21
friend constexpr std::weak_ordering operator<=>(Asset const &lhs, Asset const &rhs)
Definition Asset.h:248
bool integral() const
Definition Asset.h:133
friend constexpr bool equalTokens(Asset const &lhs, Asset const &rhs)
Return true if both assets refer to the same currency (regardless of issuer) or MPT issuance.
Definition Asset.h:286
Asset(MPTID const &issuanceID)
Definition Asset.h:77
std::variant< Issue, MPTIssue > value_type
Definition Asset.h:54
constexpr bool holds() const
Definition Asset.h:177
Asset()=default
Asset(MPTIssue const &mptIssue)
Definition Asset.h:73
friend constexpr bool operator==(Asset const &lhs, Asset const &rhs)
Definition Asset.h:230
constexpr value_type const & value() const
Definition Asset.h:201
A currency issued by an account.
Definition Issue.h:18
Currency currency
Definition Issue.h:20
bool native() const
Definition Issue.cpp:54
AccountID const & getIssuer() const
Definition Issue.h:30
Number is a floating point type that can represent a wide range of values.
Definition Number.h:351
T forward(T... args)
T holds_alternative(T... args)
T is_same_v
void hash_append(Hasher &h, T const &t) noexcept
Logically concatenate input data to a Hasher.
constexpr auto visit(Variant &&v, Visitors &&... visitors) -> decltype(auto)
Definition Concepts.h:74
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
constexpr bool operator==(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
Definition base_uint.h:606
bool isXRP(AccountID const &c)
Definition AccountID.h:84
bool validJSONAsset(json::Value const &jv)
Definition Asset.cpp:51
BaseUInt< 160, detail::CurrencyTag > Currency
Currency is a hash representing a specific currency.
Definition UintTypes.h:42
std::ostream & operator<<(std::ostream &out, BaseUInt< Bits, Tag > const &u)
Definition base_uint.h:666
bool validAsset(Asset const &asset)
Definition Asset.h:331
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
json::Value toJson(Asset const &asset)
Definition Asset.h:168
constexpr std::strong_ordering operator<=>(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
Definition base_uint.h:585
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
Definition UintTypes.h:54
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
void hash_append(Hasher &h, Slice const &v)
Definition Slice.h:194
constexpr bool kIsIssueV
Definition Asset.h:162
bool isConsistent(Asset const &asset)
Definition Asset.h:323
constexpr bool kIsMptissueV
Definition Asset.h:165
AccountID const & xrpAccount()
Compute AccountID from public key.
BadAsset const & badAsset()
Definition Asset.h:40
Asset assetFromJson(json::Value const &jv)
Definition Asset.cpp:59
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
constexpr bool equalTokens(Asset const &lhs, Asset const &rhs)
Definition Asset.h:286
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
T visit(T... args)