149 using namespace test::jtx;
151 Account
const gw{
"gateway"};
152 Account
const alice{
"alice"};
153 Account
const bob{
"bob"};
154 IOU
const USD{gw[
"USD"]};
156 Env env{*
this, features};
158 STAmount const startBalance{XRP(1000).value()};
159 env.fund(startBalance, gw, alice, bob);
165 auto writeTwoChecks = [&env, &USD,
this](Account
const& from, Account
const& to) {
172 env(check::create(from, to, XRP(2000)));
175 env(check::create(from, to, USD(50)));
181 env.require(owners(from, fromOwnerCount + 2));
182 env.require(owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
185 writeTwoChecks(alice, bob);
186 writeTwoChecks(gw, alice);
187 writeTwoChecks(alice, gw);
193 using namespace std::chrono_literals;
196 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
199 env(check::create(alice, bob, USD(50)), source_tag(2));
201 env(check::create(alice, bob, USD(50)), dest_tag(3));
203 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
205 env(check::create(alice, bob, USD(50)),
206 expiration(env.now() + 1s),
217 env(regkey(alice, alie));
222 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
226 env(check::create(alice, bob, USD(50)), sig(alie));
232 XRPAmount const baseFeeDrops{env.current()->fees().base};
233 env(check::create(alice, bob, USD(50)), msig(bogie, demon), fee(3 * baseFeeDrops));
324 using namespace test::jtx;
326 Account
const gw1{
"gateway1"};
327 Account
const gwF{
"gatewayFrozen"};
328 Account
const alice{
"alice"};
329 Account
const bob{
"bob"};
330 IOU
const USD{gw1[
"USD"]};
332 Env env{*
this, features};
334 STAmount const startBalance{XRP(1000).value()};
335 env.fund(startBalance, gw1, gwF, alice, bob);
339 env(check::create(alice, bob, USD(50)), fee(drops(-10)), ter(
temBAD_FEE));
347 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
351 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
354 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
357 env(check::create(alice, bob, drops(1)));
366 env(check::create(alice, bob, USD(1)));
375 env(check::create(alice, bob, USD(50)),
381 Account
const bogie{
"bogie"};
382 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
392 env(check::create(alice, bob, USD(50)), dest_tag(11));
399 IOU
const USF{gwF[
"USF"]};
403 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
409 env(check::create(alice, bob, USF(50)));
415 env.trust(USD(1000), alice);
416 env.trust(USD(1000), bob);
418 env(pay(gw1, alice, USD(25)));
419 env(pay(gw1, bob, USD(25)));
427 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
431 env(check::create(bob, alice, USD(50)));
433 env(pay(bob, alice, USD(1)));
435 env(check::create(gw1, alice, USD(50)));
437 env(pay(gw1, alice, USD(1)));
443 env(check::create(alice, bob, USD(50)));
445 env(check::create(bob, alice, USD(50)));
447 env(check::create(gw1, alice, USD(50)));
455 env(check::create(alice, bob, USD(50)));
457 env(pay(alice, bob, USD(1)));
459 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
463 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
474 env(check::create(alice, bob, USD(50)), expiration(env.now()), ter(
tecEXPIRED));
477 using namespace std::chrono_literals;
478 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
482 Account
const cheri{
"cheri"};
483 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
486 env(check::create(cheri, bob, USD(50)),
487 fee(drops(env.current()->fees().base)),
491 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
494 env(check::create(cheri, bob, USD(50)));
504 using namespace test::jtx;
506 Account
const alice{
"alice"};
507 Account
const bob{
"bob"};
509 Env env{*
this, features};
511 XRPAmount const baseFeeDrops{env.current()->fees().base};
512 STAmount const startBalance{XRP(300).value()};
513 env.fund(startBalance, alice, bob);
518 env(check::create(alice, bob, XRP(10)));
520 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
521 env.require(balance(bob, startBalance));
524 BEAST_EXPECT(ownerCount(env, alice) == 1);
525 BEAST_EXPECT(ownerCount(env, bob) == 0);
527 env(check::cash(bob, chkId, XRP(10)));
529 env.require(balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
530 env.require(balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
533 BEAST_EXPECT(ownerCount(env, alice) == 0);
534 BEAST_EXPECT(ownerCount(env, bob) == 0);
537 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
538 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
540 env.require(balance(alice, startBalance));
541 env.require(balance(bob, startBalance));
545 STAmount const reserve{env.current()->fees().reserve};
546 STAmount const checkAmount{startBalance - reserve - drops(baseFeeDrops)};
548 env(check::create(alice, bob, checkAmount));
552 env(check::cash(bob, chkId, checkAmount + drops(1)), ter(
tecPATH_PARTIAL));
554 env(check::cash(bob, chkId, check::DeliverMin(checkAmount + drops(1))),
561 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
563 env.require(balance(alice, reserve));
564 env.require(balance(bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
567 BEAST_EXPECT(ownerCount(env, alice) == 0);
568 BEAST_EXPECT(ownerCount(env, bob) == 0);
571 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
572 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
574 env.require(balance(alice, startBalance));
575 env.require(balance(bob, startBalance));
579 STAmount const reserve{env.current()->fees().reserve};
580 STAmount const checkAmount{startBalance - reserve - drops(baseFeeDrops - 1)};
582 env(check::create(alice, bob, checkAmount));
591 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
593 env.require(balance(alice, reserve));
594 env.require(balance(bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
597 BEAST_EXPECT(ownerCount(env, alice) == 0);
598 BEAST_EXPECT(ownerCount(env, bob) == 0);
601 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
602 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
604 env.require(balance(alice, startBalance));
605 env.require(balance(bob, startBalance));
615 using namespace test::jtx;
617 Account
const gw{
"gateway"};
618 Account
const alice{
"alice"};
619 Account
const bob{
"bob"};
620 IOU
const USD{gw[
"USD"]};
623 Env env{*
this, features};
625 env.fund(XRP(1000), gw, alice, bob);
630 env(check::create(alice, bob, USD(10)));
638 env(trust(alice, USD(20)));
640 env(pay(gw, alice, USD(9.5)));
647 env(pay(gw, alice, USD(0.5)));
651 env(trust(bob, USD(9.5)));
656 env(trust(bob, USD(10.5)));
662 env(check::cash(bob, chkId1, USD(10)));
664 env.require(balance(alice, USD(0)));
665 env.require(balance(bob, USD(10)));
668 BEAST_EXPECT(ownerCount(env, alice) == 1);
669 BEAST_EXPECT(ownerCount(env, bob) == 1);
672 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
676 env(pay(bob, alice, USD(7)));
680 env(check::create(alice, bob, USD(7)));
687 env(check::cash(bob, chkId2, USD(5)));
689 env.require(balance(alice, USD(2)));
690 env.require(balance(bob, USD(8)));
693 BEAST_EXPECT(ownerCount(env, alice) == 1);
694 BEAST_EXPECT(ownerCount(env, bob) == 1);
698 env(check::create(alice, bob, USD(2)));
701 env(check::create(alice, bob, USD(2)));
707 env(check::cash(bob, chkId4, USD(2)));
709 env.require(balance(alice, USD(0)));
710 env.require(balance(bob, USD(10)));
713 BEAST_EXPECT(ownerCount(env, alice) == 2);
714 BEAST_EXPECT(ownerCount(env, bob) == 1);
720 env.require(balance(alice, USD(0)));
721 env.require(balance(bob, USD(10)));
724 BEAST_EXPECT(ownerCount(env, alice) == 2);
725 BEAST_EXPECT(ownerCount(env, bob) == 1);
741 env(check::create(gw, bob, USD(20)));
745 env(check::cash(bob, chkId20, USD(20)));
747 env.require(balance(bob, USD(30)));
751 env(pay(bob, gw, USD(20)));
754 env(check::cancel(bob, chkId3));
756 env.require(balance(alice, USD(0)));
757 env.require(balance(bob, USD(10)));
760 BEAST_EXPECT(ownerCount(env, alice) == 1);
761 BEAST_EXPECT(ownerCount(env, bob) == 1);
765 Env env{*
this, features};
767 env.fund(XRP(1000), gw, alice, bob);
770 env(trust(alice, USD(20)));
771 env(trust(bob, USD(20)));
773 env(pay(gw, alice, USD(8)));
778 env(check::create(alice, bob, USD(9)));
781 env(check::create(alice, bob, USD(8)));
784 env(check::create(alice, bob, USD(7)));
787 env(check::create(alice, bob, USD(6)));
792 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))), ter(
tecPATH_PARTIAL));
796 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
798 env.require(balance(alice, USD(0)));
799 env.require(balance(bob, USD(8)));
802 BEAST_EXPECT(ownerCount(env, alice) == 4);
803 BEAST_EXPECT(ownerCount(env, bob) == 1);
806 env(pay(bob, alice, USD(7)));
811 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
813 env.require(balance(alice, USD(0)));
814 env.require(balance(bob, USD(8)));
817 BEAST_EXPECT(ownerCount(env, alice) == 3);
818 BEAST_EXPECT(ownerCount(env, bob) == 1);
821 env(pay(bob, alice, USD(8)));
826 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
828 env.require(balance(alice, USD(2)));
829 env.require(balance(bob, USD(6)));
832 BEAST_EXPECT(ownerCount(env, alice) == 2);
833 BEAST_EXPECT(ownerCount(env, bob) == 1);
837 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
839 env.require(balance(alice, USD(0)));
840 env.require(balance(bob, USD(8)));
843 BEAST_EXPECT(ownerCount(env, alice) == 1);
844 BEAST_EXPECT(ownerCount(env, bob) == 1);
848 Env env(*
this, features);
850 env.fund(XRP(1000), gw, alice, bob);
853 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
854 env(trust(alice, USD(20)));
856 env(pay(gw, alice, USD(8)));
862 env(check::create(alice, bob, USD(7)));
865 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
870 env(trust(bob, USD(5)));
873 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
877 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
887 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
890 env.require(balance(alice, USD(8) - bobGot));
891 env.require(balance(bob, bobGot));
895 BEAST_EXPECT(ownerCount(env, alice) == 1);
896 BEAST_EXPECT(ownerCount(env, bob) == 1);
901 Env env{*
this, features};
902 env.fund(XRP(1000), gw, alice, bob);
907 env(check::create(alice, bob, USD(1)));
911 env(check::create(alice, bob, USD(2)));
914 env(trust(alice, USD(20)));
915 env(trust(bob, USD(20)));
917 env(pay(gw, alice, USD(8)));
922 env(regkey(bob, bobby));
927 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
930 BEAST_EXPECT(ownerCount(env, bob) == 2);
933 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
935 env.require(balance(alice, USD(7)));
936 env.require(balance(bob, USD(1)));
939 BEAST_EXPECT(ownerCount(env, alice) == 2);
940 BEAST_EXPECT(ownerCount(env, bob) == 2);
943 XRPAmount const baseFeeDrops{env.current()->fees().base};
944 env(check::cash(bob, chkId2, (USD(2))), msig(bogie, demon), fee(3 * baseFeeDrops));
946 env.require(balance(alice, USD(5)));
947 env.require(balance(bob, USD(3)));
950 BEAST_EXPECT(ownerCount(env, alice) == 1);
951 BEAST_EXPECT(ownerCount(env, bob) == 2);
1031 using namespace test::jtx;
1033 Account
const gw{
"gateway"};
1034 Account
const alice{
"alice"};
1035 Account
const bob{
"bob"};
1036 IOU
const USD{gw[
"USD"]};
1038 Env env{*
this, features};
1040 env.fund(XRP(1000), gw, alice, bob);
1043 env(trust(alice, USD(1000)));
1044 env(trust(bob, USD(1000)));
1046 env(pay(gw, alice, USD(1000)));
1054 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1055 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1059 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1060 Account
const& truster,
1062 auto const& inOrOut,
1066 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1067 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1070 env(trust(truster, iou(1000)), inOrOut(pct));
1073 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1075 env.require(balance(alice, aliceStart - USD(10)));
1076 env.require(balance(bob, bobStart + USD(10)));
1080 env(trust(truster, iou(1000)), inOrOut(0));
1084 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1085 Account
const& truster,
1087 auto const& inOrOut,
1091 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1092 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1095 env(trust(truster, iou(1000)), inOrOut(pct));
1099 env(check::create(alice, bob, USD(10)));
1102 env(check::cash(bob, chkId, USD(amount)));
1104 env.require(balance(alice, aliceStart - USD(10)));
1105 env.require(balance(bob, bobStart + USD(10)));
1109 env(trust(truster, iou(1000)), inOrOut(0));
1114 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1115 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1118 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1119 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1121 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1122 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1124 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1125 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1127 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1128 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1130 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1131 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1133 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1134 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1136 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1137 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1144 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1145 Account
const& truster,
1147 auto const& inOrOut,
1155 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1158 env(trust(truster, iou(1000)), inOrOut(pct));
1162 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1164 env.require(balance(alice, aliceStart - USD(10)));
1167 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1169 env.require(balance(alice, aliceStart));
1173 env(trust(truster, iou(1000)), inOrOut(0));
1177 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1178 Account
const& truster,
1180 auto const& inOrOut,
1188 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1191 env(trust(truster, iou(1000)), inOrOut(pct));
1196 env(check::create(alice, gw, USD(max1)));
1199 env(check::cash(gw, chkAliceId, USD(amt1)));
1201 env.require(balance(alice, aliceStart - USD(10)));
1205 env(check::create(gw, alice, USD(max2)));
1208 env(check::cash(alice, chkGwId, USD(amt2)));
1210 env.require(balance(alice, aliceStart));
1214 env(trust(truster, iou(1000)), inOrOut(0));
1220 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1221 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1223 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1224 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1226 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1227 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1229 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1230 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1239 using namespace test::jtx;
1241 Account
const gw{
"gateway"};
1242 Account
const alice{
"alice"};
1243 Account
const bob{
"bob"};
1244 Account
const zoe{
"zoe"};
1245 IOU
const USD{gw[
"USD"]};
1247 Env env(*
this, features);
1249 env.fund(XRP(1000), gw, alice, bob, zoe);
1253 env(trust(alice, USD(20)));
1255 env(pay(gw, alice, USD(20)));
1259 env(trust(bob, USD(20)));
1265 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1271 env(check::create(alice, bob, USD(20)));
1275 env(check::create(alice, bob, XRP(10)));
1278 using namespace std::chrono_literals;
1280 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1284 env(check::create(alice, bob, USD(1)));
1288 env(check::create(alice, bob, USD(2)));
1292 env(check::create(alice, bob, USD(3)));
1296 env(check::create(alice, bob, USD(4)));
1300 env(check::create(alice, bob, USD(1)));
1304 env(check::create(alice, bob, USD(2)), dest_tag(7));
1308 auto failingCases = [&env, &gw, &alice, &bob](
1311 env(check::cash(bob, chkId, amount), fee(drops(-10)), ter(
temBAD_FEE));
1315 env(check::cash(bob, chkId, amount),
1341 env(check::cash(bob, chkId, amount.zeroed()), ter(
temBAD_AMOUNT));
1346 if (!amount.native())
1363 IOU
const wrongCurrency{gw[
"EUR"]};
1365 badAmount.setIssue(wrongCurrency.issue());
1366 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1372 IOU
const wrongIssuer{alice[
"USD"]};
1374 badAmount.setIssue(wrongIssuer.issue());
1375 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1384 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)), ter(
tecPATH_PARTIAL));
1388 failingCases(chkIdX, XRP(10));
1389 failingCases(chkIdU, USD(20));
1392 env(check::cash(bob, chkIdU, USD(20)));
1394 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1398 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1402 env(check::cancel(zoe, chkIdExp));
1407 env(pay(bob, alice, USD(20)));
1409 env.require(balance(alice, USD(20)));
1410 env.require(balance(bob, USD(0)));
1418 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))), ter(
tecPATH_PARTIAL));
1425 env(check::cash(bob, chkIdFroz1, USD(1)));
1427 env.require(balance(alice, USD(19)));
1428 env.require(balance(bob, USD(1)));
1435 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))), ter(
tecPATH_PARTIAL));
1441 env(check::cash(bob, chkIdFroz2, USD(2)));
1443 env.require(balance(alice, USD(17)));
1444 env.require(balance(bob, USD(3)));
1449 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1451 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))), ter(
tecFROZEN));
1457 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1459 env.require(balance(alice, USD(14)));
1460 env.require(balance(bob, USD(6)));
1466 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1468 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))), ter(
terNO_LINE));
1474 env(check::cash(bob, chkIdFroz4, USD(4)));
1476 env.require(balance(alice, USD(10)));
1477 env.require(balance(bob, USD(10)));
1486 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1491 env(check::cash(bob, chkIdHasDest2, USD(2)));
1493 env.require(balance(alice, USD(8)));
1494 env.require(balance(bob, USD(12)));
1500 env(check::cash(bob, chkIdNoDest1, USD(1)));
1502 env.require(balance(alice, USD(7)));
1503 env.require(balance(bob, USD(13)));
1513 using namespace test::jtx;
1515 Account
const gw{
"gateway"};
1516 Account
const alice{
"alice"};
1517 Account
const bob{
"bob"};
1518 Account
const zoe{
"zoe"};
1519 IOU
const USD{gw[
"USD"]};
1522 Env env{*
this, features};
1524 env.fund(XRP(1000), gw, alice, bob, zoe);
1530 env(check::create(alice, bob, USD(10)));
1534 env(check::create(alice, bob, XRP(10)));
1538 env(check::create(alice, bob, USD(10)));
1542 using namespace std::chrono_literals;
1544 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 600s));
1548 env(check::create(alice, bob, USD(10)), expiration(env.now() + 600s));
1552 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 600s));
1557 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1561 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1565 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1570 env(check::create(alice, bob, USD(10)));
1574 env(check::create(alice, bob, XRP(10)));
1577 BEAST_EXPECT(ownerCount(env, alice) == 11);
1580 env(check::cancel(alice, chkId1));
1583 BEAST_EXPECT(ownerCount(env, alice) == 10);
1585 env(check::cancel(bob, chkId2));
1588 BEAST_EXPECT(ownerCount(env, alice) == 9);
1593 BEAST_EXPECT(ownerCount(env, alice) == 9);
1596 env(check::cancel(alice, chkIdNotExp1));
1599 BEAST_EXPECT(ownerCount(env, alice) == 8);
1601 env(check::cancel(bob, chkIdNotExp2));
1604 BEAST_EXPECT(ownerCount(env, alice) == 7);
1609 BEAST_EXPECT(ownerCount(env, alice) == 7);
1612 env(check::cancel(alice, chkIdExp1));
1615 BEAST_EXPECT(ownerCount(env, alice) == 6);
1617 env(check::cancel(bob, chkIdExp2));
1620 BEAST_EXPECT(ownerCount(env, alice) == 5);
1622 env(check::cancel(zoe, chkIdExp3));
1625 BEAST_EXPECT(ownerCount(env, alice) == 4);
1629 env(regkey(alice, alie));
1634 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1638 env(check::cancel(alice, chkIdReg), sig(alie));
1641 BEAST_EXPECT(ownerCount(env, alice) == 4);
1644 XRPAmount const baseFeeDrops{env.current()->fees().base};
1645 env(check::cancel(alice, chkIdMSig), msig(bogie, demon), fee(3 * baseFeeDrops));
1648 BEAST_EXPECT(ownerCount(env, alice) == 3);
1651 env(check::cancel(alice, chkId3), sig(alice));
1654 BEAST_EXPECT(ownerCount(env, alice) == 2);
1656 env(check::cancel(bob, chkIdNotExp3));
1659 BEAST_EXPECT(ownerCount(env, alice) == 1);
1732 using namespace test::jtx;
1734 Account
const gw{
"gw"};
1735 Account
const alice{
"alice"};
1736 Account
const bob{
"bob"};
1737 IOU
const USD{gw[
"USD"]};
1739 Env env{*
this, features};
1740 env.fund(XRP(1000), gw, alice, bob);
1747 env(ticket::create(alice, 10));
1751 env(ticket::create(bob, 10));
1755 env.require(owners(alice, 10));
1756 env.require(owners(bob, 10));
1759 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1760 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1762 env.require(owners(alice, 10));
1763 env.require(owners(bob, 10));
1765 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1766 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1768 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1769 BEAST_EXPECT(env.seq(bob) == bobSeq);
1771 env(pay(gw, alice, USD(900)));
1777 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1780 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1783 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1786 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1790 env.require(owners(alice, 10));
1791 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1793 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1795 env.require(owners(bob, 10));
1796 BEAST_EXPECT(env.seq(bob) == bobSeq);
1799 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1800 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1803 env.require(owners(alice, 8));
1804 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1806 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1808 env.require(owners(bob, 8));
1809 BEAST_EXPECT(env.seq(bob) == bobSeq);
1812 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1813 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1816 env.require(owners(alice, 6));
1817 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1819 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1820 env.require(balance(alice, USD(700)));
1822 env.require(owners(bob, 6));
1823 BEAST_EXPECT(env.seq(bob) == bobSeq);
1824 env.require(balance(bob, USD(200)));
1835 using namespace test::jtx;
1837 Env env{*
this, features};
1851 ownerCount(env, acct) == owners,
"Owner count mismatch", __FILE__, line);
1855 operator Account
const()
const
1872 AccountOwns alice{*
this, env,
"alice", 0};
1873 AccountOwns bob{*
this, env,
"bob", 0};
1876 env.fund(XRP(5000), noripple(alice, bob));
1882 AccountOwns gw1{*
this, env,
"gw1", 0};
1887 env.fund(XRP(5000), noripple(gw1));
1890 IOU
const CK8 = gw1[
"CK8"];
1891 gw1.verifyOwners(__LINE__);
1893 Account
const yui{
"yui"};
1898 env.fund(XRP(200), yui);
1902 env(check::create(gw1, yui, CK8(99)));
1907 alice.verifyOwners(__LINE__);
1911 env(pay(env.master, yui, XRP(51)));
1913 env(check::cash(yui, chkId, CK8(99)));
1916 BEAST_EXPECT(ownerCount(env, yui) == 1);
1920 gw1.verifyOwners(__LINE__);
1935 auto cmpTrustLines = [
this, &env](
1936 Account
const& acct1,
1937 Account
const& acct2,
1938 IOU
const& offerIou,
1939 IOU
const& checkIou) {
1940 auto const offerLine = env.le(
keylet::line(acct1, acct2, offerIou.currency));
1941 auto const checkLine = env.le(
keylet::line(acct1, acct2, checkIou.currency));
1942 if (offerLine ==
nullptr || checkLine ==
nullptr)
1944 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
1950 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
1954 auto cmpReqAmount = [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
1955 STAmount const offerAmount = offerLine->at(sfield);
1956 STAmount const checkAmount = checkLine->at(sfield);
1959 if (!BEAST_EXPECT(!offerAmount.
native() && !checkAmount.
native()))
1967 cmpReqAmount(sfBalance);
1968 cmpReqAmount(sfLowLimit);
1969 cmpReqAmount(sfHighLimit);
1973 auto cmpOptField = [
this, offerLine, checkLine](
auto const& sfield) {
1976 offerLine->isFieldPresent(sfield) == checkLine->isFieldPresent(sfield)))
1981 if (!offerLine->isFieldPresent(sfield))
1986 BEAST_EXPECT(offerLine->at(sfield) == checkLine->at(sfield));
1988 cmpOptField(sfLowNode);
1989 cmpOptField(sfLowQualityIn);
1990 cmpOptField(sfLowQualityOut);
1992 cmpOptField(sfHighNode);
1993 cmpOptField(sfHighQualityIn);
1994 cmpOptField(sfHighQualityOut);
2002 AccountOwns gw1{*
this, env,
"gw1", 0};
2004 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2005 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2006 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2009 IOU
const OF1 = gw1[
"OF1"];
2010 env(offer(gw1, XRP(98), OF1(98)));
2012 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2013 env(offer(alice, OF1(98), XRP(98)));
2020 gw1.verifyOwners(__LINE__);
2023 alice.verifyOwners(__LINE__);
2026 IOU
const CK1 = gw1[
"CK1"];
2028 env(check::create(gw1, alice, CK1(98)));
2030 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2031 env(check::cash(alice, chkId, CK1(98)));
2039 gw1.verifyOwners(__LINE__);
2042 alice.verifyOwners(__LINE__);
2044 cmpTrustLines(gw1, alice, OF1, CK1);
2055 AccountOwns gw1{*
this, env,
"gw1", 0};
2056 IOU
const OF1 = gw1[
"OF1"];
2057 env(offer(alice, XRP(97), OF1(97)));
2059 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2060 env(offer(bob, OF1(97), XRP(97)));
2065 env.require(balance(alice, OF1(1)));
2066 env.require(balance(bob, OF1(97)));
2069 gw1.verifyOwners(__LINE__);
2070 alice.verifyOwners(__LINE__);
2071 bob.verifyOwners(__LINE__);
2079 IOU
const CK1 = gw1[
"CK1"];
2081 env(check::create(alice, bob, CK1(97)));
2083 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2084 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2087 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2088 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2091 env(check::cancel(alice, chkId));
2095 gw1.verifyOwners(__LINE__);
2096 alice.verifyOwners(__LINE__);
2097 bob.verifyOwners(__LINE__);
2104 AccountOwns gw1{*
this, env,
"gw1", 0};
2109 IOU
const OF2 = gw1[
"OF2"];
2110 env(offer(gw1, XRP(96), OF2(96)));
2112 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2113 env(offer(alice, OF2(96), XRP(96)));
2120 gw1.verifyOwners(__LINE__);
2123 alice.verifyOwners(__LINE__);
2126 IOU
const CK2 = gw1[
"CK2"];
2128 env(check::create(gw1, alice, CK2(96)));
2130 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2131 env(check::cash(alice, chkId, CK2(96)));
2139 gw1.verifyOwners(__LINE__);
2142 alice.verifyOwners(__LINE__);
2144 cmpTrustLines(gw1, alice, OF2, CK2);
2152 AccountOwns gw1{*
this, env,
"gw1", 0};
2153 IOU
const OF2 = gw1[
"OF2"];
2154 env(offer(alice, XRP(95), OF2(95)));
2156 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2157 env(offer(bob, OF2(95), XRP(95)));
2162 gw1.verifyOwners(__LINE__);
2163 alice.verifyOwners(__LINE__);
2164 bob.verifyOwners(__LINE__);
2167 IOU
const CK2 = gw1[
"CK2"];
2169 env(check::create(alice, bob, CK2(95)));
2171 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2172 env(check::cash(bob, chkId, CK2(95)));
2178 gw1.verifyOwners(__LINE__);
2179 alice.verifyOwners(__LINE__);
2180 bob.verifyOwners(__LINE__);
2182 cmpTrustLines(alice, bob, OF2, CK2);
2193 AccountOwns gw1{*
this, env,
"gw1", 0};
2200 IOU
const OF3 = gw1[
"OF3"];
2201 env(offer(gw1, XRP(94), OF3(94)));
2203 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2204 env(offer(alice, OF3(94), XRP(94)));
2211 gw1.verifyOwners(__LINE__);
2214 alice.verifyOwners(__LINE__);
2217 IOU
const CK3 = gw1[
"CK3"];
2219 env(check::create(gw1, alice, CK3(94)));
2221 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2222 env(check::cash(alice, chkId, CK3(94)));
2230 gw1.verifyOwners(__LINE__);
2233 alice.verifyOwners(__LINE__);
2235 cmpTrustLines(gw1, alice, OF3, CK3);
2243 AccountOwns gw1{*
this, env,
"gw1", 0};
2244 IOU
const OF3 = gw1[
"OF3"];
2245 env(offer(alice, XRP(93), OF3(93)));
2247 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2248 env(offer(bob, OF3(93), XRP(93)));
2253 gw1.verifyOwners(__LINE__);
2254 alice.verifyOwners(__LINE__);
2255 bob.verifyOwners(__LINE__);
2258 IOU
const CK3 = gw1[
"CK3"];
2260 env(check::create(alice, bob, CK3(93)));
2262 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2263 env(check::cash(bob, chkId, CK3(93)));
2269 gw1.verifyOwners(__LINE__);
2270 alice.verifyOwners(__LINE__);
2271 bob.verifyOwners(__LINE__);
2273 cmpTrustLines(alice, bob, OF3, CK3);
2280 AccountOwns gw1{*
this, env,
"gw1", 0};
2285 IOU
const OF4 = gw1[
"OF4"];
2286 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2288 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2289 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2293 gw1.verifyOwners(__LINE__);
2294 alice.verifyOwners(__LINE__);
2295 bob.verifyOwners(__LINE__);
2298 IOU
const CK4 = gw1[
"CK4"];
2300 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2302 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2303 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2307 gw1.verifyOwners(__LINE__);
2308 alice.verifyOwners(__LINE__);
2309 bob.verifyOwners(__LINE__);
2313 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2314 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2322 AccountOwns gw1{*
this, env,
"gw1", 0};
2323 IOU
const OF4 = gw1[
"OF4"];
2324 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2326 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2327 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2331 gw1.verifyOwners(__LINE__);
2332 alice.verifyOwners(__LINE__);
2333 bob.verifyOwners(__LINE__);
2336 IOU
const CK4 = gw1[
"CK4"];
2338 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2340 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2341 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2345 gw1.verifyOwners(__LINE__);
2346 alice.verifyOwners(__LINE__);
2347 bob.verifyOwners(__LINE__);
2351 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2352 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2361 AccountOwns gw2{*
this, env,
"gw2", 0};
2362 env.fund(XRP(5000), gw2);
2371 IOU
const OF5 = gw2[
"OF5"];
2373 env(offer(gw2, XRP(92), OF5(92)));
2376 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2377 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2382 gw2.verifyOwners(__LINE__);
2383 alice.verifyOwners(__LINE__);
2384 bob.verifyOwners(__LINE__);
2387 env(offer_cancel(gw2, gw2OfferSeq));
2390 gw2.verifyOwners(__LINE__);
2393 IOU
const CK5 = gw2[
"CK5"];
2395 env(check::create(gw2, alice, CK5(92)));
2398 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2399 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2404 gw2.verifyOwners(__LINE__);
2405 alice.verifyOwners(__LINE__);
2406 bob.verifyOwners(__LINE__);
2410 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2411 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2414 env(check::cancel(gw2, chkId));
2417 gw2.verifyOwners(__LINE__);
2425 AccountOwns gw2{*
this, env,
"gw2", 0};
2426 IOU
const OF5 = gw2[
"OF5"];
2429 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2430 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2433 gw2.verifyOwners(__LINE__);
2434 alice.verifyOwners(__LINE__);
2435 bob.verifyOwners(__LINE__);
2438 IOU
const CK5 = gw2[
"CK5"];
2440 env(check::create(alice, bob, CK5(91)));
2442 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2447 env(check::cancel(alice, chkId));
2451 gw2.verifyOwners(__LINE__);
2452 alice.verifyOwners(__LINE__);
2453 bob.verifyOwners(__LINE__);
2457 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2458 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);