rippled
Loading...
Searching...
No Matches
mpt.cpp
1#include <test/jtx.h>
2
3#include <xrpl/protocol/SField.h>
4#include <xrpl/protocol/jss.h>
5
6namespace xrpl {
7namespace test {
8namespace jtx {
9
10void
15
16void
21
22void
24{
25 env.test.expect(cb_());
26}
27
30{
32 for (auto const& h : holders)
33 {
34 if (accounts.find(h.human()) != accounts.cend())
35 Throw<std::runtime_error>("Duplicate holder");
36 accounts.emplace(h.human(), h);
37 }
38 return accounts;
39}
40
41MPTTester::MPTTester(Env& env, Account const& issuer, MPTInit const& arg)
42 : env_(env)
43 , issuer_(issuer)
44 , holders_(makeHolders(arg.holders))
45 , close_(arg.close)
46{
47 if (arg.fund)
48 {
49 env_.fund(arg.xrp, issuer_);
50 for (auto it : holders_)
51 env_.fund(arg.xrpHolders, it.second);
52 }
53 if (close_)
54 env.close();
55 if (arg.fund)
56 {
58 for (auto it : holders_)
59 {
60 if (issuer_.id() == it.second.id())
61 Throw<std::runtime_error>("Issuer can't be holder");
62 env_.require(owners(it.second, 0));
63 }
64 }
65 if (arg.create)
66 create(*arg.create);
67}
68
70 Env& env,
71 Account const& issuer,
72 MPTID const& id,
73 std::vector<Account> const& holders,
74 bool close)
75 : env_(env)
76 , issuer_(issuer)
77 , holders_(makeHolders(holders))
78 , id_(id)
79 , close_(close)
80{
81}
82
83static MPTCreate
85{
86 if (arg.pay)
87 return {
88 .maxAmt = arg.maxAmt,
89 .transferFee = arg.transferFee,
90 .pay = {{arg.holders, *arg.pay}},
91 .flags = arg.flags,
92 .authHolder = arg.authHolder};
93 return {
94 .maxAmt = arg.maxAmt,
95 .transferFee = arg.transferFee,
96 .authorize = arg.holders,
97 .flags = arg.flags,
98 .authHolder = arg.authHolder};
99}
100
102 : MPTTester{
103 arg.env,
104 arg.issuer,
105 MPTInit{
106 .fund = arg.fund,
107 .close = arg.close,
108 .create = makeMPTCreate(arg)}}
109{
110}
111
112MPTTester::operator MPT() const
113{
114 if (!id_)
115 Throw<std::runtime_error>("MPT has not been created");
116 return MPT("", *id_);
117}
118
121{
122 if (!arg.issuer)
123 Throw<std::runtime_error>("MPTTester::createjv: issuer is not set");
124 Json::Value jv;
125 jv[sfAccount] = arg.issuer->human();
126 if (arg.assetScale)
127 jv[sfAssetScale] = *arg.assetScale;
128 if (arg.transferFee)
129 jv[sfTransferFee] = *arg.transferFee;
130 if (arg.metadata)
131 jv[sfMPTokenMetadata] = strHex(*arg.metadata);
132 if (arg.maxAmt)
133 jv[sfMaximumAmount] = std::to_string(*arg.maxAmt);
134 if (arg.domainID)
135 jv[sfDomainID] = to_string(*arg.domainID);
136 if (arg.mutableFlags)
137 jv[sfMutableFlags] = *arg.mutableFlags;
138 jv[sfTransactionType] = jss::MPTokenIssuanceCreate;
139
140 return jv;
141}
142
143void
145{
146 if (id_)
147 Throw<std::runtime_error>("MPT can't be reused");
150 {.issuer = issuer_,
151 .maxAmt = arg.maxAmt,
152 .assetScale = arg.assetScale,
153 .transferFee = arg.transferFee,
154 .metadata = arg.metadata,
155 .mutableFlags = arg.mutableFlags,
156 .domainID = arg.domainID});
157 if (submit(arg, jv) != tesSUCCESS)
158 {
159 // Verify issuance doesn't exist
160 env_.require(requireAny([&]() -> bool {
161 return env_.le(keylet::mptIssuance(*id_)) == nullptr;
162 }));
163
164 id_.reset();
165 }
166 else
167 {
168 env_.require(mptflags(*this, arg.flags.value_or(0)));
169 auto authAndPay = [&](auto const& accts, auto const&& getAcct) {
170 for (auto const& it : accts)
171 {
172 authorize({.account = getAcct(it)});
173 if ((arg.flags.value_or(0) & tfMPTRequireAuth) &&
174 arg.authHolder)
175 authorize({.account = issuer_, .holder = getAcct(it)});
176 if (arg.pay && arg.pay->first.empty())
177 pay(issuer_, getAcct(it), arg.pay->second);
178 }
179 if (arg.pay)
180 {
181 for (auto const& p : arg.pay->first)
182 pay(issuer_, p, arg.pay->second);
183 }
184 };
185 if (arg.authorize)
186 {
187 if (arg.authorize->empty())
188 authAndPay(holders_, [](auto const& it) { return it.second; });
189 else
190 authAndPay(*arg.authorize, [](auto const& it) { return it; });
191 }
192 else if (arg.pay)
193 {
194 if (arg.pay->first.empty())
195 authAndPay(holders_, [](auto const& it) { return it.second; });
196 else
197 authAndPay(arg.pay->first, [](auto const& it) { return it; });
198 }
199 }
200}
201
204{
205 Json::Value jv;
206 if (!arg.issuer || !arg.id)
207 Throw<std::runtime_error>("MPTTester::destroyjv: issuer/id is not set");
208 jv[sfAccount] = arg.issuer->human();
209 jv[sfMPTokenIssuanceID] = to_string(*arg.id);
210 jv[sfTransactionType] = jss::MPTokenIssuanceDestroy;
211
212 return jv;
213}
214
215void
217{
218 if (!arg.id && !id_)
219 Throw<std::runtime_error>("MPT has not been created");
221 {.issuer = arg.issuer ? arg.issuer : issuer_,
222 .id = arg.id ? arg.id : id_});
223 submit(arg, jv);
224}
225
226Account const&
227MPTTester::holder(std::string const& holder_) const
228{
229 auto const& it = holders_.find(holder_);
230 if (it == holders_.cend())
231 Throw<std::runtime_error>("Holder is not found");
232 return it->second;
233}
234
237{
238 Json::Value jv;
239 if (!arg.account || !arg.id)
240 Throw<std::runtime_error>(
241 "MPTTester::authorizejv: issuer/id is not set");
242 jv[sfAccount] = arg.account->human();
243 jv[sfMPTokenIssuanceID] = to_string(*arg.id);
244 if (arg.holder)
245 jv[sfHolder] = arg.holder->human();
246 jv[sfTransactionType] = jss::MPTokenAuthorize;
247
248 return jv;
249}
250
251void
253{
254 if (!arg.id && !id_)
255 Throw<std::runtime_error>("MPT has not been created");
257 .account = arg.account ? arg.account : issuer_,
258 .holder = arg.holder,
259 .id = arg.id ? arg.id : id_,
260 });
261 if (auto const result = submit(arg, jv); result == tesSUCCESS)
262 {
263 // Issuer authorizes
264 if (!arg.account || *arg.account == issuer_)
265 {
266 auto const flags = getFlags(arg.holder);
267 // issuer un-authorizes the holder
268 if (arg.flags.value_or(0) == tfMPTUnauthorize)
269 env_.require(mptflags(*this, flags, arg.holder));
270 // issuer authorizes the holder
271 else
273 mptflags(*this, flags | lsfMPTAuthorized, arg.holder));
274 }
275 // Holder authorizes
276 else if (arg.flags.value_or(0) != tfMPTUnauthorize)
277 {
278 auto const flags = getFlags(arg.account);
279 // holder creates a token
280 env_.require(mptflags(*this, flags, arg.account));
281 env_.require(mptbalance(*this, *arg.account, 0));
282 }
283 else
284 {
285 // Verify that the MPToken doesn't exist.
286 forObject(
287 [&](SLEP const& sle) { return env_.test.BEAST_EXPECT(!sle); },
288 arg.account);
289 }
290 }
291 else if (
292 arg.account && *arg.account != issuer_ &&
293 arg.flags.value_or(0) != tfMPTUnauthorize && id_)
294 {
295 if (result == tecDUPLICATE)
296 {
297 // Verify that MPToken already exists
298 env_.require(requireAny([&]() -> bool {
299 return env_.le(keylet::mptoken(*id_, arg.account->id())) !=
300 nullptr;
301 }));
302 }
303 else
304 {
305 // Verify MPToken doesn't exist if holder failed authorizing(unless
306 // it already exists)
307 env_.require(requireAny([&]() -> bool {
308 return env_.le(keylet::mptoken(*id_, arg.account->id())) ==
309 nullptr;
310 }));
311 }
312 }
313}
314
315void
317{
318 for (auto const& holder : holders)
319 {
320 authorize({.account = holder});
321 }
322}
323
326{
327 Json::Value jv;
328 if (!arg.account || !arg.id)
329 Throw<std::runtime_error>("MPTTester::setjv: issuer/id is not set");
330 jv[sfAccount] = arg.account->human();
331 jv[sfMPTokenIssuanceID] = to_string(*arg.id);
332 if (arg.holder)
333 {
335 [&jv]<typename T>(T const& holder) {
336 if constexpr (std::is_same_v<T, Account>)
337 jv[sfHolder] = holder.human();
338 else if constexpr (std::is_same_v<T, AccountID>)
339 jv[sfHolder] = toBase58(holder);
340 },
341 *arg.holder);
342 }
343
344 if (arg.delegate)
345 jv[sfDelegate] = arg.delegate->human();
346 if (arg.domainID)
347 jv[sfDomainID] = to_string(*arg.domainID);
348 if (arg.mutableFlags)
349 jv[sfMutableFlags] = *arg.mutableFlags;
350 if (arg.transferFee)
351 jv[sfTransferFee] = *arg.transferFee;
352 if (arg.metadata)
353 jv[sfMPTokenMetadata] = strHex(*arg.metadata);
354 jv[sfTransactionType] = jss::MPTokenIssuanceSet;
355
356 return jv;
357}
358
359void
361{
362 if (!arg.id && !id_)
363 Throw<std::runtime_error>("MPT has not been created");
364 Json::Value jv = setjv(
365 {.account = arg.account ? arg.account : issuer_,
366 .holder = arg.holder,
367 .id = arg.id ? arg.id : id_,
368 .mutableFlags = arg.mutableFlags,
369 .transferFee = arg.transferFee,
370 .metadata = arg.metadata,
371 .delegate = arg.delegate,
372 .domainID = arg.domainID});
373 if (submit(arg, jv) == tesSUCCESS &&
374 (arg.flags.value_or(0) || arg.mutableFlags))
375 {
376 auto require = [&](std::optional<Account> const& holder,
377 bool unchanged) {
378 auto flags = getFlags(holder);
379 if (!unchanged)
380 {
381 if (arg.flags)
382 {
383 if (*arg.flags & tfMPTLock)
385 else if (*arg.flags & tfMPTUnlock)
386 flags &= ~lsfMPTLocked;
387 }
388
389 if (arg.mutableFlags)
390 {
393 else if (*arg.mutableFlags & tmfMPTClearCanLock)
394 flags &= ~lsfMPTCanLock;
395
398 else if (*arg.mutableFlags & tmfMPTClearRequireAuth)
399 flags &= ~lsfMPTRequireAuth;
400
403 else if (*arg.mutableFlags & tmfMPTClearCanEscrow)
404 flags &= ~lsfMPTCanEscrow;
405
408 else if (*arg.mutableFlags & tmfMPTClearCanClawback)
409 flags &= ~lsfMPTCanClawback;
410
413 else if (*arg.mutableFlags & tmfMPTClearCanTrade)
414 flags &= ~lsfMPTCanTrade;
415
418 else if (*arg.mutableFlags & tmfMPTClearCanTransfer)
419 flags &= ~lsfMPTCanTransfer;
420 }
421 }
422 env_.require(mptflags(*this, flags, holder));
423 };
424 if (arg.account)
425 require(std::nullopt, arg.holder.has_value());
426 if (auto const account =
427 (arg.holder ? std::get_if<Account>(&(*arg.holder)) : nullptr))
428 require(*account, false);
429 }
430}
431
432bool
434 std::function<bool(SLEP const& sle)> const& cb,
435 std::optional<Account> const& holder_) const
436{
437 if (!id_)
438 Throw<std::runtime_error>("MPT has not been created");
439 auto const key = holder_ ? keylet::mptoken(*id_, holder_->id())
441 if (auto const sle = env_.le(key))
442 return cb(sle);
443 return false;
444}
445
446[[nodiscard]] bool
448{
449 return forObject([&](SLEP const& sle) -> bool {
450 if (sle->isFieldPresent(sfDomainID))
451 return expected == sle->getFieldH256(sfDomainID);
452 return (!expected.has_value());
453 });
454}
455
456[[nodiscard]] bool
458 Account const& holder_,
459 std::int64_t expectedAmount) const
460{
461 return forObject(
462 [&](SLEP const& sle) { return expectedAmount == (*sle)[sfMPTAmount]; },
463 holder_);
464}
465
466[[nodiscard]] bool
468{
469 return forObject([&](SLEP const& sle) {
470 return expectedAmount == (*sle)[sfOutstandingAmount];
471 });
472}
473
474[[nodiscard]] bool
476 uint32_t const expectedFlags,
477 std::optional<Account> const& holder) const
478{
479 return expectedFlags == getFlags(holder);
480}
481
482[[nodiscard]] bool
484{
485 return forObject([&](SLEP const& sle) -> bool {
486 if (sle->isFieldPresent(sfMPTokenMetadata))
487 return strHex(sle->getFieldVL(sfMPTokenMetadata)) ==
488 strHex(metadata);
489 return false;
490 });
491}
492
493[[nodiscard]] bool
495{
496 return forObject([&](SLEP const& sle) -> bool {
497 return sle->isFieldPresent(sfMPTokenMetadata);
498 });
499}
500
501[[nodiscard]] bool
503{
504 return forObject([&](SLEP const& sle) -> bool {
505 if (sle->isFieldPresent(sfTransferFee))
506 return sle->getFieldU16(sfTransferFee) == transferFee;
507 return false;
508 });
509}
510
511[[nodiscard]] bool
513{
514 return forObject([&](SLEP const& sle) -> bool {
515 return sle->isFieldPresent(sfTransferFee);
516 });
517}
518
519void
521 Account const& src,
522 Account const& dest,
526{
527 if (!id_)
528 Throw<std::runtime_error>("MPT has not been created");
529 auto const srcAmt = getBalance(src);
530 auto const destAmt = getBalance(dest);
531 auto const outstnAmt = getBalance(issuer_);
532
533 if (credentials)
534 env_(
535 jtx::pay(src, dest, mpt(amount)),
536 ter(err.value_or(tesSUCCESS)),
537 credentials::ids(*credentials));
538 else
539 env_(jtx::pay(src, dest, mpt(amount)), ter(err.value_or(tesSUCCESS)));
540
541 if (env_.ter() != tesSUCCESS)
542 amount = 0;
543 if (close_)
544 env_.close();
545 if (src == issuer_)
546 {
547 env_.require(mptbalance(*this, src, srcAmt + amount));
548 env_.require(mptbalance(*this, dest, destAmt + amount));
549 }
550 else if (dest == issuer_)
551 {
552 env_.require(mptbalance(*this, src, srcAmt - amount));
553 env_.require(mptbalance(*this, dest, destAmt - amount));
554 }
555 else
556 {
557 STAmount const saAmount = {*id_, amount};
558 auto const actual =
559 multiply(saAmount, transferRate(*env_.current(), *id_))
560 .mpt()
561 .value();
562 // Sender pays the transfer fee if any
563 env_.require(mptbalance(*this, src, srcAmt - actual));
564 env_.require(mptbalance(*this, dest, destAmt + amount));
565 // Outstanding amount is reduced by the transfer fee if any
566 env_.require(mptbalance(*this, issuer_, outstnAmt - (actual - amount)));
567 }
568}
569
570void
572 Account const& issuer,
573 Account const& holder,
576{
577 if (!id_)
578 Throw<std::runtime_error>("MPT has not been created");
579 auto const issuerAmt = getBalance(issuer);
580 auto const holderAmt = getBalance(holder);
582 if (env_.ter() != tesSUCCESS)
583 amount = 0;
584 if (close_)
585 env_.close();
586
588 mptbalance(*this, issuer, issuerAmt - std::min(holderAmt, amount)));
590 mptbalance(*this, holder, holderAmt - std::min(holderAmt, amount)));
591}
592
595{
596 if (!id_)
597 Throw<std::runtime_error>("MPT has not been created");
599}
600
601MPTTester::operator Asset() const
602{
603 if (!id_)
604 Throw<std::runtime_error>("MPT has not been created");
605 return Asset(*id_);
606}
607
609MPTTester::getBalance(Account const& account) const
610{
611 if (!id_)
612 Throw<std::runtime_error>("MPT has not been created");
613 if (account == issuer_)
614 {
615 if (auto const sle = env_.le(keylet::mptIssuance(*id_)))
616 return sle->getFieldU64(sfOutstandingAmount);
617 }
618 else
619 {
620 if (auto const sle = env_.le(keylet::mptoken(*id_, account.id())))
621 return sle->getFieldU64(sfMPTAmount);
622 }
623 return 0;
624}
625
628{
630 if (!forObject(
631 [&](SLEP const& sle) {
632 flags = sle->getFlags();
633 return true;
634 },
635 holder))
636 Throw<std::runtime_error>("Failed to get the flags");
637 return flags;
638}
639
640MPT
642{
643 return MPT(name, issuanceID());
644}
645
648{
649 return MPT("", issuanceID())(amount);
650}
651
652} // namespace jtx
653} // namespace test
654} // namespace xrpl
Represents a JSON value.
Definition json_value.h:131
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
Definition suite.h:226
constexpr value_type value() const
Returns the underlying value.
Definition MPTAmount.h:114
MPTAmount mpt() const
Definition STAmount.cpp:295
Immutable cryptographic account descriptor.
Definition Account.h:20
std::string const & human() const
Returns the human readable public key.
Definition Account.h:99
std::string const & name() const
Return the name.
Definition Account.h:68
AccountID id() const
Returns the Account ID.
Definition Account.h:92
A transaction testing environment.
Definition Env.h:102
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:104
TER ter() const
Return the TER for the last JTx.
Definition Env.h:581
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition Env.cpp:260
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:272
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition Env.cpp:251
beast::unit_test::suite & test
Definition Env.h:104
void require(Args const &... args)
Check a set of requirements.
Definition Env.h:530
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:314
std::unordered_map< std::string, Account > const holders_
Definition mpt.h:166
MPTTester(Env &env, Account const &issuer, MPTInit const &constr={})
Definition mpt.cpp:41
bool forObject(std::function< bool(SLEP const &sle)> const &cb, std::optional< Account > const &holder=std::nullopt) const
Definition mpt.cpp:433
void set(MPTSet const &set={})
Definition mpt.cpp:360
bool checkMPTokenAmount(Account const &holder, std::int64_t expectedAmount) const
Definition mpt.cpp:457
std::optional< MPTID > id_
Definition mpt.h:167
void pay(Account const &src, Account const &dest, std::int64_t amount, std::optional< TER > err=std::nullopt, std::optional< std::vector< std::string > > credentials=std::nullopt)
Definition mpt.cpp:520
Account const & holder(std::string const &h) const
Definition mpt.cpp:227
void create(MPTCreate const &arg=MPTCreate{})
Definition mpt.cpp:144
bool isTransferFeePresent() const
Definition mpt.cpp:512
bool checkMetadata(std::string const &metadata) const
Definition mpt.cpp:483
bool checkFlags(uint32_t const expectedFlags, std::optional< Account > const &holder=std::nullopt) const
Definition mpt.cpp:475
bool isMetadataPresent() const
Definition mpt.cpp:494
MPT operator[](std::string const &name) const
Definition mpt.cpp:641
void authorizeHolders(Holders const &holders)
Definition mpt.cpp:316
Account const & issuer() const
Definition mpt.h:236
void authorize(MPTAuthorize const &arg=MPTAuthorize{})
Definition mpt.cpp:252
MPTID const & issuanceID() const
Definition mpt.h:261
std::int64_t getBalance(Account const &account) const
Definition mpt.cpp:609
Account const issuer_
Definition mpt.h:165
void claw(Account const &issuer, Account const &holder, std::int64_t amount, std::optional< TER > err=std::nullopt)
Definition mpt.cpp:571
TER submit(A const &arg, Json::Value const &jv)
Definition mpt.h:288
static Json::Value setjv(MPTSet const &set={})
Definition mpt.cpp:325
static Json::Value destroyjv(MPTDestroy const &arg=MPTDestroy{})
Definition mpt.cpp:203
static Json::Value createjv(MPTCreate const &arg=MPTCreate{})
Definition mpt.cpp:120
PrettyAmount mpt(std::int64_t amount) const
Definition mpt.cpp:594
static Json::Value authorizejv(MPTAuthorize const &arg=MPTAuthorize{})
Definition mpt.cpp:236
void destroy(MPTDestroy const &arg=MPTDestroy{})
Definition mpt.cpp:216
bool checkTransferFee(std::uint16_t transferFee) const
Definition mpt.cpp:502
bool checkDomainID(std::optional< uint256 > expected) const
Definition mpt.cpp:447
std::uint32_t getFlags(std::optional< Account > const &holder) const
Definition mpt.cpp:627
static std::unordered_map< std::string, Account > makeHolders(std::vector< Account > const &holders)
Definition mpt.cpp:29
PrettyAmount operator()(std::uint64_t amount) const
Definition mpt.cpp:647
bool checkMPTokenOutstandingAmount(std::int64_t expectedAmount) const
Definition mpt.cpp:467
Converts to MPT Issue or STAmount.
Match set account flags.
Definition flags.h:109
Account const & account_
Definition mpt.h:45
MPTTester const & tester_
Definition mpt.h:44
std::int64_t const amount_
Definition mpt.h:46
void operator()(Env &env) const
Definition mpt.cpp:17
std::uint32_t flags_
Definition mpt.h:24
std::optional< Account > holder_
Definition mpt.h:25
MPTTester & tester_
Definition mpt.h:23
void operator()(Env &env) const
Definition mpt.cpp:11
Match the number of items in the account's owner directory.
Definition owners.h:54
std::function< bool()> cb_
Definition mpt.h:61
void operator()(Env &env) const
Definition mpt.cpp:23
Check a set of conditions.
Definition require.h:47
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition ter.h:16
T emplace(T... args)
T cend(T... args)
T find(T... args)
T is_same_v
T min(T... args)
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
Definition Indexes.cpp:508
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
Definition Indexes.cpp:522
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount, NetClock::duration const &settleDelay, PublicKey const &pk, std::optional< NetClock::time_point > const &cancelAfter, std::optional< std::uint32_t > const &dstTag)
Json::Value claw(Account const &account, STAmount const &amount, std::optional< Account > const &mptHolder)
Definition trust.cpp:50
static MPTCreate makeMPTCreate(MPTInitDef const &arg)
Definition mpt.cpp:84
void fund(jtx::Env &env, jtx::Account const &gw, std::vector< jtx::Account > const &accounts, std::vector< STAmount > const &amts, Fund how)
Definition AMMTest.cpp:18
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Definition pay.cpp:11
auto const amount
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
constexpr std::uint32_t const tmfMPTClearCanTransfer
Definition TxFlags.h:173
constexpr std::uint32_t const tmfMPTClearCanLock
Definition TxFlags.h:165
constexpr std::uint32_t const tmfMPTClearCanClawback
Definition TxFlags.h:175
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:11
constexpr std::uint32_t const tfMPTRequireAuth
Definition TxFlags.h:130
constexpr std::uint32_t const tmfMPTClearCanEscrow
Definition TxFlags.h:169
constexpr std::uint32_t const tmfMPTSetRequireAuth
Definition TxFlags.h:166
constexpr std::uint32_t const tmfMPTClearRequireAuth
Definition TxFlags.h:167
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition Rate2.cpp:34
constexpr std::uint32_t const tfMPTUnlock
Definition TxFlags.h:158
constexpr std::uint32_t const tmfMPTSetCanLock
Definition TxFlags.h:164
constexpr std::uint32_t const tfMPTLock
Definition TxFlags.h:157
Rate transferRate(ReadView const &view, AccountID const &issuer)
Returns IOU issuer transfer fee as Rate.
Definition View.cpp:864
constexpr std::uint32_t const tmfMPTClearCanTrade
Definition TxFlags.h:171
constexpr std::uint32_t const tfMPTUnauthorize
Definition TxFlags.h:153
constexpr std::uint32_t const tmfMPTSetCanTrade
Definition TxFlags.h:170
constexpr std::uint32_t const tmfMPTSetCanClawback
Definition TxFlags.h:174
constexpr std::uint32_t const tmfMPTSetCanEscrow
Definition TxFlags.h:168
@ tecDUPLICATE
Definition TER.h:297
@ lsfMPTCanLock
@ lsfMPTCanEscrow
@ lsfMPTRequireAuth
@ lsfMPTCanTrade
@ lsfMPTLocked
@ lsfMPTAuthorized
@ lsfMPTCanTransfer
@ lsfMPTCanClawback
MPTID makeMptID(std::uint32_t sequence, AccountID const &account)
Definition Indexes.cpp:152
@ tesSUCCESS
Definition TER.h:226
constexpr std::uint32_t const tmfMPTSetCanTransfer
Definition TxFlags.h:172
T has_value(T... args)
std::optional< Account > holder
Definition mpt.h:138
std::optional< Account > account
Definition mpt.h:137
std::optional< MPTID > id
Definition mpt.h:139
std::optional< std::uint32_t > flags
Definition mpt.h:142
std::optional< std::uint8_t > assetScale
Definition mpt.h:79
std::optional< std::uint32_t > mutableFlags
Definition mpt.h:92
std::optional< std::string > metadata
Definition mpt.h:81
std::optional< std::uint32_t > flags
Definition mpt.h:91
std::optional< uint256 > domainID
Definition mpt.h:94
std::optional< std::uint64_t > maxAmt
Definition mpt.h:78
std::optional< Account > issuer
Definition mpt.h:77
std::optional< std::pair< std::vector< Account >, std::uint64_t > > pay
Definition mpt.h:89
std::optional< std::uint16_t > transferFee
Definition mpt.h:80
std::optional< std::vector< Account > > authorize
Definition mpt.h:86
std::optional< Account > issuer
Definition mpt.h:127
std::optional< MPTID > id
Definition mpt.h:128
std::uint16_t transferFee
Definition mpt.h:115
std::uint32_t flags
Definition mpt.h:117
std::optional< std::uint64_t > maxAmt
Definition mpt.h:121
std::optional< std::uint64_t > pay
Definition mpt.h:116
std::optional< MPTCreate > create
Definition mpt.h:106
PrettyAmount const xrp
Definition mpt.h:101
PrettyAmount const xrpHolders
Definition mpt.h:102
std::optional< uint256 > domainID
Definition mpt.h:158
std::optional< Account > account
Definition mpt.h:148
std::optional< MPTID > id
Definition mpt.h:150
std::optional< std::uint16_t > transferFee
Definition mpt.h:155
std::optional< std::uint32_t > flags
Definition mpt.h:153
std::optional< std::variant< Account, AccountID > > holder
Definition mpt.h:149
std::optional< std::uint32_t > mutableFlags
Definition mpt.h:154
std::optional< std::string > metadata
Definition mpt.h:156
std::optional< Account > delegate
Definition mpt.h:157
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
T to_string(T... args)
T value_or(T... args)
T visit(T... args)