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