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 bool const cashCheckMakesTrustLine =
683 features[featureCheckCashMakesTrustLine];
685 Account
const gw{
"gateway"};
686 Account
const alice{
"alice"};
687 Account
const bob{
"bob"};
688 IOU
const USD{gw[
"USD"]};
691 Env env{*
this, features};
693 env.fund(XRP(1000), gw, alice, bob);
698 env(check::create(alice, bob, USD(10)));
706 env(trust(alice, USD(20)));
708 env(pay(gw, alice, USD(9.5)));
715 env(pay(gw, alice, USD(0.5)));
717 if (!cashCheckMakesTrustLine)
722 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_LINE));
727 env(trust(bob, USD(9.5)));
729 if (!cashCheckMakesTrustLine)
740 env(trust(bob, USD(10.5)));
746 env(check::cash(bob, chkId1, USD(10)));
748 env.require(balance(alice, USD(0)));
749 env.require(balance(bob, USD(10)));
752 BEAST_EXPECT(ownerCount(env, alice) == 1);
753 BEAST_EXPECT(ownerCount(env, bob) == 1);
756 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
760 env(pay(bob, alice, USD(7)));
764 env(check::create(alice, bob, USD(7)));
771 env(check::cash(bob, chkId2, USD(5)));
773 env.require(balance(alice, USD(2)));
774 env.require(balance(bob, USD(8)));
777 BEAST_EXPECT(ownerCount(env, alice) == 1);
778 BEAST_EXPECT(ownerCount(env, bob) == 1);
782 env(check::create(alice, bob, USD(2)));
785 env(check::create(alice, bob, USD(2)));
791 env(check::cash(bob, chkId4, USD(2)));
793 env.require(balance(alice, USD(0)));
794 env.require(balance(bob, USD(10)));
797 BEAST_EXPECT(ownerCount(env, alice) == 2);
798 BEAST_EXPECT(ownerCount(env, bob) == 1);
804 env.require(balance(alice, USD(0)));
805 env.require(balance(bob, USD(10)));
808 BEAST_EXPECT(ownerCount(env, alice) == 2);
809 BEAST_EXPECT(ownerCount(env, bob) == 1);
811 if (cashCheckMakesTrustLine)
827 env(check::create(gw, bob, USD(20)));
831 env(check::cash(bob, chkId20, USD(20)));
833 env.require(balance(bob, USD(30)));
837 env(pay(bob, gw, USD(20)));
841 env(check::cancel(bob, chkId3));
843 env.require(balance(alice, USD(0)));
844 env.require(balance(bob, USD(10)));
847 BEAST_EXPECT(ownerCount(env, alice) == 1);
848 BEAST_EXPECT(ownerCount(env, bob) == 1);
852 Env env{*
this, features};
854 env.fund(XRP(1000), gw, alice, bob);
857 env(trust(alice, USD(20)));
858 env(trust(bob, USD(20)));
860 env(pay(gw, alice, USD(8)));
865 env(check::create(alice, bob, USD(9)));
868 env(check::create(alice, bob, USD(8)));
871 env(check::create(alice, bob, USD(7)));
874 env(check::create(alice, bob, USD(6)));
879 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
884 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
886 env.require(balance(alice, USD(0)));
887 env.require(balance(bob, USD(8)));
890 BEAST_EXPECT(ownerCount(env, alice) == 4);
891 BEAST_EXPECT(ownerCount(env, bob) == 1);
894 env(pay(bob, alice, USD(7)));
899 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
901 env.require(balance(alice, USD(0)));
902 env.require(balance(bob, USD(8)));
905 BEAST_EXPECT(ownerCount(env, alice) == 3);
906 BEAST_EXPECT(ownerCount(env, bob) == 1);
909 env(pay(bob, alice, USD(8)));
914 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
916 env.require(balance(alice, USD(2)));
917 env.require(balance(bob, USD(6)));
920 BEAST_EXPECT(ownerCount(env, alice) == 2);
921 BEAST_EXPECT(ownerCount(env, bob) == 1);
925 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
927 env.require(balance(alice, USD(0)));
928 env.require(balance(bob, USD(8)));
931 BEAST_EXPECT(ownerCount(env, alice) == 1);
932 BEAST_EXPECT(ownerCount(env, bob) == 1);
936 Env env(*
this, features);
938 env.fund(XRP(1000), gw, alice, bob);
941 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
942 env(trust(alice, USD(20)));
944 env(pay(gw, alice, USD(8)));
950 env(check::create(alice, bob, USD(7)));
953 env(check::cash(bob, chkId, USD(7)),
959 env(trust(bob, USD(5)));
962 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
966 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
971 if (!cashCheckMakesTrustLine)
987 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
988 STAmount const bobGot = cashCheckMakesTrustLine ? USD(7) : USD(5);
990 env.require(balance(alice, USD(8) - bobGot));
991 env.require(balance(bob, bobGot));
995 BEAST_EXPECT(ownerCount(env, alice) == 1);
996 BEAST_EXPECT(ownerCount(env, bob) == 1);
1002 for (
auto const& testFeatures :
1003 {features - featureMultiSignReserve,
1004 features | featureMultiSignReserve})
1006 Env env{*
this, testFeatures};
1008 env.fund(XRP(1000), gw, alice, bob);
1013 env(check::create(alice, bob, USD(1)));
1017 env(check::create(alice, bob, USD(2)));
1020 env(trust(alice, USD(20)));
1021 env(trust(bob, USD(20)));
1023 env(pay(gw, alice, USD(8)));
1028 env(regkey(bob, bobby));
1033 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
1038 int const signersCount = {
1039 testFeatures[featureMultiSignReserve] ? 1 : 4};
1040 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1043 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
1045 env.require(balance(alice, USD(7)));
1046 env.require(balance(bob, USD(1)));
1049 BEAST_EXPECT(ownerCount(env, alice) == 2);
1050 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1053 XRPAmount const baseFeeDrops{env.current()->fees().base};
1054 env(check::cash(bob, chkId2, (USD(2))),
1056 fee(3 * baseFeeDrops));
1058 env.require(balance(alice, USD(5)));
1059 env.require(balance(bob, USD(3)));
1062 BEAST_EXPECT(ownerCount(env, alice) == 1);
1063 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1144 using namespace test::jtx;
1146 Account
const gw{
"gateway"};
1147 Account
const alice{
"alice"};
1148 Account
const bob{
"bob"};
1149 IOU
const USD{gw[
"USD"]};
1151 Env env{*
this, features};
1153 env.fund(XRP(1000), gw, alice, bob);
1156 env(trust(alice, USD(1000)));
1157 env(trust(bob, USD(1000)));
1159 env(pay(gw, alice, USD(1000)));
1167 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1168 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1172 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1173 Account
const& truster,
1175 auto const& inOrOut,
1179 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1180 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1183 env(trust(truster, iou(1000)), inOrOut(pct));
1186 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1188 env.require(balance(alice, aliceStart - USD(10)));
1189 env.require(balance(bob, bobStart + USD(10)));
1193 env(trust(truster, iou(1000)), inOrOut(0));
1197 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1198 Account
const& truster,
1200 auto const& inOrOut,
1204 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1205 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1208 env(trust(truster, iou(1000)), inOrOut(pct));
1212 env(check::create(alice, bob, USD(10)));
1215 env(check::cash(bob, chkId, USD(amount)));
1217 env.require(balance(alice, aliceStart - USD(10)));
1218 env.require(balance(bob, bobStart + USD(10)));
1222 env(trust(truster, iou(1000)), inOrOut(0));
1227 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1228 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1231 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1232 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1234 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1235 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1237 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1238 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1240 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1241 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1243 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1244 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1246 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1247 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1249 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1250 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1257 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1258 Account
const& truster,
1260 auto const& inOrOut,
1268 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1271 env(trust(truster, iou(1000)), inOrOut(pct));
1275 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1277 env.require(balance(alice, aliceStart - USD(10)));
1280 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1282 env.require(balance(alice, aliceStart));
1286 env(trust(truster, iou(1000)), inOrOut(0));
1290 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1291 Account
const& truster,
1293 auto const& inOrOut,
1301 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1304 env(trust(truster, iou(1000)), inOrOut(pct));
1309 env(check::create(alice, gw, USD(max1)));
1312 env(check::cash(gw, chkAliceId, USD(amt1)));
1314 env.require(balance(alice, aliceStart - USD(10)));
1318 env(check::create(gw, alice, USD(max2)));
1321 env(check::cash(alice, chkGwId, USD(amt2)));
1323 env.require(balance(alice, aliceStart));
1327 env(trust(truster, iou(1000)), inOrOut(0));
1333 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1334 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1336 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1337 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1339 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1340 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1342 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1343 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1352 using namespace test::jtx;
1354 Account
const gw{
"gateway"};
1355 Account
const alice{
"alice"};
1356 Account
const bob{
"bob"};
1357 Account
const zoe{
"zoe"};
1358 IOU
const USD{gw[
"USD"]};
1360 Env env(*
this, features);
1362 env.fund(XRP(1000), gw, alice, bob, zoe);
1366 env(trust(alice, USD(20)));
1368 env(pay(gw, alice, USD(20)));
1375 env(check::create(alice, bob, USD(20)));
1378 if (!features[featureCheckCashMakesTrustLine])
1383 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_LINE));
1389 env(trust(bob, USD(20)));
1395 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1401 env(check::create(alice, bob, USD(20)));
1405 env(check::create(alice, bob, XRP(10)));
1408 using namespace std::chrono_literals;
1410 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1414 env(check::create(alice, bob, USD(1)));
1418 env(check::create(alice, bob, USD(2)));
1422 env(check::create(alice, bob, USD(3)));
1426 env(check::create(alice, bob, USD(4)));
1430 env(check::create(alice, bob, USD(1)));
1434 env(check::create(alice, bob, USD(2)), dest_tag(7));
1438 auto failingCases = [&env, &gw, &alice, &bob](
1441 env(check::cash(bob, chkId, amount),
1447 env(check::cash(bob, chkId, amount),
1473 env(check::cash(bob, chkId, amount.zeroed()),
1479 if (!amount.native())
1496 IOU
const wrongCurrency{gw[
"EUR"]};
1498 badAmount.
setIssue(wrongCurrency.issue());
1499 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1505 IOU
const wrongIssuer{alice[
"USD"]};
1507 badAmount.
setIssue(wrongIssuer.issue());
1508 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1517 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1522 failingCases(chkIdX, XRP(10));
1523 failingCases(chkIdU, USD(20));
1526 env(check::cash(bob, chkIdU, USD(20)));
1528 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1532 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1536 env(check::cancel(zoe, chkIdExp));
1541 env(pay(bob, alice, USD(20)));
1543 env.require(balance(alice, USD(20)));
1544 env.require(balance(bob, USD(0)));
1552 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1560 env(check::cash(bob, chkIdFroz1, USD(1)));
1562 env.require(balance(alice, USD(19)));
1563 env.require(balance(bob, USD(1)));
1570 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1577 env(check::cash(bob, chkIdFroz2, USD(2)));
1579 env.require(balance(alice, USD(17)));
1580 env.require(balance(bob, USD(3)));
1585 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1587 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1594 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1596 env.require(balance(alice, USD(14)));
1597 env.require(balance(bob, USD(6)));
1603 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1605 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1612 env(check::cash(bob, chkIdFroz4, USD(4)));
1614 env.require(balance(alice, USD(10)));
1615 env.require(balance(bob, USD(10)));
1624 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1629 env(check::cash(bob, chkIdHasDest2, USD(2)));
1631 env.require(balance(alice, USD(8)));
1632 env.require(balance(bob, USD(12)));
1638 env(check::cash(bob, chkIdNoDest1, USD(1)));
1640 env.require(balance(alice, USD(7)));
1641 env.require(balance(bob, USD(13)));
1651 using namespace test::jtx;
1653 Account
const gw{
"gateway"};
1654 Account
const alice{
"alice"};
1655 Account
const bob{
"bob"};
1656 Account
const zoe{
"zoe"};
1657 IOU
const USD{gw[
"USD"]};
1661 for (
auto const& testFeatures :
1662 {features - featureMultiSignReserve,
1663 features | featureMultiSignReserve})
1665 Env env{*
this, testFeatures};
1667 env.fund(XRP(1000), gw, alice, bob, zoe);
1673 env(check::create(alice, bob, USD(10)));
1677 env(check::create(alice, bob, XRP(10)));
1681 env(check::create(alice, bob, USD(10)));
1685 using namespace std::chrono_literals;
1687 env(check::create(alice, bob, XRP(10)),
1688 expiration(env.now() + 600s));
1692 env(check::create(alice, bob, USD(10)),
1693 expiration(env.now() + 600s));
1697 env(check::create(alice, bob, XRP(10)),
1698 expiration(env.now() + 600s));
1703 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1707 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1711 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1716 env(check::create(alice, bob, USD(10)));
1720 env(check::create(alice, bob, XRP(10)));
1723 BEAST_EXPECT(ownerCount(env, alice) == 11);
1726 env(check::cancel(alice, chkId1));
1729 BEAST_EXPECT(ownerCount(env, alice) == 10);
1731 env(check::cancel(bob, chkId2));
1734 BEAST_EXPECT(ownerCount(env, alice) == 9);
1739 BEAST_EXPECT(ownerCount(env, alice) == 9);
1742 env(check::cancel(alice, chkIdNotExp1));
1745 BEAST_EXPECT(ownerCount(env, alice) == 8);
1747 env(check::cancel(bob, chkIdNotExp2));
1750 BEAST_EXPECT(ownerCount(env, alice) == 7);
1755 BEAST_EXPECT(ownerCount(env, alice) == 7);
1758 env(check::cancel(alice, chkIdExp1));
1761 BEAST_EXPECT(ownerCount(env, alice) == 6);
1763 env(check::cancel(bob, chkIdExp2));
1766 BEAST_EXPECT(ownerCount(env, alice) == 5);
1768 env(check::cancel(zoe, chkIdExp3));
1771 BEAST_EXPECT(ownerCount(env, alice) == 4);
1775 env(regkey(alice, alie));
1780 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1785 int const signersCount{
1786 testFeatures[featureMultiSignReserve] ? 1 : 4};
1789 env(check::cancel(alice, chkIdReg), sig(alie));
1792 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 3);
1795 XRPAmount const baseFeeDrops{env.current()->fees().base};
1796 env(check::cancel(alice, chkIdMSig),
1798 fee(3 * baseFeeDrops));
1801 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 2);
1804 env(check::cancel(alice, chkId3), sig(alice));
1807 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 1);
1809 env(check::cancel(bob, chkIdNotExp3));
1812 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 0);
1887 using namespace test::jtx;
1889 Account
const gw{
"gw"};
1890 Account
const alice{
"alice"};
1891 Account
const bob{
"bob"};
1892 IOU
const USD{gw[
"USD"]};
1894 Env env{*
this, features};
1895 env.fund(XRP(1000), gw, alice, bob);
1902 env(ticket::create(alice, 10));
1906 env(ticket::create(bob, 10));
1910 env.require(owners(alice, 10));
1911 env.require(owners(bob, 10));
1914 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1915 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1917 env.require(owners(alice, 10));
1918 env.require(owners(bob, 10));
1920 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1921 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1923 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1924 BEAST_EXPECT(env.seq(bob) == bobSeq);
1926 env(pay(gw, alice, USD(900)));
1932 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1935 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1938 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1941 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1945 env.require(owners(alice, 10));
1946 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1948 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1950 env.require(owners(bob, 10));
1951 BEAST_EXPECT(env.seq(bob) == bobSeq);
1954 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1955 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1958 env.require(owners(alice, 8));
1959 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1961 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1963 env.require(owners(bob, 8));
1964 BEAST_EXPECT(env.seq(bob) == bobSeq);
1967 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1968 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1971 env.require(owners(alice, 6));
1972 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1974 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1975 env.require(balance(alice, USD(700)));
1977 env.require(owners(bob, 6));
1978 BEAST_EXPECT(env.seq(bob) == bobSeq);
1979 env.require(balance(bob, USD(200)));
1990 assert(features[featureCheckCashMakesTrustLine]);
1994 using namespace test::jtx;
1996 Env env{*
this, features};
2010 ownerCount(env, acct) == owners,
2011 "Owner count mismatch",
2017 operator Account
const()
const
2034 AccountOwns alice{*
this, env,
"alice", 0};
2035 AccountOwns bob{*
this, env,
"bob", 0};
2038 env.fund(XRP(5000), noripple(alice, bob));
2044 AccountOwns gw1{*
this, env,
"gw1", 0};
2049 env.fund(XRP(5000), noripple(gw1));
2052 IOU
const CK8 = gw1[
"CK8"];
2053 gw1.verifyOwners(__LINE__);
2055 Account
const yui{
"yui"};
2060 env.fund(XRP(200), yui);
2064 env(check::create(gw1, yui, CK8(99)));
2067 env(check::cash(yui, chkId, CK8(99)),
2070 alice.verifyOwners(__LINE__);
2074 env(pay(env.master, yui, XRP(51)));
2076 env(check::cash(yui, chkId, CK8(99)));
2079 BEAST_EXPECT(ownerCount(env, yui) == 1);
2083 gw1.verifyOwners(__LINE__);
2098 auto cmpTrustLines = [
this, &env](
2099 Account
const& acct1,
2100 Account
const& acct2,
2101 IOU
const& offerIou,
2102 IOU
const& checkIou) {
2103 auto const offerLine =
2105 auto const checkLine =
2107 if (offerLine ==
nullptr || checkLine ==
nullptr)
2109 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
2115 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2120 [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
2121 STAmount const offerAmount = offerLine->at(sfield);
2122 STAmount const checkAmount = checkLine->at(sfield);
2139 cmpReqAmount(sfBalance);
2140 cmpReqAmount(sfLowLimit);
2141 cmpReqAmount(sfHighLimit);
2146 [
this, offerLine, checkLine](
auto const& sfield) {
2149 offerLine->isFieldPresent(sfield) ==
2150 checkLine->isFieldPresent(sfield)))
2155 if (!offerLine->isFieldPresent(sfield))
2161 offerLine->at(sfield) == checkLine->at(sfield));
2163 cmpOptField(sfLowNode);
2164 cmpOptField(sfLowQualityIn);
2165 cmpOptField(sfLowQualityOut);
2167 cmpOptField(sfHighNode);
2168 cmpOptField(sfHighQualityIn);
2169 cmpOptField(sfHighQualityOut);
2177 AccountOwns gw1{*
this, env,
"gw1", 0};
2179 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2180 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2181 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2184 IOU
const OF1 = gw1[
"OF1"];
2185 env(offer(gw1, XRP(98), OF1(98)));
2188 env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2189 env(offer(alice, OF1(98), XRP(98)));
2196 gw1.verifyOwners(__LINE__);
2199 alice.verifyOwners(__LINE__);
2202 IOU
const CK1 = gw1[
"CK1"];
2204 env(check::create(gw1, alice, CK1(98)));
2207 env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2208 env(check::cash(alice, chkId, CK1(98)));
2216 gw1.verifyOwners(__LINE__);
2219 alice.verifyOwners(__LINE__);
2221 cmpTrustLines(gw1, alice, OF1, CK1);
2232 AccountOwns gw1{*
this, env,
"gw1", 0};
2233 IOU
const OF1 = gw1[
"OF1"];
2234 env(offer(alice, XRP(97), OF1(97)));
2237 env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2238 env(offer(bob, OF1(97), XRP(97)));
2243 env.require(balance(alice, OF1(1)));
2244 env.require(balance(bob, OF1(97)));
2247 gw1.verifyOwners(__LINE__);
2248 alice.verifyOwners(__LINE__);
2249 bob.verifyOwners(__LINE__);
2257 IOU
const CK1 = gw1[
"CK1"];
2259 env(check::create(alice, bob, CK1(97)));
2262 env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2263 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2267 env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2269 env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2272 env(check::cancel(alice, chkId));
2276 gw1.verifyOwners(__LINE__);
2277 alice.verifyOwners(__LINE__);
2278 bob.verifyOwners(__LINE__);
2285 AccountOwns gw1{*
this, env,
"gw1", 0};
2290 IOU
const OF2 = gw1[
"OF2"];
2291 env(offer(gw1, XRP(96), OF2(96)));
2294 env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2295 env(offer(alice, OF2(96), XRP(96)));
2302 gw1.verifyOwners(__LINE__);
2305 alice.verifyOwners(__LINE__);
2308 IOU
const CK2 = gw1[
"CK2"];
2310 env(check::create(gw1, alice, CK2(96)));
2313 env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2314 env(check::cash(alice, chkId, CK2(96)));
2322 gw1.verifyOwners(__LINE__);
2325 alice.verifyOwners(__LINE__);
2327 cmpTrustLines(gw1, alice, OF2, CK2);
2335 AccountOwns gw1{*
this, env,
"gw1", 0};
2336 IOU
const OF2 = gw1[
"OF2"];
2337 env(offer(alice, XRP(95), OF2(95)));
2340 env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2341 env(offer(bob, OF2(95), XRP(95)));
2346 gw1.verifyOwners(__LINE__);
2347 alice.verifyOwners(__LINE__);
2348 bob.verifyOwners(__LINE__);
2351 IOU
const CK2 = gw1[
"CK2"];
2353 env(check::create(alice, bob, CK2(95)));
2356 env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2357 env(check::cash(bob, chkId, CK2(95)));
2363 gw1.verifyOwners(__LINE__);
2364 alice.verifyOwners(__LINE__);
2365 bob.verifyOwners(__LINE__);
2367 cmpTrustLines(alice, bob, OF2, CK2);
2378 AccountOwns gw1{*
this, env,
"gw1", 0};
2385 IOU
const OF3 = gw1[
"OF3"];
2386 env(offer(gw1, XRP(94), OF3(94)));
2389 env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2390 env(offer(alice, OF3(94), XRP(94)));
2397 gw1.verifyOwners(__LINE__);
2400 alice.verifyOwners(__LINE__);
2403 IOU
const CK3 = gw1[
"CK3"];
2405 env(check::create(gw1, alice, CK3(94)));
2408 env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2409 env(check::cash(alice, chkId, CK3(94)));
2417 gw1.verifyOwners(__LINE__);
2420 alice.verifyOwners(__LINE__);
2422 cmpTrustLines(gw1, alice, OF3, CK3);
2430 AccountOwns gw1{*
this, env,
"gw1", 0};
2431 IOU
const OF3 = gw1[
"OF3"];
2432 env(offer(alice, XRP(93), OF3(93)));
2435 env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2436 env(offer(bob, OF3(93), XRP(93)));
2441 gw1.verifyOwners(__LINE__);
2442 alice.verifyOwners(__LINE__);
2443 bob.verifyOwners(__LINE__);
2446 IOU
const CK3 = gw1[
"CK3"];
2448 env(check::create(alice, bob, CK3(93)));
2451 env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2452 env(check::cash(bob, chkId, CK3(93)));
2458 gw1.verifyOwners(__LINE__);
2459 alice.verifyOwners(__LINE__);
2460 bob.verifyOwners(__LINE__);
2462 cmpTrustLines(alice, bob, OF3, CK3);
2469 AccountOwns gw1{*
this, env,
"gw1", 0};
2474 IOU
const OF4 = gw1[
"OF4"];
2475 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2478 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2479 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2483 gw1.verifyOwners(__LINE__);
2484 alice.verifyOwners(__LINE__);
2485 bob.verifyOwners(__LINE__);
2488 IOU
const CK4 = gw1[
"CK4"];
2490 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2493 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2494 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2498 gw1.verifyOwners(__LINE__);
2499 alice.verifyOwners(__LINE__);
2500 bob.verifyOwners(__LINE__);
2505 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2507 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2515 AccountOwns gw1{*
this, env,
"gw1", 0};
2516 IOU
const OF4 = gw1[
"OF4"];
2517 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2520 env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2521 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2525 gw1.verifyOwners(__LINE__);
2526 alice.verifyOwners(__LINE__);
2527 bob.verifyOwners(__LINE__);
2530 IOU
const CK4 = gw1[
"CK4"];
2532 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2535 env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2536 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2540 gw1.verifyOwners(__LINE__);
2541 alice.verifyOwners(__LINE__);
2542 bob.verifyOwners(__LINE__);
2547 env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2549 env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2558 AccountOwns gw2{*
this, env,
"gw2", 0};
2559 env.fund(XRP(5000), gw2);
2568 IOU
const OF5 = gw2[
"OF5"];
2570 env(offer(gw2, XRP(92), OF5(92)));
2574 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2575 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2580 gw2.verifyOwners(__LINE__);
2581 alice.verifyOwners(__LINE__);
2582 bob.verifyOwners(__LINE__);
2585 env(offer_cancel(gw2, gw2OfferSeq));
2588 gw2.verifyOwners(__LINE__);
2591 IOU
const CK5 = gw2[
"CK5"];
2593 env(check::create(gw2, alice, CK5(92)));
2597 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2598 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2603 gw2.verifyOwners(__LINE__);
2604 alice.verifyOwners(__LINE__);
2605 bob.verifyOwners(__LINE__);
2610 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2612 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2615 env(check::cancel(gw2, chkId));
2618 gw2.verifyOwners(__LINE__);
2626 AccountOwns gw2{*
this, env,
"gw2", 0};
2627 IOU
const OF5 = gw2[
"OF5"];
2630 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2632 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2635 gw2.verifyOwners(__LINE__);
2636 alice.verifyOwners(__LINE__);
2637 bob.verifyOwners(__LINE__);
2640 IOU
const CK5 = gw2[
"CK5"];
2642 env(check::create(alice, bob, CK5(91)));
2645 env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2650 env(check::cancel(alice, chkId));
2654 gw2.verifyOwners(__LINE__);
2655 alice.verifyOwners(__LINE__);
2656 bob.verifyOwners(__LINE__);
2661 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2663 env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);