rippled
Loading...
Searching...
No Matches
SetTrust_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2016 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#include <test/jtx.h>
21
22#include <xrpl/protocol/TxFlags.h>
23#include <xrpl/protocol/jss.h>
24
25namespace ripple {
26
27namespace test {
28
30{
31 FeatureBitset const disallowIncoming{featureDisallowIncoming};
32
33public:
34 void
36 {
38 "Test deletion of trust lines: revert trust line limit to zero");
39
40 using namespace jtx;
41 Env env(*this);
42
43 Account const alice = Account{"alice"};
44 Account const becky = Account{"becky"};
45
46 env.fund(XRP(10000), becky, alice);
47 env.close();
48
49 // becky wants to hold at most 50 tokens of alice["USD"]
50 // becky is the customer, alice is the issuer
51 // becky can be sent at most 50 tokens of alice's USD
52 env(trust(becky, alice["USD"](50)));
53 env.close();
54
55 // Since the settings of the trust lines are non-default for both
56 // alice and becky, both of them will be charged an owner reserve
57 // Irrespective of whether the issuer or the customer initiated
58 // the trust-line creation, both will be charged
59 env.require(lines(alice, 1));
60 env.require(lines(becky, 1));
61
62 // Fetch the trust-lines via RPC for verification
63 Json::Value jv;
64 jv["account"] = becky.human();
65 auto beckyLines = env.rpc("json", "account_lines", to_string(jv));
66
67 jv["account"] = alice.human();
68 auto aliceLines = env.rpc("json", "account_lines", to_string(jv));
69
70 BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 1);
71 BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 1);
72
73 // reset the trust line limits to zero
74 env(trust(becky, alice["USD"](0)));
75 env.close();
76
77 // the reset of the trust line limits deletes the trust-line
78 // this occurs despite the authorization of the trust-line by the
79 // issuer(alice, in this unit test)
80 env.require(lines(becky, 0));
81 env.require(lines(alice, 0));
82
83 // second verification check via RPC calls
84 jv["account"] = becky.human();
85 beckyLines = env.rpc("json", "account_lines", to_string(jv));
86
87 jv["account"] = alice.human();
88 aliceLines = env.rpc("json", "account_lines", to_string(jv));
89
90 BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 0);
91 BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 0);
92
93 // additionally, verify that account_objects is an empty array
94 jv["account"] = becky.human();
95 auto const beckyObj = env.rpc("json", "account_objects", to_string(jv));
96 BEAST_EXPECT(beckyObj[jss::result][jss::account_objects].size() == 0);
97
98 jv["account"] = alice.human();
99 auto const aliceObj = env.rpc("json", "account_objects", to_string(jv));
100 BEAST_EXPECT(aliceObj[jss::result][jss::account_objects].size() == 0);
101 }
102
103 void
105 {
106 testcase(
107 "Reset trust line limit with Authorised Lines: Verify "
108 "deletion of trust lines");
109
110 using namespace jtx;
111 Env env(*this);
112
113 Account const alice = Account{"alice"};
114 Account const becky = Account{"becky"};
115
116 env.fund(XRP(10000), becky, alice);
117 env.close();
118
119 // alice wants to ensure that all holders of her tokens are authorised
120 env(fset(alice, asfRequireAuth));
121 env.close();
122
123 // becky wants to hold at most 50 tokens of alice["USD"]
124 // becky is the customer, alice is the issuer
125 // becky can be sent at most 50 tokens of alice's USD
126 env(trust(becky, alice["USD"](50)));
127 env.close();
128
129 // alice authorizes becky to hold alice["USD"] tokens
130 env(trust(alice, alice["USD"](0), becky, tfSetfAuth));
131 env.close();
132
133 // Since the settings of the trust lines are non-default for both
134 // alice and becky, both of them will be charged an owner reserve
135 // Irrespective of whether the issuer or the customer initiated
136 // the trust-line creation, both will be charged
137 env.require(lines(alice, 1));
138 env.require(lines(becky, 1));
139
140 // Fetch the trust-lines via RPC for verification
141 Json::Value jv;
142 jv["account"] = becky.human();
143 auto beckyLines = env.rpc("json", "account_lines", to_string(jv));
144
145 jv["account"] = alice.human();
146 auto aliceLines = env.rpc("json", "account_lines", to_string(jv));
147
148 BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 1);
149 BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 1);
150
151 // reset the trust line limits to zero
152 env(trust(becky, alice["USD"](0)));
153 env.close();
154
155 // the reset of the trust line limits deletes the trust-line
156 // this occurs despite the authorization of the trust-line by the
157 // issuer(alice, in this unit test)
158 env.require(lines(becky, 0));
159 env.require(lines(alice, 0));
160
161 // second verification check via RPC calls
162 jv["account"] = becky.human();
163 beckyLines = env.rpc("json", "account_lines", to_string(jv));
164
165 jv["account"] = alice.human();
166 aliceLines = env.rpc("json", "account_lines", to_string(jv));
167
168 BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 0);
169 BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 0);
170 }
171
172 void
174 FeatureBitset features,
175 bool thirdLineCreatesLE,
176 bool createOnHighAcct)
177 {
178 if (thirdLineCreatesLE)
179 testcase("Allow two free trustlines");
180 else
181 testcase("Dynamic reserve for trustline");
182
183 using namespace jtx;
184 Env env(*this, features);
185
186 auto const gwA = Account{"gwA"};
187 auto const gwB = Account{"gwB"};
188 auto const acctC = Account{"acctC"};
189 auto const acctD = Account{"acctD"};
190
191 auto const& creator = createOnHighAcct ? acctD : acctC;
192 auto const& assistor = createOnHighAcct ? acctC : acctD;
193
194 auto const txFee = env.current()->fees().base;
195 auto const baseReserve = env.current()->fees().accountReserve(0);
196 auto const threelineReserve = env.current()->fees().accountReserve(3);
197
198 env.fund(XRP(10000), gwA, gwB, assistor);
199
200 // Fund creator with ...
201 env.fund(
202 baseReserve /* enough to hold an account */
203 + drops(3 * txFee) /* and to pay for 3 transactions */,
204 creator);
205
206 env(trust(creator, gwA["USD"](100)), require(lines(creator, 1)));
207 env(trust(creator, gwB["USD"](100)), require(lines(creator, 2)));
208
209 if (thirdLineCreatesLE)
210 {
211 // creator does not have enough for the third trust line
212 env(trust(creator, assistor["USD"](100)),
214 require(lines(creator, 2)));
215 }
216 else
217 {
218 // First establish opposite trust direction from assistor
219 env(trust(assistor, creator["USD"](100)),
220 require(lines(creator, 3)));
221
222 // creator does not have enough to create the other direction on
223 // the existing trust line ledger entry
224 env(trust(creator, assistor["USD"](100)),
226 }
227
228 // Fund creator additional amount to cover
229 env(pay(env.master, creator, STAmount{threelineReserve - baseReserve}));
230
231 if (thirdLineCreatesLE)
232 {
233 env(trust(creator, assistor["USD"](100)),
234 require(lines(creator, 3)));
235 }
236 else
237 {
238 env(trust(creator, assistor["USD"](100)),
239 require(lines(creator, 3)));
240
241 Json::Value jv;
242 jv["account"] = creator.human();
243 auto const lines = env.rpc("json", "account_lines", to_string(jv));
244 // Verify that all lines have 100 limit from creator
245 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
246 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 3);
247 for (auto const& line : lines[jss::result][jss::lines])
248 {
249 BEAST_EXPECT(line[jss::limit] == "100");
250 }
251 }
252 }
253
254 void
256 {
257 testcase("SetTrust using a ticket");
258
259 using namespace jtx;
260
261 // Verify that TrustSet transactions can use tickets.
262 Env env{*this, features};
263 auto const gw = Account{"gateway"};
264 auto const alice = Account{"alice"};
265 auto const USD = gw["USD"];
266
267 env.fund(XRP(10000), gw, alice);
268 env.close();
269
270 // Cannot pay alice without a trustline.
271 env(pay(gw, alice, USD(200)), ter(tecPATH_DRY));
272 env.close();
273
274 // Create a ticket.
275 std::uint32_t const ticketSeq{env.seq(alice) + 1};
276 env(ticket::create(alice, 1));
277 env.close();
278
279 // Use that ticket to create a trust line.
280 env(trust(alice, USD(1000)), ticket::use(ticketSeq));
281 env.close();
282
283 // Now the payment succeeds.
284 env(pay(gw, alice, USD(200)));
285 env.close();
286 }
287
290 {
291 Json::Value jv;
292 jv[jss::Account] = a.human();
293 jv[jss::LimitAmount] = amt.getJson(JsonOptions::none);
294 jv[jss::TransactionType] = jss::TrustSet;
295 jv[jss::Flags] = 0;
296 return jv;
297 }
298
299 void
301 {
302 testcase("SetTrust checks for malformed transactions");
303
304 using namespace jtx;
305 Env env{*this, features};
306
307 auto const gw = Account{"gateway"};
308 auto const alice = Account{"alice"};
309 env.fund(XRP(10000), gw, alice);
310
311 // Require valid tf flags
312 for (std::uint64_t badFlag = 1u;
313 badFlag <= std::numeric_limits<std::uint32_t>::max();
314 badFlag *= 2)
315 {
316 if (badFlag & tfTrustSetMask)
317 env(trust(
318 alice,
319 gw["USD"](100),
320 static_cast<std::uint32_t>(badFlag)),
322 }
323
324 // trust amount can't be XRP
325 env(trust_explicit_amt(alice, drops(10000)), ter(temBAD_LIMIT));
326
327 // trust amount can't be badCurrency IOU
328 env(trust_explicit_amt(alice, gw[to_string(badCurrency())](100)),
330
331 // trust amount can't be negative
332 env(trust(alice, gw["USD"](-1000)), ter(temBAD_LIMIT));
333
334 // trust amount can't be from invalid issuer
336 alice, STAmount{Issue{to_currency("USD"), noAccount()}, 100}),
338
339 // trust cannot be to self
340 env(trust(alice, alice["USD"](100)), ter(temDST_IS_SRC));
341
342 // tfSetAuth flag should not be set if not required by lsfRequireAuth
343 env(trust(alice, gw["USD"](100), tfSetfAuth), ter(tefNO_AUTH_REQUIRED));
344 }
345
346 void
348 {
349 testcase(
350 "Ensure that trust line limits are respected in payment "
351 "transactions");
352
353 using namespace jtx;
354 Env env{*this};
355
356 auto const gw = Account{"gateway"};
357 auto const alice = Account{"alice"};
358 env.fund(XRP(10000), gw, alice);
359
360 // alice wants to hold at most 100 of gw's USD tokens
361 env(trust(alice, gw["USD"](100)));
362 env.close();
363
364 // send a payment for a large quantity through the trust line
365 env(pay(gw, alice, gw["USD"](200)), ter(tecPATH_PARTIAL));
366 env.close();
367
368 // on the other hand, smaller payments should succeed
369 env(pay(gw, alice, gw["USD"](20)));
370 env.close();
371 }
372
373 void
375 {
376 testcase(
377 "Ensure that authorised trust lines do not allow payments "
378 "from unauthorised counter-parties");
379
380 using namespace jtx;
381 Env env{*this};
382
383 auto const bob = Account{"bob"};
384 auto const alice = Account{"alice"};
385 env.fund(XRP(10000), bob, alice);
386
387 // alice wants to ensure that all holders of her tokens are authorised
388 env(fset(alice, asfRequireAuth));
389 env.close();
390
391 // create a trust line from bob to alice. bob wants to hold at most
392 // 100 of alice's USD tokens. Note: alice hasn't authorised this
393 // trust line yet.
394 env(trust(bob, alice["USD"](100)));
395 env.close();
396
397 // send a payment from alice to bob, validate that the payment fails
398 env(pay(alice, bob, alice["USD"](10)), ter(tecPATH_DRY));
399 env.close();
400 }
401
402 void
404 {
405 testcase(
406 "Check that trust line limits are respected in conjunction "
407 "with rippling feature");
408
409 using namespace jtx;
410 Env env{*this};
411
412 auto const bob = Account{"bob"};
413 auto const alice = Account{"alice"};
414 env.fund(XRP(10000), bob, alice);
415
416 // create a trust line from bob to alice. bob wants to hold at most
417 // 100 of alice's USD tokens.
418 env(trust(bob, alice["USD"](100)));
419 env.close();
420
421 // archetypical payment transaction from alice to bob must succeed
422 env(pay(alice, bob, alice["USD"](20)), ter(tesSUCCESS));
423 env.close();
424
425 // Issued tokens are fungible. i.e. alice's USD is identical to bob's
426 // USD
427 env(pay(bob, alice, bob["USD"](10)), ter(tesSUCCESS));
428 env.close();
429
430 // bob cannot place alice in his debt i.e. alice's balance of the USD
431 // tokens cannot go below zero.
432 env(pay(bob, alice, bob["USD"](11)), ter(tecPATH_PARTIAL));
433 env.close();
434
435 // payments that respect the trust line limits of alice should succeed
436 env(pay(bob, alice, bob["USD"](10)), ter(tesSUCCESS));
437 env.close();
438 }
439
440 void
442 FeatureBitset features,
443 bool createQuality,
444 bool createOnHighAcct)
445 {
446 testcase << "SetTrust " << (createQuality ? "creates" : "removes")
447 << " quality of trustline for "
448 << (createOnHighAcct ? "high" : "low") << " account";
449
450 using namespace jtx;
451 Env env{*this, features};
452
453 auto const alice = Account{"alice"};
454 auto const bob = Account{"bob"};
455
456 auto const& fromAcct = createOnHighAcct ? alice : bob;
457 auto const& toAcct = createOnHighAcct ? bob : alice;
458
459 env.fund(XRP(10000), fromAcct, toAcct);
460
461 auto txWithoutQuality = trust(toAcct, fromAcct["USD"](100));
462 txWithoutQuality["QualityIn"] = "0";
463 txWithoutQuality["QualityOut"] = "0";
464
465 auto txWithQuality = txWithoutQuality;
466 txWithQuality["QualityIn"] = "1000";
467 txWithQuality["QualityOut"] = "1000";
468
469 auto& tx1 = createQuality ? txWithQuality : txWithoutQuality;
470 auto& tx2 = createQuality ? txWithoutQuality : txWithQuality;
471
472 auto check_quality = [&](bool const exists) {
473 Json::Value jv;
474 jv["account"] = toAcct.human();
475 auto const lines = env.rpc("json", "account_lines", to_string(jv));
476 auto quality = exists ? 1000 : 0;
477 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
478 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 1);
479 BEAST_EXPECT(
480 lines[jss::result][jss::lines][0u][jss::quality_in] == quality);
481 BEAST_EXPECT(
482 lines[jss::result][jss::lines][0u][jss::quality_out] ==
483 quality);
484 };
485
486 env(tx1, require(lines(toAcct, 1)), require(lines(fromAcct, 1)));
487 check_quality(createQuality);
488
489 env(tx2, require(lines(toAcct, 1)), require(lines(fromAcct, 1)));
490 check_quality(!createQuality);
491 }
492
493 void
495 {
496 testcase("Create trustline with disallow incoming");
497
498 using namespace test::jtx;
499
500 // test flag doesn't set unless amendment enabled
501 {
502 Env env{*this, features - disallowIncoming};
503 Account const alice{"alice"};
504 env.fund(XRP(10000), alice);
506 env.close();
507 auto const sle = env.le(alice);
508 uint32_t flags = sle->getFlags();
509 BEAST_EXPECT(!(flags & lsfDisallowIncomingTrustline));
510 }
511
512 // fixDisallowIncomingV1
513 {
514 for (bool const withFix : {true, false})
515 {
516 auto const amend = withFix
517 ? features | disallowIncoming
518 : (features | disallowIncoming) - fixDisallowIncomingV1;
519
520 Env env{*this, amend};
521 auto const dist = Account("dist");
522 auto const gw = Account("gw");
523 auto const USD = gw["USD"];
524 auto const distUSD = dist["USD"];
525
526 env.fund(XRP(1000), gw, dist);
527 env.close();
528
529 env(fset(gw, asfRequireAuth));
530 env.close();
531
533 env.close();
534
535 env(trust(dist, USD(10000)));
536 env.close();
537
538 // withFix: can set trustline
539 // withOutFix: cannot set trustline
540 auto const trustResult =
541 withFix ? ter(tesSUCCESS) : ter(tecNO_PERMISSION);
542 env(trust(gw, distUSD(10000)),
544 trustResult);
545 env.close();
546
547 auto const txResult =
548 withFix ? ter(tesSUCCESS) : ter(tecPATH_DRY);
549 env(pay(gw, dist, USD(1000)), txResult);
550 env.close();
551 }
552 }
553
554 Env env{*this, features | disallowIncoming};
555
556 auto const gw = Account{"gateway"};
557 auto const alice = Account{"alice"};
558 auto const bob = Account{"bob"};
559 auto const USD = gw["USD"];
560
561 env.fund(XRP(10000), gw, alice, bob);
562 env.close();
563
564 // Set flag on gateway
566 env.close();
567
568 // Create a trustline which will fail
569 env(trust(alice, USD(1000)), ter(tecNO_PERMISSION));
570 env.close();
571
572 // Unset the flag
574 env.close();
575
576 // Create a trustline which will now succeed
577 env(trust(alice, USD(1000)));
578 env.close();
579
580 // Now the payment succeeds.
581 env(pay(gw, alice, USD(200)));
582 env.close();
583
584 // Set flag on gateway again
586 env.close();
587
588 // Destroy the balance by sending it back
589 env(pay(gw, alice, USD(200)));
590 env.close();
591
592 // The trustline still exists in default state
593 // So a further payment should work
594 env(pay(gw, alice, USD(200)));
595 env.close();
596
597 // Also set the flag on bob
599 env.close();
600
601 // But now bob can't open a trustline because he didn't already have one
602 env(trust(bob, USD(1000)), ter(tecNO_PERMISSION));
603 env.close();
604
605 // The gateway also can't open this trustline because bob has the flag
606 // set
607 env(trust(gw, bob["USD"](1000)), ter(tecNO_PERMISSION));
608 env.close();
609
610 // Unset the flag only on the gateway
612 env.close();
613
614 // Now bob can open a trustline
615 env(trust(bob, USD(1000)));
616 env.close();
617
618 // And the gateway can send bob a balance
619 env(pay(gw, bob, USD(200)));
620 env.close();
621 }
622
623 void
625 {
626 testFreeTrustlines(features, true, false);
627 testFreeTrustlines(features, false, true);
628 testFreeTrustlines(features, false, true);
629 // true, true case doesn't matter since creating a trustline ledger
630 // entry requires reserve from the creator
631 // independent of hi/low account ids for endpoints
632 testTicketSetTrust(features);
633 testMalformedTransaction(features);
634 testModifyQualityOfTrustline(features, false, false);
635 testModifyQualityOfTrustline(features, false, true);
636 testModifyQualityOfTrustline(features, true, false);
637 testModifyQualityOfTrustline(features, true, true);
638 testDisallowIncoming(features);
644 }
645
646public:
647 void
648 run() override
649 {
650 using namespace test::jtx;
651 auto const sa = testable_amendments();
653 testWithFeats(sa);
654 }
655};
656BEAST_DEFINE_TESTSUITE(SetTrust, app, ripple);
657} // namespace test
658} // namespace ripple
Represents a JSON value.
Definition json_value.h:149
A testsuite class.
Definition suite.h:55
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:155
A currency issued by an account.
Definition Issue.h:33
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STAmount.cpp:795
void run() override
Runs the suite.
void testMalformedTransaction(FeatureBitset features)
void testTicketSetTrust(FeatureBitset features)
void testModifyQualityOfTrustline(FeatureBitset features, bool createQuality, bool createOnHighAcct)
void testFreeTrustlines(FeatureBitset features, bool thirdLineCreatesLE, bool createOnHighAcct)
void testWithFeats(FeatureBitset features)
void testDisallowIncoming(FeatureBitset features)
FeatureBitset const disallowIncoming
Json::Value trust_explicit_amt(jtx::Account const &a, STAmount const &amt)
Immutable cryptographic account descriptor.
Definition Account.h:39
std::string const & human() const
Returns the human readable public key.
Definition Account.h:118
A transaction testing environment.
Definition Env.h:121
void require(Args const &... args)
Check a set of requirements.
Definition Env.h:547
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition Env.h:331
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:121
Account const & master
Definition Env.h:125
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition Env.h:791
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:289
Match set account flags.
Definition flags.h:128
Check a set of conditions.
Definition require.h:66
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition ter.h:35
Set a ticket sequence on a JTx.
Definition ticket.h:48
Set the flags on a JTx.
Definition txflags.h:31
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
Definition ticket.cpp:31
owner_count< ltRIPPLE_STATE > lines
Match the number of trust lines in the account's owner directory.
Definition owners.h:89
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
Definition flags.h:121
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Definition trust.cpp:32
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Definition flags.cpp:29
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Definition pay.cpp:30
FeatureBitset testable_amendments()
Definition Env.h:74
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:111
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
AccountID const & noAccount()
A placeholder for empty accounts.
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
@ lsfDisallowIncomingTrustline
constexpr std::uint32_t asfDisallowIncomingTrustline
Definition TxFlags.h:93
@ tefNO_AUTH_REQUIRED
Definition TER.h:174
constexpr std::uint32_t tfSetfAuth
Definition TxFlags.h:115
@ tecNO_LINE_INSUF_RESERVE
Definition TER.h:292
@ tecINSUF_RESERVE_LINE
Definition TER.h:288
@ tecNO_PERMISSION
Definition TER.h:305
@ tecPATH_PARTIAL
Definition TER.h:282
@ tecPATH_DRY
Definition TER.h:294
@ tesSUCCESS
Definition TER.h:244
constexpr std::uint32_t tfTrustSetMask
Definition TxFlags.h:122
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:630
constexpr std::uint32_t asfRequireAuth
Definition TxFlags.h:78
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
Definition UintTypes.cpp:84
@ temBAD_LIMIT
Definition TER.h:94
@ temDST_NEEDED
Definition TER.h:109
@ temBAD_CURRENCY
Definition TER.h:90
@ temINVALID_FLAG
Definition TER.h:111
@ temDST_IS_SRC
Definition TER.h:108