179 using namespace test::jtx;
181 Account
const gw{
"gateway"};
182 Account
const alice{
"alice"};
183 Account
const bob{
"bob"};
184 IOU
const USD{gw[
"USD"]};
186 Env env{*
this, features};
188 STAmount const startBalance{XRP(1000).value()};
189 env.fund(startBalance, gw, alice, bob);
195 auto writeTwoChecks = [&env, &USD,
this](
196 Account
const& from, Account
const& to) {
203 env(check::create(from, to, XRP(2000)));
206 env(check::create(from, to, USD(50)));
212 env.require(owners(from, fromOwnerCount + 2));
214 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
217 writeTwoChecks(alice, bob);
218 writeTwoChecks(gw, alice);
219 writeTwoChecks(alice, gw);
225 using namespace std::chrono_literals;
228 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
231 env(check::create(alice, bob, USD(50)), source_tag(2));
233 env(check::create(alice, bob, USD(50)), dest_tag(3));
235 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
237 env(check::create(alice, bob, USD(50)),
238 expiration(env.now() + 1s),
249 env(regkey(alice, alie));
254 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
258 env(check::create(alice, bob, USD(50)), sig(alie));
264 XRPAmount const baseFeeDrops{env.current()->fees().base};
265 env(check::create(alice, bob, USD(50)),
267 fee(3 * baseFeeDrops));
374 using namespace test::jtx;
376 Account
const gw1{
"gateway1"};
377 Account
const gwF{
"gatewayFrozen"};
378 Account
const alice{
"alice"};
379 Account
const bob{
"bob"};
380 IOU
const USD{gw1[
"USD"]};
382 Env env{*
this, features};
384 STAmount const startBalance{XRP(1000).value()};
385 env.fund(startBalance, gw1, gwF, alice, bob);
389 env(check::create(alice, bob, USD(50)),
395 env(check::create(alice, bob, USD(50)),
401 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
405 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
408 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
411 env(check::create(alice, bob, drops(1)));
420 env(check::create(alice, bob, USD(1)));
429 env(check::create(alice, bob, USD(50)),
435 Account
const bogie{
"bogie"};
436 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
446 env(check::create(alice, bob, USD(50)), dest_tag(11));
453 IOU
const USF{gwF[
"USF"]};
457 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
463 env(check::create(alice, bob, USF(50)));
469 env.trust(USD(1000), alice);
470 env.trust(USD(1000), bob);
472 env(pay(gw1, alice, USD(25)));
473 env(pay(gw1, bob, USD(25)));
481 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
485 env(check::create(bob, alice, USD(50)));
487 env(pay(bob, alice, USD(1)));
489 env(check::create(gw1, alice, USD(50)));
491 env(pay(gw1, alice, USD(1)));
497 env(check::create(alice, bob, USD(50)));
499 env(check::create(bob, alice, USD(50)));
501 env(check::create(gw1, alice, USD(50)));
509 env(check::create(alice, bob, USD(50)));
511 env(pay(alice, bob, USD(1)));
513 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
517 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
528 env(check::create(alice, bob, USD(50)),
529 expiration(env.now()),
533 using namespace std::chrono_literals;
534 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
538 Account
const cheri{
"cheri"};
539 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
542 env(check::create(cheri, bob, USD(50)),
543 fee(drops(env.current()->fees().base)),
547 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
550 env(check::create(cheri, bob, USD(50)));
560 using namespace test::jtx;
562 Account
const alice{
"alice"};
563 Account
const bob{
"bob"};
565 Env env{*
this, features};
567 XRPAmount const baseFeeDrops{env.current()->fees().base};
568 STAmount const startBalance{XRP(300).value()};
569 env.fund(startBalance, alice, bob);
574 env(check::create(alice, bob, XRP(10)));
576 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
577 env.require(balance(bob, startBalance));
580 BEAST_EXPECT(ownerCount(env, alice) == 1);
581 BEAST_EXPECT(ownerCount(env, bob) == 0);
583 env(check::cash(bob, chkId, XRP(10)));
586 balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
588 balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
591 BEAST_EXPECT(ownerCount(env, alice) == 0);
592 BEAST_EXPECT(ownerCount(env, bob) == 0);
595 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
596 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
598 env.require(balance(alice, startBalance));
599 env.require(balance(bob, startBalance));
603 STAmount const reserve{env.current()->fees().reserve};
605 startBalance - reserve - drops(baseFeeDrops)};
607 env(check::create(alice, bob, checkAmount));
611 env(check::cash(bob, chkId, checkAmount + drops(1)),
615 bob, chkId, check::DeliverMin(checkAmount + drops(1))),
622 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
624 env.require(balance(alice, reserve));
626 bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
629 BEAST_EXPECT(ownerCount(env, alice) == 0);
630 BEAST_EXPECT(ownerCount(env, bob) == 0);
633 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
634 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
636 env.require(balance(alice, startBalance));
637 env.require(balance(bob, startBalance));
641 STAmount const reserve{env.current()->fees().reserve};
643 startBalance - reserve - drops(baseFeeDrops - 1)};
645 env(check::create(alice, bob, checkAmount));
654 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
656 env.require(balance(alice, reserve));
658 bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
661 BEAST_EXPECT(ownerCount(env, alice) == 0);
662 BEAST_EXPECT(ownerCount(env, bob) == 0);
665 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
667 bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
669 env.require(balance(alice, startBalance));
670 env.require(balance(bob, startBalance));
680 using namespace test::jtx;
682 Account
const gw{
"gateway"};
683 Account
const alice{
"alice"};
684 Account
const bob{
"bob"};
685 IOU
const USD{gw[
"USD"]};
688 Env env{*
this, features};
690 env.fund(XRP(1000), gw, alice, bob);
695 env(check::create(alice, bob, USD(10)));
703 env(trust(alice, USD(20)));
705 env(pay(gw, alice, USD(9.5)));
712 env(pay(gw, alice, USD(0.5)));
716 env(trust(bob, USD(9.5)));
721 env(trust(bob, USD(10.5)));
727 env(check::cash(bob, chkId1, USD(10)));
729 env.require(balance(alice, USD(0)));
730 env.require(balance(bob, USD(10)));
733 BEAST_EXPECT(ownerCount(env, alice) == 1);
734 BEAST_EXPECT(ownerCount(env, bob) == 1);
737 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
741 env(pay(bob, alice, USD(7)));
745 env(check::create(alice, bob, USD(7)));
752 env(check::cash(bob, chkId2, USD(5)));
754 env.require(balance(alice, USD(2)));
755 env.require(balance(bob, USD(8)));
758 BEAST_EXPECT(ownerCount(env, alice) == 1);
759 BEAST_EXPECT(ownerCount(env, bob) == 1);
763 env(check::create(alice, bob, USD(2)));
766 env(check::create(alice, bob, USD(2)));
772 env(check::cash(bob, chkId4, USD(2)));
774 env.require(balance(alice, USD(0)));
775 env.require(balance(bob, USD(10)));
778 BEAST_EXPECT(ownerCount(env, alice) == 2);
779 BEAST_EXPECT(ownerCount(env, bob) == 1);
785 env.require(balance(alice, USD(0)));
786 env.require(balance(bob, USD(10)));
789 BEAST_EXPECT(ownerCount(env, alice) == 2);
790 BEAST_EXPECT(ownerCount(env, bob) == 1);
806 env(check::create(gw, bob, USD(20)));
810 env(check::cash(bob, chkId20, USD(20)));
812 env.require(balance(bob, USD(30)));
816 env(pay(bob, gw, USD(20)));
819 env(check::cancel(bob, chkId3));
821 env.require(balance(alice, USD(0)));
822 env.require(balance(bob, USD(10)));
825 BEAST_EXPECT(ownerCount(env, alice) == 1);
826 BEAST_EXPECT(ownerCount(env, bob) == 1);
830 Env env{*
this, features};
832 env.fund(XRP(1000), gw, alice, bob);
835 env(trust(alice, USD(20)));
836 env(trust(bob, USD(20)));
838 env(pay(gw, alice, USD(8)));
843 env(check::create(alice, bob, USD(9)));
846 env(check::create(alice, bob, USD(8)));
849 env(check::create(alice, bob, USD(7)));
852 env(check::create(alice, bob, USD(6)));
857 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
862 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
864 env.require(balance(alice, USD(0)));
865 env.require(balance(bob, USD(8)));
868 BEAST_EXPECT(ownerCount(env, alice) == 4);
869 BEAST_EXPECT(ownerCount(env, bob) == 1);
872 env(pay(bob, alice, USD(7)));
877 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
879 env.require(balance(alice, USD(0)));
880 env.require(balance(bob, USD(8)));
883 BEAST_EXPECT(ownerCount(env, alice) == 3);
884 BEAST_EXPECT(ownerCount(env, bob) == 1);
887 env(pay(bob, alice, USD(8)));
892 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
894 env.require(balance(alice, USD(2)));
895 env.require(balance(bob, USD(6)));
898 BEAST_EXPECT(ownerCount(env, alice) == 2);
899 BEAST_EXPECT(ownerCount(env, bob) == 1);
903 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
905 env.require(balance(alice, USD(0)));
906 env.require(balance(bob, USD(8)));
909 BEAST_EXPECT(ownerCount(env, alice) == 1);
910 BEAST_EXPECT(ownerCount(env, bob) == 1);
914 Env env(*
this, features);
916 env.fund(XRP(1000), gw, alice, bob);
919 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
920 env(trust(alice, USD(20)));
922 env(pay(gw, alice, USD(8)));
928 env(check::create(alice, bob, USD(7)));
931 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
936 env(trust(bob, USD(5)));
939 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
943 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
953 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
956 env.require(balance(alice, USD(8) - bobGot));
957 env.require(balance(bob, bobGot));
961 BEAST_EXPECT(ownerCount(env, alice) == 1);
962 BEAST_EXPECT(ownerCount(env, bob) == 1);
967 Env env{*
this, features};
968 env.fund(XRP(1000), gw, alice, bob);
973 env(check::create(alice, bob, USD(1)));
977 env(check::create(alice, bob, USD(2)));
980 env(trust(alice, USD(20)));
981 env(trust(bob, USD(20)));
983 env(pay(gw, alice, USD(8)));
988 env(regkey(bob, bobby));
993 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
996 BEAST_EXPECT(ownerCount(env, bob) == 2);
999 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
1001 env.require(balance(alice, USD(7)));
1002 env.require(balance(bob, USD(1)));
1005 BEAST_EXPECT(ownerCount(env, alice) == 2);
1006 BEAST_EXPECT(ownerCount(env, bob) == 2);
1009 XRPAmount const baseFeeDrops{env.current()->fees().base};
1010 env(check::cash(bob, chkId2, (USD(2))),
1012 fee(3 * baseFeeDrops));
1014 env.require(balance(alice, USD(5)));
1015 env.require(balance(bob, USD(3)));
1018 BEAST_EXPECT(ownerCount(env, alice) == 1);
1019 BEAST_EXPECT(ownerCount(env, bob) == 2);
1100 using namespace test::jtx;
1102 Account
const gw{
"gateway"};
1103 Account
const alice{
"alice"};
1104 Account
const bob{
"bob"};
1105 IOU
const USD{gw[
"USD"]};
1107 Env env{*
this, features};
1109 env.fund(XRP(1000), gw, alice, bob);
1112 env(trust(alice, USD(1000)));
1113 env(trust(bob, USD(1000)));
1115 env(pay(gw, alice, USD(1000)));
1123 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1124 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1128 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1129 Account
const& truster,
1131 auto const& inOrOut,
1135 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1136 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1139 env(trust(truster, iou(1000)), inOrOut(pct));
1142 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1144 env.require(balance(alice, aliceStart - USD(10)));
1145 env.require(balance(bob, bobStart + USD(10)));
1149 env(trust(truster, iou(1000)), inOrOut(0));
1153 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1154 Account
const& truster,
1156 auto const& inOrOut,
1160 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1161 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1164 env(trust(truster, iou(1000)), inOrOut(pct));
1168 env(check::create(alice, bob, USD(10)));
1171 env(check::cash(bob, chkId, USD(amount)));
1173 env.require(balance(alice, aliceStart - USD(10)));
1174 env.require(balance(bob, bobStart + USD(10)));
1178 env(trust(truster, iou(1000)), inOrOut(0));
1183 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1184 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1187 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1188 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1190 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1191 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1193 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1194 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1196 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1197 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1199 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1200 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1202 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1203 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1205 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1206 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1213 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1214 Account
const& truster,
1216 auto const& inOrOut,
1224 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1227 env(trust(truster, iou(1000)), inOrOut(pct));
1231 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1233 env.require(balance(alice, aliceStart - USD(10)));
1236 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1238 env.require(balance(alice, aliceStart));
1242 env(trust(truster, iou(1000)), inOrOut(0));
1246 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1247 Account
const& truster,
1249 auto const& inOrOut,
1257 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1260 env(trust(truster, iou(1000)), inOrOut(pct));
1265 env(check::create(alice, gw, USD(max1)));
1268 env(check::cash(gw, chkAliceId, USD(amt1)));
1270 env.require(balance(alice, aliceStart - USD(10)));
1274 env(check::create(gw, alice, USD(max2)));
1277 env(check::cash(alice, chkGwId, USD(amt2)));
1279 env.require(balance(alice, aliceStart));
1283 env(trust(truster, iou(1000)), inOrOut(0));
1289 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1290 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1292 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1293 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1295 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1296 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1298 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1299 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1308 using namespace test::jtx;
1310 Account
const gw{
"gateway"};
1311 Account
const alice{
"alice"};
1312 Account
const bob{
"bob"};
1313 Account
const zoe{
"zoe"};
1314 IOU
const USD{gw[
"USD"]};
1316 Env env(*
this, features);
1318 env.fund(XRP(1000), gw, alice, bob, zoe);
1322 env(trust(alice, USD(20)));
1324 env(pay(gw, alice, USD(20)));
1328 env(trust(bob, USD(20)));
1334 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1340 env(check::create(alice, bob, USD(20)));
1344 env(check::create(alice, bob, XRP(10)));
1347 using namespace std::chrono_literals;
1349 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1353 env(check::create(alice, bob, USD(1)));
1357 env(check::create(alice, bob, USD(2)));
1361 env(check::create(alice, bob, USD(3)));
1365 env(check::create(alice, bob, USD(4)));
1369 env(check::create(alice, bob, USD(1)));
1373 env(check::create(alice, bob, USD(2)), dest_tag(7));
1377 auto failingCases = [&env, &gw, &alice, &bob](
1380 env(check::cash(bob, chkId, amount),
1386 env(check::cash(bob, chkId, amount),
1412 env(check::cash(bob, chkId, amount.zeroed()),
1418 if (!amount.native())
1435 IOU
const wrongCurrency{gw[
"EUR"]};
1437 badAmount.
setIssue(wrongCurrency.issue());
1438 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1444 IOU
const wrongIssuer{alice[
"USD"]};
1446 badAmount.
setIssue(wrongIssuer.issue());
1447 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1456 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1461 failingCases(chkIdX, XRP(10));
1462 failingCases(chkIdU, USD(20));
1465 env(check::cash(bob, chkIdU, USD(20)));
1467 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1471 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1475 env(check::cancel(zoe, chkIdExp));
1480 env(pay(bob, alice, USD(20)));
1482 env.require(balance(alice, USD(20)));
1483 env.require(balance(bob, USD(0)));
1491 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1499 env(check::cash(bob, chkIdFroz1, USD(1)));
1501 env.require(balance(alice, USD(19)));
1502 env.require(balance(bob, USD(1)));
1509 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1516 env(check::cash(bob, chkIdFroz2, USD(2)));
1518 env.require(balance(alice, USD(17)));
1519 env.require(balance(bob, USD(3)));
1524 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1526 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1533 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1535 env.require(balance(alice, USD(14)));
1536 env.require(balance(bob, USD(6)));
1542 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1544 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1551 env(check::cash(bob, chkIdFroz4, USD(4)));
1553 env.require(balance(alice, USD(10)));
1554 env.require(balance(bob, USD(10)));
1563 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1568 env(check::cash(bob, chkIdHasDest2, USD(2)));
1570 env.require(balance(alice, USD(8)));
1571 env.require(balance(bob, USD(12)));
1577 env(check::cash(bob, chkIdNoDest1, USD(1)));
1579 env.require(balance(alice, USD(7)));
1580 env.require(balance(bob, USD(13)));
1590 using namespace test::jtx;
1592 Account
const gw{
"gateway"};
1593 Account
const alice{
"alice"};
1594 Account
const bob{
"bob"};
1595 Account
const zoe{
"zoe"};
1596 IOU
const USD{gw[
"USD"]};
1599 Env env{*
this, features};
1601 env.fund(XRP(1000), gw, alice, bob, zoe);
1607 env(check::create(alice, bob, USD(10)));
1611 env(check::create(alice, bob, XRP(10)));
1615 env(check::create(alice, bob, USD(10)));
1619 using namespace std::chrono_literals;
1621 env(check::create(alice, bob, XRP(10)),
1622 expiration(env.now() + 600s));
1626 env(check::create(alice, bob, USD(10)),
1627 expiration(env.now() + 600s));
1631 env(check::create(alice, bob, XRP(10)),
1632 expiration(env.now() + 600s));
1637 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1641 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1645 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1650 env(check::create(alice, bob, USD(10)));
1654 env(check::create(alice, bob, XRP(10)));
1657 BEAST_EXPECT(ownerCount(env, alice) == 11);
1660 env(check::cancel(alice, chkId1));
1663 BEAST_EXPECT(ownerCount(env, alice) == 10);
1665 env(check::cancel(bob, chkId2));
1668 BEAST_EXPECT(ownerCount(env, alice) == 9);
1673 BEAST_EXPECT(ownerCount(env, alice) == 9);
1676 env(check::cancel(alice, chkIdNotExp1));
1679 BEAST_EXPECT(ownerCount(env, alice) == 8);
1681 env(check::cancel(bob, chkIdNotExp2));
1684 BEAST_EXPECT(ownerCount(env, alice) == 7);
1689 BEAST_EXPECT(ownerCount(env, alice) == 7);
1692 env(check::cancel(alice, chkIdExp1));
1695 BEAST_EXPECT(ownerCount(env, alice) == 6);
1697 env(check::cancel(bob, chkIdExp2));
1700 BEAST_EXPECT(ownerCount(env, alice) == 5);
1702 env(check::cancel(zoe, chkIdExp3));
1705 BEAST_EXPECT(ownerCount(env, alice) == 4);
1709 env(regkey(alice, alie));
1714 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1718 env(check::cancel(alice, chkIdReg), sig(alie));
1721 BEAST_EXPECT(ownerCount(env, alice) == 4);
1724 XRPAmount const baseFeeDrops{env.current()->fees().base};
1725 env(check::cancel(alice, chkIdMSig),
1727 fee(3 * baseFeeDrops));
1730 BEAST_EXPECT(ownerCount(env, alice) == 3);
1733 env(check::cancel(alice, chkId3), sig(alice));
1736 BEAST_EXPECT(ownerCount(env, alice) == 2);
1738 env(check::cancel(bob, chkIdNotExp3));
1741 BEAST_EXPECT(ownerCount(env, alice) == 1);
1816 using namespace test::jtx;
1818 Account
const gw{
"gw"};
1819 Account
const alice{
"alice"};
1820 Account
const bob{
"bob"};
1821 IOU
const USD{gw[
"USD"]};
1823 Env env{*
this, features};
1824 env.fund(XRP(1000), gw, alice, bob);
1831 env(ticket::create(alice, 10));
1835 env(ticket::create(bob, 10));
1839 env.require(owners(alice, 10));
1840 env.require(owners(bob, 10));
1843 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1844 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1846 env.require(owners(alice, 10));
1847 env.require(owners(bob, 10));
1849 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1850 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1852 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1853 BEAST_EXPECT(env.seq(bob) == bobSeq);
1855 env(pay(gw, alice, USD(900)));
1861 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1864 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1867 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1870 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1874 env.require(owners(alice, 10));
1875 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1877 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1879 env.require(owners(bob, 10));
1880 BEAST_EXPECT(env.seq(bob) == bobSeq);
1883 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1884 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1887 env.require(owners(alice, 8));
1888 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1890 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1892 env.require(owners(bob, 8));
1893 BEAST_EXPECT(env.seq(bob) == bobSeq);
1896 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1897 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1900 env.require(owners(alice, 6));
1901 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1903 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1904 env.require(balance(alice, USD(700)));
1906 env.require(owners(bob, 6));
1907 BEAST_EXPECT(env.seq(bob) == bobSeq);
1908 env.require(balance(bob, USD(200)));
1919 using namespace test::jtx;
1921 Env env{*
this, features};
1935 ownerCount(env, acct) == owners,
1936 "Owner count mismatch",
1942 operator Account
const()
const
1959 AccountOwns alice{*
this, env,
"alice", 0};
1960 AccountOwns bob{*
this, env,
"bob", 0};
1963 env.fund(XRP(5000), noripple(alice, bob));
1969 AccountOwns gw1{*
this, env,
"gw1", 0};
1974 env.fund(XRP(5000), noripple(gw1));
1977 IOU
const CK8 = gw1[
"CK8"];
1978 gw1.verifyOwners(__LINE__);
1980 Account
const yui{
"yui"};
1985 env.fund(XRP(200), yui);
1989 env(check::create(gw1, yui, CK8(99)));
1992 env(check::cash(yui, chkId, CK8(99)),
1995 alice.verifyOwners(__LINE__);
1999 env(pay(env.master, yui, XRP(51)));
2001 env(check::cash(yui, chkId, CK8(99)));
2004 BEAST_EXPECT(ownerCount(env, yui) == 1);
2008 gw1.verifyOwners(__LINE__);
2023 auto cmpTrustLines = [
this, &env](
2024 Account
const& acct1,
2025 Account
const& acct2,
2026 IOU
const& offerIou,
2027 IOU
const& checkIou) {
2028 auto const offerLine =
2030 auto const checkLine =
2032 if (offerLine ==
nullptr || checkLine ==
nullptr)
2034 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
2040 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2045 [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
2046 STAmount const offerAmount = offerLine->at(sfield);
2047 STAmount const checkAmount = checkLine->at(sfield);
2064 cmpReqAmount(sfBalance);
2065 cmpReqAmount(sfLowLimit);
2066 cmpReqAmount(sfHighLimit);
2071 [
this, offerLine, checkLine](
auto const& sfield) {
2074 offerLine->isFieldPresent(sfield) ==
2075 checkLine->isFieldPresent(sfield)))
2080 if (!offerLine->isFieldPresent(sfield))
2086 offerLine->at(sfield) == checkLine->at(sfield));
2088 cmpOptField(sfLowNode);
2089 cmpOptField(sfLowQualityIn);
2090 cmpOptField(sfLowQualityOut);
2092 cmpOptField(sfHighNode);
2093 cmpOptField(sfHighQualityIn);
2094 cmpOptField(sfHighQualityOut);
2102 AccountOwns gw1{*
this, env,
"gw1", 0};
2104 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2105 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2106 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2109 IOU
const OF1 = gw1[
"OF1"];
2110 env(offer(gw1, XRP(98), OF1(98)));
2113 env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2114 env(offer(alice, OF1(98), XRP(98)));
2121 gw1.verifyOwners(__LINE__);
2124 alice.verifyOwners(__LINE__);
2127 IOU
const CK1 = gw1[
"CK1"];
2129 env(check::create(gw1, alice, CK1(98)));
2132 env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2133 env(check::cash(alice, chkId, CK1(98)));
2141 gw1.verifyOwners(__LINE__);
2144 alice.verifyOwners(__LINE__);
2146 cmpTrustLines(gw1, alice, OF1, CK1);
2157 AccountOwns gw1{*
this, env,
"gw1", 0};
2158 IOU
const OF1 = gw1[
"OF1"];
2159 env(offer(alice, XRP(97), OF1(97)));
2162 env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2163 env(offer(bob, OF1(97), XRP(97)));
2168 env.require(balance(alice, OF1(1)));
2169 env.require(balance(bob, OF1(97)));
2172 gw1.verifyOwners(__LINE__);
2173 alice.verifyOwners(__LINE__);
2174 bob.verifyOwners(__LINE__);
2182 IOU
const CK1 = gw1[
"CK1"];
2184 env(check::create(alice, bob, CK1(97)));
2187 env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2188 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2192 env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2194 env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2197 env(check::cancel(alice, chkId));
2201 gw1.verifyOwners(__LINE__);
2202 alice.verifyOwners(__LINE__);
2203 bob.verifyOwners(__LINE__);
2210 AccountOwns gw1{*
this, env,
"gw1", 0};
2215 IOU
const OF2 = gw1[
"OF2"];
2216 env(offer(gw1, XRP(96), OF2(96)));
2219 env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2220 env(offer(alice, OF2(96), XRP(96)));
2227 gw1.verifyOwners(__LINE__);
2230 alice.verifyOwners(__LINE__);
2233 IOU
const CK2 = gw1[
"CK2"];
2235 env(check::create(gw1, alice, CK2(96)));
2238 env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2239 env(check::cash(alice, chkId, CK2(96)));
2247 gw1.verifyOwners(__LINE__);
2250 alice.verifyOwners(__LINE__);
2252 cmpTrustLines(gw1, alice, OF2, CK2);
2260 AccountOwns gw1{*
this, env,
"gw1", 0};
2261 IOU
const OF2 = gw1[
"OF2"];
2262 env(offer(alice, XRP(95), OF2(95)));
2265 env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2266 env(offer(bob, OF2(95), XRP(95)));
2271 gw1.verifyOwners(__LINE__);
2272 alice.verifyOwners(__LINE__);
2273 bob.verifyOwners(__LINE__);
2276 IOU
const CK2 = gw1[
"CK2"];
2278 env(check::create(alice, bob, CK2(95)));
2281 env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2282 env(check::cash(bob, chkId, CK2(95)));
2288 gw1.verifyOwners(__LINE__);
2289 alice.verifyOwners(__LINE__);
2290 bob.verifyOwners(__LINE__);
2292 cmpTrustLines(alice, bob, OF2, CK2);
2303 AccountOwns gw1{*
this, env,
"gw1", 0};
2310 IOU
const OF3 = gw1[
"OF3"];
2311 env(offer(gw1, XRP(94), OF3(94)));
2314 env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2315 env(offer(alice, OF3(94), XRP(94)));
2322 gw1.verifyOwners(__LINE__);
2325 alice.verifyOwners(__LINE__);
2328 IOU
const CK3 = gw1[
"CK3"];
2330 env(check::create(gw1, alice, CK3(94)));
2333 env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2334 env(check::cash(alice, chkId, CK3(94)));
2342 gw1.verifyOwners(__LINE__);
2345 alice.verifyOwners(__LINE__);
2347 cmpTrustLines(gw1, alice, OF3, CK3);
2355 AccountOwns gw1{*
this, env,
"gw1", 0};
2356 IOU
const OF3 = gw1[
"OF3"];
2357 env(offer(alice, XRP(93), OF3(93)));
2360 env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2361 env(offer(bob, OF3(93), XRP(93)));
2366 gw1.verifyOwners(__LINE__);
2367 alice.verifyOwners(__LINE__);
2368 bob.verifyOwners(__LINE__);
2371 IOU
const CK3 = gw1[
"CK3"];
2373 env(check::create(alice, bob, CK3(93)));
2376 env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2377 env(check::cash(bob, chkId, CK3(93)));
2383 gw1.verifyOwners(__LINE__);
2384 alice.verifyOwners(__LINE__);
2385 bob.verifyOwners(__LINE__);
2387 cmpTrustLines(alice, bob, OF3, CK3);
2394 AccountOwns gw1{*
this, env,
"gw1", 0};
2399 IOU
const OF4 = gw1[
"OF4"];
2400 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2403 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2404 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2408 gw1.verifyOwners(__LINE__);
2409 alice.verifyOwners(__LINE__);
2410 bob.verifyOwners(__LINE__);
2413 IOU
const CK4 = gw1[
"CK4"];
2415 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2418 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2419 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2423 gw1.verifyOwners(__LINE__);
2424 alice.verifyOwners(__LINE__);
2425 bob.verifyOwners(__LINE__);
2430 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2432 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2440 AccountOwns gw1{*
this, env,
"gw1", 0};
2441 IOU
const OF4 = gw1[
"OF4"];
2442 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2445 env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2446 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2450 gw1.verifyOwners(__LINE__);
2451 alice.verifyOwners(__LINE__);
2452 bob.verifyOwners(__LINE__);
2455 IOU
const CK4 = gw1[
"CK4"];
2457 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2460 env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2461 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2465 gw1.verifyOwners(__LINE__);
2466 alice.verifyOwners(__LINE__);
2467 bob.verifyOwners(__LINE__);
2472 env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2474 env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2483 AccountOwns gw2{*
this, env,
"gw2", 0};
2484 env.fund(XRP(5000), gw2);
2493 IOU
const OF5 = gw2[
"OF5"];
2495 env(offer(gw2, XRP(92), OF5(92)));
2499 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2500 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2505 gw2.verifyOwners(__LINE__);
2506 alice.verifyOwners(__LINE__);
2507 bob.verifyOwners(__LINE__);
2510 env(offer_cancel(gw2, gw2OfferSeq));
2513 gw2.verifyOwners(__LINE__);
2516 IOU
const CK5 = gw2[
"CK5"];
2518 env(check::create(gw2, alice, CK5(92)));
2522 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2523 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2528 gw2.verifyOwners(__LINE__);
2529 alice.verifyOwners(__LINE__);
2530 bob.verifyOwners(__LINE__);
2535 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2537 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2540 env(check::cancel(gw2, chkId));
2543 gw2.verifyOwners(__LINE__);
2551 AccountOwns gw2{*
this, env,
"gw2", 0};
2552 IOU
const OF5 = gw2[
"OF5"];
2555 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2557 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2560 gw2.verifyOwners(__LINE__);
2561 alice.verifyOwners(__LINE__);
2562 bob.verifyOwners(__LINE__);
2565 IOU
const CK5 = gw2[
"CK5"];
2567 env(check::create(alice, bob, CK5(91)));
2570 env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2575 env(check::cancel(alice, chkId));
2579 gw2.verifyOwners(__LINE__);
2580 alice.verifyOwners(__LINE__);
2581 bob.verifyOwners(__LINE__);
2586 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2588 env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);