160 using namespace test::jtx;
162 Account
const gw{
"gateway"};
163 Account
const alice{
"alice"};
164 Account
const bob{
"bob"};
165 IOU
const USD{gw[
"USD"]};
167 Env env{*
this, features};
169 STAmount const startBalance{XRP(1000).value()};
170 env.fund(startBalance, gw, alice, bob);
176 auto writeTwoChecks = [&env, &USD,
this](
177 Account
const& from, Account
const& to) {
184 env(check::create(from, to, XRP(2000)));
187 env(check::create(from, to, USD(50)));
193 env.require(owners(from, fromOwnerCount + 2));
195 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
198 writeTwoChecks(alice, bob);
199 writeTwoChecks(gw, alice);
200 writeTwoChecks(alice, gw);
206 using namespace std::chrono_literals;
209 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
212 env(check::create(alice, bob, USD(50)), source_tag(2));
214 env(check::create(alice, bob, USD(50)), dest_tag(3));
216 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
218 env(check::create(alice, bob, USD(50)),
219 expiration(env.now() + 1s),
230 env(regkey(alice, alie));
235 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
239 env(check::create(alice, bob, USD(50)), sig(alie));
245 XRPAmount const baseFeeDrops{env.current()->fees().base};
246 env(check::create(alice, bob, USD(50)),
248 fee(3 * baseFeeDrops));
355 using namespace test::jtx;
357 Account
const gw1{
"gateway1"};
358 Account
const gwF{
"gatewayFrozen"};
359 Account
const alice{
"alice"};
360 Account
const bob{
"bob"};
361 IOU
const USD{gw1[
"USD"]};
363 Env env{*
this, features};
365 STAmount const startBalance{XRP(1000).value()};
366 env.fund(startBalance, gw1, gwF, alice, bob);
370 env(check::create(alice, bob, USD(50)),
376 env(check::create(alice, bob, USD(50)),
382 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
386 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
389 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
392 env(check::create(alice, bob, drops(1)));
401 env(check::create(alice, bob, USD(1)));
410 env(check::create(alice, bob, USD(50)),
416 Account
const bogie{
"bogie"};
417 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
427 env(check::create(alice, bob, USD(50)), dest_tag(11));
434 IOU
const USF{gwF[
"USF"]};
438 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
444 env(check::create(alice, bob, USF(50)));
450 env.trust(USD(1000), alice);
451 env.trust(USD(1000), bob);
453 env(pay(gw1, alice, USD(25)));
454 env(pay(gw1, bob, USD(25)));
462 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
466 env(check::create(bob, alice, USD(50)));
468 env(pay(bob, alice, USD(1)));
470 env(check::create(gw1, alice, USD(50)));
472 env(pay(gw1, alice, USD(1)));
478 env(check::create(alice, bob, USD(50)));
480 env(check::create(bob, alice, USD(50)));
482 env(check::create(gw1, alice, USD(50)));
490 env(check::create(alice, bob, USD(50)));
492 env(pay(alice, bob, USD(1)));
494 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
498 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
509 env(check::create(alice, bob, USD(50)),
510 expiration(env.now()),
514 using namespace std::chrono_literals;
515 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
519 Account
const cheri{
"cheri"};
520 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
523 env(check::create(cheri, bob, USD(50)),
524 fee(drops(env.current()->fees().base)),
528 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
531 env(check::create(cheri, bob, USD(50)));
541 using namespace test::jtx;
543 Account
const alice{
"alice"};
544 Account
const bob{
"bob"};
546 Env env{*
this, features};
548 XRPAmount const baseFeeDrops{env.current()->fees().base};
549 STAmount const startBalance{XRP(300).value()};
550 env.fund(startBalance, alice, bob);
555 env(check::create(alice, bob, XRP(10)));
557 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
558 env.require(balance(bob, startBalance));
561 BEAST_EXPECT(ownerCount(env, alice) == 1);
562 BEAST_EXPECT(ownerCount(env, bob) == 0);
564 env(check::cash(bob, chkId, XRP(10)));
567 balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
569 balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
572 BEAST_EXPECT(ownerCount(env, alice) == 0);
573 BEAST_EXPECT(ownerCount(env, bob) == 0);
576 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
577 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
579 env.require(balance(alice, startBalance));
580 env.require(balance(bob, startBalance));
584 STAmount const reserve{env.current()->fees().reserve};
586 startBalance - reserve - drops(baseFeeDrops)};
588 env(check::create(alice, bob, checkAmount));
592 env(check::cash(bob, chkId, checkAmount + drops(1)),
596 bob, chkId, check::DeliverMin(checkAmount + drops(1))),
603 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
605 env.require(balance(alice, reserve));
607 bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
610 BEAST_EXPECT(ownerCount(env, alice) == 0);
611 BEAST_EXPECT(ownerCount(env, bob) == 0);
614 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
615 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
617 env.require(balance(alice, startBalance));
618 env.require(balance(bob, startBalance));
622 STAmount const reserve{env.current()->fees().reserve};
624 startBalance - reserve - drops(baseFeeDrops - 1)};
626 env(check::create(alice, bob, checkAmount));
635 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
637 env.require(balance(alice, reserve));
639 bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
642 BEAST_EXPECT(ownerCount(env, alice) == 0);
643 BEAST_EXPECT(ownerCount(env, bob) == 0);
646 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
648 bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
650 env.require(balance(alice, startBalance));
651 env.require(balance(bob, startBalance));
661 using namespace test::jtx;
663 Account
const gw{
"gateway"};
664 Account
const alice{
"alice"};
665 Account
const bob{
"bob"};
666 IOU
const USD{gw[
"USD"]};
669 Env env{*
this, features};
671 env.fund(XRP(1000), gw, alice, bob);
676 env(check::create(alice, bob, USD(10)));
684 env(trust(alice, USD(20)));
686 env(pay(gw, alice, USD(9.5)));
693 env(pay(gw, alice, USD(0.5)));
697 env(trust(bob, USD(9.5)));
702 env(trust(bob, USD(10.5)));
708 env(check::cash(bob, chkId1, USD(10)));
710 env.require(balance(alice, USD(0)));
711 env.require(balance(bob, USD(10)));
714 BEAST_EXPECT(ownerCount(env, alice) == 1);
715 BEAST_EXPECT(ownerCount(env, bob) == 1);
718 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
722 env(pay(bob, alice, USD(7)));
726 env(check::create(alice, bob, USD(7)));
733 env(check::cash(bob, chkId2, USD(5)));
735 env.require(balance(alice, USD(2)));
736 env.require(balance(bob, USD(8)));
739 BEAST_EXPECT(ownerCount(env, alice) == 1);
740 BEAST_EXPECT(ownerCount(env, bob) == 1);
744 env(check::create(alice, bob, USD(2)));
747 env(check::create(alice, bob, USD(2)));
753 env(check::cash(bob, chkId4, USD(2)));
755 env.require(balance(alice, USD(0)));
756 env.require(balance(bob, USD(10)));
759 BEAST_EXPECT(ownerCount(env, alice) == 2);
760 BEAST_EXPECT(ownerCount(env, bob) == 1);
766 env.require(balance(alice, USD(0)));
767 env.require(balance(bob, USD(10)));
770 BEAST_EXPECT(ownerCount(env, alice) == 2);
771 BEAST_EXPECT(ownerCount(env, bob) == 1);
787 env(check::create(gw, bob, USD(20)));
791 env(check::cash(bob, chkId20, USD(20)));
793 env.require(balance(bob, USD(30)));
797 env(pay(bob, gw, USD(20)));
800 env(check::cancel(bob, chkId3));
802 env.require(balance(alice, USD(0)));
803 env.require(balance(bob, USD(10)));
806 BEAST_EXPECT(ownerCount(env, alice) == 1);
807 BEAST_EXPECT(ownerCount(env, bob) == 1);
811 Env env{*
this, features};
813 env.fund(XRP(1000), gw, alice, bob);
816 env(trust(alice, USD(20)));
817 env(trust(bob, USD(20)));
819 env(pay(gw, alice, USD(8)));
824 env(check::create(alice, bob, USD(9)));
827 env(check::create(alice, bob, USD(8)));
830 env(check::create(alice, bob, USD(7)));
833 env(check::create(alice, bob, USD(6)));
838 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
843 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
845 env.require(balance(alice, USD(0)));
846 env.require(balance(bob, USD(8)));
849 BEAST_EXPECT(ownerCount(env, alice) == 4);
850 BEAST_EXPECT(ownerCount(env, bob) == 1);
853 env(pay(bob, alice, USD(7)));
858 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
860 env.require(balance(alice, USD(0)));
861 env.require(balance(bob, USD(8)));
864 BEAST_EXPECT(ownerCount(env, alice) == 3);
865 BEAST_EXPECT(ownerCount(env, bob) == 1);
868 env(pay(bob, alice, USD(8)));
873 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
875 env.require(balance(alice, USD(2)));
876 env.require(balance(bob, USD(6)));
879 BEAST_EXPECT(ownerCount(env, alice) == 2);
880 BEAST_EXPECT(ownerCount(env, bob) == 1);
884 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
886 env.require(balance(alice, USD(0)));
887 env.require(balance(bob, USD(8)));
890 BEAST_EXPECT(ownerCount(env, alice) == 1);
891 BEAST_EXPECT(ownerCount(env, bob) == 1);
895 Env env(*
this, features);
897 env.fund(XRP(1000), gw, alice, bob);
900 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
901 env(trust(alice, USD(20)));
903 env(pay(gw, alice, USD(8)));
909 env(check::create(alice, bob, USD(7)));
912 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
917 env(trust(bob, USD(5)));
920 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
924 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
934 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
937 env.require(balance(alice, USD(8) - bobGot));
938 env.require(balance(bob, bobGot));
942 BEAST_EXPECT(ownerCount(env, alice) == 1);
943 BEAST_EXPECT(ownerCount(env, bob) == 1);
948 Env env{*
this, features};
949 env.fund(XRP(1000), gw, alice, bob);
954 env(check::create(alice, bob, USD(1)));
958 env(check::create(alice, bob, USD(2)));
961 env(trust(alice, USD(20)));
962 env(trust(bob, USD(20)));
964 env(pay(gw, alice, USD(8)));
969 env(regkey(bob, bobby));
974 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
977 BEAST_EXPECT(ownerCount(env, bob) == 2);
980 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
982 env.require(balance(alice, USD(7)));
983 env.require(balance(bob, USD(1)));
986 BEAST_EXPECT(ownerCount(env, alice) == 2);
987 BEAST_EXPECT(ownerCount(env, bob) == 2);
990 XRPAmount const baseFeeDrops{env.current()->fees().base};
991 env(check::cash(bob, chkId2, (USD(2))),
993 fee(3 * baseFeeDrops));
995 env.require(balance(alice, USD(5)));
996 env.require(balance(bob, USD(3)));
999 BEAST_EXPECT(ownerCount(env, alice) == 1);
1000 BEAST_EXPECT(ownerCount(env, bob) == 2);
1081 using namespace test::jtx;
1083 Account
const gw{
"gateway"};
1084 Account
const alice{
"alice"};
1085 Account
const bob{
"bob"};
1086 IOU
const USD{gw[
"USD"]};
1088 Env env{*
this, features};
1090 env.fund(XRP(1000), gw, alice, bob);
1093 env(trust(alice, USD(1000)));
1094 env(trust(bob, USD(1000)));
1096 env(pay(gw, alice, USD(1000)));
1104 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1105 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1109 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1110 Account
const& truster,
1112 auto const& inOrOut,
1116 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1117 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1120 env(trust(truster, iou(1000)), inOrOut(pct));
1123 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1125 env.require(balance(alice, aliceStart - USD(10)));
1126 env.require(balance(bob, bobStart + USD(10)));
1130 env(trust(truster, iou(1000)), inOrOut(0));
1134 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1135 Account
const& truster,
1137 auto const& inOrOut,
1141 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1142 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1145 env(trust(truster, iou(1000)), inOrOut(pct));
1149 env(check::create(alice, bob, USD(10)));
1152 env(check::cash(bob, chkId, USD(amount)));
1154 env.require(balance(alice, aliceStart - USD(10)));
1155 env.require(balance(bob, bobStart + USD(10)));
1159 env(trust(truster, iou(1000)), inOrOut(0));
1164 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1165 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1168 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1169 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1171 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1172 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1174 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1175 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1177 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1178 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1180 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1181 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1183 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1184 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1186 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1187 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1194 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1195 Account
const& truster,
1197 auto const& inOrOut,
1205 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1208 env(trust(truster, iou(1000)), inOrOut(pct));
1212 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1214 env.require(balance(alice, aliceStart - USD(10)));
1217 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1219 env.require(balance(alice, aliceStart));
1223 env(trust(truster, iou(1000)), inOrOut(0));
1227 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1228 Account
const& truster,
1230 auto const& inOrOut,
1238 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1241 env(trust(truster, iou(1000)), inOrOut(pct));
1246 env(check::create(alice, gw, USD(max1)));
1249 env(check::cash(gw, chkAliceId, USD(amt1)));
1251 env.require(balance(alice, aliceStart - USD(10)));
1255 env(check::create(gw, alice, USD(max2)));
1258 env(check::cash(alice, chkGwId, USD(amt2)));
1260 env.require(balance(alice, aliceStart));
1264 env(trust(truster, iou(1000)), inOrOut(0));
1270 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1271 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1273 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1274 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1276 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1277 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1279 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1280 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1289 using namespace test::jtx;
1291 Account
const gw{
"gateway"};
1292 Account
const alice{
"alice"};
1293 Account
const bob{
"bob"};
1294 Account
const zoe{
"zoe"};
1295 IOU
const USD{gw[
"USD"]};
1297 Env env(*
this, features);
1299 env.fund(XRP(1000), gw, alice, bob, zoe);
1303 env(trust(alice, USD(20)));
1305 env(pay(gw, alice, USD(20)));
1309 env(trust(bob, USD(20)));
1315 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1321 env(check::create(alice, bob, USD(20)));
1325 env(check::create(alice, bob, XRP(10)));
1328 using namespace std::chrono_literals;
1330 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1334 env(check::create(alice, bob, USD(1)));
1338 env(check::create(alice, bob, USD(2)));
1342 env(check::create(alice, bob, USD(3)));
1346 env(check::create(alice, bob, USD(4)));
1350 env(check::create(alice, bob, USD(1)));
1354 env(check::create(alice, bob, USD(2)), dest_tag(7));
1358 auto failingCases = [&env, &gw, &alice, &bob](
1361 env(check::cash(bob, chkId, amount),
1367 env(check::cash(bob, chkId, amount),
1393 env(check::cash(bob, chkId, amount.zeroed()),
1399 if (!amount.native())
1416 IOU
const wrongCurrency{gw[
"EUR"]};
1418 badAmount.
setIssue(wrongCurrency.issue());
1419 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1425 IOU
const wrongIssuer{alice[
"USD"]};
1427 badAmount.
setIssue(wrongIssuer.issue());
1428 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1437 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1442 failingCases(chkIdX, XRP(10));
1443 failingCases(chkIdU, USD(20));
1446 env(check::cash(bob, chkIdU, USD(20)));
1448 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1452 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1456 env(check::cancel(zoe, chkIdExp));
1461 env(pay(bob, alice, USD(20)));
1463 env.require(balance(alice, USD(20)));
1464 env.require(balance(bob, USD(0)));
1472 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1480 env(check::cash(bob, chkIdFroz1, USD(1)));
1482 env.require(balance(alice, USD(19)));
1483 env.require(balance(bob, USD(1)));
1490 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1497 env(check::cash(bob, chkIdFroz2, USD(2)));
1499 env.require(balance(alice, USD(17)));
1500 env.require(balance(bob, USD(3)));
1505 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1507 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1514 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1516 env.require(balance(alice, USD(14)));
1517 env.require(balance(bob, USD(6)));
1523 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1525 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1532 env(check::cash(bob, chkIdFroz4, USD(4)));
1534 env.require(balance(alice, USD(10)));
1535 env.require(balance(bob, USD(10)));
1544 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1549 env(check::cash(bob, chkIdHasDest2, USD(2)));
1551 env.require(balance(alice, USD(8)));
1552 env.require(balance(bob, USD(12)));
1558 env(check::cash(bob, chkIdNoDest1, USD(1)));
1560 env.require(balance(alice, USD(7)));
1561 env.require(balance(bob, USD(13)));
1571 using namespace test::jtx;
1573 Account
const gw{
"gateway"};
1574 Account
const alice{
"alice"};
1575 Account
const bob{
"bob"};
1576 Account
const zoe{
"zoe"};
1577 IOU
const USD{gw[
"USD"]};
1580 Env env{*
this, features};
1582 env.fund(XRP(1000), gw, alice, bob, zoe);
1588 env(check::create(alice, bob, USD(10)));
1592 env(check::create(alice, bob, XRP(10)));
1596 env(check::create(alice, bob, USD(10)));
1600 using namespace std::chrono_literals;
1602 env(check::create(alice, bob, XRP(10)),
1603 expiration(env.now() + 600s));
1607 env(check::create(alice, bob, USD(10)),
1608 expiration(env.now() + 600s));
1612 env(check::create(alice, bob, XRP(10)),
1613 expiration(env.now() + 600s));
1618 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1622 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1626 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1631 env(check::create(alice, bob, USD(10)));
1635 env(check::create(alice, bob, XRP(10)));
1638 BEAST_EXPECT(ownerCount(env, alice) == 11);
1641 env(check::cancel(alice, chkId1));
1644 BEAST_EXPECT(ownerCount(env, alice) == 10);
1646 env(check::cancel(bob, chkId2));
1649 BEAST_EXPECT(ownerCount(env, alice) == 9);
1654 BEAST_EXPECT(ownerCount(env, alice) == 9);
1657 env(check::cancel(alice, chkIdNotExp1));
1660 BEAST_EXPECT(ownerCount(env, alice) == 8);
1662 env(check::cancel(bob, chkIdNotExp2));
1665 BEAST_EXPECT(ownerCount(env, alice) == 7);
1670 BEAST_EXPECT(ownerCount(env, alice) == 7);
1673 env(check::cancel(alice, chkIdExp1));
1676 BEAST_EXPECT(ownerCount(env, alice) == 6);
1678 env(check::cancel(bob, chkIdExp2));
1681 BEAST_EXPECT(ownerCount(env, alice) == 5);
1683 env(check::cancel(zoe, chkIdExp3));
1686 BEAST_EXPECT(ownerCount(env, alice) == 4);
1690 env(regkey(alice, alie));
1695 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1699 env(check::cancel(alice, chkIdReg), sig(alie));
1702 BEAST_EXPECT(ownerCount(env, alice) == 4);
1705 XRPAmount const baseFeeDrops{env.current()->fees().base};
1706 env(check::cancel(alice, chkIdMSig),
1708 fee(3 * baseFeeDrops));
1711 BEAST_EXPECT(ownerCount(env, alice) == 3);
1714 env(check::cancel(alice, chkId3), sig(alice));
1717 BEAST_EXPECT(ownerCount(env, alice) == 2);
1719 env(check::cancel(bob, chkIdNotExp3));
1722 BEAST_EXPECT(ownerCount(env, alice) == 1);
1797 using namespace test::jtx;
1799 Account
const gw{
"gw"};
1800 Account
const alice{
"alice"};
1801 Account
const bob{
"bob"};
1802 IOU
const USD{gw[
"USD"]};
1804 Env env{*
this, features};
1805 env.fund(XRP(1000), gw, alice, bob);
1812 env(ticket::create(alice, 10));
1816 env(ticket::create(bob, 10));
1820 env.require(owners(alice, 10));
1821 env.require(owners(bob, 10));
1824 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1825 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1827 env.require(owners(alice, 10));
1828 env.require(owners(bob, 10));
1830 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1831 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1833 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1834 BEAST_EXPECT(env.seq(bob) == bobSeq);
1836 env(pay(gw, alice, USD(900)));
1842 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1845 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1848 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1851 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1855 env.require(owners(alice, 10));
1856 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1858 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1860 env.require(owners(bob, 10));
1861 BEAST_EXPECT(env.seq(bob) == bobSeq);
1864 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1865 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1868 env.require(owners(alice, 8));
1869 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1871 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1873 env.require(owners(bob, 8));
1874 BEAST_EXPECT(env.seq(bob) == bobSeq);
1877 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1878 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1881 env.require(owners(alice, 6));
1882 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1884 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1885 env.require(balance(alice, USD(700)));
1887 env.require(owners(bob, 6));
1888 BEAST_EXPECT(env.seq(bob) == bobSeq);
1889 env.require(balance(bob, USD(200)));
1900 using namespace test::jtx;
1902 Env env{*
this, features};
1916 ownerCount(env, acct) == owners,
1917 "Owner count mismatch",
1923 operator Account
const()
const
1940 AccountOwns alice{*
this, env,
"alice", 0};
1941 AccountOwns bob{*
this, env,
"bob", 0};
1944 env.fund(XRP(5000), noripple(alice, bob));
1950 AccountOwns gw1{*
this, env,
"gw1", 0};
1955 env.fund(XRP(5000), noripple(gw1));
1958 IOU
const CK8 = gw1[
"CK8"];
1959 gw1.verifyOwners(__LINE__);
1961 Account
const yui{
"yui"};
1966 env.fund(XRP(200), yui);
1970 env(check::create(gw1, yui, CK8(99)));
1973 env(check::cash(yui, chkId, CK8(99)),
1976 alice.verifyOwners(__LINE__);
1980 env(pay(env.master, yui, XRP(51)));
1982 env(check::cash(yui, chkId, CK8(99)));
1985 BEAST_EXPECT(ownerCount(env, yui) == 1);
1989 gw1.verifyOwners(__LINE__);
2004 auto cmpTrustLines = [
this, &env](
2005 Account
const& acct1,
2006 Account
const& acct2,
2007 IOU
const& offerIou,
2008 IOU
const& checkIou) {
2009 auto const offerLine =
2011 auto const checkLine =
2013 if (offerLine ==
nullptr || checkLine ==
nullptr)
2015 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
2021 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2026 [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
2027 STAmount const offerAmount = offerLine->at(sfield);
2028 STAmount const checkAmount = checkLine->at(sfield);
2045 cmpReqAmount(sfBalance);
2046 cmpReqAmount(sfLowLimit);
2047 cmpReqAmount(sfHighLimit);
2052 [
this, offerLine, checkLine](
auto const& sfield) {
2055 offerLine->isFieldPresent(sfield) ==
2056 checkLine->isFieldPresent(sfield)))
2061 if (!offerLine->isFieldPresent(sfield))
2067 offerLine->at(sfield) == checkLine->at(sfield));
2069 cmpOptField(sfLowNode);
2070 cmpOptField(sfLowQualityIn);
2071 cmpOptField(sfLowQualityOut);
2073 cmpOptField(sfHighNode);
2074 cmpOptField(sfHighQualityIn);
2075 cmpOptField(sfHighQualityOut);
2083 AccountOwns gw1{*
this, env,
"gw1", 0};
2085 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2086 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2087 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2090 IOU
const OF1 = gw1[
"OF1"];
2091 env(offer(gw1, XRP(98), OF1(98)));
2094 env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2095 env(offer(alice, OF1(98), XRP(98)));
2102 gw1.verifyOwners(__LINE__);
2105 alice.verifyOwners(__LINE__);
2108 IOU
const CK1 = gw1[
"CK1"];
2110 env(check::create(gw1, alice, CK1(98)));
2113 env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2114 env(check::cash(alice, chkId, CK1(98)));
2122 gw1.verifyOwners(__LINE__);
2125 alice.verifyOwners(__LINE__);
2127 cmpTrustLines(gw1, alice, OF1, CK1);
2138 AccountOwns gw1{*
this, env,
"gw1", 0};
2139 IOU
const OF1 = gw1[
"OF1"];
2140 env(offer(alice, XRP(97), OF1(97)));
2143 env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2144 env(offer(bob, OF1(97), XRP(97)));
2149 env.require(balance(alice, OF1(1)));
2150 env.require(balance(bob, OF1(97)));
2153 gw1.verifyOwners(__LINE__);
2154 alice.verifyOwners(__LINE__);
2155 bob.verifyOwners(__LINE__);
2163 IOU
const CK1 = gw1[
"CK1"];
2165 env(check::create(alice, bob, CK1(97)));
2168 env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2169 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2173 env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2175 env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2178 env(check::cancel(alice, chkId));
2182 gw1.verifyOwners(__LINE__);
2183 alice.verifyOwners(__LINE__);
2184 bob.verifyOwners(__LINE__);
2191 AccountOwns gw1{*
this, env,
"gw1", 0};
2196 IOU
const OF2 = gw1[
"OF2"];
2197 env(offer(gw1, XRP(96), OF2(96)));
2200 env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2201 env(offer(alice, OF2(96), XRP(96)));
2208 gw1.verifyOwners(__LINE__);
2211 alice.verifyOwners(__LINE__);
2214 IOU
const CK2 = gw1[
"CK2"];
2216 env(check::create(gw1, alice, CK2(96)));
2219 env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2220 env(check::cash(alice, chkId, CK2(96)));
2228 gw1.verifyOwners(__LINE__);
2231 alice.verifyOwners(__LINE__);
2233 cmpTrustLines(gw1, alice, OF2, CK2);
2241 AccountOwns gw1{*
this, env,
"gw1", 0};
2242 IOU
const OF2 = gw1[
"OF2"];
2243 env(offer(alice, XRP(95), OF2(95)));
2246 env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2247 env(offer(bob, OF2(95), XRP(95)));
2252 gw1.verifyOwners(__LINE__);
2253 alice.verifyOwners(__LINE__);
2254 bob.verifyOwners(__LINE__);
2257 IOU
const CK2 = gw1[
"CK2"];
2259 env(check::create(alice, bob, CK2(95)));
2262 env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2263 env(check::cash(bob, chkId, CK2(95)));
2269 gw1.verifyOwners(__LINE__);
2270 alice.verifyOwners(__LINE__);
2271 bob.verifyOwners(__LINE__);
2273 cmpTrustLines(alice, bob, OF2, CK2);
2284 AccountOwns gw1{*
this, env,
"gw1", 0};
2291 IOU
const OF3 = gw1[
"OF3"];
2292 env(offer(gw1, XRP(94), OF3(94)));
2295 env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2296 env(offer(alice, OF3(94), XRP(94)));
2303 gw1.verifyOwners(__LINE__);
2306 alice.verifyOwners(__LINE__);
2309 IOU
const CK3 = gw1[
"CK3"];
2311 env(check::create(gw1, alice, CK3(94)));
2314 env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2315 env(check::cash(alice, chkId, CK3(94)));
2323 gw1.verifyOwners(__LINE__);
2326 alice.verifyOwners(__LINE__);
2328 cmpTrustLines(gw1, alice, OF3, CK3);
2336 AccountOwns gw1{*
this, env,
"gw1", 0};
2337 IOU
const OF3 = gw1[
"OF3"];
2338 env(offer(alice, XRP(93), OF3(93)));
2341 env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2342 env(offer(bob, OF3(93), XRP(93)));
2347 gw1.verifyOwners(__LINE__);
2348 alice.verifyOwners(__LINE__);
2349 bob.verifyOwners(__LINE__);
2352 IOU
const CK3 = gw1[
"CK3"];
2354 env(check::create(alice, bob, CK3(93)));
2357 env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2358 env(check::cash(bob, chkId, CK3(93)));
2364 gw1.verifyOwners(__LINE__);
2365 alice.verifyOwners(__LINE__);
2366 bob.verifyOwners(__LINE__);
2368 cmpTrustLines(alice, bob, OF3, CK3);
2375 AccountOwns gw1{*
this, env,
"gw1", 0};
2380 IOU
const OF4 = gw1[
"OF4"];
2381 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2384 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2385 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2389 gw1.verifyOwners(__LINE__);
2390 alice.verifyOwners(__LINE__);
2391 bob.verifyOwners(__LINE__);
2394 IOU
const CK4 = gw1[
"CK4"];
2396 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2399 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2400 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2404 gw1.verifyOwners(__LINE__);
2405 alice.verifyOwners(__LINE__);
2406 bob.verifyOwners(__LINE__);
2411 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2413 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2421 AccountOwns gw1{*
this, env,
"gw1", 0};
2422 IOU
const OF4 = gw1[
"OF4"];
2423 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2426 env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2427 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2431 gw1.verifyOwners(__LINE__);
2432 alice.verifyOwners(__LINE__);
2433 bob.verifyOwners(__LINE__);
2436 IOU
const CK4 = gw1[
"CK4"];
2438 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2441 env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2442 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2446 gw1.verifyOwners(__LINE__);
2447 alice.verifyOwners(__LINE__);
2448 bob.verifyOwners(__LINE__);
2453 env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2455 env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2464 AccountOwns gw2{*
this, env,
"gw2", 0};
2465 env.fund(XRP(5000), gw2);
2474 IOU
const OF5 = gw2[
"OF5"];
2476 env(offer(gw2, XRP(92), OF5(92)));
2480 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2481 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2486 gw2.verifyOwners(__LINE__);
2487 alice.verifyOwners(__LINE__);
2488 bob.verifyOwners(__LINE__);
2491 env(offer_cancel(gw2, gw2OfferSeq));
2494 gw2.verifyOwners(__LINE__);
2497 IOU
const CK5 = gw2[
"CK5"];
2499 env(check::create(gw2, alice, CK5(92)));
2503 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2504 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2509 gw2.verifyOwners(__LINE__);
2510 alice.verifyOwners(__LINE__);
2511 bob.verifyOwners(__LINE__);
2516 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2518 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2521 env(check::cancel(gw2, chkId));
2524 gw2.verifyOwners(__LINE__);
2532 AccountOwns gw2{*
this, env,
"gw2", 0};
2533 IOU
const OF5 = gw2[
"OF5"];
2536 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2538 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2541 gw2.verifyOwners(__LINE__);
2542 alice.verifyOwners(__LINE__);
2543 bob.verifyOwners(__LINE__);
2546 IOU
const CK5 = gw2[
"CK5"];
2548 env(check::create(alice, bob, CK5(91)));
2551 env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2556 env(check::cancel(alice, chkId));
2560 gw2.verifyOwners(__LINE__);
2561 alice.verifyOwners(__LINE__);
2562 bob.verifyOwners(__LINE__);
2567 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2569 env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);