20 #include <ripple/protocol/Feature.h>
21 #include <ripple/protocol/jss.h>
103 if (sle->getType() == ltCHECK)
104 result.push_back(sle);
114 if (
auto const sleAccount = env.
le(account))
132 Json::Value const meta = env.
rpc(
"tx", txHash)[jss::result][jss::meta];
152 using namespace test::jtx;
153 Account
const alice{
"alice"};
159 env.fund(XRP(1000), alice);
163 env(check::create(env.master, alice, XRP(100)), ter(
temDISABLED));
166 env(check::cash(alice, checkId, XRP(100)), ter(
temDISABLED));
169 env(check::cancel(alice, checkId), ter(
temDISABLED));
177 env.fund(XRP(1000), alice);
181 env(check::create(env.master, alice, XRP(100)));
184 env(check::cash(alice, checkId1, XRP(100)));
189 env(check::create(env.master, alice, XRP(100)));
192 env(check::cancel(alice, checkId2));
201 testcase(
"Create valid");
203 using namespace test::jtx;
205 Account
const gw{
"gateway"};
206 Account
const alice{
"alice"};
207 Account
const bob{
"bob"};
208 IOU
const USD{gw[
"USD"]};
212 STAmount const startBalance{XRP(1000).value()};
213 env.fund(startBalance, gw, alice, bob);
218 auto writeTwoChecks = [&env, &USD,
this](
219 Account
const& from, Account
const& to) {
226 env(check::create(from, to, XRP(2000)));
229 env(check::create(from, to, USD(50)));
235 env.require(owners(from, fromOwnerCount + 2));
237 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
240 writeTwoChecks(alice, bob);
241 writeTwoChecks(gw, alice);
242 writeTwoChecks(alice, gw);
248 using namespace std::chrono_literals;
251 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
254 env(check::create(alice, bob, USD(50)), source_tag(2));
256 env(check::create(alice, bob, USD(50)), dest_tag(3));
258 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
260 env(check::create(alice, bob, USD(50)),
261 expiration(env.now() + 1s),
272 env(regkey(alice, alie));
277 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
281 env(check::create(alice, bob, USD(50)), sig(alie));
287 XRPAmount const baseFeeDrops{env.current()->fees().base};
288 env(check::create(alice, bob, USD(50)),
290 fee(3 * baseFeeDrops));
300 testcase(
"Create invalid");
302 using namespace test::jtx;
304 Account
const gw1{
"gateway1"};
305 Account
const gwF{
"gatewayFrozen"};
306 Account
const alice{
"alice"};
307 Account
const bob{
"bob"};
308 IOU
const USD{gw1[
"USD"]};
312 STAmount const startBalance{XRP(1000).value()};
313 env.fund(startBalance, gw1, gwF, alice, bob);
316 env(check::create(alice, bob, USD(50)),
322 env(check::create(alice, bob, USD(50)),
328 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
332 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
335 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
338 env(check::create(alice, bob, drops(1)));
347 env(check::create(alice, bob, USD(1)));
356 env(check::create(alice, bob, USD(50)),
362 Account
const bogie{
"bogie"};
363 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
373 env(check::create(alice, bob, USD(50)), dest_tag(11));
380 IOU
const USF{gwF[
"USF"]};
384 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
390 env(check::create(alice, bob, USF(50)));
396 env.trust(USD(1000), alice);
397 env.trust(USD(1000), bob);
399 env(pay(gw1, alice, USD(25)));
400 env(pay(gw1, bob, USD(25)));
408 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
412 env(check::create(bob, alice, USD(50)));
414 env(pay(bob, alice, USD(1)));
416 env(check::create(gw1, alice, USD(50)));
418 env(pay(gw1, alice, USD(1)));
424 env(check::create(alice, bob, USD(50)));
426 env(check::create(bob, alice, USD(50)));
428 env(check::create(gw1, alice, USD(50)));
436 env(check::create(alice, bob, USD(50)));
438 env(pay(alice, bob, USD(1)));
440 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
444 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
455 env(check::create(alice, bob, USD(50)),
456 expiration(env.now()),
460 using namespace std::chrono_literals;
461 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
465 Account
const cheri{
"cheri"};
466 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
468 env(check::create(cheri, bob, USD(50)),
469 fee(drops(env.current()->fees().base)),
473 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
476 env(check::create(cheri, bob, USD(50)));
484 testcase(
"Cash XRP");
486 using namespace test::jtx;
488 Account
const alice{
"alice"};
489 Account
const bob{
"bob"};
493 XRPAmount const baseFeeDrops{env.current()->fees().base};
494 STAmount const startBalance{XRP(300).value()};
495 env.fund(startBalance, alice, bob);
499 env(check::create(alice, bob, XRP(10)));
501 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
502 env.require(balance(bob, startBalance));
508 env(check::cash(bob, chkId, XRP(10)));
511 balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
513 balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
520 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
521 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
523 env.require(balance(alice, startBalance));
524 env.require(balance(bob, startBalance));
528 STAmount const reserve{env.current()->fees().accountReserve(0)};
530 startBalance - reserve - drops(baseFeeDrops)};
532 env(check::create(alice, bob, checkAmount));
536 env(check::cash(bob, chkId, checkAmount + drops(1)),
540 bob, chkId, check::DeliverMin(checkAmount + drops(1))),
547 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
549 env.require(balance(alice, reserve));
551 bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
558 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
559 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
561 env.require(balance(alice, startBalance));
562 env.require(balance(bob, startBalance));
566 STAmount const reserve{env.current()->fees().accountReserve(0)};
568 startBalance - reserve - drops(baseFeeDrops - 1)};
570 env(check::create(alice, bob, checkAmount));
579 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
581 env.require(balance(alice, reserve));
583 bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
590 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
592 bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
594 env.require(balance(alice, startBalance));
595 env.require(balance(bob, startBalance));
603 testcase(
"Cash IOU");
605 using namespace test::jtx;
607 Account
const gw{
"gateway"};
608 Account
const alice{
"alice"};
609 Account
const bob{
"bob"};
610 IOU
const USD{gw[
"USD"]};
615 env.fund(XRP(1000), gw, alice, bob);
619 env(check::create(alice, bob, USD(10)));
627 env(trust(alice, USD(20)));
629 env(pay(gw, alice, USD(9.5)));
636 env(pay(gw, alice, USD(0.5)));
638 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_LINE));
642 env(trust(bob, USD(9.5)));
649 env(trust(bob, USD(10.5)));
655 env(check::cash(bob, chkId1, USD(10)));
657 env.require(balance(alice, USD(0)));
658 env.require(balance(bob, USD(10)));
665 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
669 env(pay(bob, alice, USD(7)));
673 env(check::create(alice, bob, USD(7)));
680 env(check::cash(bob, chkId2, USD(5)));
682 env.require(balance(alice, USD(2)));
683 env.require(balance(bob, USD(8)));
691 env(check::create(alice, bob, USD(2)));
694 env(check::create(alice, bob, USD(2)));
700 env(check::cash(bob, chkId4, USD(2)));
702 env.require(balance(alice, USD(0)));
703 env.require(balance(bob, USD(10)));
713 env.require(balance(alice, USD(0)));
714 env.require(balance(bob, USD(10)));
721 env(check::cancel(bob, chkId3));
723 env.require(balance(alice, USD(0)));
724 env.require(balance(bob, USD(10)));
734 env.fund(XRP(1000), gw, alice, bob);
736 env(trust(alice, USD(20)));
737 env(trust(bob, USD(20)));
739 env(pay(gw, alice, USD(8)));
744 env(check::create(alice, bob, USD(9)));
747 env(check::create(alice, bob, USD(8)));
750 env(check::create(alice, bob, USD(7)));
753 env(check::create(alice, bob, USD(6)));
758 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
763 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
765 env.require(balance(alice, USD(0)));
766 env.require(balance(bob, USD(8)));
773 env(pay(bob, alice, USD(7)));
778 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
780 env.require(balance(alice, USD(0)));
781 env.require(balance(bob, USD(8)));
788 env(pay(bob, alice, USD(8)));
793 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
795 env.require(balance(alice, USD(2)));
796 env.require(balance(bob, USD(6)));
804 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
806 env.require(balance(alice, USD(0)));
807 env.require(balance(bob, USD(8)));
817 env.fund(XRP(1000), gw, alice, bob);
820 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
821 env(trust(alice, USD(20)));
823 env(pay(gw, alice, USD(8)));
829 env(check::create(alice, bob, USD(7)));
832 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_LINE));
837 env(trust(bob, USD(5)));
840 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
844 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
854 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
856 env.require(balance(alice, USD(3)));
857 env.require(balance(bob, USD(5)));
868 for (
auto const features :
872 Env env{*
this, features};
874 env.fund(XRP(1000), gw, alice, bob);
878 env(check::create(alice, bob, USD(1)));
882 env(check::create(alice, bob, USD(2)));
885 env(trust(alice, USD(20)));
886 env(trust(bob, USD(20)));
888 env(pay(gw, alice, USD(8)));
893 env(regkey(bob, bobby));
898 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
904 BEAST_EXPECT(
ownerCount(env, bob) == signersCount + 1);
907 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
909 env.require(balance(alice, USD(7)));
910 env.require(balance(bob, USD(1)));
914 BEAST_EXPECT(
ownerCount(env, bob) == signersCount + 1);
917 XRPAmount const baseFeeDrops{env.current()->fees().base};
918 env(check::cash(bob, chkId2, (USD(2))),
920 fee(3 * baseFeeDrops));
922 env.require(balance(alice, USD(5)));
923 env.require(balance(bob, USD(3)));
927 BEAST_EXPECT(
ownerCount(env, bob) == signersCount + 1);
935 testcase(
"Cash with transfer fee");
937 using namespace test::jtx;
939 Account
const gw{
"gateway"};
940 Account
const alice{
"alice"};
941 Account
const bob{
"bob"};
942 IOU
const USD{gw[
"USD"]};
946 env.fund(XRP(1000), gw, alice, bob);
948 env(trust(alice, USD(1000)));
949 env(trust(bob, USD(1000)));
951 env(pay(gw, alice, USD(1000)));
961 env(check::create(alice, bob, USD(125)));
968 env(check::create(alice, bob, USD(120)));
974 env(check::cash(bob, chkId125, check::DeliverMin(USD(101))),
980 env(check::cash(bob, chkId125, check::DeliverMin(USD(75))));
982 env.require(balance(alice, USD(1000 - 125)));
983 env.require(balance(bob, USD(0 + 100)));
993 env(check::cash(bob, chkId120, USD(50)));
995 env.require(balance(alice, USD(1000 - 125 - 60)));
996 env.require(balance(bob, USD(0 + 100 + 50)));
1005 testcase(
"Cash quality");
1007 using namespace test::jtx;
1009 Account
const gw{
"gateway"};
1010 Account
const alice{
"alice"};
1011 Account
const bob{
"bob"};
1012 IOU
const USD{gw[
"USD"]};
1016 env.fund(XRP(1000), gw, alice, bob);
1018 env(trust(alice, USD(1000)));
1019 env(trust(bob, USD(1000)));
1021 env(pay(gw, alice, USD(1000)));
1029 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1030 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1034 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1035 Account
const& truster,
1037 auto const& inOrOut,
1041 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1042 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1045 env(trust(truster, iou(1000)), inOrOut(pct));
1048 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1050 env.require(balance(alice, aliceStart - USD(10)));
1051 env.require(balance(bob, bobStart + USD(10)));
1055 env(trust(truster, iou(1000)), inOrOut(0));
1059 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1060 Account
const& truster,
1062 auto const& inOrOut,
1066 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1067 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1070 env(trust(truster, iou(1000)), inOrOut(pct));
1074 env(check::create(alice, bob, USD(10)));
1077 env(check::cash(bob, chkId, USD(amount)));
1079 env.require(balance(alice, aliceStart - USD(10)));
1080 env.require(balance(bob, bobStart + USD(10)));
1084 env(trust(truster, iou(1000)), inOrOut(0));
1089 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1090 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1093 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1094 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1096 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1097 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1099 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1100 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1102 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1103 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1105 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1106 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1108 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1109 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1111 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1112 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1119 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1120 Account
const& truster,
1122 auto const& inOrOut,
1130 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1133 env(trust(truster, iou(1000)), inOrOut(pct));
1137 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1139 env.require(balance(alice, aliceStart - USD(10)));
1142 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1144 env.require(balance(alice, aliceStart));
1148 env(trust(truster, iou(1000)), inOrOut(0));
1152 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1153 Account
const& truster,
1155 auto const& inOrOut,
1163 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1166 env(trust(truster, iou(1000)), inOrOut(pct));
1171 env(check::create(alice, gw, USD(max1)));
1174 env(check::cash(gw, chkAliceId, USD(amt1)));
1176 env.require(balance(alice, aliceStart - USD(10)));
1180 env(check::create(gw, alice, USD(max2)));
1183 env(check::cash(alice, chkGwId, USD(amt2)));
1185 env.require(balance(alice, aliceStart));
1189 env(trust(truster, iou(1000)), inOrOut(0));
1195 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1196 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1198 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1199 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1201 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1202 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1204 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1205 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1212 testcase(
"Cash invalid");
1214 using namespace test::jtx;
1216 Account
const gw{
"gateway"};
1217 Account
const alice{
"alice"};
1218 Account
const bob{
"bob"};
1219 Account
const zoe{
"zoe"};
1220 IOU
const USD{gw[
"USD"]};
1224 env.fund(XRP(1000), gw, alice, bob, zoe);
1227 env(trust(alice, USD(20)));
1229 env(pay(gw, alice, USD(20)));
1236 env(check::create(alice, bob, USD(20)));
1239 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_LINE));
1244 env(trust(bob, USD(20)));
1250 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1256 env(check::create(alice, bob, USD(20)));
1260 env(check::create(alice, bob, XRP(10)));
1263 using namespace std::chrono_literals;
1265 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1269 env(check::create(alice, bob, USD(1)));
1273 env(check::create(alice, bob, USD(2)));
1277 env(check::create(alice, bob, USD(3)));
1281 env(check::create(alice, bob, USD(4)));
1285 env(check::create(alice, bob, USD(1)));
1289 env(check::create(alice, bob, USD(2)), dest_tag(7));
1293 auto failingCases = [&env, &gw, &alice, &bob](
1296 env(check::cash(bob, chkId, amount),
1302 env(check::cash(bob, chkId, amount),
1328 env(check::cash(bob, chkId, amount.zeroed()),
1334 if (!amount.native())
1351 IOU
const wrongCurrency{gw[
"EUR"]};
1353 badAmount.
setIssue(wrongCurrency.issue());
1354 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1360 IOU
const wrongIssuer{alice[
"USD"]};
1362 badAmount.
setIssue(wrongIssuer.issue());
1363 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1372 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1377 failingCases(chkIdX, XRP(10));
1378 failingCases(chkIdU, USD(20));
1381 env(check::cash(bob, chkIdU, USD(20)));
1383 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1387 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1391 env(check::cancel(zoe, chkIdExp));
1396 env(pay(bob, alice, USD(20)));
1398 env.require(balance(alice, USD(20)));
1399 env.require(balance(bob, USD(0)));
1407 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1415 env(check::cash(bob, chkIdFroz1, USD(1)));
1417 env.require(balance(alice, USD(19)));
1418 env.require(balance(bob, USD(1)));
1425 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1432 env(check::cash(bob, chkIdFroz2, USD(2)));
1434 env.require(balance(alice, USD(17)));
1435 env.require(balance(bob, USD(3)));
1440 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1442 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1449 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1451 env.require(balance(alice, USD(14)));
1452 env.require(balance(bob, USD(6)));
1458 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1460 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1467 env(check::cash(bob, chkIdFroz4, USD(4)));
1469 env.require(balance(alice, USD(10)));
1470 env.require(balance(bob, USD(10)));
1479 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1484 env(check::cash(bob, chkIdHasDest2, USD(2)));
1486 env.require(balance(alice, USD(8)));
1487 env.require(balance(bob, USD(12)));
1493 env(check::cash(bob, chkIdNoDest1, USD(1)));
1495 env.require(balance(alice, USD(7)));
1496 env.require(balance(bob, USD(13)));
1504 testcase(
"Cancel valid");
1506 using namespace test::jtx;
1508 Account
const gw{
"gateway"};
1509 Account
const alice{
"alice"};
1510 Account
const bob{
"bob"};
1511 Account
const zoe{
"zoe"};
1512 IOU
const USD{gw[
"USD"]};
1517 for (
auto const features :
1521 Env env{*
this, features};
1523 env.fund(XRP(1000), gw, alice, bob, zoe);
1528 env(check::create(alice, bob, USD(10)));
1532 env(check::create(alice, bob, XRP(10)));
1536 env(check::create(alice, bob, USD(10)));
1540 using namespace std::chrono_literals;
1542 env(check::create(alice, bob, XRP(10)),
1543 expiration(env.now() + 600s));
1547 env(check::create(alice, bob, USD(10)),
1548 expiration(env.now() + 600s));
1552 env(check::create(alice, bob, XRP(10)),
1553 expiration(env.now() + 600s));
1558 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1562 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1566 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1571 env(check::create(alice, bob, USD(10)));
1575 env(check::create(alice, bob, XRP(10)));
1581 env(check::cancel(alice, chkId1));
1586 env(check::cancel(bob, chkId2));
1597 env(check::cancel(alice, chkIdNotExp1));
1602 env(check::cancel(bob, chkIdNotExp2));
1613 env(check::cancel(alice, chkIdExp1));
1618 env(check::cancel(bob, chkIdExp2));
1623 env(check::cancel(zoe, chkIdExp3));
1630 env(regkey(alice, alie));
1635 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1643 env(check::cancel(alice, chkIdReg), sig(alie));
1646 BEAST_EXPECT(
ownerCount(env, alice) == signersCount + 3);
1649 XRPAmount const baseFeeDrops{env.current()->fees().base};
1650 env(check::cancel(alice, chkIdMSig),
1652 fee(3 * baseFeeDrops));
1655 BEAST_EXPECT(
ownerCount(env, alice) == signersCount + 2);
1658 env(check::cancel(alice, chkId3), sig(alice));
1661 BEAST_EXPECT(
ownerCount(env, alice) == signersCount + 1);
1663 env(check::cancel(bob, chkIdNotExp3));
1666 BEAST_EXPECT(
ownerCount(env, alice) == signersCount + 0);
1674 testcase(
"Cancel invalid");
1676 using namespace test::jtx;
1678 Account
const alice{
"alice"};
1679 Account
const bob{
"bob"};
1683 env.fund(XRP(1000), alice, bob);
1686 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1692 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1698 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1706 testcase(
"Fix1623 enable");
1708 using namespace test::jtx;
1710 auto testEnable = [
this](
1715 Account
const alice{
"alice"};
1716 Account
const bob{
"bob"};
1718 Env env{*
this, features};
1720 env.fund(XRP(1000), alice, bob);
1724 env(check::create(alice, bob, XRP(200)));
1727 env(check::cash(bob, chkId, check::DeliverMin(XRP(100))));
1737 env.rpc(
"tx", txHash)[jss::result][jss::meta];
1741 BEAST_EXPECT(meta.
isMember(jss::delivered_amount) == hasFields);
1745 testEnable(supported_amendments() -
fix1623,
false);
1746 testEnable(supported_amendments(),
true);
1752 testcase(
"With Tickets");
1754 using namespace test::jtx;
1756 Account
const gw{
"gw"};
1757 Account
const alice{
"alice"};
1758 Account
const bob{
"bob"};
1759 IOU
const USD{gw[
"USD"]};
1762 env.fund(XRP(1000), gw, alice, bob);
1769 env(ticket::create(alice, 10));
1773 env(ticket::create(bob, 10));
1777 env.require(owners(alice, 10));
1778 env.require(owners(bob, 10));
1781 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1782 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1784 env.require(owners(alice, 10));
1785 env.require(owners(bob, 10));
1787 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1788 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1790 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1791 BEAST_EXPECT(env.seq(bob) == bobSeq);
1793 env(pay(gw, alice, USD(900)));
1799 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1802 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1805 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1808 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1812 env.require(owners(alice, 10));
1813 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1815 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1817 env.require(owners(bob, 10));
1818 BEAST_EXPECT(env.seq(bob) == bobSeq);
1821 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1822 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1825 env.require(owners(alice, 8));
1826 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1828 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1830 env.require(owners(bob, 8));
1831 BEAST_EXPECT(env.seq(bob) == bobSeq);
1834 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1835 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1838 env.require(owners(alice, 6));
1839 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1841 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1842 env.require(balance(alice, USD(700)));
1843 env.require(balance(alice, drops(699
'999'940)));
1845 env.require(owners(bob, 6));
1846 BEAST_EXPECT(env.seq(bob) == bobSeq);
1847 env.require(balance(bob, USD(200)));
1848 env.require(balance(bob, drops(1
'299'999
'940)));
1857 testCreateInvalid();
1864 testCancelInvalid();
1865 testFix1623Enable();
1870 BEAST_DEFINE_TESTSUITE(Check, tx, ripple);
1872 } // namespace ripple