150 using namespace test::jtx;
152 Account
const gw{
"gateway"};
153 Account
const alice{
"alice"};
154 Account
const bob{
"bob"};
155 IOU
const USD{gw[
"USD"]};
157 Env env{*
this, features};
159 STAmount const startBalance{XRP(1000).value()};
160 env.fund(startBalance, gw, alice, bob);
166 auto writeTwoChecks = [&env, &USD,
this](Account
const& from, Account
const& to) {
173 env(check::create(from, to, XRP(2000)));
176 env(check::create(from, to, USD(50)));
182 env.require(owners(from, fromOwnerCount + 2));
183 env.require(owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
186 writeTwoChecks(alice, bob);
187 writeTwoChecks(gw, alice);
188 writeTwoChecks(alice, gw);
194 using namespace std::chrono_literals;
197 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
200 env(check::create(alice, bob, USD(50)), source_tag(2));
202 env(check::create(alice, bob, USD(50)), dest_tag(3));
204 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
206 env(check::create(alice, bob, USD(50)),
207 expiration(env.now() + 1s),
218 env(regkey(alice, alie));
223 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
227 env(check::create(alice, bob, USD(50)), sig(alie));
233 XRPAmount const baseFeeDrops{env.current()->fees().base};
234 env(check::create(alice, bob, USD(50)), msig(bogie, demon), fee(3 * baseFeeDrops));
325 using namespace test::jtx;
327 Account
const gw1{
"gateway1"};
328 Account
const gwF{
"gatewayFrozen"};
329 Account
const alice{
"alice"};
330 Account
const bob{
"bob"};
331 IOU
const USD{gw1[
"USD"]};
333 Env env{*
this, features};
335 STAmount const startBalance{XRP(1000).value()};
336 env.fund(startBalance, gw1, gwF, alice, bob);
340 env(check::create(alice, bob, USD(50)), fee(drops(-10)), ter(
temBAD_FEE));
344 env(check::create(alice, bob, USD(50)), txflags(tfImmediateOrCancel), ter(
temINVALID_FLAG));
348 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
352 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
355 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
358 env(check::create(alice, bob, drops(1)));
367 env(check::create(alice, bob, USD(1)));
376 env(check::create(alice, bob, USD(50)),
382 Account
const bogie{
"bogie"};
383 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
387 env(fset(bob, asfRequireDest));
393 env(check::create(alice, bob, USD(50)), dest_tag(11));
396 env(fclear(bob, asfRequireDest));
400 IOU
const USF{gwF[
"USF"]};
401 env(fset(gwF, asfGlobalFreeze));
404 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
407 env(fclear(gwF, asfGlobalFreeze));
410 env(check::create(alice, bob, USF(50)));
416 env.trust(USD(1000), alice);
417 env.trust(USD(1000), bob);
419 env(pay(gw1, alice, USD(25)));
420 env(pay(gw1, bob, USD(25)));
426 env(trust(gw1, alice[
"USD"](0), tfSetFreeze));
428 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
432 env(check::create(bob, alice, USD(50)));
434 env(pay(bob, alice, USD(1)));
436 env(check::create(gw1, alice, USD(50)));
438 env(pay(gw1, alice, USD(1)));
442 env(trust(gw1, alice[
"USD"](0), tfClearFreeze));
444 env(check::create(alice, bob, USD(50)));
446 env(check::create(bob, alice, USD(50)));
448 env(check::create(gw1, alice, USD(50)));
454 env(trust(alice, USD(0), tfSetFreeze));
456 env(check::create(alice, bob, USD(50)));
458 env(pay(alice, bob, USD(1)));
460 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
464 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
470 env(trust(alice, USD(0), tfClearFreeze));
475 env(check::create(alice, bob, USD(50)), expiration(env.now()), ter(
tecEXPIRED));
478 using namespace std::chrono_literals;
479 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
483 Account
const cheri{
"cheri"};
484 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
487 env(check::create(cheri, bob, USD(50)),
488 fee(drops(env.current()->fees().base)),
492 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
495 env(check::create(cheri, bob, USD(50)));
505 using namespace test::jtx;
507 Account
const alice{
"alice"};
508 Account
const bob{
"bob"};
510 Env env{*
this, features};
512 XRPAmount const baseFeeDrops{env.current()->fees().base};
513 STAmount const startBalance{XRP(300).value()};
514 env.fund(startBalance, alice, bob);
519 env(check::create(alice, bob, XRP(10)));
521 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
522 env.require(balance(bob, startBalance));
525 BEAST_EXPECT(ownerCount(env, alice) == 1);
526 BEAST_EXPECT(ownerCount(env, bob) == 0);
528 env(check::cash(bob, chkId, XRP(10)));
530 env.require(balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
531 env.require(balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
534 BEAST_EXPECT(ownerCount(env, alice) == 0);
535 BEAST_EXPECT(ownerCount(env, bob) == 0);
538 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
539 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
541 env.require(balance(alice, startBalance));
542 env.require(balance(bob, startBalance));
546 STAmount const reserve{env.current()->fees().reserve};
547 STAmount const checkAmount{startBalance - reserve - drops(baseFeeDrops)};
549 env(check::create(alice, bob, checkAmount));
553 env(check::cash(bob, chkId, checkAmount + drops(1)), ter(
tecPATH_PARTIAL));
555 env(check::cash(bob, chkId, check::DeliverMin(checkAmount + drops(1))),
562 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
564 env.require(balance(alice, reserve));
565 env.require(balance(bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
568 BEAST_EXPECT(ownerCount(env, alice) == 0);
569 BEAST_EXPECT(ownerCount(env, bob) == 0);
572 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
573 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
575 env.require(balance(alice, startBalance));
576 env.require(balance(bob, startBalance));
580 STAmount const reserve{env.current()->fees().reserve};
581 STAmount const checkAmount{startBalance - reserve - drops(baseFeeDrops - 1)};
583 env(check::create(alice, bob, checkAmount));
592 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
594 env.require(balance(alice, reserve));
595 env.require(balance(bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
598 BEAST_EXPECT(ownerCount(env, alice) == 0);
599 BEAST_EXPECT(ownerCount(env, bob) == 0);
602 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
603 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
605 env.require(balance(alice, startBalance));
606 env.require(balance(bob, startBalance));
616 using namespace test::jtx;
618 Account
const gw{
"gateway"};
619 Account
const alice{
"alice"};
620 Account
const bob{
"bob"};
621 IOU
const USD{gw[
"USD"]};
624 Env env{*
this, features};
626 env.fund(XRP(1000), gw, alice, bob);
631 env(check::create(alice, bob, USD(10)));
639 env(trust(alice, USD(20)));
641 env(pay(gw, alice, USD(9.5)));
648 env(pay(gw, alice, USD(0.5)));
652 env(trust(bob, USD(9.5)));
657 env(trust(bob, USD(10.5)));
663 env(check::cash(bob, chkId1, USD(10)));
665 env.require(balance(alice, USD(0)));
666 env.require(balance(bob, USD(10)));
669 BEAST_EXPECT(ownerCount(env, alice) == 1);
670 BEAST_EXPECT(ownerCount(env, bob) == 1);
673 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
677 env(pay(bob, alice, USD(7)));
681 env(check::create(alice, bob, USD(7)));
688 env(check::cash(bob, chkId2, USD(5)));
690 env.require(balance(alice, USD(2)));
691 env.require(balance(bob, USD(8)));
694 BEAST_EXPECT(ownerCount(env, alice) == 1);
695 BEAST_EXPECT(ownerCount(env, bob) == 1);
699 env(check::create(alice, bob, USD(2)));
702 env(check::create(alice, bob, USD(2)));
708 env(check::cash(bob, chkId4, USD(2)));
710 env.require(balance(alice, USD(0)));
711 env.require(balance(bob, USD(10)));
714 BEAST_EXPECT(ownerCount(env, alice) == 2);
715 BEAST_EXPECT(ownerCount(env, bob) == 1);
721 env.require(balance(alice, USD(0)));
722 env.require(balance(bob, USD(10)));
725 BEAST_EXPECT(ownerCount(env, alice) == 2);
726 BEAST_EXPECT(ownerCount(env, bob) == 1);
742 env(check::create(gw, bob, USD(20)));
746 env(check::cash(bob, chkId20, USD(20)));
748 env.require(balance(bob, USD(30)));
752 env(pay(bob, gw, USD(20)));
755 env(check::cancel(bob, chkId3));
757 env.require(balance(alice, USD(0)));
758 env.require(balance(bob, USD(10)));
761 BEAST_EXPECT(ownerCount(env, alice) == 1);
762 BEAST_EXPECT(ownerCount(env, bob) == 1);
766 Env env{*
this, features};
768 env.fund(XRP(1000), gw, alice, bob);
771 env(trust(alice, USD(20)));
772 env(trust(bob, USD(20)));
774 env(pay(gw, alice, USD(8)));
779 env(check::create(alice, bob, USD(9)));
782 env(check::create(alice, bob, USD(8)));
785 env(check::create(alice, bob, USD(7)));
788 env(check::create(alice, bob, USD(6)));
793 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))), ter(
tecPATH_PARTIAL));
797 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
799 env.require(balance(alice, USD(0)));
800 env.require(balance(bob, USD(8)));
803 BEAST_EXPECT(ownerCount(env, alice) == 4);
804 BEAST_EXPECT(ownerCount(env, bob) == 1);
807 env(pay(bob, alice, USD(7)));
812 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
814 env.require(balance(alice, USD(0)));
815 env.require(balance(bob, USD(8)));
818 BEAST_EXPECT(ownerCount(env, alice) == 3);
819 BEAST_EXPECT(ownerCount(env, bob) == 1);
822 env(pay(bob, alice, USD(8)));
827 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
829 env.require(balance(alice, USD(2)));
830 env.require(balance(bob, USD(6)));
833 BEAST_EXPECT(ownerCount(env, alice) == 2);
834 BEAST_EXPECT(ownerCount(env, bob) == 1);
838 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
840 env.require(balance(alice, USD(0)));
841 env.require(balance(bob, USD(8)));
844 BEAST_EXPECT(ownerCount(env, alice) == 1);
845 BEAST_EXPECT(ownerCount(env, bob) == 1);
849 Env env(*
this, features);
851 env.fund(XRP(1000), gw, alice, bob);
852 env(fset(gw, asfRequireAuth));
854 env(trust(gw, alice[
"USD"](100)), txflags(tfSetfAuth));
855 env(trust(alice, USD(20)));
857 env(pay(gw, alice, USD(8)));
863 env(check::create(alice, bob, USD(7)));
866 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
871 env(trust(bob, USD(5)));
874 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
878 env(trust(gw, bob[
"USD"](1)), txflags(tfSetfAuth));
888 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
891 env.require(balance(alice, USD(8) - bobGot));
892 env.require(balance(bob, bobGot));
896 BEAST_EXPECT(ownerCount(env, alice) == 1);
897 BEAST_EXPECT(ownerCount(env, bob) == 1);
902 Env env{*
this, features};
903 env.fund(XRP(1000), gw, alice, bob);
908 env(check::create(alice, bob, USD(1)));
912 env(check::create(alice, bob, USD(2)));
915 env(trust(alice, USD(20)));
916 env(trust(bob, USD(20)));
918 env(pay(gw, alice, USD(8)));
923 env(regkey(bob, bobby));
928 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
931 BEAST_EXPECT(ownerCount(env, bob) == 2);
934 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
936 env.require(balance(alice, USD(7)));
937 env.require(balance(bob, USD(1)));
940 BEAST_EXPECT(ownerCount(env, alice) == 2);
941 BEAST_EXPECT(ownerCount(env, bob) == 2);
944 XRPAmount const baseFeeDrops{env.current()->fees().base};
945 env(check::cash(bob, chkId2, (USD(2))), msig(bogie, demon), fee(3 * baseFeeDrops));
947 env.require(balance(alice, USD(5)));
948 env.require(balance(bob, USD(3)));
951 BEAST_EXPECT(ownerCount(env, alice) == 1);
952 BEAST_EXPECT(ownerCount(env, bob) == 2);
1032 using namespace test::jtx;
1034 Account
const gw{
"gateway"};
1035 Account
const alice{
"alice"};
1036 Account
const bob{
"bob"};
1037 IOU
const USD{gw[
"USD"]};
1039 Env env{*
this, features};
1041 env.fund(XRP(1000), gw, alice, bob);
1044 env(trust(alice, USD(1000)));
1045 env(trust(bob, USD(1000)));
1047 env(pay(gw, alice, USD(1000)));
1055 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1056 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1060 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1061 Account
const& truster,
1063 auto const& inOrOut,
1067 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1068 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1071 env(trust(truster, iou(1000)), inOrOut(pct));
1074 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1076 env.require(balance(alice, aliceStart - USD(10)));
1077 env.require(balance(bob, bobStart + USD(10)));
1081 env(trust(truster, iou(1000)), inOrOut(0));
1085 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1086 Account
const& truster,
1088 auto const& inOrOut,
1092 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1093 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1096 env(trust(truster, iou(1000)), inOrOut(pct));
1100 env(check::create(alice, bob, USD(10)));
1103 env(check::cash(bob, chkId, USD(amount)));
1105 env.require(balance(alice, aliceStart - USD(10)));
1106 env.require(balance(bob, bobStart + USD(10)));
1110 env(trust(truster, iou(1000)), inOrOut(0));
1115 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1116 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1119 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1120 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1122 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1123 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1125 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1126 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1128 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1129 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1131 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1132 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1134 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1135 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1137 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1138 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1145 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1146 Account
const& truster,
1148 auto const& inOrOut,
1156 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1159 env(trust(truster, iou(1000)), inOrOut(pct));
1163 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1165 env.require(balance(alice, aliceStart - USD(10)));
1168 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1170 env.require(balance(alice, aliceStart));
1174 env(trust(truster, iou(1000)), inOrOut(0));
1178 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1179 Account
const& truster,
1181 auto const& inOrOut,
1189 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1192 env(trust(truster, iou(1000)), inOrOut(pct));
1197 env(check::create(alice, gw, USD(max1)));
1200 env(check::cash(gw, chkAliceId, USD(amt1)));
1202 env.require(balance(alice, aliceStart - USD(10)));
1206 env(check::create(gw, alice, USD(max2)));
1209 env(check::cash(alice, chkGwId, USD(amt2)));
1211 env.require(balance(alice, aliceStart));
1215 env(trust(truster, iou(1000)), inOrOut(0));
1221 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1222 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1224 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1225 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1227 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1228 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1230 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1231 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1240 using namespace test::jtx;
1242 Account
const gw{
"gateway"};
1243 Account
const alice{
"alice"};
1244 Account
const bob{
"bob"};
1245 Account
const zoe{
"zoe"};
1246 IOU
const USD{gw[
"USD"]};
1248 Env env(*
this, features);
1250 env.fund(XRP(1000), gw, alice, bob, zoe);
1254 env(trust(alice, USD(20)));
1256 env(pay(gw, alice, USD(20)));
1260 env(trust(bob, USD(20)));
1266 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1272 env(check::create(alice, bob, USD(20)));
1276 env(check::create(alice, bob, XRP(10)));
1279 using namespace std::chrono_literals;
1281 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1285 env(check::create(alice, bob, USD(1)));
1289 env(check::create(alice, bob, USD(2)));
1293 env(check::create(alice, bob, USD(3)));
1297 env(check::create(alice, bob, USD(4)));
1301 env(check::create(alice, bob, USD(1)));
1305 env(check::create(alice, bob, USD(2)), dest_tag(7));
1309 auto failingCases = [&env, &gw, &alice, &bob](
1312 env(check::cash(bob, chkId, amount), fee(drops(-10)), ter(
temBAD_FEE));
1316 env(check::cash(bob, chkId, amount),
1317 txflags(tfImmediateOrCancel),
1342 env(check::cash(bob, chkId, amount.zeroed()), ter(
temBAD_AMOUNT));
1347 if (!amount.native())
1364 IOU
const wrongCurrency{gw[
"EUR"]};
1366 badAmount.setIssue(wrongCurrency.issue());
1367 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1373 IOU
const wrongIssuer{alice[
"USD"]};
1375 badAmount.setIssue(wrongIssuer.issue());
1376 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1385 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)), ter(
tecPATH_PARTIAL));
1389 failingCases(chkIdX, XRP(10));
1390 failingCases(chkIdU, USD(20));
1393 env(check::cash(bob, chkIdU, USD(20)));
1395 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1399 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1403 env(check::cancel(zoe, chkIdExp));
1408 env(pay(bob, alice, USD(20)));
1410 env.require(balance(alice, USD(20)));
1411 env.require(balance(bob, USD(0)));
1414 env(fset(gw, asfGlobalFreeze));
1419 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))), ter(
tecPATH_PARTIAL));
1422 env(fclear(gw, asfGlobalFreeze));
1426 env(check::cash(bob, chkIdFroz1, USD(1)));
1428 env.require(balance(alice, USD(19)));
1429 env.require(balance(bob, USD(1)));
1432 env(trust(gw, alice[
"USD"](0), tfSetFreeze));
1436 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))), ter(
tecPATH_PARTIAL));
1440 env(trust(gw, alice[
"USD"](0), tfClearFreeze));
1442 env(check::cash(bob, chkIdFroz2, USD(2)));
1444 env.require(balance(alice, USD(17)));
1445 env.require(balance(bob, USD(3)));
1448 env(trust(gw, bob[
"USD"](0), tfSetFreeze));
1450 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1452 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))), ter(
tecFROZEN));
1456 env(trust(gw, bob[
"USD"](0), tfClearFreeze));
1458 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1460 env.require(balance(alice, USD(14)));
1461 env.require(balance(bob, USD(6)));
1465 env(trust(bob, USD(20), tfSetFreeze));
1467 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1469 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))), ter(
terNO_LINE));
1473 env(trust(bob, USD(20), tfClearFreeze));
1475 env(check::cash(bob, chkIdFroz4, USD(4)));
1477 env.require(balance(alice, USD(10)));
1478 env.require(balance(bob, USD(10)));
1483 env(fset(bob, asfRequireDest));
1487 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1492 env(check::cash(bob, chkIdHasDest2, USD(2)));
1494 env.require(balance(alice, USD(8)));
1495 env.require(balance(bob, USD(12)));
1499 env(fclear(bob, asfRequireDest));
1501 env(check::cash(bob, chkIdNoDest1, USD(1)));
1503 env.require(balance(alice, USD(7)));
1504 env.require(balance(bob, USD(13)));
1514 using namespace test::jtx;
1516 Account
const gw{
"gateway"};
1517 Account
const alice{
"alice"};
1518 Account
const bob{
"bob"};
1519 Account
const zoe{
"zoe"};
1520 IOU
const USD{gw[
"USD"]};
1523 Env env{*
this, features};
1525 env.fund(XRP(1000), gw, alice, bob, zoe);
1531 env(check::create(alice, bob, USD(10)));
1535 env(check::create(alice, bob, XRP(10)));
1539 env(check::create(alice, bob, USD(10)));
1543 using namespace std::chrono_literals;
1545 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 600s));
1549 env(check::create(alice, bob, USD(10)), expiration(env.now() + 600s));
1553 env(check::create(alice, bob, XRP(10)), 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)));
1578 BEAST_EXPECT(ownerCount(env, alice) == 11);
1581 env(check::cancel(alice, chkId1));
1584 BEAST_EXPECT(ownerCount(env, alice) == 10);
1586 env(check::cancel(bob, chkId2));
1589 BEAST_EXPECT(ownerCount(env, alice) == 9);
1594 BEAST_EXPECT(ownerCount(env, alice) == 9);
1597 env(check::cancel(alice, chkIdNotExp1));
1600 BEAST_EXPECT(ownerCount(env, alice) == 8);
1602 env(check::cancel(bob, chkIdNotExp2));
1605 BEAST_EXPECT(ownerCount(env, alice) == 7);
1610 BEAST_EXPECT(ownerCount(env, alice) == 7);
1613 env(check::cancel(alice, chkIdExp1));
1616 BEAST_EXPECT(ownerCount(env, alice) == 6);
1618 env(check::cancel(bob, chkIdExp2));
1621 BEAST_EXPECT(ownerCount(env, alice) == 5);
1623 env(check::cancel(zoe, chkIdExp3));
1626 BEAST_EXPECT(ownerCount(env, alice) == 4);
1630 env(regkey(alice, alie));
1635 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1639 env(check::cancel(alice, chkIdReg), sig(alie));
1642 BEAST_EXPECT(ownerCount(env, alice) == 4);
1645 XRPAmount const baseFeeDrops{env.current()->fees().base};
1646 env(check::cancel(alice, chkIdMSig), msig(bogie, demon), fee(3 * baseFeeDrops));
1649 BEAST_EXPECT(ownerCount(env, alice) == 3);
1652 env(check::cancel(alice, chkId3), sig(alice));
1655 BEAST_EXPECT(ownerCount(env, alice) == 2);
1657 env(check::cancel(bob, chkIdNotExp3));
1660 BEAST_EXPECT(ownerCount(env, alice) == 1);
1733 using namespace test::jtx;
1735 Account
const gw{
"gw"};
1736 Account
const alice{
"alice"};
1737 Account
const bob{
"bob"};
1738 IOU
const USD{gw[
"USD"]};
1740 Env env{*
this, features};
1741 env.fund(XRP(1000), gw, alice, bob);
1748 env(ticket::create(alice, 10));
1752 env(ticket::create(bob, 10));
1756 env.require(owners(alice, 10));
1757 env.require(owners(bob, 10));
1760 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1761 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1763 env.require(owners(alice, 10));
1764 env.require(owners(bob, 10));
1766 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1767 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1769 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1770 BEAST_EXPECT(env.seq(bob) == bobSeq);
1772 env(pay(gw, alice, USD(900)));
1778 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1781 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1784 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1787 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1791 env.require(owners(alice, 10));
1792 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1794 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1796 env.require(owners(bob, 10));
1797 BEAST_EXPECT(env.seq(bob) == bobSeq);
1800 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1801 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1804 env.require(owners(alice, 8));
1805 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1807 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1809 env.require(owners(bob, 8));
1810 BEAST_EXPECT(env.seq(bob) == bobSeq);
1813 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1814 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1817 env.require(owners(alice, 6));
1818 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1820 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1821 env.require(balance(alice, USD(700)));
1823 env.require(owners(bob, 6));
1824 BEAST_EXPECT(env.seq(bob) == bobSeq);
1825 env.require(balance(bob, USD(200)));
1836 using namespace test::jtx;
1838 Env env{*
this, features};
1852 ownerCount(env, acct) == owners,
"Owner count mismatch", __FILE__, line);
1856 operator Account()
const
1873 AccountOwns alice{*
this, env,
"alice", 0};
1874 AccountOwns bob{*
this, env,
"bob", 0};
1877 env.fund(XRP(5000), noripple(alice, bob));
1883 AccountOwns
const gw1{*
this, env,
"gw1", 0};
1888 env.fund(XRP(5000), noripple(gw1));
1891 IOU
const CK8 = gw1[
"CK8"];
1892 gw1.verifyOwners(__LINE__);
1894 Account
const yui{
"yui"};
1899 env.fund(XRP(200), yui);
1903 env(check::create(gw1, yui, CK8(99)));
1908 alice.verifyOwners(__LINE__);
1912 env(pay(env.master, yui, XRP(51)));
1914 env(check::cash(yui, chkId, CK8(99)));
1917 BEAST_EXPECT(ownerCount(env, yui) == 1);
1921 gw1.verifyOwners(__LINE__);
1936 auto cmpTrustLines = [
this, &env](
1937 Account
const& acct1,
1938 Account
const& acct2,
1939 IOU
const& offerIou,
1940 IOU
const& checkIou) {
1941 auto const offerLine = env.le(
keylet::line(acct1, acct2, offerIou.currency));
1942 auto const checkLine = env.le(
keylet::line(acct1, acct2, checkIou.currency));
1943 if (offerLine ==
nullptr || checkLine ==
nullptr)
1945 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
1951 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
1955 auto cmpReqAmount = [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
1956 STAmount const offerAmount = offerLine->at(sfield);
1957 STAmount const checkAmount = checkLine->at(sfield);
1960 if (!BEAST_EXPECT(!offerAmount.
native() && !checkAmount.
native()))
1968 cmpReqAmount(sfBalance);
1969 cmpReqAmount(sfLowLimit);
1970 cmpReqAmount(sfHighLimit);
1974 auto cmpOptField = [
this, offerLine, checkLine](
auto const& sfield) {
1977 offerLine->isFieldPresent(sfield) == checkLine->isFieldPresent(sfield)))
1982 if (!offerLine->isFieldPresent(sfield))
1987 BEAST_EXPECT(offerLine->at(sfield) == checkLine->at(sfield));
1989 cmpOptField(sfLowNode);
1990 cmpOptField(sfLowQualityIn);
1991 cmpOptField(sfLowQualityOut);
1993 cmpOptField(sfHighNode);
1994 cmpOptField(sfHighQualityIn);
1995 cmpOptField(sfHighQualityOut);
2003 AccountOwns
const gw1{*
this, env,
"gw1", 0};
2005 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2006 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2007 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2010 IOU
const OF1 = gw1[
"OF1"];
2011 env(offer(gw1, XRP(98), OF1(98)));
2013 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2014 env(offer(alice, OF1(98), XRP(98)));
2021 gw1.verifyOwners(__LINE__);
2024 alice.verifyOwners(__LINE__);
2027 IOU
const CK1 = gw1[
"CK1"];
2029 env(check::create(gw1, alice, CK1(98)));
2031 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2032 env(check::cash(alice, chkId, CK1(98)));
2040 gw1.verifyOwners(__LINE__);
2043 alice.verifyOwners(__LINE__);
2045 cmpTrustLines(gw1, alice, OF1, CK1);
2056 AccountOwns
const gw1{*
this, env,
"gw1", 0};
2057 IOU
const OF1 = gw1[
"OF1"];
2058 env(offer(alice, XRP(97), OF1(97)));
2060 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2061 env(offer(bob, OF1(97), XRP(97)));
2066 env.require(balance(alice, OF1(1)));
2067 env.require(balance(bob, OF1(97)));
2070 gw1.verifyOwners(__LINE__);
2071 alice.verifyOwners(__LINE__);
2072 bob.verifyOwners(__LINE__);
2080 IOU
const CK1 = gw1[
"CK1"];
2082 env(check::create(alice, bob, CK1(97)));
2084 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2085 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2088 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2089 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2092 env(check::cancel(alice, chkId));
2096 gw1.verifyOwners(__LINE__);
2097 alice.verifyOwners(__LINE__);
2098 bob.verifyOwners(__LINE__);
2105 AccountOwns
const gw1{*
this, env,
"gw1", 0};
2106 env(fset(gw1, asfDefaultRipple));
2110 IOU
const OF2 = gw1[
"OF2"];
2111 env(offer(gw1, XRP(96), OF2(96)));
2113 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2114 env(offer(alice, OF2(96), XRP(96)));
2121 gw1.verifyOwners(__LINE__);
2124 alice.verifyOwners(__LINE__);
2127 IOU
const CK2 = gw1[
"CK2"];
2129 env(check::create(gw1, alice, CK2(96)));
2131 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2132 env(check::cash(alice, chkId, CK2(96)));
2140 gw1.verifyOwners(__LINE__);
2143 alice.verifyOwners(__LINE__);
2145 cmpTrustLines(gw1, alice, OF2, CK2);
2153 AccountOwns
const gw1{*
this, env,
"gw1", 0};
2154 IOU
const OF2 = gw1[
"OF2"];
2155 env(offer(alice, XRP(95), OF2(95)));
2157 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2158 env(offer(bob, OF2(95), XRP(95)));
2163 gw1.verifyOwners(__LINE__);
2164 alice.verifyOwners(__LINE__);
2165 bob.verifyOwners(__LINE__);
2168 IOU
const CK2 = gw1[
"CK2"];
2170 env(check::create(alice, bob, CK2(95)));
2172 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2173 env(check::cash(bob, chkId, CK2(95)));
2179 gw1.verifyOwners(__LINE__);
2180 alice.verifyOwners(__LINE__);
2181 bob.verifyOwners(__LINE__);
2183 cmpTrustLines(alice, bob, OF2, CK2);
2194 AccountOwns
const gw1{*
this, env,
"gw1", 0};
2195 env(fset(gw1, asfDepositAuth));
2196 env(fset(alice, asfDepositAuth));
2197 env(fset(bob, asfDepositAuth));
2201 IOU
const OF3 = gw1[
"OF3"];
2202 env(offer(gw1, XRP(94), OF3(94)));
2204 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2205 env(offer(alice, OF3(94), XRP(94)));
2212 gw1.verifyOwners(__LINE__);
2215 alice.verifyOwners(__LINE__);
2218 IOU
const CK3 = gw1[
"CK3"];
2220 env(check::create(gw1, alice, CK3(94)));
2222 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2223 env(check::cash(alice, chkId, CK3(94)));
2231 gw1.verifyOwners(__LINE__);
2234 alice.verifyOwners(__LINE__);
2236 cmpTrustLines(gw1, alice, OF3, CK3);
2244 AccountOwns
const gw1{*
this, env,
"gw1", 0};
2245 IOU
const OF3 = gw1[
"OF3"];
2246 env(offer(alice, XRP(93), OF3(93)));
2248 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2249 env(offer(bob, OF3(93), XRP(93)));
2254 gw1.verifyOwners(__LINE__);
2255 alice.verifyOwners(__LINE__);
2256 bob.verifyOwners(__LINE__);
2259 IOU
const CK3 = gw1[
"CK3"];
2261 env(check::create(alice, bob, CK3(93)));
2263 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2264 env(check::cash(bob, chkId, CK3(93)));
2270 gw1.verifyOwners(__LINE__);
2271 alice.verifyOwners(__LINE__);
2272 bob.verifyOwners(__LINE__);
2274 cmpTrustLines(alice, bob, OF3, CK3);
2281 AccountOwns
const gw1{*
this, env,
"gw1", 0};
2282 env(fset(gw1, asfGlobalFreeze));
2286 IOU
const OF4 = gw1[
"OF4"];
2287 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2289 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2290 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2294 gw1.verifyOwners(__LINE__);
2295 alice.verifyOwners(__LINE__);
2296 bob.verifyOwners(__LINE__);
2299 IOU
const CK4 = gw1[
"CK4"];
2301 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2303 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2304 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2308 gw1.verifyOwners(__LINE__);
2309 alice.verifyOwners(__LINE__);
2310 bob.verifyOwners(__LINE__);
2314 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2315 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2323 AccountOwns
const gw1{*
this, env,
"gw1", 0};
2324 IOU
const OF4 = gw1[
"OF4"];
2325 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2327 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2328 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2332 gw1.verifyOwners(__LINE__);
2333 alice.verifyOwners(__LINE__);
2334 bob.verifyOwners(__LINE__);
2337 IOU
const CK4 = gw1[
"CK4"];
2339 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2341 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2342 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2346 gw1.verifyOwners(__LINE__);
2347 alice.verifyOwners(__LINE__);
2348 bob.verifyOwners(__LINE__);
2352 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2353 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2362 AccountOwns gw2{*
this, env,
"gw2", 0};
2363 env.fund(XRP(5000), gw2);
2368 env(fset(gw2, asfRequireAuth));
2372 IOU
const OF5 = gw2[
"OF5"];
2374 env(offer(gw2, XRP(92), OF5(92)));
2377 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2378 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2383 gw2.verifyOwners(__LINE__);
2384 alice.verifyOwners(__LINE__);
2385 bob.verifyOwners(__LINE__);
2388 env(offer_cancel(gw2, gw2OfferSeq));
2391 gw2.verifyOwners(__LINE__);
2394 IOU
const CK5 = gw2[
"CK5"];
2396 env(check::create(gw2, alice, CK5(92)));
2399 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2400 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2405 gw2.verifyOwners(__LINE__);
2406 alice.verifyOwners(__LINE__);
2407 bob.verifyOwners(__LINE__);
2411 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2412 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2415 env(check::cancel(gw2, chkId));
2418 gw2.verifyOwners(__LINE__);
2426 AccountOwns
const gw2{*
this, env,
"gw2", 0};
2427 IOU
const OF5 = gw2[
"OF5"];
2430 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2431 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2434 gw2.verifyOwners(__LINE__);
2435 alice.verifyOwners(__LINE__);
2436 bob.verifyOwners(__LINE__);
2439 IOU
const CK5 = gw2[
"CK5"];
2441 env(check::create(alice, bob, CK5(91)));
2443 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2448 env(check::cancel(alice, chkId));
2452 gw2.verifyOwners(__LINE__);
2453 alice.verifyOwners(__LINE__);
2454 bob.verifyOwners(__LINE__);
2458 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2459 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);