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