rippled
Loading...
Searching...
No Matches
Freeze_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 <test/jtx/AMM.h>
22#include <xrpl/protocol/AccountID.h>
23#include <xrpl/protocol/Feature.h>
24#include <xrpl/protocol/SField.h>
25#include <xrpl/protocol/TxFlags.h>
26#include <xrpl/protocol/jss.h>
27
28namespace ripple {
29
31{
32 void
34 {
35 testcase("RippleState Freeze");
36
37 using namespace test::jtx;
38 Env env(*this, features);
39
40 Account G1{"G1"};
41 Account alice{"alice"};
42 Account bob{"bob"};
43
44 env.fund(XRP(1000), G1, alice, bob);
45 env.close();
46
47 env.trust(G1["USD"](100), bob);
48 env.trust(G1["USD"](100), alice);
49 env.close();
50
51 env(pay(G1, bob, G1["USD"](10)));
52 env(pay(G1, alice, G1["USD"](100)));
53 env.close();
54
55 env(offer(alice, XRP(500), G1["USD"](100)));
56 env.close();
57
58 {
59 auto lines = getAccountLines(env, bob);
60 if (!BEAST_EXPECT(checkArraySize(lines[jss::lines], 1u)))
61 return;
62 BEAST_EXPECT(lines[jss::lines][0u][jss::account] == G1.human());
63 BEAST_EXPECT(lines[jss::lines][0u][jss::limit] == "100");
64 BEAST_EXPECT(lines[jss::lines][0u][jss::balance] == "10");
65 }
66
67 {
68 auto lines = getAccountLines(env, alice);
69 if (!BEAST_EXPECT(checkArraySize(lines[jss::lines], 1u)))
70 return;
71 BEAST_EXPECT(lines[jss::lines][0u][jss::account] == G1.human());
72 BEAST_EXPECT(lines[jss::lines][0u][jss::limit] == "100");
73 BEAST_EXPECT(lines[jss::lines][0u][jss::balance] == "100");
74 }
75
76 {
77 // Account with line unfrozen (proving operations normally work)
78 // test: can make Payment on that line
79 env(pay(alice, bob, G1["USD"](1)));
80
81 // test: can receive Payment on that line
82 env(pay(bob, alice, G1["USD"](1)));
83 env.close();
84 }
85
86 {
87 // Is created via a TrustSet with SetFreeze flag
88 // test: sets LowFreeze | HighFreeze flags
89 env(trust(G1, bob["USD"](0), tfSetFreeze));
90 auto affected = env.meta()->getJson(
91 JsonOptions::none)[sfAffectedNodes.fieldName];
92 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
93 return;
94 auto ff =
95 affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
96 BEAST_EXPECT(
97 ff[sfLowLimit.fieldName] ==
98 G1["USD"](0).value().getJson(JsonOptions::none));
99 BEAST_EXPECT(ff[jss::Flags].asUInt() & lsfLowFreeze);
100 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfHighFreeze));
101 env.close();
102 }
103
104 {
105 // Account with line frozen by issuer
106 // test: can buy more assets on that line
107 env(offer(bob, G1["USD"](5), XRP(25)));
108 auto affected = env.meta()->getJson(
109 JsonOptions::none)[sfAffectedNodes.fieldName];
110 if (!BEAST_EXPECT(checkArraySize(affected, 5u)))
111 return;
112 auto ff =
113 affected[3u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
114 BEAST_EXPECT(
115 ff[sfHighLimit.fieldName] ==
116 bob["USD"](100).value().getJson(JsonOptions::none));
117 auto amt = STAmount{Issue{to_currency("USD"), noAccount()}, -15}
118 .value()
119 .getJson(JsonOptions::none);
120 BEAST_EXPECT(ff[sfBalance.fieldName] == amt);
121 env.close();
122 }
123
124 {
125 // test: can not sell assets from that line
126 env(offer(bob, XRP(1), G1["USD"](5)), ter(tecUNFUNDED_OFFER));
127
128 // test: can receive Payment on that line
129 env(pay(alice, bob, G1["USD"](1)));
130
131 // test: can not make Payment from that line
132 env(pay(bob, alice, G1["USD"](1)), ter(tecPATH_DRY));
133 }
134
135 {
136 // check G1 account lines
137 // test: shows freeze
138 auto lines = getAccountLines(env, G1);
139 Json::Value bobLine;
140 for (auto const& it : lines[jss::lines])
141 {
142 if (it[jss::account] == bob.human())
143 {
144 bobLine = it;
145 break;
146 }
147 }
148 if (!BEAST_EXPECT(bobLine))
149 return;
150 BEAST_EXPECT(bobLine[jss::freeze] == true);
151 BEAST_EXPECT(bobLine[jss::balance] == "-16");
152 }
153
154 {
155 // test: shows freeze peer
156 auto lines = getAccountLines(env, bob);
157 Json::Value g1Line;
158 for (auto const& it : lines[jss::lines])
159 {
160 if (it[jss::account] == G1.human())
161 {
162 g1Line = it;
163 break;
164 }
165 }
166 if (!BEAST_EXPECT(g1Line))
167 return;
168 BEAST_EXPECT(g1Line[jss::freeze_peer] == true);
169 BEAST_EXPECT(g1Line[jss::balance] == "16");
170 }
171
172 {
173 // Is cleared via a TrustSet with ClearFreeze flag
174 // test: sets LowFreeze | HighFreeze flags
175 env(trust(G1, bob["USD"](0), tfClearFreeze));
176 auto affected = env.meta()->getJson(
177 JsonOptions::none)[sfAffectedNodes.fieldName];
178 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
179 return;
180 auto ff =
181 affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
182 BEAST_EXPECT(
183 ff[sfLowLimit.fieldName] ==
184 G1["USD"](0).value().getJson(JsonOptions::none));
185 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfLowFreeze));
186 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfHighFreeze));
187 env.close();
188 }
189 }
190
191 void
193 {
194 testcase("Deep Freeze");
195
196 using namespace test::jtx;
197 Env env(*this, features);
198
199 Account G1{"G1"};
200 Account A1{"A1"};
201
202 env.fund(XRP(10000), G1, A1);
203 env.close();
204
205 env.trust(G1["USD"](1000), A1);
206 env.close();
207
208 if (features[featureDeepFreeze])
209 {
210 // test: Issuer deep freezing the trust line in a single
211 // transaction
212 env(trust(G1, A1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
213 {
214 auto const flags = getTrustlineFlags(env, 2u, 1u);
215 BEAST_EXPECT(flags & lsfLowFreeze);
216 BEAST_EXPECT(flags & lsfLowDeepFreeze);
217 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
218 env.close();
219 }
220
221 // test: Issuer clearing deep freeze and normal freeze in a single
222 // transaction
223 env(trust(G1, A1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
224 {
225 auto const flags = getTrustlineFlags(env, 2u, 1u);
226 BEAST_EXPECT(!(flags & (lsfLowFreeze | lsfLowDeepFreeze)));
227 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
228 env.close();
229 }
230
231 // test: Issuer deep freezing not already frozen line must fail
232 env(trust(G1, A1["USD"](0), tfSetDeepFreeze),
233 ter(tecNO_PERMISSION));
234
235 env(trust(G1, A1["USD"](0), tfSetFreeze));
236 env.close();
237
238 // test: Issuer deep freezing already frozen trust line
239 env(trust(G1, A1["USD"](0), tfSetDeepFreeze));
240 {
241 auto const flags = getTrustlineFlags(env, 2u, 1u);
242 BEAST_EXPECT(flags & lsfLowFreeze);
243 BEAST_EXPECT(flags & lsfLowDeepFreeze);
244 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
245 env.close();
246 }
247
248 // test: Holder clearing freeze flags has no effect. Each sides'
249 // flags are independent
250 env(trust(A1, G1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
251 {
252 auto const flags = getTrustlineFlags(env, 2u, 1u);
253 BEAST_EXPECT(flags & lsfLowFreeze);
254 BEAST_EXPECT(flags & lsfLowDeepFreeze);
255 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
256 env.close();
257 }
258
259 // test: Issuer can't clear normal freeze when line is deep frozen
260 env(trust(G1, A1["USD"](0), tfClearFreeze), ter(tecNO_PERMISSION));
261
262 // test: Issuer clearing deep freeze but normal freeze is still in
263 // effect
264 env(trust(G1, A1["USD"](0), tfClearDeepFreeze));
265 {
266 auto const flags = getTrustlineFlags(env, 2u, 1u);
267 BEAST_EXPECT(flags & lsfLowFreeze);
268 BEAST_EXPECT(!(flags & lsfLowDeepFreeze));
269 BEAST_EXPECT(!(flags & (lsfHighFreeze | lsfHighDeepFreeze)));
270 env.close();
271 }
272 }
273 else
274 {
275 // test: applying deep freeze before amendment fails
276 env(trust(G1, A1["USD"](0), tfSetDeepFreeze), ter(temINVALID_FLAG));
277
278 // test: clearing deep freeze before amendment fails
279 env(trust(G1, A1["USD"](0), tfClearDeepFreeze),
280 ter(temINVALID_FLAG));
281 }
282 }
283
284 void
286 {
287 testcase("Create Frozen Trustline");
288
289 using namespace test::jtx;
290 Env env(*this, features);
291
292 Account G1{"G1"};
293 Account A1{"A1"};
294
295 env.fund(XRP(10000), G1, A1);
296 env.close();
297
298 // test: can create frozen trustline
299 {
300 env(trust(G1, A1["USD"](1000), tfSetFreeze));
301 auto const flags = getTrustlineFlags(env, 5u, 3u, false);
302 BEAST_EXPECT(flags & lsfLowFreeze);
303 env.close();
304 env.require(lines(A1, 1));
305 }
306
307 // Cleanup
308 env(trust(G1, A1["USD"](0), tfClearFreeze));
309 env.close();
310 env.require(lines(G1, 0));
311 env.require(lines(A1, 0));
312
313 // test: cannot create deep frozen trustline without normal freeze
314 if (features[featureDeepFreeze])
315 {
316 env(trust(G1, A1["USD"](1000), tfSetDeepFreeze),
317 ter(tecNO_PERMISSION));
318 env.close();
319 env.require(lines(A1, 0));
320 }
321
322 // test: can create deep frozen trustline together with normal freeze
323 if (features[featureDeepFreeze])
324 {
325 env(trust(G1, A1["USD"](1000), tfSetFreeze | tfSetDeepFreeze));
326 auto const flags = getTrustlineFlags(env, 5u, 3u, false);
327 BEAST_EXPECT(flags & lsfLowFreeze);
328 BEAST_EXPECT(flags & lsfLowDeepFreeze);
329 env.close();
330 env.require(lines(A1, 1));
331 }
332 }
333
334 void
336 {
337 testcase("Freeze Set and Clear");
338
339 using namespace test::jtx;
340 Env env(*this, features);
341
342 Account G1{"G1"};
343 Account A1{"A1"};
344
345 env.fund(XRP(10000), G1, A1);
346 env.close();
347
348 env.trust(G1["USD"](1000), A1);
349 env.close();
350
351 if (features[featureDeepFreeze])
352 {
353 // test: can't have both set and clear flag families in the same
354 // transaction
355 env(trust(G1, A1["USD"](0), tfSetFreeze | tfClearFreeze),
356 ter(tecNO_PERMISSION));
357 env(trust(G1, A1["USD"](0), tfSetFreeze | tfClearDeepFreeze),
358 ter(tecNO_PERMISSION));
359 env(trust(G1, A1["USD"](0), tfSetDeepFreeze | tfClearFreeze),
360 ter(tecNO_PERMISSION));
361 env(trust(G1, A1["USD"](0), tfSetDeepFreeze | tfClearDeepFreeze),
362 ter(tecNO_PERMISSION));
363 }
364 else
365 {
366 // test: old behavior, transaction succeed with no effect on a
367 // trust line
368 env(trust(G1, A1["USD"](0), tfSetFreeze | tfClearFreeze));
369 {
370 auto affected = env.meta()->getJson(
371 JsonOptions::none)[sfAffectedNodes.fieldName];
372 BEAST_EXPECT(checkArraySize(
373 affected, 1u)); // means no trustline changes
374 }
375 }
376 }
377
378 void
380 {
381 testcase("Global Freeze");
382
383 using namespace test::jtx;
384 Env env(*this, features);
385
386 Account G1{"G1"};
387 Account A1{"A1"};
388 Account A2{"A2"};
389 Account A3{"A3"};
390 Account A4{"A4"};
391
392 env.fund(XRP(12000), G1);
393 env.fund(XRP(1000), A1);
394 env.fund(XRP(20000), A2, A3, A4);
395 env.close();
396
397 env.trust(G1["USD"](1200), A1);
398 env.trust(G1["USD"](200), A2);
399 env.trust(G1["BTC"](100), A3);
400 env.trust(G1["BTC"](100), A4);
401 env.close();
402
403 env(pay(G1, A1, G1["USD"](1000)));
404 env(pay(G1, A2, G1["USD"](100)));
405 env(pay(G1, A3, G1["BTC"](100)));
406 env(pay(G1, A4, G1["BTC"](100)));
407 env.close();
408
409 env(offer(G1, XRP(10000), G1["USD"](100)), txflags(tfPassive));
410 env(offer(G1, G1["USD"](100), XRP(10000)), txflags(tfPassive));
411 env(offer(A1, XRP(10000), G1["USD"](100)), txflags(tfPassive));
412 env(offer(A2, G1["USD"](100), XRP(10000)), txflags(tfPassive));
413 env.close();
414
415 {
416 // Is toggled via AccountSet using SetFlag and ClearFlag
417 // test: SetFlag GlobalFreeze
418 env.require(nflags(G1, asfGlobalFreeze));
419 env(fset(G1, asfGlobalFreeze));
420 env.require(flags(G1, asfGlobalFreeze));
421 env.require(nflags(G1, asfNoFreeze));
422
423 // test: ClearFlag GlobalFreeze
424 env(fclear(G1, asfGlobalFreeze));
425 env.require(nflags(G1, asfGlobalFreeze));
426 env.require(nflags(G1, asfNoFreeze));
427 }
428
429 {
430 // Account without GlobalFreeze (proving operations normally work)
431 // test: visible offers where taker_pays is unfrozen issuer
432 auto offers = env.rpc(
433 "book_offers",
434 std::string("USD/") + G1.human(),
435 "XRP")[jss::result][jss::offers];
436 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
437 return;
438 std::set<std::string> accounts;
439 for (auto const& offer : offers)
440 {
441 accounts.insert(offer[jss::Account].asString());
442 }
443 BEAST_EXPECT(accounts.find(A2.human()) != std::end(accounts));
444 BEAST_EXPECT(accounts.find(G1.human()) != std::end(accounts));
445
446 // test: visible offers where taker_gets is unfrozen issuer
447 offers = env.rpc(
448 "book_offers",
449 "XRP",
450 std::string("USD/") + G1.human())[jss::result][jss::offers];
451 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
452 return;
453 accounts.clear();
454 for (auto const& offer : offers)
455 {
456 accounts.insert(offer[jss::Account].asString());
457 }
458 BEAST_EXPECT(accounts.find(A1.human()) != std::end(accounts));
459 BEAST_EXPECT(accounts.find(G1.human()) != std::end(accounts));
460 }
461
462 {
463 // Offers/Payments
464 // test: assets can be bought on the market
465 env(offer(A3, G1["BTC"](1), XRP(1)));
466
467 // test: assets can be sold on the market
468 env(offer(A4, XRP(1), G1["BTC"](1)));
469
470 // test: direct issues can be sent
471 env(pay(G1, A2, G1["USD"](1)));
472
473 // test: direct redemptions can be sent
474 env(pay(A2, G1, G1["USD"](1)));
475
476 // test: via rippling can be sent
477 env(pay(A2, A1, G1["USD"](1)));
478
479 // test: via rippling can be sent back
480 env(pay(A1, A2, G1["USD"](1)));
481 }
482
483 {
484 // Account with GlobalFreeze
485 // set GlobalFreeze first
486 // test: SetFlag GlobalFreeze will toggle back to freeze
487 env.require(nflags(G1, asfGlobalFreeze));
488 env(fset(G1, asfGlobalFreeze));
489 env.require(flags(G1, asfGlobalFreeze));
490 env.require(nflags(G1, asfNoFreeze));
491
492 // test: assets can't be bought on the market
493 env(offer(A3, G1["BTC"](1), XRP(1)), ter(tecFROZEN));
494
495 // test: assets can't be sold on the market
496 env(offer(A4, XRP(1), G1["BTC"](1)), ter(tecFROZEN));
497 }
498
499 {
500 // offers are filtered (seems to be broken?)
501 // test: account_offers always shows own offers
502 auto offers = getAccountOffers(env, G1)[jss::offers];
503 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
504 return;
505
506 // test: book_offers shows offers
507 // (should these actually be filtered?)
508 offers = env.rpc(
509 "book_offers",
510 "XRP",
511 std::string("USD/") + G1.human())[jss::result][jss::offers];
512 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
513 return;
514
515 offers = env.rpc(
516 "book_offers",
517 std::string("USD/") + G1.human(),
518 "XRP")[jss::result][jss::offers];
519 if (!BEAST_EXPECT(checkArraySize(offers, 2u)))
520 return;
521 }
522
523 {
524 // Payments
525 // test: direct issues can be sent
526 env(pay(G1, A2, G1["USD"](1)));
527
528 // test: direct redemptions can be sent
529 env(pay(A2, G1, G1["USD"](1)));
530
531 // test: via rippling cant be sent
532 env(pay(A2, A1, G1["USD"](1)), ter(tecPATH_DRY));
533 }
534 }
535
536 void
538 {
539 testcase("No Freeze");
540
541 using namespace test::jtx;
542 Env env(*this, features);
543
544 Account G1{"G1"};
545 Account A1{"A1"};
546 Account frozenAcc{"A2"};
547 Account deepFrozenAcc{"A3"};
548
549 env.fund(XRP(12000), G1);
550 env.fund(XRP(1000), A1);
551 env.fund(XRP(1000), frozenAcc);
552 env.fund(XRP(1000), deepFrozenAcc);
553 env.close();
554
555 env.trust(G1["USD"](1000), A1);
556 env.trust(G1["USD"](1000), frozenAcc);
557 env.trust(G1["USD"](1000), deepFrozenAcc);
558 env.close();
559
560 env(pay(G1, A1, G1["USD"](1000)));
561 env(pay(G1, frozenAcc, G1["USD"](1000)));
562 env(pay(G1, deepFrozenAcc, G1["USD"](1000)));
563
564 // Freezing and deep freezing some of the trust lines to check deep
565 // freeze and clearing of freeze separately
566 env(trust(G1, frozenAcc["USD"](0), tfSetFreeze));
567 {
568 auto const flags = getTrustlineFlags(env, 2u, 1u);
569 BEAST_EXPECT(flags & lsfLowFreeze);
570 BEAST_EXPECT(!(flags & lsfHighFreeze));
571 }
572 if (features[featureDeepFreeze])
573 {
574 env(trust(
575 G1, deepFrozenAcc["USD"](0), tfSetFreeze | tfSetDeepFreeze));
576 {
577 auto const flags = getTrustlineFlags(env, 2u, 1u);
578 BEAST_EXPECT(!(flags & (lsfLowFreeze | lsfLowDeepFreeze)));
579 BEAST_EXPECT(flags & lsfHighFreeze);
580 BEAST_EXPECT(flags & lsfHighDeepFreeze);
581 }
582 }
583 env.close();
584
585 // TrustSet NoFreeze
586 // test: should set NoFreeze in Flags
587 env.require(nflags(G1, asfNoFreeze));
588 env(fset(G1, asfNoFreeze));
589 env.require(flags(G1, asfNoFreeze));
590 env.require(nflags(G1, asfGlobalFreeze));
591
592 // test: cannot be cleared
593 env(fclear(G1, asfNoFreeze));
594 env.require(flags(G1, asfNoFreeze));
595 env.require(nflags(G1, asfGlobalFreeze));
596
597 // test: can set GlobalFreeze
598 env(fset(G1, asfGlobalFreeze));
599 env.require(flags(G1, asfNoFreeze));
600 env.require(flags(G1, asfGlobalFreeze));
601
602 // test: cannot unset GlobalFreeze
603 env(fclear(G1, asfGlobalFreeze));
604 env.require(flags(G1, asfNoFreeze));
605 env.require(flags(G1, asfGlobalFreeze));
606
607 // test: trustlines can't be frozen when no freeze enacted
608 if (features[featureDeepFreeze])
609 {
610 env(trust(G1, A1["USD"](0), tfSetFreeze), ter(tecNO_PERMISSION));
611
612 // test: cannot deep freeze already frozen line when no freeze
613 // enacted
614 env(trust(G1, frozenAcc["USD"](0), tfSetDeepFreeze),
615 ter(tecNO_PERMISSION));
616 }
617 else
618 {
619 // test: previous functionality, checking there's no changes to a
620 // trust line
621 env(trust(G1, A1["USD"](0), tfSetFreeze));
622 auto affected = env.meta()->getJson(
623 JsonOptions::none)[sfAffectedNodes.fieldName];
624 if (!BEAST_EXPECT(checkArraySize(affected, 1u)))
625 return;
626
627 auto let = affected[0u][sfModifiedNode.fieldName]
628 [sfLedgerEntryType.fieldName];
629 BEAST_EXPECT(let == jss::AccountRoot);
630 }
631
632 // test: can clear freeze on account
633 env(trust(G1, frozenAcc["USD"](0), tfClearFreeze));
634 {
635 auto const flags = getTrustlineFlags(env, 2u, 1u);
636 BEAST_EXPECT(!(flags & lsfLowFreeze));
637 }
638
639 if (features[featureDeepFreeze])
640 {
641 // test: can clear deep freeze on account
642 env(trust(G1, deepFrozenAcc["USD"](0), tfClearDeepFreeze));
643 {
644 auto const flags = getTrustlineFlags(env, 2u, 1u);
645 BEAST_EXPECT(flags & lsfHighFreeze);
646 BEAST_EXPECT(!(flags & lsfHighDeepFreeze));
647 }
648 }
649 }
650
651 void
653 {
654 testcase("Offers for Frozen Trust Lines");
655
656 using namespace test::jtx;
657 Env env(*this, features);
658
659 Account G1{"G1"};
660 Account A2{"A2"};
661 Account A3{"A3"};
662 Account A4{"A4"};
663
664 env.fund(XRP(1000), G1, A3, A4);
665 env.fund(XRP(2000), A2);
666 env.close();
667
668 env.trust(G1["USD"](1000), A2);
669 env.trust(G1["USD"](2000), A3);
670 env.trust(G1["USD"](2000), A4);
671 env.close();
672
673 env(pay(G1, A3, G1["USD"](2000)));
674 env(pay(G1, A4, G1["USD"](2000)));
675 env.close();
676
677 env(offer(A3, XRP(1000), G1["USD"](1000)), txflags(tfPassive));
678 env.close();
679
680 // removal after successful payment
681 // test: make a payment with partially consuming offer
682 env(pay(A2, G1, G1["USD"](1)), paths(G1["USD"]), sendmax(XRP(1)));
683 env.close();
684
685 // test: offer was only partially consumed
686 auto offers = getAccountOffers(env, A3)[jss::offers];
687 if (!BEAST_EXPECT(checkArraySize(offers, 1u)))
688 return;
689 BEAST_EXPECT(
690 offers[0u][jss::taker_gets] ==
691 G1["USD"](999).value().getJson(JsonOptions::none));
692
693 // test: someone else creates an offer providing liquidity
694 env(offer(A4, XRP(999), G1["USD"](999)));
695 env.close();
696
697 // test: owner of partially consumed offers line is frozen
698 env(trust(G1, A3["USD"](0), tfSetFreeze));
699 auto affected =
700 env.meta()->getJson(JsonOptions::none)[sfAffectedNodes.fieldName];
701 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
702 return;
703 auto ff =
704 affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
705 BEAST_EXPECT(
706 ff[sfHighLimit.fieldName] ==
707 G1["USD"](0).value().getJson(JsonOptions::none));
708 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfLowFreeze));
709 BEAST_EXPECT(ff[jss::Flags].asUInt() & lsfHighFreeze);
710 env.close();
711
712 // verify offer on the books
713 offers = getAccountOffers(env, A3)[jss::offers];
714 if (!BEAST_EXPECT(checkArraySize(offers, 1u)))
715 return;
716
717 // test: Can make a payment via the new offer
718 env(pay(A2, G1, G1["USD"](1)), paths(G1["USD"]), sendmax(XRP(1)));
719 env.close();
720
721 // test: Partially consumed offer was removed by tes* payment
722 offers = getAccountOffers(env, A3)[jss::offers];
723 if (!BEAST_EXPECT(checkArraySize(offers, 0u)))
724 return;
725
726 // removal buy successful OfferCreate
727 // test: freeze the new offer
728 env(trust(G1, A4["USD"](0), tfSetFreeze));
729 affected =
730 env.meta()->getJson(JsonOptions::none)[sfAffectedNodes.fieldName];
731 if (!BEAST_EXPECT(checkArraySize(affected, 2u)))
732 return;
733 ff = affected[0u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
734 BEAST_EXPECT(
735 ff[sfLowLimit.fieldName] ==
736 G1["USD"](0).value().getJson(JsonOptions::none));
737 BEAST_EXPECT(ff[jss::Flags].asUInt() & lsfLowFreeze);
738 BEAST_EXPECT(!(ff[jss::Flags].asUInt() & lsfHighFreeze));
739 env.close();
740
741 // test: can no longer create a crossing offer
742 env(offer(A2, G1["USD"](999), XRP(999)));
743 affected =
744 env.meta()->getJson(JsonOptions::none)[sfAffectedNodes.fieldName];
745 if (!BEAST_EXPECT(checkArraySize(affected, 8u)))
746 return;
747 auto created = affected[0u][sfCreatedNode.fieldName];
748 BEAST_EXPECT(
749 created[sfNewFields.fieldName][jss::Account] == A2.human());
750 env.close();
751
752 // test: offer was removed by offer_create
753 offers = getAccountOffers(env, A4)[jss::offers];
754 if (!BEAST_EXPECT(checkArraySize(offers, 0u)))
755 return;
756 }
757
758 void
760 {
761 testcase("Offers on frozen trust lines");
762
763 using namespace test::jtx;
764 Env env(*this, features);
765
766 Account G1{"G1"};
767 Account A1{"A1"};
768 Account A2{"A2"};
769 Account A3{"A3"};
770 auto const USD{G1["USD"]};
771
772 env.fund(XRP(10000), G1, A1, A2, A3);
773 env.close();
774
775 auto const limit = USD(10000);
776 env.trust(limit, A1, A2, A3);
777 env.close();
778
779 env(pay(G1, A1, USD(1000)));
780 env(pay(G1, A2, USD(1000)));
781 env.close();
782
783 // Making large passive sell offer
784 // Wants to sell 50 USD for 100 XRP
785 env(offer(A2, XRP(100), USD(50)), txflags(tfPassive));
786 env.close();
787 // Making large passive buy offer
788 // Wants to buy 100 USD for 100 XRP
789 env(offer(A3, USD(100), XRP(100)), txflags(tfPassive));
790 env.close();
791 env.require(offers(A2, 1), offers(A3, 1));
792
793 // Checking A1 can buy from A2 by crossing it's offer
794 env(offer(A1, USD(1), XRP(2)), txflags(tfFillOrKill));
795 env.close();
796 env.require(balance(A1, USD(1001)), balance(A2, USD(999)));
797
798 // Checking A1 can sell to A3 by crossing it's offer
799 env(offer(A1, XRP(1), USD(1)), txflags(tfFillOrKill));
800 env.close();
801 env.require(balance(A1, USD(1000)), balance(A3, USD(1)));
802
803 // Testing aggressive and passive offer placing, trustline frozen by
804 // the issuer
805 {
806 env(trust(G1, A1["USD"](0), tfSetFreeze));
807 env.close();
808
809 // test: can still make passive buy offer
810 env(offer(A1, USD(1), XRP(0.5)), txflags(tfPassive));
811 env.close();
812 env.require(balance(A1, USD(1000)), offers(A1, 1));
813 // Cleanup
814 env(offer_cancel(A1, env.seq(A1) - 1));
815 env.require(offers(A1, 0));
816 env.close();
817
818 // test: can still buy from A2
819 env(offer(A1, USD(1), XRP(2)), txflags(tfFillOrKill));
820 env.close();
821 env.require(
822 balance(A1, USD(1001)), balance(A2, USD(998)), offers(A1, 0));
823
824 // test: cannot create passive sell offer
825 env(offer(A1, XRP(2), USD(1)),
826 txflags(tfPassive),
827 ter(tecUNFUNDED_OFFER));
828 env.close();
829 env.require(balance(A1, USD(1001)), offers(A1, 0));
830
831 // test: cannot sell to A3
832 env(offer(A1, XRP(1), USD(1)),
833 txflags(tfFillOrKill),
834 ter(tecUNFUNDED_OFFER));
835 env.close();
836 env.require(balance(A1, USD(1001)), offers(A1, 0));
837
838 env(trust(G1, A1["USD"](0), tfClearFreeze));
839 env.close();
840 }
841
842 // Testing aggressive and passive offer placing, trustline deep frozen
843 // by the issuer
844 if (features[featureDeepFreeze])
845 {
846 env(trust(G1, A1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
847 env.close();
848
849 // test: cannot create passive buy offer
850 env(offer(A1, USD(1), XRP(0.5)),
851 txflags(tfPassive),
852 ter(tecFROZEN));
853 env.close();
854
855 // test: cannot buy from A2
856 env(offer(A1, USD(1), XRP(2)),
857 txflags(tfFillOrKill),
858 ter(tecFROZEN));
859 env.close();
860
861 // test: cannot create passive sell offer
862 env(offer(A1, XRP(2), USD(1)),
863 txflags(tfPassive),
864 ter(tecUNFUNDED_OFFER));
865 env.close();
866
867 // test: cannot sell to A3
868 env(offer(A1, XRP(1), USD(1)),
869 txflags(tfFillOrKill),
870 ter(tecUNFUNDED_OFFER));
871 env.close();
872
873 env(trust(G1, A1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
874 env.close();
875 env.require(balance(A1, USD(1001)), offers(A1, 0));
876 }
877
878 // Testing already existing offers behavior after trustline is frozen by
879 // the issuer
880 {
881 env.require(balance(A1, USD(1001)));
882 env(offer(A1, XRP(1.9), USD(1)));
883 env(offer(A1, USD(1), XRP(1.1)));
884 env.close();
885 env.require(balance(A1, USD(1001)), offers(A1, 2));
886
887 env(trust(G1, A1["USD"](0), tfSetFreeze));
888 env.close();
889
890 // test: A2 wants to sell to A1, must succeed
891 env.require(balance(A1, USD(1001)), balance(A2, USD(998)));
892 env(offer(A2, XRP(1.1), USD(1)), txflags(tfFillOrKill));
893 env.close();
894 env.require(
895 balance(A1, USD(1002)), balance(A2, USD(997)), offers(A1, 1));
896
897 // test: A3 wants to buy from A1, must fail
898 env.require(
899 balance(A1, USD(1002)), balance(A3, USD(1)), offers(A1, 1));
900 env(offer(A3, USD(1), XRP(1.9)),
901 txflags(tfFillOrKill),
902 ter(tecKILLED));
903 env.close();
904 env.require(
905 balance(A1, USD(1002)), balance(A3, USD(1)), offers(A1, 0));
906
907 env(trust(G1, A1["USD"](0), tfClearFreeze));
908 env.close();
909 }
910
911 // Testing existing offers behavior after trustline is deep frozen by
912 // the issuer
913 if (features[featureDeepFreeze])
914 {
915 env.require(balance(A1, USD(1002)));
916 env(offer(A1, XRP(1.9), USD(1)));
917 env(offer(A1, USD(1), XRP(1.1)));
918 env.close();
919 env.require(balance(A1, USD(1002)), offers(A1, 2));
920
921 env(trust(G1, A1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
922 env.close();
923
924 // test: A2 wants to sell to A1, must fail
925 env.require(balance(A1, USD(1002)), balance(A2, USD(997)));
926 env(offer(A2, XRP(1.1), USD(1)),
927 txflags(tfFillOrKill),
928 ter(tecKILLED));
929 env.close();
930 env.require(
931 balance(A1, USD(1002)), balance(A2, USD(997)), offers(A1, 1));
932
933 // test: A3 wants to buy from A1, must fail
934 env.require(
935 balance(A1, USD(1002)), balance(A3, USD(1)), offers(A1, 1));
936 env(offer(A3, USD(1), XRP(1.9)),
937 txflags(tfFillOrKill),
938 ter(tecKILLED));
939 env.close();
940 env.require(
941 balance(A1, USD(1002)), balance(A3, USD(1)), offers(A1, 0));
942
943 env(trust(G1, A1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
944 env.close();
945 }
946
947 // Testing aggressive and passive offer placing, trustline frozen by
948 // the holder
949 {
950 env(trust(A1, limit, tfSetFreeze));
951 env.close();
952
953 // test: A1 can make passive buy offer
954 env(offer(A1, USD(1), XRP(0.5)), txflags(tfPassive));
955 env.close();
956 env.require(balance(A1, USD(1002)), offers(A1, 1));
957 // Cleanup
958 env(offer_cancel(A1, env.seq(A1) - 1));
959 env.require(offers(A1, 0));
960 env.close();
961
962 // test: A1 wants to buy, must fail
963 if (features[featureFlowCross])
964 {
965 env(offer(A1, USD(1), XRP(2)),
966 txflags(tfFillOrKill),
967 ter(tecKILLED));
968 env.close();
969 env.require(
970 balance(A1, USD(1002)),
971 balance(A2, USD(997)),
972 offers(A1, 0));
973 }
974 else
975 {
976 // The transaction that should be here would succeed.
977 // I don't want to adjust balances in following tests. Flow
978 // cross feature flag is not relevant to this particular test
979 // case so we're not missing out some corner cases checks.
980 }
981
982 // test: A1 can create passive sell offer
983 env(offer(A1, XRP(2), USD(1)), txflags(tfPassive));
984 env.close();
985 env.require(balance(A1, USD(1002)), offers(A1, 1));
986 // Cleanup
987 env(offer_cancel(A1, env.seq(A1) - 1));
988 env.require(offers(A1, 0));
989 env.close();
990
991 // test: A1 can sell to A3
992 env(offer(A1, XRP(1), USD(1)), txflags(tfFillOrKill));
993 env.close();
994 env.require(balance(A1, USD(1001)), offers(A1, 0));
995
996 env(trust(A1, limit, tfClearFreeze));
997 env.close();
998 }
999
1000 // Testing aggressive and passive offer placing, trustline deep frozen
1001 // by the holder
1002 if (features[featureDeepFreeze])
1003 {
1004 env(trust(A1, limit, tfSetFreeze | tfSetDeepFreeze));
1005 env.close();
1006
1007 // test: A1 cannot create passive buy offer
1008 env(offer(A1, USD(1), XRP(0.5)),
1009 txflags(tfPassive),
1010 ter(tecFROZEN));
1011 env.close();
1012
1013 // test: A1 cannot buy, must fail
1014 env(offer(A1, USD(1), XRP(2)),
1015 txflags(tfFillOrKill),
1016 ter(tecFROZEN));
1017 env.close();
1018
1019 // test: A1 cannot create passive sell offer
1020 env(offer(A1, XRP(2), USD(1)),
1021 txflags(tfPassive),
1022 ter(tecUNFUNDED_OFFER));
1023 env.close();
1024
1025 // test: A1 cannot sell to A3
1026 env(offer(A1, XRP(1), USD(1)),
1027 txflags(tfFillOrKill),
1028 ter(tecUNFUNDED_OFFER));
1029 env.close();
1030
1031 env(trust(A1, limit, tfClearFreeze | tfClearDeepFreeze));
1032 env.close();
1033 }
1034 }
1035
1036 void
1038 {
1039 testcase("Longer paths payment on frozen trust lines");
1040 using namespace test::jtx;
1041 using path = test::jtx::path;
1042
1043 Env env(*this, features);
1044 Account G1{"G1"};
1045 Account A1{"A1"};
1046 Account A2{"A2"};
1047 auto const USD{G1["USD"]};
1048
1049 env.fund(XRP(10000), G1, A1, A2);
1050 env.close();
1051
1052 auto const limit = USD(10000);
1053 env.trust(limit, A1, A2);
1054 env.close();
1055
1056 env(pay(G1, A1, USD(1000)));
1057 env(pay(G1, A2, USD(1000)));
1058 env.close();
1059
1060 env(offer(A2, XRP(100), USD(100)), txflags(tfPassive));
1061 env.close();
1062
1063 // Testing payments A1 <-> G1 using offer from A2 frozen by issuer.
1064 {
1065 env(trust(G1, A2["USD"](0), tfSetFreeze));
1066 env.close();
1067
1068 // test: A1 cannot send USD using XRP through A2 offer
1069 env(pay(A1, G1, USD(10)),
1070 path(~USD),
1071 sendmax(XRP(11)),
1072 txflags(tfNoRippleDirect),
1073 ter(tecPATH_PARTIAL));
1074 env.close();
1075
1076 // test: G1 cannot send USD using XRP through A2 offer
1077 env(pay(G1, A1, USD(10)),
1078 path(~USD),
1079 sendmax(XRP(11)),
1080 txflags(tfNoRippleDirect),
1081 ter(tecPATH_PARTIAL));
1082 env.close();
1083
1084 env(trust(G1, A2["USD"](0), tfClearFreeze));
1085 env.close();
1086 }
1087
1088 // Testing payments A1 <-> G1 using offer from A2 deep frozen by issuer.
1089 if (features[featureDeepFreeze])
1090 {
1091 env(trust(G1, A2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1092 env.close();
1093
1094 // test: A1 cannot send USD using XRP through A2 offer
1095 env(pay(A1, G1, USD(10)),
1096 path(~USD),
1097 sendmax(XRP(11)),
1098 txflags(tfNoRippleDirect),
1099 ter(tecPATH_PARTIAL));
1100 env.close();
1101
1102 // test: G1 cannot send USD using XRP through A2 offer
1103 env(pay(G1, A1, USD(10)),
1104 path(~USD),
1105 sendmax(XRP(11)),
1106 txflags(tfNoRippleDirect),
1107 ter(tecPATH_PARTIAL));
1108 env.close();
1109
1110 env(trust(G1, A2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1111 env.close();
1112 }
1113
1114 // Testing payments A1 <-> G1 using offer from A2 frozen by currency
1115 // holder.
1116 {
1117 env(trust(A2, limit, tfSetFreeze));
1118 env.close();
1119
1120 // test: A1 can send USD using XRP through A2 offer
1121 env(pay(A1, G1, USD(10)),
1122 path(~USD),
1123 sendmax(XRP(11)),
1124 txflags(tfNoRippleDirect));
1125 env.close();
1126
1127 // test: G1 can send USD using XRP through A2 offer
1128 env(pay(G1, A1, USD(10)),
1129 path(~USD),
1130 sendmax(XRP(11)),
1131 txflags(tfNoRippleDirect));
1132 env.close();
1133
1134 env(trust(A2, limit, tfClearFreeze));
1135 env.close();
1136 }
1137
1138 // Testing payments A1 <-> G1 using offer from A2 deep frozen by
1139 // currency holder.
1140 if (features[featureDeepFreeze])
1141 {
1142 env(trust(A2, limit, tfSetFreeze | tfSetDeepFreeze));
1143 env.close();
1144
1145 // test: A1 cannot send USD using XRP through A2 offer
1146 env(pay(A1, G1, USD(10)),
1147 path(~USD),
1148 sendmax(XRP(11)),
1149 txflags(tfNoRippleDirect),
1150 ter(tecPATH_PARTIAL));
1151 env.close();
1152
1153 // test: G1 cannot send USD using XRP through A2 offer
1154 env(pay(G1, A1, USD(10)),
1155 path(~USD),
1156 sendmax(XRP(11)),
1157 txflags(tfNoRippleDirect),
1158 ter(tecPATH_PARTIAL));
1159 env.close();
1160
1161 env(trust(A2, limit, tfClearFreeze | tfClearDeepFreeze));
1162 env.close();
1163 }
1164
1165 // Cleanup
1166 env(offer_cancel(A1, env.seq(A1) - 1));
1167 env.require(offers(A1, 0));
1168 env.close();
1169
1170 env(offer(A2, USD(100), XRP(100)), txflags(tfPassive));
1171 env.close();
1172
1173 // Testing payments A1 <-> G1 using offer from A2 frozen by issuer.
1174 {
1175 env(trust(G1, A2["USD"](0), tfSetFreeze));
1176 env.close();
1177
1178 // test: A1 can send XRP using USD through A2 offer
1179 env(pay(A1, G1, XRP(10)),
1180 path(~XRP),
1181 sendmax(USD(11)),
1182 txflags(tfNoRippleDirect));
1183 env.close();
1184
1185 // test: G1 can send XRP using USD through A2 offer
1186 env(pay(G1, A1, XRP(10)),
1187 path(~XRP),
1188 sendmax(USD(11)),
1189 txflags(tfNoRippleDirect));
1190 env.close();
1191
1192 env(trust(G1, A2["USD"](0), tfClearFreeze));
1193 env.close();
1194 }
1195
1196 // Testing payments A1 <-> G1 using offer from A2 deep frozen by
1197 // issuer.
1198 if (features[featureDeepFreeze])
1199 {
1200 env(trust(G1, A2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1201 env.close();
1202
1203 // test: A1 cannot send XRP using USD through A2 offer
1204 env(pay(A1, G1, XRP(10)),
1205 path(~XRP),
1206 sendmax(USD(11)),
1207 txflags(tfNoRippleDirect),
1208 ter(tecPATH_PARTIAL));
1209 env.close();
1210
1211 // test: G1 cannot send XRP using USD through A2 offer
1212 env(pay(G1, A1, XRP(10)),
1213 path(~XRP),
1214 sendmax(USD(11)),
1215 txflags(tfNoRippleDirect),
1216 ter(tecPATH_PARTIAL));
1217 env.close();
1218
1219 env(trust(G1, A2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1220 env.close();
1221 }
1222
1223 // Testing payments A1 <-> G1 using offer from A2 frozen by currency
1224 // holder.
1225 {
1226 env(trust(A2, limit, tfSetFreeze));
1227 env.close();
1228
1229 // test: A1 can send XRP using USD through A2 offer
1230 env(pay(A1, G1, XRP(10)),
1231 path(~XRP),
1232 sendmax(USD(11)),
1233 txflags(tfNoRippleDirect));
1234 env.close();
1235
1236 // test: G1 can send XRP using USD through A2 offer
1237 env(pay(G1, A1, XRP(10)),
1238 path(~XRP),
1239 sendmax(USD(11)),
1240 txflags(tfNoRippleDirect));
1241 env.close();
1242
1243 env(trust(A2, limit, tfClearFreeze));
1244 env.close();
1245 }
1246
1247 // Testing payments A1 <-> G1 using offer from A2 deep frozen by
1248 // currency holder.
1249 if (features[featureDeepFreeze])
1250 {
1251 env(trust(A2, limit, tfSetFreeze | tfSetDeepFreeze));
1252 env.close();
1253
1254 // test: A1 cannot send XRP using USD through A2 offer
1255 env(pay(A1, G1, XRP(10)),
1256 path(~XRP),
1257 sendmax(USD(11)),
1258 txflags(tfNoRippleDirect),
1259 ter(tecPATH_PARTIAL));
1260 env.close();
1261
1262 // test: G1 cannot send XRP using USD through A2 offer
1263 env(pay(G1, A1, XRP(10)),
1264 path(~XRP),
1265 sendmax(USD(11)),
1266 txflags(tfNoRippleDirect),
1267 ter(tecPATH_PARTIAL));
1268 env.close();
1269
1270 env(trust(A2, limit, tfClearFreeze | tfClearDeepFreeze));
1271 env.close();
1272 }
1273
1274 // Cleanup
1275 env(offer_cancel(A1, env.seq(A1) - 1));
1276 env.require(offers(A1, 0));
1277 env.close();
1278 }
1279
1280 void
1282 {
1283 testcase("Direct payments on frozen trust lines");
1284
1285 using namespace test::jtx;
1286 Env env(*this, features);
1287
1288 Account G1{"G1"};
1289 Account A1{"A1"};
1290 Account A2{"A2"};
1291 auto const USD{G1["USD"]};
1292
1293 env.fund(XRP(10000), G1, A1, A2);
1294 env.close();
1295
1296 auto const limit = USD(10000);
1297 env.trust(limit, A1, A2);
1298 env.close();
1299
1300 env(pay(G1, A1, USD(1000)));
1301 env(pay(G1, A2, USD(1000)));
1302 env.close();
1303
1304 // Checking payments before freeze
1305 // To issuer:
1306 env(pay(A1, G1, USD(1)));
1307 env(pay(A2, G1, USD(1)));
1308 env.close();
1309
1310 // To each other:
1311 env(pay(A1, A2, USD(1)));
1312 env(pay(A2, A1, USD(1)));
1313 env.close();
1314
1315 // Freeze A1
1316 env(trust(G1, A1["USD"](0), tfSetFreeze));
1317 env.close();
1318
1319 // Issuer and A1 can send payments to each other
1320 env(pay(A1, G1, USD(1)));
1321 env(pay(G1, A1, USD(1)));
1322 env.close();
1323
1324 // A1 cannot send tokens to A2
1325 env(pay(A1, A2, USD(1)), ter(tecPATH_DRY));
1326
1327 // A2 can still send to A1
1328 env(pay(A2, A1, USD(1)));
1329 env.close();
1330
1331 if (features[featureDeepFreeze])
1332 {
1333 // Deep freeze A1
1334 env(trust(G1, A1["USD"](0), tfSetDeepFreeze));
1335 env.close();
1336
1337 // Issuer and A1 can send payments to each other
1338 env(pay(A1, G1, USD(1)));
1339 env(pay(G1, A1, USD(1)));
1340 env.close();
1341
1342 // A1 cannot send tokens to A2
1343 env(pay(A1, A2, USD(1)), ter(tecPATH_DRY));
1344
1345 // A2 cannot send tokens to A1
1346 env(pay(A2, A1, USD(1)), ter(tecPATH_DRY));
1347
1348 // Clear deep freeze on A1
1349 env(trust(G1, A1["USD"](0), tfClearDeepFreeze));
1350 env.close();
1351 }
1352
1353 // Clear freeze on A1
1354 env(trust(G1, A1["USD"](0), tfClearFreeze));
1355 env.close();
1356
1357 // A1 freezes trust line
1358 env(trust(A1, limit, tfSetFreeze));
1359 env.close();
1360
1361 // Issuer and A2 must not be affected
1362 env(pay(A2, G1, USD(1)));
1363 env(pay(G1, A2, USD(1)));
1364 env.close();
1365
1366 // A1 can send tokens to the issuer
1367 env(pay(A1, G1, USD(1)));
1368 env.close();
1369 // A1 can send tokens to A2
1370 env(pay(A1, A2, USD(1)));
1371 env.close();
1372
1373 // Issuer can sent tokens to A1
1374 env(pay(G1, A1, USD(1)));
1375 // A2 cannot send tokens to A1
1376 env(pay(A2, A1, USD(1)), ter(tecPATH_DRY));
1377
1378 if (features[featureDeepFreeze])
1379 {
1380 // A1 deep freezes trust line
1381 env(trust(A1, limit, tfSetDeepFreeze));
1382 env.close();
1383
1384 // Issuer and A2 must not be affected
1385 env(pay(A2, G1, USD(1)));
1386 env(pay(G1, A2, USD(1)));
1387 env.close();
1388
1389 // A1 can still send token to issuer
1390 env(pay(A1, G1, USD(1)));
1391 env.close();
1392
1393 // Issuer can send tokens to A1
1394 env(pay(G1, A1, USD(1)));
1395 // A2 cannot send tokens to A1
1396 env(pay(A2, A1, USD(1)), ter(tecPATH_DRY));
1397 // A1 cannot send tokens to A2
1398 env(pay(A1, A2, USD(1)), ter(tecPATH_DRY));
1399 }
1400 }
1401
1402 void
1404 {
1405 testcase("Checks on frozen trust lines");
1406
1407 using namespace test::jtx;
1408 Env env(*this, features);
1409
1410 Account G1{"G1"};
1411 Account A1{"A1"};
1412 Account A2{"A2"};
1413 auto const USD{G1["USD"]};
1414
1415 env.fund(XRP(10000), G1, A1, A2);
1416 env.close();
1417
1418 auto const limit = USD(10000);
1419 env.trust(limit, A1, A2);
1420 env.close();
1421
1422 env(pay(G1, A1, USD(1000)));
1423 env(pay(G1, A2, USD(1000)));
1424 env.close();
1425
1426 // Confirming we can write and cash checks
1427 {
1428 uint256 const checkId{getCheckIndex(G1, env.seq(G1))};
1429 env(check::create(G1, A1, USD(10)));
1430 env.close();
1431 env(check::cash(A1, checkId, USD(10)));
1432 env.close();
1433 }
1434
1435 {
1436 uint256 const checkId{getCheckIndex(G1, env.seq(G1))};
1437 env(check::create(G1, A2, USD(10)));
1438 env.close();
1439 env(check::cash(A2, checkId, USD(10)));
1440 env.close();
1441 }
1442
1443 {
1444 uint256 const checkId{getCheckIndex(A1, env.seq(A1))};
1445 env(check::create(A1, G1, USD(10)));
1446 env.close();
1447 env(check::cash(G1, checkId, USD(10)));
1448 env.close();
1449 }
1450
1451 {
1452 uint256 const checkId{getCheckIndex(A1, env.seq(A1))};
1453 env(check::create(A1, A2, USD(10)));
1454 env.close();
1455 env(check::cash(A2, checkId, USD(10)));
1456 env.close();
1457 }
1458
1459 {
1460 uint256 const checkId{getCheckIndex(A2, env.seq(A2))};
1461 env(check::create(A2, G1, USD(10)));
1462 env.close();
1463 env(check::cash(G1, checkId, USD(10)));
1464 env.close();
1465 }
1466
1467 {
1468 uint256 const checkId{getCheckIndex(A2, env.seq(A2))};
1469 env(check::create(A2, A1, USD(10)));
1470 env.close();
1471 env(check::cash(A1, checkId, USD(10)));
1472 env.close();
1473 }
1474
1475 // Testing creation and cashing of checks on a trustline frozen by
1476 // issuer
1477 {
1478 env(trust(G1, A1["USD"](0), tfSetFreeze));
1479 env.close();
1480
1481 // test: issuer writes check to A1.
1482 {
1483 uint256 const checkId{getCheckIndex(G1, env.seq(G1))};
1484 env(check::create(G1, A1, USD(10)));
1485 env.close();
1486 env(check::cash(A1, checkId, USD(10)), ter(tecFROZEN));
1487 env.close();
1488 }
1489
1490 // test: A2 writes check to A1.
1491 {
1492 uint256 const checkId{getCheckIndex(A2, env.seq(A2))};
1493 env(check::create(A2, A1, USD(10)));
1494 env.close();
1495 // Same as previous test
1496 env(check::cash(A1, checkId, USD(10)), ter(tecFROZEN));
1497 env.close();
1498 }
1499
1500 // test: A1 writes check to issuer
1501 {
1502 env(check::create(A1, G1, USD(10)), ter(tecFROZEN));
1503 env.close();
1504 }
1505
1506 // test: A1 writes check to A2
1507 {
1508 // Same as previous test
1509 env(check::create(A1, A2, USD(10)), ter(tecFROZEN));
1510 env.close();
1511 }
1512
1513 // Unfreeze the trustline to create a couple of checks so that we
1514 // could try to cash them later when the trustline is frozen again.
1515 env(trust(G1, A1["USD"](0), tfClearFreeze));
1516 env.close();
1517
1518 uint256 const checkId1{getCheckIndex(A1, env.seq(A1))};
1519 env(check::create(A1, G1, USD(10)));
1520 env.close();
1521 uint256 const checkId2{getCheckIndex(A1, env.seq(A1))};
1522 env(check::create(A1, A2, USD(10)));
1523 env.close();
1524
1525 env(trust(G1, A1["USD"](0), tfSetFreeze));
1526 env.close();
1527
1528 // test: issuer tries to cash the check from A1
1529 {
1530 env(check::cash(G1, checkId1, USD(10)), ter(tecPATH_PARTIAL));
1531 env.close();
1532 }
1533
1534 // test: A2 tries to cash the check from A1
1535 {
1536 env(check::cash(A2, checkId2, USD(10)), ter(tecPATH_PARTIAL));
1537 env.close();
1538 }
1539
1540 env(trust(G1, A1["USD"](0), tfClearFreeze));
1541 env.close();
1542 }
1543
1544 // Testing creation and cashing of checks on a trustline deep frozen by
1545 // issuer
1546 if (features[featureDeepFreeze])
1547 {
1548 env(trust(G1, A1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1549 env.close();
1550
1551 // test: issuer writes check to A1.
1552 {
1553 uint256 const checkId{getCheckIndex(G1, env.seq(G1))};
1554 env(check::create(G1, A1, USD(10)));
1555 env.close();
1556
1557 env(check::cash(A1, checkId, USD(10)), ter(tecFROZEN));
1558 env.close();
1559 }
1560
1561 // test: A2 writes check to A1.
1562 {
1563 uint256 const checkId{getCheckIndex(A2, env.seq(A2))};
1564 env(check::create(A2, A1, USD(10)));
1565 env.close();
1566 // Same as previous test
1567 env(check::cash(A1, checkId, USD(10)), ter(tecFROZEN));
1568 env.close();
1569 }
1570
1571 // test: A1 writes check to issuer
1572 {
1573 env(check::create(A1, G1, USD(10)), ter(tecFROZEN));
1574 env.close();
1575 }
1576
1577 // test: A1 writes check to A2
1578 {
1579 // Same as previous test
1580 env(check::create(A1, A2, USD(10)), ter(tecFROZEN));
1581 env.close();
1582 }
1583
1584 // Unfreeze the trustline to create a couple of checks so that we
1585 // could try to cash them later when the trustline is frozen again.
1586 env(trust(G1, A1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1587 env.close();
1588
1589 uint256 const checkId1{getCheckIndex(A1, env.seq(A1))};
1590 env(check::create(A1, G1, USD(10)));
1591 env.close();
1592 uint256 const checkId2{getCheckIndex(A1, env.seq(A1))};
1593 env(check::create(A1, A2, USD(10)));
1594 env.close();
1595
1596 env(trust(G1, A1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1597 env.close();
1598
1599 // test: issuer tries to cash the check from A1
1600 {
1601 env(check::cash(G1, checkId1, USD(10)), ter(tecPATH_PARTIAL));
1602 env.close();
1603 }
1604
1605 // test: A2 tries to cash the check from A1
1606 {
1607 env(check::cash(A2, checkId2, USD(10)), ter(tecPATH_PARTIAL));
1608 env.close();
1609 }
1610
1611 env(trust(G1, A1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1612 env.close();
1613 }
1614
1615 // Testing creation and cashing of checks on a trustline frozen by
1616 // a currency holder
1617 {
1618 env(trust(A1, limit, tfSetFreeze));
1619 env.close();
1620
1621 // test: issuer writes check to A1.
1622 {
1623 env(check::create(G1, A1, USD(10)), ter(tecFROZEN));
1624 env.close();
1625 }
1626
1627 // test: A2 writes check to A1.
1628 {
1629 env(check::create(A2, A1, USD(10)), ter(tecFROZEN));
1630 env.close();
1631 }
1632
1633 // test: A1 writes check to issuer
1634 {
1635 uint256 const checkId{getCheckIndex(A1, env.seq(A1))};
1636 env(check::create(A1, G1, USD(10)));
1637 env.close();
1638 env(check::cash(G1, checkId, USD(10)));
1639 env.close();
1640 }
1641
1642 // test: A1 writes check to A2
1643 {
1644 uint256 const checkId{getCheckIndex(A1, env.seq(A1))};
1645 env(check::create(A1, A2, USD(10)));
1646 env.close();
1647 env(check::cash(A2, checkId, USD(10)));
1648 env.close();
1649 }
1650
1651 env(trust(A1, limit, tfClearFreeze));
1652 env.close();
1653 }
1654
1655 // Testing creation and cashing of checks on a trustline deep frozen by
1656 // a currency holder
1657 if (features[featureDeepFreeze])
1658 {
1659 env(trust(A1, limit, tfSetFreeze | tfSetDeepFreeze));
1660 env.close();
1661
1662 // test: issuer writes check to A1.
1663 {
1664 env(check::create(G1, A1, USD(10)), ter(tecFROZEN));
1665 env.close();
1666 }
1667
1668 // test: A2 writes check to A1.
1669 {
1670 env(check::create(A2, A1, USD(10)), ter(tecFROZEN));
1671 env.close();
1672 }
1673
1674 // test: A1 writes check to issuer
1675 {
1676 uint256 const checkId{getCheckIndex(A1, env.seq(A1))};
1677 env(check::create(A1, G1, USD(10)));
1678 env.close();
1679 env(check::cash(G1, checkId, USD(10)), ter(tecPATH_PARTIAL));
1680 env.close();
1681 }
1682
1683 // test: A1 writes check to A2
1684 {
1685 uint256 const checkId{getCheckIndex(A1, env.seq(A1))};
1686 env(check::create(A1, A2, USD(10)));
1687 env.close();
1688 env(check::cash(A2, checkId, USD(10)), ter(tecPATH_PARTIAL));
1689 env.close();
1690 }
1691
1692 env(trust(A1, limit, tfClearFreeze | tfClearDeepFreeze));
1693 env.close();
1694 }
1695 }
1696
1697 void
1699 {
1700 testcase("AMM payments on frozen trust lines");
1701 using namespace test::jtx;
1702 using path = test::jtx::path;
1703
1704 Env env(*this, features);
1705 Account G1{"G1"};
1706 Account A1{"A1"};
1707 Account A2{"A2"};
1708 auto const USD{G1["USD"]};
1709
1710 env.fund(XRP(10000), G1, A1, A2);
1711 env.close();
1712
1713 env.trust(G1["USD"](10000), A1, A2);
1714 env.close();
1715
1716 env(pay(G1, A1, USD(1000)));
1717 env(pay(G1, A2, USD(1000)));
1718 env.close();
1719
1720 AMM ammG1(env, G1, XRP(1'000), USD(1'000));
1721 env.close();
1722
1723 // Testing basic payment using AMM when freezing one of the trust lines.
1724 {
1725 env(trust(G1, A1["USD"](0), tfSetFreeze));
1726 env.close();
1727
1728 // test: can still use XRP to make payment
1729 env(pay(A1, A2, USD(10)),
1730 path(~USD),
1731 sendmax(XRP(11)),
1732 txflags(tfNoRippleDirect));
1733 env.close();
1734
1735 // test: cannot use USD to make payment
1736 env(pay(A1, A2, XRP(10)),
1737 path(~XRP),
1738 sendmax(USD(11)),
1739 txflags(tfNoRippleDirect),
1740 ter(tecPATH_DRY));
1741 env.close();
1742
1743 // test: can still receive USD payments.
1744 env(pay(A2, A1, USD(10)),
1745 path(~USD),
1746 sendmax(XRP(11)),
1747 txflags(tfNoRippleDirect));
1748 env.close();
1749
1750 // test: can still receive XRP payments.
1751 env(pay(A2, A1, XRP(10)),
1752 path(~XRP),
1753 sendmax(USD(11)),
1754 txflags(tfNoRippleDirect));
1755 env.close();
1756
1757 env(trust(G1, A1["USD"](0), tfClearFreeze));
1758 env.close();
1759 }
1760
1761 // Testing basic payment using AMM when deep freezing one of the trust
1762 // lines.
1763 if (features[featureDeepFreeze])
1764 {
1765 env(trust(G1, A1["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1766 env.close();
1767
1768 // test: can still use XRP to make payment
1769 env(pay(A1, A2, USD(10)),
1770 path(~USD),
1771 sendmax(XRP(11)),
1772 txflags(tfNoRippleDirect));
1773 env.close();
1774
1775 // test: cannot use USD to make payment
1776 env(pay(A1, A2, XRP(10)),
1777 path(~XRP),
1778 sendmax(USD(11)),
1779 txflags(tfNoRippleDirect),
1780 ter(tecPATH_DRY));
1781 env.close();
1782
1783 // test: cannot receive USD payments.
1784 env(pay(A2, A1, USD(10)),
1785 path(~USD),
1786 sendmax(XRP(11)),
1787 txflags(tfNoRippleDirect),
1788 ter(tecPATH_DRY));
1789 env.close();
1790
1791 // test: can still receive XRP payments.
1792 env(pay(A2, A1, XRP(10)),
1793 path(~XRP),
1794 sendmax(USD(11)),
1795 txflags(tfNoRippleDirect));
1796 env.close();
1797
1798 env(trust(G1, A1["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1799 env.close();
1800 }
1801 }
1802
1803 void
1805 {
1806 testcase("NFT offers on frozen trust lines");
1807 using namespace test::jtx;
1808
1809 Env env(*this, features);
1810 Account G1{"G1"};
1811 Account A1{"A1"};
1812 Account A2{"A2"};
1813 auto const USD{G1["USD"]};
1814
1815 env.fund(XRP(10000), G1, A1, A2);
1816 env.close();
1817
1818 auto const limit = USD(10000);
1819 env.trust(limit, A1, A2);
1820 env.close();
1821
1822 env(pay(G1, A1, USD(1000)));
1823 env(pay(G1, A2, USD(1000)));
1824 env.close();
1825
1826 // Testing A2 nft offer sell when A2 frozen by issuer
1827 {
1828 auto const sellOfferIndex = createNFTSellOffer(env, A2, USD(10));
1829 env(trust(G1, A2["USD"](0), tfSetFreeze));
1830 env.close();
1831
1832 // test: A2 can still receive USD for his NFT
1833 env(token::acceptSellOffer(A1, sellOfferIndex));
1834 env.close();
1835
1836 env(trust(G1, A2["USD"](0), tfClearFreeze));
1837 env.close();
1838 }
1839
1840 // Testing A2 nft offer sell when A2 deep frozen by issuer
1841 if (features[featureDeepFreeze])
1842 {
1843 auto const sellOfferIndex = createNFTSellOffer(env, A2, USD(10));
1844
1845 env(trust(G1, A2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1846 env.close();
1847
1848 // test: A2 cannot receive USD for his NFT
1849 env(token::acceptSellOffer(A1, sellOfferIndex), ter(tecFROZEN));
1850 env.close();
1851
1852 env(trust(G1, A2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1853 env.close();
1854 }
1855
1856 // Testing A1 nft offer sell when A2 frozen by issuer
1857 {
1858 auto const sellOfferIndex = createNFTSellOffer(env, A1, USD(10));
1859 env(trust(G1, A2["USD"](0), tfSetFreeze));
1860 env.close();
1861
1862 // test: A2 cannot send USD for NFT
1863 env(token::acceptSellOffer(A2, sellOfferIndex),
1865 env.close();
1866
1867 env(trust(G1, A2["USD"](0), tfClearFreeze));
1868 env.close();
1869 }
1870
1871 // Testing A1 nft offer sell when A2 deep frozen by issuer
1872 if (features[featureDeepFreeze])
1873 {
1874 auto const sellOfferIndex = createNFTSellOffer(env, A1, USD(10));
1875 env(trust(G1, A2["USD"](0), tfSetFreeze | tfSetDeepFreeze));
1876 env.close();
1877
1878 // test: A2 cannot send USD for NFT
1879 env(token::acceptSellOffer(A2, sellOfferIndex),
1881 env.close();
1882
1883 env(trust(G1, A2["USD"](0), tfClearFreeze | tfClearDeepFreeze));
1884 env.close();
1885 }
1886
1887 // Testing A2 nft offer sell when A2 frozen by currency holder
1888 {
1889 auto const sellOfferIndex = createNFTSellOffer(env, A2, USD(10));
1890 env(trust(A2, limit, tfSetFreeze));
1891 env.close();
1892
1893 // test: offer can still be accepted.
1894 env(token::acceptSellOffer(A1, sellOfferIndex));
1895 env.close();
1896
1897 env(trust(A2, limit, tfClearFreeze));
1898 env.close();
1899 }
1900
1901 // Testing A2 nft offer sell when A2 deep frozen by currency holder
1902 if (features[featureDeepFreeze])
1903 {
1904 auto const sellOfferIndex = createNFTSellOffer(env, A2, USD(10));
1905
1906 env(trust(A2, limit, tfSetFreeze | tfSetDeepFreeze));
1907 env.close();
1908
1909 // test: A2 cannot receive USD for his NFT
1910 env(token::acceptSellOffer(A1, sellOfferIndex), ter(tecFROZEN));
1911 env.close();
1912
1913 env(trust(A2, limit, tfClearFreeze | tfClearDeepFreeze));
1914 env.close();
1915 }
1916
1917 // Testing A1 nft offer sell when A2 frozen by currency holder
1918 {
1919 auto const sellOfferIndex = createNFTSellOffer(env, A1, USD(10));
1920 env(trust(A2, limit, tfSetFreeze));
1921 env.close();
1922
1923 // test: A2 cannot send USD for NFT
1924 env(token::acceptSellOffer(A2, sellOfferIndex));
1925 env.close();
1926
1927 env(trust(A2, limit, tfClearFreeze));
1928 env.close();
1929 }
1930
1931 // Testing A1 nft offer sell when A2 deep frozen by currency holder
1932 if (features[featureDeepFreeze])
1933 {
1934 auto const sellOfferIndex = createNFTSellOffer(env, A1, USD(10));
1935 env(trust(A2, limit, tfSetFreeze | tfSetDeepFreeze));
1936 env.close();
1937
1938 // test: A2 cannot send USD for NFT
1939 env(token::acceptSellOffer(A2, sellOfferIndex),
1941 env.close();
1942
1943 env(trust(A2, limit, tfClearFreeze | tfClearDeepFreeze));
1944 env.close();
1945 }
1946 }
1947
1948 // Helper function to extract trustline flags from open ledger
1949 uint32_t
1951 test::jtx::Env& env,
1952 size_t expectedArraySize,
1953 size_t expectedArrayIndex,
1954 bool modified = true)
1955 {
1956 using namespace test::jtx;
1957 auto const affected =
1958 env.meta()->getJson(JsonOptions::none)[sfAffectedNodes.fieldName];
1959 if (!BEAST_EXPECT(checkArraySize(affected, expectedArraySize)))
1960 return 0;
1961
1962 if (modified)
1963 {
1964 return affected[expectedArrayIndex][sfModifiedNode.fieldName]
1965 [sfFinalFields.fieldName][jss::Flags]
1966 .asUInt();
1967 }
1968
1969 return affected[expectedArrayIndex][sfCreatedNode.fieldName]
1970 [sfNewFields.fieldName][jss::Flags]
1971 .asUInt();
1972 }
1973
1974 // Helper function that returns the index of the next check on account
1975 uint256
1976 getCheckIndex(AccountID const& account, std::uint32_t uSequence)
1977 {
1978 return keylet::check(account, uSequence).key;
1979 }
1980
1981 uint256
1983 test::jtx::Env& env,
1984 test::jtx::Account const& account,
1985 test::jtx::PrettyAmount const& currency)
1986 {
1987 using namespace test::jtx;
1988 uint256 const nftID{token::getNextID(env, account, 0u, tfTransferable)};
1989 env(token::mint(account, 0), txflags(tfTransferable));
1990 env.close();
1991
1992 uint256 const sellOfferIndex =
1993 keylet::nftoffer(account, env.seq(account)).key;
1994 env(token::createOffer(account, nftID, currency),
1995 txflags(tfSellNFToken));
1996 env.close();
1997
1998 return sellOfferIndex;
1999 }
2000
2001public:
2002 void
2003 run() override
2004 {
2005 auto testAll = [this](FeatureBitset features) {
2006 testRippleState(features);
2007 testDeepFreeze(features);
2008 testCreateFrozenTrustline(features);
2009 testSetAndClear(features);
2010 testGlobalFreeze(features);
2011 testNoFreeze(features);
2012 testOffersWhenFrozen(features);
2013 testOffersWhenDeepFrozen(features);
2015 testChecksWhenFrozen(features);
2016 testAMMWhenFreeze(features);
2017 testPathsWhenFrozen(features);
2018 testNFTOffersWhenFreeze(features);
2019 };
2020 using namespace test::jtx;
2021 auto const sa = supported_amendments();
2022 testAll(sa - featureFlowCross - featureDeepFreeze);
2023 testAll(sa - featureFlowCross);
2024 testAll(sa - featureDeepFreeze);
2025 testAll(sa);
2026 }
2027};
2028
2029BEAST_DEFINE_TESTSUITE(Freeze, app, ripple);
2030} // 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
void testOffersWhenDeepFrozen(FeatureBitset features)
uint256 createNFTSellOffer(test::jtx::Env &env, test::jtx::Account const &account, test::jtx::PrettyAmount const &currency)
uint32_t getTrustlineFlags(test::jtx::Env &env, size_t expectedArraySize, size_t expectedArrayIndex, bool modified=true)
void testGlobalFreeze(FeatureBitset features)
void testDeepFreeze(FeatureBitset features)
void testPaymentsWhenDeepFrozen(FeatureBitset features)
void testNoFreeze(FeatureBitset features)
void testNFTOffersWhenFreeze(FeatureBitset features)
void testAMMWhenFreeze(FeatureBitset features)
void testPathsWhenFrozen(FeatureBitset features)
void run() override
Runs the suite.
uint256 getCheckIndex(AccountID const &account, std::uint32_t uSequence)
void testCreateFrozenTrustline(FeatureBitset features)
void testRippleState(FeatureBitset features)
Definition: Freeze_test.cpp:33
void testSetAndClear(FeatureBitset features)
void testOffersWhenFrozen(FeatureBitset features)
void testChecksWhenFrozen(FeatureBitset features)
A currency issued by an account.
Definition: Issue.h:36
Immutable cryptographic account descriptor.
Definition: Account.h:39
A transaction testing environment.
Definition: Env.h:118
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition: Env.cpp:210
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:115
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Definition: Env.cpp:445
Add a path.
Definition: paths.h:57
T clear(T... args)
T end(T... args)
T find(T... args)
T insert(T... args)
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Definition: Indexes.cpp:418
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Definition: Indexes.cpp:327
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
constexpr std::uint32_t asfGlobalFreeze
Definition: TxFlags.h:82
constexpr std::uint32_t tfSetDeepFreeze
Definition: TxFlags.h:117
constexpr std::uint32_t const tfSellNFToken
Definition: TxFlags.h:189
@ lsfHighDeepFreeze
@ lsfHighFreeze
@ lsfLowFreeze
@ lsfLowDeepFreeze
constexpr std::uint32_t asfNoFreeze
Definition: TxFlags.h:81
constexpr std::uint32_t tfFillOrKill
Definition: TxFlags.h:98
constexpr std::uint32_t tfPassive
Definition: TxFlags.h:96
constexpr std::uint32_t tfClearFreeze
Definition: TxFlags.h:116
@ tecUNFUNDED_OFFER
Definition: TER.h:271
@ tecFROZEN
Definition: TER.h:290
@ tecKILLED
Definition: TER.h:303
@ tecINSUFFICIENT_FUNDS
Definition: TER.h:312
@ tecNO_PERMISSION
Definition: TER.h:292
@ tecPATH_PARTIAL
Definition: TER.h:269
@ tecPATH_DRY
Definition: TER.h:281
constexpr std::uint32_t tfNoRippleDirect
Definition: TxFlags.h:104
constexpr std::uint32_t tfClearDeepFreeze
Definition: TxFlags.h:118
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
constexpr std::uint32_t tfSetFreeze
Definition: TxFlags.h:115
constexpr std::uint32_t const tfTransferable
Definition: TxFlags.h:136
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
Definition: UintTypes.cpp:84
@ temINVALID_FLAG
Definition: TER.h:111
uint256 key
Definition: Keylet.h:40
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...