198 using namespace test::jtx;
200 Account
const gw{
"gateway"};
201 Account
const alice{
"alice"};
202 Account
const bob{
"bob"};
203 IOU
const USD{gw[
"USD"]};
205 Env env{*
this, features};
207 STAmount const startBalance{XRP(1000).value()};
208 env.fund(startBalance, gw, alice, bob);
214 auto writeTwoChecks = [&env, &USD,
this](
215 Account
const& from, Account
const& to) {
222 env(check::create(from, to, XRP(2000)));
225 env(check::create(from, to, USD(50)));
231 env.require(owners(from, fromOwnerCount + 2));
233 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
236 writeTwoChecks(alice, bob);
237 writeTwoChecks(gw, alice);
238 writeTwoChecks(alice, gw);
244 using namespace std::chrono_literals;
247 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
250 env(check::create(alice, bob, USD(50)), source_tag(2));
252 env(check::create(alice, bob, USD(50)), dest_tag(3));
254 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
256 env(check::create(alice, bob, USD(50)),
257 expiration(env.now() + 1s),
268 env(regkey(alice, alie));
273 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
277 env(check::create(alice, bob, USD(50)), sig(alie));
283 XRPAmount const baseFeeDrops{env.current()->fees().base};
284 env(check::create(alice, bob, USD(50)),
286 fee(3 * baseFeeDrops));
393 using namespace test::jtx;
395 Account
const gw1{
"gateway1"};
396 Account
const gwF{
"gatewayFrozen"};
397 Account
const alice{
"alice"};
398 Account
const bob{
"bob"};
399 IOU
const USD{gw1[
"USD"]};
401 Env env{*
this, features};
403 STAmount const startBalance{XRP(1000).value()};
404 env.fund(startBalance, gw1, gwF, alice, bob);
408 env(check::create(alice, bob, USD(50)),
414 env(check::create(alice, bob, USD(50)),
420 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
424 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
427 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
430 env(check::create(alice, bob, drops(1)));
439 env(check::create(alice, bob, USD(1)));
448 env(check::create(alice, bob, USD(50)),
454 Account
const bogie{
"bogie"};
455 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
465 env(check::create(alice, bob, USD(50)), dest_tag(11));
472 IOU
const USF{gwF[
"USF"]};
476 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
482 env(check::create(alice, bob, USF(50)));
488 env.trust(USD(1000), alice);
489 env.trust(USD(1000), bob);
491 env(pay(gw1, alice, USD(25)));
492 env(pay(gw1, bob, USD(25)));
500 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
504 env(check::create(bob, alice, USD(50)));
506 env(pay(bob, alice, USD(1)));
508 env(check::create(gw1, alice, USD(50)));
510 env(pay(gw1, alice, USD(1)));
516 env(check::create(alice, bob, USD(50)));
518 env(check::create(bob, alice, USD(50)));
520 env(check::create(gw1, alice, USD(50)));
528 env(check::create(alice, bob, USD(50)));
530 env(pay(alice, bob, USD(1)));
532 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
536 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
547 env(check::create(alice, bob, USD(50)),
548 expiration(env.now()),
552 using namespace std::chrono_literals;
553 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
557 Account
const cheri{
"cheri"};
558 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
561 env(check::create(cheri, bob, USD(50)),
562 fee(drops(env.current()->fees().base)),
566 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
569 env(check::create(cheri, bob, USD(50)));
579 using namespace test::jtx;
581 Account
const alice{
"alice"};
582 Account
const bob{
"bob"};
584 Env env{*
this, features};
586 XRPAmount const baseFeeDrops{env.current()->fees().base};
587 STAmount const startBalance{XRP(300).value()};
588 env.fund(startBalance, alice, bob);
593 env(check::create(alice, bob, XRP(10)));
595 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
596 env.require(balance(bob, startBalance));
599 BEAST_EXPECT(ownerCount(env, alice) == 1);
600 BEAST_EXPECT(ownerCount(env, bob) == 0);
602 env(check::cash(bob, chkId, XRP(10)));
605 balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
607 balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
610 BEAST_EXPECT(ownerCount(env, alice) == 0);
611 BEAST_EXPECT(ownerCount(env, bob) == 0);
614 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
615 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
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)};
626 env(check::create(alice, bob, checkAmount));
630 env(check::cash(bob, chkId, checkAmount + drops(1)),
634 bob, chkId, check::DeliverMin(checkAmount + drops(1))),
641 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
643 env.require(balance(alice, reserve));
645 bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
648 BEAST_EXPECT(ownerCount(env, alice) == 0);
649 BEAST_EXPECT(ownerCount(env, bob) == 0);
652 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
653 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
655 env.require(balance(alice, startBalance));
656 env.require(balance(bob, startBalance));
660 STAmount const reserve{env.current()->fees().reserve};
662 startBalance - reserve - drops(baseFeeDrops - 1)};
664 env(check::create(alice, bob, checkAmount));
673 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
675 env.require(balance(alice, reserve));
677 bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
680 BEAST_EXPECT(ownerCount(env, alice) == 0);
681 BEAST_EXPECT(ownerCount(env, bob) == 0);
684 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
686 bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
688 env.require(balance(alice, startBalance));
689 env.require(balance(bob, startBalance));
699 using namespace test::jtx;
701 bool const cashCheckMakesTrustLine =
702 features[featureCheckCashMakesTrustLine];
704 Account
const gw{
"gateway"};
705 Account
const alice{
"alice"};
706 Account
const bob{
"bob"};
707 IOU
const USD{gw[
"USD"]};
710 Env env{*
this, features};
712 env.fund(XRP(1000), gw, alice, bob);
717 env(check::create(alice, bob, USD(10)));
725 env(trust(alice, USD(20)));
727 env(pay(gw, alice, USD(9.5)));
734 env(pay(gw, alice, USD(0.5)));
736 if (!cashCheckMakesTrustLine)
741 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_LINE));
746 env(trust(bob, USD(9.5)));
748 if (!cashCheckMakesTrustLine)
759 env(trust(bob, USD(10.5)));
765 env(check::cash(bob, chkId1, USD(10)));
767 env.require(balance(alice, USD(0)));
768 env.require(balance(bob, USD(10)));
771 BEAST_EXPECT(ownerCount(env, alice) == 1);
772 BEAST_EXPECT(ownerCount(env, bob) == 1);
775 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
779 env(pay(bob, alice, USD(7)));
783 env(check::create(alice, bob, USD(7)));
790 env(check::cash(bob, chkId2, USD(5)));
792 env.require(balance(alice, USD(2)));
793 env.require(balance(bob, USD(8)));
796 BEAST_EXPECT(ownerCount(env, alice) == 1);
797 BEAST_EXPECT(ownerCount(env, bob) == 1);
801 env(check::create(alice, bob, USD(2)));
804 env(check::create(alice, bob, USD(2)));
810 env(check::cash(bob, chkId4, USD(2)));
812 env.require(balance(alice, USD(0)));
813 env.require(balance(bob, USD(10)));
816 BEAST_EXPECT(ownerCount(env, alice) == 2);
817 BEAST_EXPECT(ownerCount(env, bob) == 1);
823 env.require(balance(alice, USD(0)));
824 env.require(balance(bob, USD(10)));
827 BEAST_EXPECT(ownerCount(env, alice) == 2);
828 BEAST_EXPECT(ownerCount(env, bob) == 1);
830 if (cashCheckMakesTrustLine)
846 env(check::create(gw, bob, USD(20)));
850 env(check::cash(bob, chkId20, USD(20)));
852 env.require(balance(bob, USD(30)));
856 env(pay(bob, gw, USD(20)));
860 env(check::cancel(bob, chkId3));
862 env.require(balance(alice, USD(0)));
863 env.require(balance(bob, USD(10)));
866 BEAST_EXPECT(ownerCount(env, alice) == 1);
867 BEAST_EXPECT(ownerCount(env, bob) == 1);
871 Env env{*
this, features};
873 env.fund(XRP(1000), gw, alice, bob);
876 env(trust(alice, USD(20)));
877 env(trust(bob, USD(20)));
879 env(pay(gw, alice, USD(8)));
884 env(check::create(alice, bob, USD(9)));
887 env(check::create(alice, bob, USD(8)));
890 env(check::create(alice, bob, USD(7)));
893 env(check::create(alice, bob, USD(6)));
898 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
903 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
905 env.require(balance(alice, USD(0)));
906 env.require(balance(bob, USD(8)));
909 BEAST_EXPECT(ownerCount(env, alice) == 4);
910 BEAST_EXPECT(ownerCount(env, bob) == 1);
913 env(pay(bob, alice, USD(7)));
918 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
920 env.require(balance(alice, USD(0)));
921 env.require(balance(bob, USD(8)));
924 BEAST_EXPECT(ownerCount(env, alice) == 3);
925 BEAST_EXPECT(ownerCount(env, bob) == 1);
928 env(pay(bob, alice, USD(8)));
933 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
935 env.require(balance(alice, USD(2)));
936 env.require(balance(bob, USD(6)));
939 BEAST_EXPECT(ownerCount(env, alice) == 2);
940 BEAST_EXPECT(ownerCount(env, bob) == 1);
944 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
946 env.require(balance(alice, USD(0)));
947 env.require(balance(bob, USD(8)));
950 BEAST_EXPECT(ownerCount(env, alice) == 1);
951 BEAST_EXPECT(ownerCount(env, bob) == 1);
955 Env env(*
this, features);
957 env.fund(XRP(1000), gw, alice, bob);
960 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
961 env(trust(alice, USD(20)));
963 env(pay(gw, alice, USD(8)));
969 env(check::create(alice, bob, USD(7)));
972 env(check::cash(bob, chkId, USD(7)),
978 env(trust(bob, USD(5)));
981 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
985 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
990 if (!cashCheckMakesTrustLine)
1006 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
1007 STAmount const bobGot = cashCheckMakesTrustLine ? USD(7) : USD(5);
1009 env.require(balance(alice, USD(8) - bobGot));
1010 env.require(balance(bob, bobGot));
1014 BEAST_EXPECT(ownerCount(env, alice) == 1);
1015 BEAST_EXPECT(ownerCount(env, bob) == 1);
1021 for (
auto const& testFeatures :
1022 {features - featureMultiSignReserve,
1023 features | featureMultiSignReserve})
1025 Env env{*
this, testFeatures};
1027 env.fund(XRP(1000), gw, alice, bob);
1032 env(check::create(alice, bob, USD(1)));
1036 env(check::create(alice, bob, USD(2)));
1039 env(trust(alice, USD(20)));
1040 env(trust(bob, USD(20)));
1042 env(pay(gw, alice, USD(8)));
1047 env(regkey(bob, bobby));
1052 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
1057 int const signersCount = {
1058 testFeatures[featureMultiSignReserve] ? 1 : 4};
1059 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1062 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
1064 env.require(balance(alice, USD(7)));
1065 env.require(balance(bob, USD(1)));
1068 BEAST_EXPECT(ownerCount(env, alice) == 2);
1069 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1072 XRPAmount const baseFeeDrops{env.current()->fees().base};
1073 env(check::cash(bob, chkId2, (USD(2))),
1075 fee(3 * baseFeeDrops));
1077 env.require(balance(alice, USD(5)));
1078 env.require(balance(bob, USD(3)));
1081 BEAST_EXPECT(ownerCount(env, alice) == 1);
1082 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1163 using namespace test::jtx;
1165 Account
const gw{
"gateway"};
1166 Account
const alice{
"alice"};
1167 Account
const bob{
"bob"};
1168 IOU
const USD{gw[
"USD"]};
1170 Env env{*
this, features};
1172 env.fund(XRP(1000), gw, alice, bob);
1175 env(trust(alice, USD(1000)));
1176 env(trust(bob, USD(1000)));
1178 env(pay(gw, alice, USD(1000)));
1186 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1187 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1191 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1192 Account
const& truster,
1194 auto const& inOrOut,
1198 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1199 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1202 env(trust(truster, iou(1000)), inOrOut(pct));
1205 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1207 env.require(balance(alice, aliceStart - USD(10)));
1208 env.require(balance(bob, bobStart + USD(10)));
1212 env(trust(truster, iou(1000)), inOrOut(0));
1216 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1217 Account
const& truster,
1219 auto const& inOrOut,
1223 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1224 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1227 env(trust(truster, iou(1000)), inOrOut(pct));
1231 env(check::create(alice, bob, USD(10)));
1234 env(check::cash(bob, chkId, USD(amount)));
1236 env.require(balance(alice, aliceStart - USD(10)));
1237 env.require(balance(bob, bobStart + USD(10)));
1241 env(trust(truster, iou(1000)), inOrOut(0));
1246 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1247 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1250 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1251 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1253 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1254 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1256 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1257 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1259 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1260 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1262 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1263 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1265 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1266 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1268 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1269 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1276 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1277 Account
const& truster,
1279 auto const& inOrOut,
1287 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1290 env(trust(truster, iou(1000)), inOrOut(pct));
1294 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1296 env.require(balance(alice, aliceStart - USD(10)));
1299 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1301 env.require(balance(alice, aliceStart));
1305 env(trust(truster, iou(1000)), inOrOut(0));
1309 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1310 Account
const& truster,
1312 auto const& inOrOut,
1320 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1323 env(trust(truster, iou(1000)), inOrOut(pct));
1328 env(check::create(alice, gw, USD(max1)));
1331 env(check::cash(gw, chkAliceId, USD(amt1)));
1333 env.require(balance(alice, aliceStart - USD(10)));
1337 env(check::create(gw, alice, USD(max2)));
1340 env(check::cash(alice, chkGwId, USD(amt2)));
1342 env.require(balance(alice, aliceStart));
1346 env(trust(truster, iou(1000)), inOrOut(0));
1352 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1353 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1355 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1356 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1358 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1359 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1361 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1362 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1371 using namespace test::jtx;
1373 Account
const gw{
"gateway"};
1374 Account
const alice{
"alice"};
1375 Account
const bob{
"bob"};
1376 Account
const zoe{
"zoe"};
1377 IOU
const USD{gw[
"USD"]};
1379 Env env(*
this, features);
1381 env.fund(XRP(1000), gw, alice, bob, zoe);
1385 env(trust(alice, USD(20)));
1387 env(pay(gw, alice, USD(20)));
1394 env(check::create(alice, bob, USD(20)));
1397 if (!features[featureCheckCashMakesTrustLine])
1402 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_LINE));
1408 env(trust(bob, USD(20)));
1414 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1420 env(check::create(alice, bob, USD(20)));
1424 env(check::create(alice, bob, XRP(10)));
1427 using namespace std::chrono_literals;
1429 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1433 env(check::create(alice, bob, USD(1)));
1437 env(check::create(alice, bob, USD(2)));
1441 env(check::create(alice, bob, USD(3)));
1445 env(check::create(alice, bob, USD(4)));
1449 env(check::create(alice, bob, USD(1)));
1453 env(check::create(alice, bob, USD(2)), dest_tag(7));
1457 auto failingCases = [&env, &gw, &alice, &bob](
1460 env(check::cash(bob, chkId, amount),
1466 env(check::cash(bob, chkId, amount),
1492 env(check::cash(bob, chkId, amount.zeroed()),
1498 if (!amount.native())
1515 IOU
const wrongCurrency{gw[
"EUR"]};
1517 badAmount.
setIssue(wrongCurrency.issue());
1518 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1524 IOU
const wrongIssuer{alice[
"USD"]};
1526 badAmount.
setIssue(wrongIssuer.issue());
1527 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1536 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1541 failingCases(chkIdX, XRP(10));
1542 failingCases(chkIdU, USD(20));
1545 env(check::cash(bob, chkIdU, USD(20)));
1547 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1551 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1555 env(check::cancel(zoe, chkIdExp));
1560 env(pay(bob, alice, USD(20)));
1562 env.require(balance(alice, USD(20)));
1563 env.require(balance(bob, USD(0)));
1571 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1579 env(check::cash(bob, chkIdFroz1, USD(1)));
1581 env.require(balance(alice, USD(19)));
1582 env.require(balance(bob, USD(1)));
1589 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1596 env(check::cash(bob, chkIdFroz2, USD(2)));
1598 env.require(balance(alice, USD(17)));
1599 env.require(balance(bob, USD(3)));
1604 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1606 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1613 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1615 env.require(balance(alice, USD(14)));
1616 env.require(balance(bob, USD(6)));
1622 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1624 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1631 env(check::cash(bob, chkIdFroz4, USD(4)));
1633 env.require(balance(alice, USD(10)));
1634 env.require(balance(bob, USD(10)));
1643 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1648 env(check::cash(bob, chkIdHasDest2, USD(2)));
1650 env.require(balance(alice, USD(8)));
1651 env.require(balance(bob, USD(12)));
1657 env(check::cash(bob, chkIdNoDest1, USD(1)));
1659 env.require(balance(alice, USD(7)));
1660 env.require(balance(bob, USD(13)));
1670 using namespace test::jtx;
1672 Account
const gw{
"gateway"};
1673 Account
const alice{
"alice"};
1674 Account
const bob{
"bob"};
1675 Account
const zoe{
"zoe"};
1676 IOU
const USD{gw[
"USD"]};
1680 for (
auto const& testFeatures :
1681 {features - featureMultiSignReserve,
1682 features | featureMultiSignReserve})
1684 Env env{*
this, testFeatures};
1686 env.fund(XRP(1000), gw, alice, bob, zoe);
1692 env(check::create(alice, bob, USD(10)));
1696 env(check::create(alice, bob, XRP(10)));
1700 env(check::create(alice, bob, USD(10)));
1704 using namespace std::chrono_literals;
1706 env(check::create(alice, bob, XRP(10)),
1707 expiration(env.now() + 600s));
1711 env(check::create(alice, bob, USD(10)),
1712 expiration(env.now() + 600s));
1716 env(check::create(alice, bob, XRP(10)),
1717 expiration(env.now() + 600s));
1722 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1726 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1730 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1735 env(check::create(alice, bob, USD(10)));
1739 env(check::create(alice, bob, XRP(10)));
1742 BEAST_EXPECT(ownerCount(env, alice) == 11);
1745 env(check::cancel(alice, chkId1));
1748 BEAST_EXPECT(ownerCount(env, alice) == 10);
1750 env(check::cancel(bob, chkId2));
1753 BEAST_EXPECT(ownerCount(env, alice) == 9);
1758 BEAST_EXPECT(ownerCount(env, alice) == 9);
1761 env(check::cancel(alice, chkIdNotExp1));
1764 BEAST_EXPECT(ownerCount(env, alice) == 8);
1766 env(check::cancel(bob, chkIdNotExp2));
1769 BEAST_EXPECT(ownerCount(env, alice) == 7);
1774 BEAST_EXPECT(ownerCount(env, alice) == 7);
1777 env(check::cancel(alice, chkIdExp1));
1780 BEAST_EXPECT(ownerCount(env, alice) == 6);
1782 env(check::cancel(bob, chkIdExp2));
1785 BEAST_EXPECT(ownerCount(env, alice) == 5);
1787 env(check::cancel(zoe, chkIdExp3));
1790 BEAST_EXPECT(ownerCount(env, alice) == 4);
1794 env(regkey(alice, alie));
1799 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1804 int const signersCount{
1805 testFeatures[featureMultiSignReserve] ? 1 : 4};
1808 env(check::cancel(alice, chkIdReg), sig(alie));
1811 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 3);
1814 XRPAmount const baseFeeDrops{env.current()->fees().base};
1815 env(check::cancel(alice, chkIdMSig),
1817 fee(3 * baseFeeDrops));
1820 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 2);
1823 env(check::cancel(alice, chkId3), sig(alice));
1826 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 1);
1828 env(check::cancel(bob, chkIdNotExp3));
1831 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 0);
1906 using namespace test::jtx;
1908 Account
const gw{
"gw"};
1909 Account
const alice{
"alice"};
1910 Account
const bob{
"bob"};
1911 IOU
const USD{gw[
"USD"]};
1913 Env env{*
this, features};
1914 env.fund(XRP(1000), gw, alice, bob);
1921 env(ticket::create(alice, 10));
1925 env(ticket::create(bob, 10));
1929 env.require(owners(alice, 10));
1930 env.require(owners(bob, 10));
1933 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1934 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1936 env.require(owners(alice, 10));
1937 env.require(owners(bob, 10));
1939 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1940 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1942 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1943 BEAST_EXPECT(env.seq(bob) == bobSeq);
1945 env(pay(gw, alice, USD(900)));
1951 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1954 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1957 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1960 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1964 env.require(owners(alice, 10));
1965 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1967 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1969 env.require(owners(bob, 10));
1970 BEAST_EXPECT(env.seq(bob) == bobSeq);
1973 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1974 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1977 env.require(owners(alice, 8));
1978 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1980 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1982 env.require(owners(bob, 8));
1983 BEAST_EXPECT(env.seq(bob) == bobSeq);
1986 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1987 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1990 env.require(owners(alice, 6));
1991 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1993 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1994 env.require(balance(alice, USD(700)));
1996 env.require(owners(bob, 6));
1997 BEAST_EXPECT(env.seq(bob) == bobSeq);
1998 env.require(balance(bob, USD(200)));
2009 assert(features[featureCheckCashMakesTrustLine]);
2013 using namespace test::jtx;
2015 Env env{*
this, features};
2029 ownerCount(env, acct) == owners,
2030 "Owner count mismatch",
2036 operator Account
const()
const
2053 AccountOwns alice{*
this, env,
"alice", 0};
2054 AccountOwns bob{*
this, env,
"bob", 0};
2057 env.fund(XRP(5000), noripple(alice, bob));
2063 AccountOwns gw1{*
this, env,
"gw1", 0};
2068 env.fund(XRP(5000), noripple(gw1));
2071 IOU
const CK8 = gw1[
"CK8"];
2072 gw1.verifyOwners(__LINE__);
2074 Account
const yui{
"yui"};
2079 env.fund(XRP(200), yui);
2083 env(check::create(gw1, yui, CK8(99)));
2086 env(check::cash(yui, chkId, CK8(99)),
2089 alice.verifyOwners(__LINE__);
2093 env(pay(env.master, yui, XRP(51)));
2095 env(check::cash(yui, chkId, CK8(99)));
2098 BEAST_EXPECT(ownerCount(env, yui) == 1);
2102 gw1.verifyOwners(__LINE__);
2117 auto cmpTrustLines = [
this, &env](
2118 Account
const& acct1,
2119 Account
const& acct2,
2120 IOU
const& offerIou,
2121 IOU
const& checkIou) {
2122 auto const offerLine =
2124 auto const checkLine =
2126 if (offerLine ==
nullptr || checkLine ==
nullptr)
2128 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
2134 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2139 [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
2140 STAmount const offerAmount = offerLine->at(sfield);
2141 STAmount const checkAmount = checkLine->at(sfield);
2158 cmpReqAmount(sfBalance);
2159 cmpReqAmount(sfLowLimit);
2160 cmpReqAmount(sfHighLimit);
2165 [
this, offerLine, checkLine](
auto const& sfield) {
2168 offerLine->isFieldPresent(sfield) ==
2169 checkLine->isFieldPresent(sfield)))
2174 if (!offerLine->isFieldPresent(sfield))
2180 offerLine->at(sfield) == checkLine->at(sfield));
2182 cmpOptField(sfLowNode);
2183 cmpOptField(sfLowQualityIn);
2184 cmpOptField(sfLowQualityOut);
2186 cmpOptField(sfHighNode);
2187 cmpOptField(sfHighQualityIn);
2188 cmpOptField(sfHighQualityOut);
2196 AccountOwns gw1{*
this, env,
"gw1", 0};
2198 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2199 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2200 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2203 IOU
const OF1 = gw1[
"OF1"];
2204 env(offer(gw1, XRP(98), OF1(98)));
2207 env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2208 env(offer(alice, OF1(98), XRP(98)));
2215 gw1.verifyOwners(__LINE__);
2218 alice.verifyOwners(__LINE__);
2221 IOU
const CK1 = gw1[
"CK1"];
2223 env(check::create(gw1, alice, CK1(98)));
2226 env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2227 env(check::cash(alice, chkId, CK1(98)));
2235 gw1.verifyOwners(__LINE__);
2238 alice.verifyOwners(__LINE__);
2240 cmpTrustLines(gw1, alice, OF1, CK1);
2251 AccountOwns gw1{*
this, env,
"gw1", 0};
2252 IOU
const OF1 = gw1[
"OF1"];
2253 env(offer(alice, XRP(97), OF1(97)));
2256 env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2257 env(offer(bob, OF1(97), XRP(97)));
2262 env.require(balance(alice, OF1(1)));
2263 env.require(balance(bob, OF1(97)));
2266 gw1.verifyOwners(__LINE__);
2267 alice.verifyOwners(__LINE__);
2268 bob.verifyOwners(__LINE__);
2276 IOU
const CK1 = gw1[
"CK1"];
2278 env(check::create(alice, bob, CK1(97)));
2281 env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2282 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2286 env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2288 env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2291 env(check::cancel(alice, chkId));
2295 gw1.verifyOwners(__LINE__);
2296 alice.verifyOwners(__LINE__);
2297 bob.verifyOwners(__LINE__);
2304 AccountOwns gw1{*
this, env,
"gw1", 0};
2309 IOU
const OF2 = gw1[
"OF2"];
2310 env(offer(gw1, XRP(96), OF2(96)));
2313 env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2314 env(offer(alice, OF2(96), XRP(96)));
2321 gw1.verifyOwners(__LINE__);
2324 alice.verifyOwners(__LINE__);
2327 IOU
const CK2 = gw1[
"CK2"];
2329 env(check::create(gw1, alice, CK2(96)));
2332 env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2333 env(check::cash(alice, chkId, CK2(96)));
2341 gw1.verifyOwners(__LINE__);
2344 alice.verifyOwners(__LINE__);
2346 cmpTrustLines(gw1, alice, OF2, CK2);
2354 AccountOwns gw1{*
this, env,
"gw1", 0};
2355 IOU
const OF2 = gw1[
"OF2"];
2356 env(offer(alice, XRP(95), OF2(95)));
2359 env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2360 env(offer(bob, OF2(95), XRP(95)));
2365 gw1.verifyOwners(__LINE__);
2366 alice.verifyOwners(__LINE__);
2367 bob.verifyOwners(__LINE__);
2370 IOU
const CK2 = gw1[
"CK2"];
2372 env(check::create(alice, bob, CK2(95)));
2375 env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2376 env(check::cash(bob, chkId, CK2(95)));
2382 gw1.verifyOwners(__LINE__);
2383 alice.verifyOwners(__LINE__);
2384 bob.verifyOwners(__LINE__);
2386 cmpTrustLines(alice, bob, OF2, CK2);
2397 AccountOwns gw1{*
this, env,
"gw1", 0};
2404 IOU
const OF3 = gw1[
"OF3"];
2405 env(offer(gw1, XRP(94), OF3(94)));
2408 env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2409 env(offer(alice, OF3(94), XRP(94)));
2416 gw1.verifyOwners(__LINE__);
2419 alice.verifyOwners(__LINE__);
2422 IOU
const CK3 = gw1[
"CK3"];
2424 env(check::create(gw1, alice, CK3(94)));
2427 env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2428 env(check::cash(alice, chkId, CK3(94)));
2436 gw1.verifyOwners(__LINE__);
2439 alice.verifyOwners(__LINE__);
2441 cmpTrustLines(gw1, alice, OF3, CK3);
2449 AccountOwns gw1{*
this, env,
"gw1", 0};
2450 IOU
const OF3 = gw1[
"OF3"];
2451 env(offer(alice, XRP(93), OF3(93)));
2454 env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2455 env(offer(bob, OF3(93), XRP(93)));
2460 gw1.verifyOwners(__LINE__);
2461 alice.verifyOwners(__LINE__);
2462 bob.verifyOwners(__LINE__);
2465 IOU
const CK3 = gw1[
"CK3"];
2467 env(check::create(alice, bob, CK3(93)));
2470 env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2471 env(check::cash(bob, chkId, CK3(93)));
2477 gw1.verifyOwners(__LINE__);
2478 alice.verifyOwners(__LINE__);
2479 bob.verifyOwners(__LINE__);
2481 cmpTrustLines(alice, bob, OF3, CK3);
2488 AccountOwns gw1{*
this, env,
"gw1", 0};
2493 IOU
const OF4 = gw1[
"OF4"];
2494 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2497 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2498 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2502 gw1.verifyOwners(__LINE__);
2503 alice.verifyOwners(__LINE__);
2504 bob.verifyOwners(__LINE__);
2507 IOU
const CK4 = gw1[
"CK4"];
2509 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2512 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2513 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2517 gw1.verifyOwners(__LINE__);
2518 alice.verifyOwners(__LINE__);
2519 bob.verifyOwners(__LINE__);
2524 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2526 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2534 AccountOwns gw1{*
this, env,
"gw1", 0};
2535 IOU
const OF4 = gw1[
"OF4"];
2536 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2539 env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2540 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2544 gw1.verifyOwners(__LINE__);
2545 alice.verifyOwners(__LINE__);
2546 bob.verifyOwners(__LINE__);
2549 IOU
const CK4 = gw1[
"CK4"];
2551 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2554 env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2555 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2559 gw1.verifyOwners(__LINE__);
2560 alice.verifyOwners(__LINE__);
2561 bob.verifyOwners(__LINE__);
2566 env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2568 env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2577 AccountOwns gw2{*
this, env,
"gw2", 0};
2578 env.fund(XRP(5000), gw2);
2587 IOU
const OF5 = gw2[
"OF5"];
2589 env(offer(gw2, XRP(92), OF5(92)));
2593 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2594 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2599 gw2.verifyOwners(__LINE__);
2600 alice.verifyOwners(__LINE__);
2601 bob.verifyOwners(__LINE__);
2604 env(offer_cancel(gw2, gw2OfferSeq));
2607 gw2.verifyOwners(__LINE__);
2610 IOU
const CK5 = gw2[
"CK5"];
2612 env(check::create(gw2, alice, CK5(92)));
2616 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2617 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2622 gw2.verifyOwners(__LINE__);
2623 alice.verifyOwners(__LINE__);
2624 bob.verifyOwners(__LINE__);
2629 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2631 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2634 env(check::cancel(gw2, chkId));
2637 gw2.verifyOwners(__LINE__);
2645 AccountOwns gw2{*
this, env,
"gw2", 0};
2646 IOU
const OF5 = gw2[
"OF5"];
2649 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2651 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2654 gw2.verifyOwners(__LINE__);
2655 alice.verifyOwners(__LINE__);
2656 bob.verifyOwners(__LINE__);
2659 IOU
const CK5 = gw2[
"CK5"];
2661 env(check::create(alice, bob, CK5(91)));
2664 env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2669 env(check::cancel(alice, chkId));
2673 gw2.verifyOwners(__LINE__);
2674 alice.verifyOwners(__LINE__);
2675 bob.verifyOwners(__LINE__);
2680 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2682 env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);