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);
968 for (
auto const& testFeatures :
969 {features - featureMultiSignReserve,
970 features | featureMultiSignReserve})
972 Env env{*
this, testFeatures};
974 env.fund(XRP(1000), gw, alice, bob);
979 env(check::create(alice, bob, USD(1)));
983 env(check::create(alice, bob, USD(2)));
986 env(trust(alice, USD(20)));
987 env(trust(bob, USD(20)));
989 env(pay(gw, alice, USD(8)));
994 env(regkey(bob, bobby));
999 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
1004 int const signersCount = {
1005 testFeatures[featureMultiSignReserve] ? 1 : 4};
1006 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1009 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
1011 env.require(balance(alice, USD(7)));
1012 env.require(balance(bob, USD(1)));
1015 BEAST_EXPECT(ownerCount(env, alice) == 2);
1016 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1019 XRPAmount const baseFeeDrops{env.current()->fees().base};
1020 env(check::cash(bob, chkId2, (USD(2))),
1022 fee(3 * baseFeeDrops));
1024 env.require(balance(alice, USD(5)));
1025 env.require(balance(bob, USD(3)));
1028 BEAST_EXPECT(ownerCount(env, alice) == 1);
1029 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1110 using namespace test::jtx;
1112 Account
const gw{
"gateway"};
1113 Account
const alice{
"alice"};
1114 Account
const bob{
"bob"};
1115 IOU
const USD{gw[
"USD"]};
1117 Env env{*
this, features};
1119 env.fund(XRP(1000), gw, alice, bob);
1122 env(trust(alice, USD(1000)));
1123 env(trust(bob, USD(1000)));
1125 env(pay(gw, alice, USD(1000)));
1133 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1134 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1138 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1139 Account
const& truster,
1141 auto const& inOrOut,
1145 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1146 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1149 env(trust(truster, iou(1000)), inOrOut(pct));
1152 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1154 env.require(balance(alice, aliceStart - USD(10)));
1155 env.require(balance(bob, bobStart + USD(10)));
1159 env(trust(truster, iou(1000)), inOrOut(0));
1163 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1164 Account
const& truster,
1166 auto const& inOrOut,
1170 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1171 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1174 env(trust(truster, iou(1000)), inOrOut(pct));
1178 env(check::create(alice, bob, USD(10)));
1181 env(check::cash(bob, chkId, USD(amount)));
1183 env.require(balance(alice, aliceStart - USD(10)));
1184 env.require(balance(bob, bobStart + USD(10)));
1188 env(trust(truster, iou(1000)), inOrOut(0));
1193 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1194 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1197 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1198 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1200 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1201 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1203 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1204 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1206 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1207 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1209 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1210 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1212 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1213 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1215 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1216 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1223 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1224 Account
const& truster,
1226 auto const& inOrOut,
1234 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1237 env(trust(truster, iou(1000)), inOrOut(pct));
1241 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1243 env.require(balance(alice, aliceStart - USD(10)));
1246 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1248 env.require(balance(alice, aliceStart));
1252 env(trust(truster, iou(1000)), inOrOut(0));
1256 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1257 Account
const& truster,
1259 auto const& inOrOut,
1267 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1270 env(trust(truster, iou(1000)), inOrOut(pct));
1275 env(check::create(alice, gw, USD(max1)));
1278 env(check::cash(gw, chkAliceId, USD(amt1)));
1280 env.require(balance(alice, aliceStart - USD(10)));
1284 env(check::create(gw, alice, USD(max2)));
1287 env(check::cash(alice, chkGwId, USD(amt2)));
1289 env.require(balance(alice, aliceStart));
1293 env(trust(truster, iou(1000)), inOrOut(0));
1299 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1300 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1302 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1303 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1305 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1306 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1308 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1309 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1318 using namespace test::jtx;
1320 Account
const gw{
"gateway"};
1321 Account
const alice{
"alice"};
1322 Account
const bob{
"bob"};
1323 Account
const zoe{
"zoe"};
1324 IOU
const USD{gw[
"USD"]};
1326 Env env(*
this, features);
1328 env.fund(XRP(1000), gw, alice, bob, zoe);
1332 env(trust(alice, USD(20)));
1334 env(pay(gw, alice, USD(20)));
1338 env(trust(bob, USD(20)));
1344 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1350 env(check::create(alice, bob, USD(20)));
1354 env(check::create(alice, bob, XRP(10)));
1357 using namespace std::chrono_literals;
1359 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1363 env(check::create(alice, bob, USD(1)));
1367 env(check::create(alice, bob, USD(2)));
1371 env(check::create(alice, bob, USD(3)));
1375 env(check::create(alice, bob, USD(4)));
1379 env(check::create(alice, bob, USD(1)));
1383 env(check::create(alice, bob, USD(2)), dest_tag(7));
1387 auto failingCases = [&env, &gw, &alice, &bob](
1390 env(check::cash(bob, chkId, amount),
1396 env(check::cash(bob, chkId, amount),
1422 env(check::cash(bob, chkId, amount.zeroed()),
1428 if (!amount.native())
1445 IOU
const wrongCurrency{gw[
"EUR"]};
1447 badAmount.
setIssue(wrongCurrency.issue());
1448 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1454 IOU
const wrongIssuer{alice[
"USD"]};
1456 badAmount.
setIssue(wrongIssuer.issue());
1457 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1466 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1471 failingCases(chkIdX, XRP(10));
1472 failingCases(chkIdU, USD(20));
1475 env(check::cash(bob, chkIdU, USD(20)));
1477 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1481 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1485 env(check::cancel(zoe, chkIdExp));
1490 env(pay(bob, alice, USD(20)));
1492 env.require(balance(alice, USD(20)));
1493 env.require(balance(bob, USD(0)));
1501 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1509 env(check::cash(bob, chkIdFroz1, USD(1)));
1511 env.require(balance(alice, USD(19)));
1512 env.require(balance(bob, USD(1)));
1519 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1526 env(check::cash(bob, chkIdFroz2, USD(2)));
1528 env.require(balance(alice, USD(17)));
1529 env.require(balance(bob, USD(3)));
1534 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1536 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1543 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1545 env.require(balance(alice, USD(14)));
1546 env.require(balance(bob, USD(6)));
1552 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1554 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1561 env(check::cash(bob, chkIdFroz4, USD(4)));
1563 env.require(balance(alice, USD(10)));
1564 env.require(balance(bob, USD(10)));
1573 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1578 env(check::cash(bob, chkIdHasDest2, USD(2)));
1580 env.require(balance(alice, USD(8)));
1581 env.require(balance(bob, USD(12)));
1587 env(check::cash(bob, chkIdNoDest1, USD(1)));
1589 env.require(balance(alice, USD(7)));
1590 env.require(balance(bob, USD(13)));
1600 using namespace test::jtx;
1602 Account
const gw{
"gateway"};
1603 Account
const alice{
"alice"};
1604 Account
const bob{
"bob"};
1605 Account
const zoe{
"zoe"};
1606 IOU
const USD{gw[
"USD"]};
1610 for (
auto const& testFeatures :
1611 {features - featureMultiSignReserve,
1612 features | featureMultiSignReserve})
1614 Env env{*
this, testFeatures};
1616 env.fund(XRP(1000), gw, alice, bob, zoe);
1622 env(check::create(alice, bob, USD(10)));
1626 env(check::create(alice, bob, XRP(10)));
1630 env(check::create(alice, bob, USD(10)));
1634 using namespace std::chrono_literals;
1636 env(check::create(alice, bob, XRP(10)),
1637 expiration(env.now() + 600s));
1641 env(check::create(alice, bob, USD(10)),
1642 expiration(env.now() + 600s));
1646 env(check::create(alice, bob, XRP(10)),
1647 expiration(env.now() + 600s));
1652 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1656 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1660 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1665 env(check::create(alice, bob, USD(10)));
1669 env(check::create(alice, bob, XRP(10)));
1672 BEAST_EXPECT(ownerCount(env, alice) == 11);
1675 env(check::cancel(alice, chkId1));
1678 BEAST_EXPECT(ownerCount(env, alice) == 10);
1680 env(check::cancel(bob, chkId2));
1683 BEAST_EXPECT(ownerCount(env, alice) == 9);
1688 BEAST_EXPECT(ownerCount(env, alice) == 9);
1691 env(check::cancel(alice, chkIdNotExp1));
1694 BEAST_EXPECT(ownerCount(env, alice) == 8);
1696 env(check::cancel(bob, chkIdNotExp2));
1699 BEAST_EXPECT(ownerCount(env, alice) == 7);
1704 BEAST_EXPECT(ownerCount(env, alice) == 7);
1707 env(check::cancel(alice, chkIdExp1));
1710 BEAST_EXPECT(ownerCount(env, alice) == 6);
1712 env(check::cancel(bob, chkIdExp2));
1715 BEAST_EXPECT(ownerCount(env, alice) == 5);
1717 env(check::cancel(zoe, chkIdExp3));
1720 BEAST_EXPECT(ownerCount(env, alice) == 4);
1724 env(regkey(alice, alie));
1729 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1734 int const signersCount{
1735 testFeatures[featureMultiSignReserve] ? 1 : 4};
1738 env(check::cancel(alice, chkIdReg), sig(alie));
1741 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 3);
1744 XRPAmount const baseFeeDrops{env.current()->fees().base};
1745 env(check::cancel(alice, chkIdMSig),
1747 fee(3 * baseFeeDrops));
1750 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 2);
1753 env(check::cancel(alice, chkId3), sig(alice));
1756 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 1);
1758 env(check::cancel(bob, chkIdNotExp3));
1761 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 0);
1836 using namespace test::jtx;
1838 Account
const gw{
"gw"};
1839 Account
const alice{
"alice"};
1840 Account
const bob{
"bob"};
1841 IOU
const USD{gw[
"USD"]};
1843 Env env{*
this, features};
1844 env.fund(XRP(1000), gw, alice, bob);
1851 env(ticket::create(alice, 10));
1855 env(ticket::create(bob, 10));
1859 env.require(owners(alice, 10));
1860 env.require(owners(bob, 10));
1863 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1864 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1866 env.require(owners(alice, 10));
1867 env.require(owners(bob, 10));
1869 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1870 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1872 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1873 BEAST_EXPECT(env.seq(bob) == bobSeq);
1875 env(pay(gw, alice, USD(900)));
1881 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1884 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1887 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1890 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1894 env.require(owners(alice, 10));
1895 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1897 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1899 env.require(owners(bob, 10));
1900 BEAST_EXPECT(env.seq(bob) == bobSeq);
1903 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1904 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1907 env.require(owners(alice, 8));
1908 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1910 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1912 env.require(owners(bob, 8));
1913 BEAST_EXPECT(env.seq(bob) == bobSeq);
1916 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1917 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1920 env.require(owners(alice, 6));
1921 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1923 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1924 env.require(balance(alice, USD(700)));
1926 env.require(owners(bob, 6));
1927 BEAST_EXPECT(env.seq(bob) == bobSeq);
1928 env.require(balance(bob, USD(200)));
1939 using namespace test::jtx;
1941 Env env{*
this, features};
1955 ownerCount(env, acct) == owners,
1956 "Owner count mismatch",
1962 operator Account
const()
const
1979 AccountOwns alice{*
this, env,
"alice", 0};
1980 AccountOwns bob{*
this, env,
"bob", 0};
1983 env.fund(XRP(5000), noripple(alice, bob));
1989 AccountOwns gw1{*
this, env,
"gw1", 0};
1994 env.fund(XRP(5000), noripple(gw1));
1997 IOU
const CK8 = gw1[
"CK8"];
1998 gw1.verifyOwners(__LINE__);
2000 Account
const yui{
"yui"};
2005 env.fund(XRP(200), yui);
2009 env(check::create(gw1, yui, CK8(99)));
2012 env(check::cash(yui, chkId, CK8(99)),
2015 alice.verifyOwners(__LINE__);
2019 env(pay(env.master, yui, XRP(51)));
2021 env(check::cash(yui, chkId, CK8(99)));
2024 BEAST_EXPECT(ownerCount(env, yui) == 1);
2028 gw1.verifyOwners(__LINE__);
2043 auto cmpTrustLines = [
this, &env](
2044 Account
const& acct1,
2045 Account
const& acct2,
2046 IOU
const& offerIou,
2047 IOU
const& checkIou) {
2048 auto const offerLine =
2050 auto const checkLine =
2052 if (offerLine ==
nullptr || checkLine ==
nullptr)
2054 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
2060 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2065 [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
2066 STAmount const offerAmount = offerLine->at(sfield);
2067 STAmount const checkAmount = checkLine->at(sfield);
2084 cmpReqAmount(sfBalance);
2085 cmpReqAmount(sfLowLimit);
2086 cmpReqAmount(sfHighLimit);
2091 [
this, offerLine, checkLine](
auto const& sfield) {
2094 offerLine->isFieldPresent(sfield) ==
2095 checkLine->isFieldPresent(sfield)))
2100 if (!offerLine->isFieldPresent(sfield))
2106 offerLine->at(sfield) == checkLine->at(sfield));
2108 cmpOptField(sfLowNode);
2109 cmpOptField(sfLowQualityIn);
2110 cmpOptField(sfLowQualityOut);
2112 cmpOptField(sfHighNode);
2113 cmpOptField(sfHighQualityIn);
2114 cmpOptField(sfHighQualityOut);
2122 AccountOwns gw1{*
this, env,
"gw1", 0};
2124 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2125 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2126 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2129 IOU
const OF1 = gw1[
"OF1"];
2130 env(offer(gw1, XRP(98), OF1(98)));
2133 env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2134 env(offer(alice, OF1(98), XRP(98)));
2141 gw1.verifyOwners(__LINE__);
2144 alice.verifyOwners(__LINE__);
2147 IOU
const CK1 = gw1[
"CK1"];
2149 env(check::create(gw1, alice, CK1(98)));
2152 env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2153 env(check::cash(alice, chkId, CK1(98)));
2161 gw1.verifyOwners(__LINE__);
2164 alice.verifyOwners(__LINE__);
2166 cmpTrustLines(gw1, alice, OF1, CK1);
2177 AccountOwns gw1{*
this, env,
"gw1", 0};
2178 IOU
const OF1 = gw1[
"OF1"];
2179 env(offer(alice, XRP(97), OF1(97)));
2182 env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2183 env(offer(bob, OF1(97), XRP(97)));
2188 env.require(balance(alice, OF1(1)));
2189 env.require(balance(bob, OF1(97)));
2192 gw1.verifyOwners(__LINE__);
2193 alice.verifyOwners(__LINE__);
2194 bob.verifyOwners(__LINE__);
2202 IOU
const CK1 = gw1[
"CK1"];
2204 env(check::create(alice, bob, CK1(97)));
2207 env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2208 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2212 env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2214 env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2217 env(check::cancel(alice, chkId));
2221 gw1.verifyOwners(__LINE__);
2222 alice.verifyOwners(__LINE__);
2223 bob.verifyOwners(__LINE__);
2230 AccountOwns gw1{*
this, env,
"gw1", 0};
2235 IOU
const OF2 = gw1[
"OF2"];
2236 env(offer(gw1, XRP(96), OF2(96)));
2239 env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2240 env(offer(alice, OF2(96), XRP(96)));
2247 gw1.verifyOwners(__LINE__);
2250 alice.verifyOwners(__LINE__);
2253 IOU
const CK2 = gw1[
"CK2"];
2255 env(check::create(gw1, alice, CK2(96)));
2258 env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2259 env(check::cash(alice, chkId, CK2(96)));
2267 gw1.verifyOwners(__LINE__);
2270 alice.verifyOwners(__LINE__);
2272 cmpTrustLines(gw1, alice, OF2, CK2);
2280 AccountOwns gw1{*
this, env,
"gw1", 0};
2281 IOU
const OF2 = gw1[
"OF2"];
2282 env(offer(alice, XRP(95), OF2(95)));
2285 env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2286 env(offer(bob, OF2(95), XRP(95)));
2291 gw1.verifyOwners(__LINE__);
2292 alice.verifyOwners(__LINE__);
2293 bob.verifyOwners(__LINE__);
2296 IOU
const CK2 = gw1[
"CK2"];
2298 env(check::create(alice, bob, CK2(95)));
2301 env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2302 env(check::cash(bob, chkId, CK2(95)));
2308 gw1.verifyOwners(__LINE__);
2309 alice.verifyOwners(__LINE__);
2310 bob.verifyOwners(__LINE__);
2312 cmpTrustLines(alice, bob, OF2, CK2);
2323 AccountOwns gw1{*
this, env,
"gw1", 0};
2330 IOU
const OF3 = gw1[
"OF3"];
2331 env(offer(gw1, XRP(94), OF3(94)));
2334 env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2335 env(offer(alice, OF3(94), XRP(94)));
2342 gw1.verifyOwners(__LINE__);
2345 alice.verifyOwners(__LINE__);
2348 IOU
const CK3 = gw1[
"CK3"];
2350 env(check::create(gw1, alice, CK3(94)));
2353 env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2354 env(check::cash(alice, chkId, CK3(94)));
2362 gw1.verifyOwners(__LINE__);
2365 alice.verifyOwners(__LINE__);
2367 cmpTrustLines(gw1, alice, OF3, CK3);
2375 AccountOwns gw1{*
this, env,
"gw1", 0};
2376 IOU
const OF3 = gw1[
"OF3"];
2377 env(offer(alice, XRP(93), OF3(93)));
2380 env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2381 env(offer(bob, OF3(93), XRP(93)));
2386 gw1.verifyOwners(__LINE__);
2387 alice.verifyOwners(__LINE__);
2388 bob.verifyOwners(__LINE__);
2391 IOU
const CK3 = gw1[
"CK3"];
2393 env(check::create(alice, bob, CK3(93)));
2396 env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2397 env(check::cash(bob, chkId, CK3(93)));
2403 gw1.verifyOwners(__LINE__);
2404 alice.verifyOwners(__LINE__);
2405 bob.verifyOwners(__LINE__);
2407 cmpTrustLines(alice, bob, OF3, CK3);
2414 AccountOwns gw1{*
this, env,
"gw1", 0};
2419 IOU
const OF4 = gw1[
"OF4"];
2420 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2423 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2424 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2428 gw1.verifyOwners(__LINE__);
2429 alice.verifyOwners(__LINE__);
2430 bob.verifyOwners(__LINE__);
2433 IOU
const CK4 = gw1[
"CK4"];
2435 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2438 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2439 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2443 gw1.verifyOwners(__LINE__);
2444 alice.verifyOwners(__LINE__);
2445 bob.verifyOwners(__LINE__);
2450 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2452 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2460 AccountOwns gw1{*
this, env,
"gw1", 0};
2461 IOU
const OF4 = gw1[
"OF4"];
2462 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2465 env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2466 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2470 gw1.verifyOwners(__LINE__);
2471 alice.verifyOwners(__LINE__);
2472 bob.verifyOwners(__LINE__);
2475 IOU
const CK4 = gw1[
"CK4"];
2477 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2480 env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2481 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2485 gw1.verifyOwners(__LINE__);
2486 alice.verifyOwners(__LINE__);
2487 bob.verifyOwners(__LINE__);
2492 env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2494 env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2503 AccountOwns gw2{*
this, env,
"gw2", 0};
2504 env.fund(XRP(5000), gw2);
2513 IOU
const OF5 = gw2[
"OF5"];
2515 env(offer(gw2, XRP(92), OF5(92)));
2519 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2520 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2525 gw2.verifyOwners(__LINE__);
2526 alice.verifyOwners(__LINE__);
2527 bob.verifyOwners(__LINE__);
2530 env(offer_cancel(gw2, gw2OfferSeq));
2533 gw2.verifyOwners(__LINE__);
2536 IOU
const CK5 = gw2[
"CK5"];
2538 env(check::create(gw2, alice, CK5(92)));
2542 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2543 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2548 gw2.verifyOwners(__LINE__);
2549 alice.verifyOwners(__LINE__);
2550 bob.verifyOwners(__LINE__);
2555 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2557 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2560 env(check::cancel(gw2, chkId));
2563 gw2.verifyOwners(__LINE__);
2571 AccountOwns gw2{*
this, env,
"gw2", 0};
2572 IOU
const OF5 = gw2[
"OF5"];
2575 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2577 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2580 gw2.verifyOwners(__LINE__);
2581 alice.verifyOwners(__LINE__);
2582 bob.verifyOwners(__LINE__);
2585 IOU
const CK5 = gw2[
"CK5"];
2587 env(check::create(alice, bob, CK5(91)));
2590 env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2595 env(check::cancel(alice, chkId));
2599 gw2.verifyOwners(__LINE__);
2600 alice.verifyOwners(__LINE__);
2601 bob.verifyOwners(__LINE__);
2606 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2608 env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);