148 using namespace test::jtx;
150 Account
const gw{
"gateway"};
151 Account
const alice{
"alice"};
152 Account
const bob{
"bob"};
153 IOU
const USD{gw[
"USD"]};
155 Env env{*
this, features};
157 STAmount const startBalance{XRP(1000).value()};
158 env.fund(startBalance, gw, alice, bob);
164 auto writeTwoChecks = [&env, &USD,
this](Account
const& from, Account
const& to) {
171 env(check::create(from, to, XRP(2000)));
174 env(check::create(from, to, USD(50)));
180 env.require(owners(from, fromOwnerCount + 2));
181 env.require(owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
184 writeTwoChecks(alice, bob);
185 writeTwoChecks(gw, alice);
186 writeTwoChecks(alice, gw);
192 using namespace std::chrono_literals;
195 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
198 env(check::create(alice, bob, USD(50)), source_tag(2));
200 env(check::create(alice, bob, USD(50)), dest_tag(3));
202 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
204 env(check::create(alice, bob, USD(50)),
205 expiration(env.now() + 1s),
216 env(regkey(alice, alie));
221 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
225 env(check::create(alice, bob, USD(50)), sig(alie));
231 XRPAmount const baseFeeDrops{env.current()->fees().base};
232 env(check::create(alice, bob, USD(50)), msig(bogie, demon), fee(3 * baseFeeDrops));
322 using namespace test::jtx;
324 Account
const gw1{
"gateway1"};
325 Account
const gwF{
"gatewayFrozen"};
326 Account
const alice{
"alice"};
327 Account
const bob{
"bob"};
328 IOU
const USD{gw1[
"USD"]};
330 Env env{*
this, features};
332 STAmount const startBalance{XRP(1000).value()};
333 env.fund(startBalance, gw1, gwF, alice, bob);
337 env(check::create(alice, bob, USD(50)), fee(drops(-10)), ter(
temBAD_FEE));
345 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
349 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
352 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
355 env(check::create(alice, bob, drops(1)));
364 env(check::create(alice, bob, USD(1)));
377 Account
const bogie{
"bogie"};
378 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
388 env(check::create(alice, bob, USD(50)), dest_tag(11));
395 IOU
const USF{gwF[
"USF"]};
399 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
405 env(check::create(alice, bob, USF(50)));
411 env.trust(USD(1000), alice);
412 env.trust(USD(1000), bob);
414 env(pay(gw1, alice, USD(25)));
415 env(pay(gw1, bob, USD(25)));
423 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
427 env(check::create(bob, alice, USD(50)));
429 env(pay(bob, alice, USD(1)));
431 env(check::create(gw1, alice, USD(50)));
433 env(pay(gw1, alice, USD(1)));
439 env(check::create(alice, bob, USD(50)));
441 env(check::create(bob, alice, USD(50)));
443 env(check::create(gw1, alice, USD(50)));
451 env(check::create(alice, bob, USD(50)));
453 env(pay(alice, bob, USD(1)));
455 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
459 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
470 env(check::create(alice, bob, USD(50)), expiration(env.now()), ter(
tecEXPIRED));
473 using namespace std::chrono_literals;
474 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
478 Account
const cheri{
"cheri"};
479 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
485 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
488 env(check::create(cheri, bob, USD(50)));
498 using namespace test::jtx;
500 Account
const alice{
"alice"};
501 Account
const bob{
"bob"};
503 Env env{*
this, features};
505 XRPAmount const baseFeeDrops{env.current()->fees().base};
506 STAmount const startBalance{XRP(300).value()};
507 env.fund(startBalance, alice, bob);
512 env(check::create(alice, bob, XRP(10)));
514 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
515 env.require(balance(bob, startBalance));
518 BEAST_EXPECT(ownerCount(env, alice) == 1);
519 BEAST_EXPECT(ownerCount(env, bob) == 0);
521 env(check::cash(bob, chkId, XRP(10)));
523 env.require(balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
524 env.require(balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
527 BEAST_EXPECT(ownerCount(env, alice) == 0);
528 BEAST_EXPECT(ownerCount(env, bob) == 0);
531 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
532 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
534 env.require(balance(alice, startBalance));
535 env.require(balance(bob, startBalance));
539 STAmount const reserve{env.current()->fees().reserve};
540 STAmount const checkAmount{startBalance - reserve - drops(baseFeeDrops)};
542 env(check::create(alice, bob, checkAmount));
546 env(check::cash(bob, chkId, checkAmount + drops(1)), ter(
tecPATH_PARTIAL));
548 env(check::cash(bob, chkId, check::DeliverMin(checkAmount + drops(1))), ter(
tecPATH_PARTIAL));
554 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
556 env.require(balance(alice, reserve));
557 env.require(balance(bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
560 BEAST_EXPECT(ownerCount(env, alice) == 0);
561 BEAST_EXPECT(ownerCount(env, bob) == 0);
564 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
565 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
567 env.require(balance(alice, startBalance));
568 env.require(balance(bob, startBalance));
572 STAmount const reserve{env.current()->fees().reserve};
573 STAmount const checkAmount{startBalance - reserve - drops(baseFeeDrops - 1)};
575 env(check::create(alice, bob, checkAmount));
584 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
586 env.require(balance(alice, reserve));
587 env.require(balance(bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
590 BEAST_EXPECT(ownerCount(env, alice) == 0);
591 BEAST_EXPECT(ownerCount(env, bob) == 0);
594 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
595 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
597 env.require(balance(alice, startBalance));
598 env.require(balance(bob, startBalance));
608 using namespace test::jtx;
610 Account
const gw{
"gateway"};
611 Account
const alice{
"alice"};
612 Account
const bob{
"bob"};
613 IOU
const USD{gw[
"USD"]};
616 Env env{*
this, features};
618 env.fund(XRP(1000), gw, alice, bob);
623 env(check::create(alice, bob, USD(10)));
631 env(trust(alice, USD(20)));
633 env(pay(gw, alice, USD(9.5)));
640 env(pay(gw, alice, USD(0.5)));
644 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)));
661 BEAST_EXPECT(ownerCount(env, alice) == 1);
662 BEAST_EXPECT(ownerCount(env, bob) == 1);
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)));
686 BEAST_EXPECT(ownerCount(env, alice) == 1);
687 BEAST_EXPECT(ownerCount(env, bob) == 1);
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)));
706 BEAST_EXPECT(ownerCount(env, alice) == 2);
707 BEAST_EXPECT(ownerCount(env, bob) == 1);
713 env.require(balance(alice, USD(0)));
714 env.require(balance(bob, USD(10)));
717 BEAST_EXPECT(ownerCount(env, alice) == 2);
718 BEAST_EXPECT(ownerCount(env, bob) == 1);
734 env(check::create(gw, bob, USD(20)));
738 env(check::cash(bob, chkId20, USD(20)));
740 env.require(balance(bob, USD(30)));
744 env(pay(bob, gw, USD(20)));
747 env(check::cancel(bob, chkId3));
749 env.require(balance(alice, USD(0)));
750 env.require(balance(bob, USD(10)));
753 BEAST_EXPECT(ownerCount(env, alice) == 1);
754 BEAST_EXPECT(ownerCount(env, bob) == 1);
758 Env env{*
this, features};
760 env.fund(XRP(1000), gw, alice, bob);
763 env(trust(alice, USD(20)));
764 env(trust(bob, USD(20)));
766 env(pay(gw, alice, USD(8)));
771 env(check::create(alice, bob, USD(9)));
774 env(check::create(alice, bob, USD(8)));
777 env(check::create(alice, bob, USD(7)));
780 env(check::create(alice, bob, USD(6)));
785 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))), ter(
tecPATH_PARTIAL));
789 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
791 env.require(balance(alice, USD(0)));
792 env.require(balance(bob, USD(8)));
795 BEAST_EXPECT(ownerCount(env, alice) == 4);
796 BEAST_EXPECT(ownerCount(env, bob) == 1);
799 env(pay(bob, alice, USD(7)));
804 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
806 env.require(balance(alice, USD(0)));
807 env.require(balance(bob, USD(8)));
810 BEAST_EXPECT(ownerCount(env, alice) == 3);
811 BEAST_EXPECT(ownerCount(env, bob) == 1);
814 env(pay(bob, alice, USD(8)));
819 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
821 env.require(balance(alice, USD(2)));
822 env.require(balance(bob, USD(6)));
825 BEAST_EXPECT(ownerCount(env, alice) == 2);
826 BEAST_EXPECT(ownerCount(env, bob) == 1);
830 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
832 env.require(balance(alice, USD(0)));
833 env.require(balance(bob, USD(8)));
836 BEAST_EXPECT(ownerCount(env, alice) == 1);
837 BEAST_EXPECT(ownerCount(env, bob) == 1);
841 Env env(*
this, features);
843 env.fund(XRP(1000), gw, alice, bob);
846 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
847 env(trust(alice, USD(20)));
849 env(pay(gw, alice, USD(8)));
855 env(check::create(alice, bob, USD(7)));
858 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
863 env(trust(bob, USD(5)));
866 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
870 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
880 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
883 env.require(balance(alice, USD(8) - bobGot));
884 env.require(balance(bob, bobGot));
888 BEAST_EXPECT(ownerCount(env, alice) == 1);
889 BEAST_EXPECT(ownerCount(env, bob) == 1);
894 Env env{*
this, features};
895 env.fund(XRP(1000), gw, alice, bob);
900 env(check::create(alice, bob, USD(1)));
904 env(check::create(alice, bob, USD(2)));
907 env(trust(alice, USD(20)));
908 env(trust(bob, USD(20)));
910 env(pay(gw, alice, USD(8)));
915 env(regkey(bob, bobby));
920 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
923 BEAST_EXPECT(ownerCount(env, bob) == 2);
926 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
928 env.require(balance(alice, USD(7)));
929 env.require(balance(bob, USD(1)));
932 BEAST_EXPECT(ownerCount(env, alice) == 2);
933 BEAST_EXPECT(ownerCount(env, bob) == 2);
936 XRPAmount const baseFeeDrops{env.current()->fees().base};
937 env(check::cash(bob, chkId2, (USD(2))), msig(bogie, demon), fee(3 * baseFeeDrops));
939 env.require(balance(alice, USD(5)));
940 env.require(balance(bob, USD(3)));
943 BEAST_EXPECT(ownerCount(env, alice) == 1);
944 BEAST_EXPECT(ownerCount(env, bob) == 2);
1024 using namespace test::jtx;
1026 Account
const gw{
"gateway"};
1027 Account
const alice{
"alice"};
1028 Account
const bob{
"bob"};
1029 IOU
const USD{gw[
"USD"]};
1031 Env env{*
this, features};
1033 env.fund(XRP(1000), gw, alice, bob);
1036 env(trust(alice, USD(1000)));
1037 env(trust(bob, USD(1000)));
1039 env(pay(gw, alice, USD(1000)));
1047 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1048 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1052 auto testNonIssuerQPay =
1053 [&env, &alice, &bob, &USD](
1054 Account
const& truster, IOU
const& iou,
auto const& inOrOut,
double pct,
double amount) {
1056 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1057 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1060 env(trust(truster, iou(1000)), inOrOut(pct));
1063 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1065 env.require(balance(alice, aliceStart - USD(10)));
1066 env.require(balance(bob, bobStart + USD(10)));
1070 env(trust(truster, iou(1000)), inOrOut(0));
1074 auto testNonIssuerQCheck =
1075 [&env, &alice, &bob, &USD](
1076 Account
const& truster, IOU
const& iou,
auto const& inOrOut,
double pct,
double amount) {
1078 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1079 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1082 env(trust(truster, iou(1000)), inOrOut(pct));
1086 env(check::create(alice, bob, USD(10)));
1089 env(check::cash(bob, chkId, USD(amount)));
1091 env.require(balance(alice, aliceStart - USD(10)));
1092 env.require(balance(bob, bobStart + USD(10)));
1096 env(trust(truster, iou(1000)), inOrOut(0));
1101 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1102 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1105 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1106 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1108 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1109 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1111 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1112 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1114 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1115 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1117 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1118 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1120 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1121 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1123 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1124 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1131 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1132 Account
const& truster,
1134 auto const& inOrOut,
1142 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1145 env(trust(truster, iou(1000)), inOrOut(pct));
1149 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1151 env.require(balance(alice, aliceStart - USD(10)));
1154 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1156 env.require(balance(alice, aliceStart));
1160 env(trust(truster, iou(1000)), inOrOut(0));
1164 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1165 Account
const& truster,
1167 auto const& inOrOut,
1175 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1178 env(trust(truster, iou(1000)), inOrOut(pct));
1183 env(check::create(alice, gw, USD(max1)));
1186 env(check::cash(gw, chkAliceId, USD(amt1)));
1188 env.require(balance(alice, aliceStart - USD(10)));
1192 env(check::create(gw, alice, USD(max2)));
1195 env(check::cash(alice, chkGwId, USD(amt2)));
1197 env.require(balance(alice, aliceStart));
1201 env(trust(truster, iou(1000)), inOrOut(0));
1207 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1208 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1210 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1211 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1213 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1214 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1216 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1217 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1226 using namespace test::jtx;
1228 Account
const gw{
"gateway"};
1229 Account
const alice{
"alice"};
1230 Account
const bob{
"bob"};
1231 Account
const zoe{
"zoe"};
1232 IOU
const USD{gw[
"USD"]};
1234 Env env(*
this, features);
1236 env.fund(XRP(1000), gw, alice, bob, zoe);
1240 env(trust(alice, USD(20)));
1242 env(pay(gw, alice, USD(20)));
1246 env(trust(bob, USD(20)));
1252 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1258 env(check::create(alice, bob, USD(20)));
1262 env(check::create(alice, bob, XRP(10)));
1265 using namespace std::chrono_literals;
1267 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1271 env(check::create(alice, bob, USD(1)));
1275 env(check::create(alice, bob, USD(2)));
1279 env(check::create(alice, bob, USD(3)));
1283 env(check::create(alice, bob, USD(4)));
1287 env(check::create(alice, bob, USD(1)));
1291 env(check::create(alice, bob, USD(2)), dest_tag(7));
1295 auto failingCases = [&env, &gw, &alice, &bob](
uint256 const& chkId,
STAmount const& amount) {
1297 env(check::cash(bob, chkId, amount), fee(drops(-10)), ter(
temBAD_FEE));
1325 env(check::cash(bob, chkId, amount.zeroed()), ter(
temBAD_AMOUNT));
1330 if (!amount.native())
1347 IOU
const wrongCurrency{gw[
"EUR"]};
1349 badAmount.setIssue(wrongCurrency.issue());
1350 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1356 IOU
const wrongIssuer{alice[
"USD"]};
1358 badAmount.setIssue(wrongIssuer.issue());
1359 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1368 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)), ter(
tecPATH_PARTIAL));
1372 failingCases(chkIdX, XRP(10));
1373 failingCases(chkIdU, USD(20));
1376 env(check::cash(bob, chkIdU, USD(20)));
1378 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1382 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1386 env(check::cancel(zoe, chkIdExp));
1391 env(pay(bob, alice, USD(20)));
1393 env.require(balance(alice, USD(20)));
1394 env.require(balance(bob, USD(0)));
1402 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))), ter(
tecPATH_PARTIAL));
1409 env(check::cash(bob, chkIdFroz1, USD(1)));
1411 env.require(balance(alice, USD(19)));
1412 env.require(balance(bob, USD(1)));
1419 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))), ter(
tecPATH_PARTIAL));
1425 env(check::cash(bob, chkIdFroz2, USD(2)));
1427 env.require(balance(alice, USD(17)));
1428 env.require(balance(bob, USD(3)));
1433 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1435 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))), ter(
tecFROZEN));
1441 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1443 env.require(balance(alice, USD(14)));
1444 env.require(balance(bob, USD(6)));
1450 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1452 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))), ter(
terNO_LINE));
1458 env(check::cash(bob, chkIdFroz4, USD(4)));
1460 env.require(balance(alice, USD(10)));
1461 env.require(balance(bob, USD(10)));
1470 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))), ter(
tecDST_TAG_NEEDED));
1474 env(check::cash(bob, chkIdHasDest2, USD(2)));
1476 env.require(balance(alice, USD(8)));
1477 env.require(balance(bob, USD(12)));
1483 env(check::cash(bob, chkIdNoDest1, USD(1)));
1485 env.require(balance(alice, USD(7)));
1486 env.require(balance(bob, USD(13)));
1496 using namespace test::jtx;
1498 Account
const gw{
"gateway"};
1499 Account
const alice{
"alice"};
1500 Account
const bob{
"bob"};
1501 Account
const zoe{
"zoe"};
1502 IOU
const USD{gw[
"USD"]};
1505 Env env{*
this, features};
1507 env.fund(XRP(1000), gw, alice, bob, zoe);
1513 env(check::create(alice, bob, USD(10)));
1517 env(check::create(alice, bob, XRP(10)));
1521 env(check::create(alice, bob, USD(10)));
1525 using namespace std::chrono_literals;
1527 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 600s));
1531 env(check::create(alice, bob, USD(10)), expiration(env.now() + 600s));
1535 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 600s));
1540 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1544 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1548 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1553 env(check::create(alice, bob, USD(10)));
1557 env(check::create(alice, bob, XRP(10)));
1560 BEAST_EXPECT(ownerCount(env, alice) == 11);
1563 env(check::cancel(alice, chkId1));
1566 BEAST_EXPECT(ownerCount(env, alice) == 10);
1568 env(check::cancel(bob, chkId2));
1571 BEAST_EXPECT(ownerCount(env, alice) == 9);
1576 BEAST_EXPECT(ownerCount(env, alice) == 9);
1579 env(check::cancel(alice, chkIdNotExp1));
1582 BEAST_EXPECT(ownerCount(env, alice) == 8);
1584 env(check::cancel(bob, chkIdNotExp2));
1587 BEAST_EXPECT(ownerCount(env, alice) == 7);
1592 BEAST_EXPECT(ownerCount(env, alice) == 7);
1595 env(check::cancel(alice, chkIdExp1));
1598 BEAST_EXPECT(ownerCount(env, alice) == 6);
1600 env(check::cancel(bob, chkIdExp2));
1603 BEAST_EXPECT(ownerCount(env, alice) == 5);
1605 env(check::cancel(zoe, chkIdExp3));
1608 BEAST_EXPECT(ownerCount(env, alice) == 4);
1612 env(regkey(alice, alie));
1617 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1621 env(check::cancel(alice, chkIdReg), sig(alie));
1624 BEAST_EXPECT(ownerCount(env, alice) == 4);
1627 XRPAmount const baseFeeDrops{env.current()->fees().base};
1628 env(check::cancel(alice, chkIdMSig), msig(bogie, demon), fee(3 * baseFeeDrops));
1631 BEAST_EXPECT(ownerCount(env, alice) == 3);
1634 env(check::cancel(alice, chkId3), sig(alice));
1637 BEAST_EXPECT(ownerCount(env, alice) == 2);
1639 env(check::cancel(bob, chkIdNotExp3));
1642 BEAST_EXPECT(ownerCount(env, alice) == 1);
1713 using namespace test::jtx;
1715 Account
const gw{
"gw"};
1716 Account
const alice{
"alice"};
1717 Account
const bob{
"bob"};
1718 IOU
const USD{gw[
"USD"]};
1720 Env env{*
this, features};
1721 env.fund(XRP(1000), gw, alice, bob);
1728 env(ticket::create(alice, 10));
1732 env(ticket::create(bob, 10));
1736 env.require(owners(alice, 10));
1737 env.require(owners(bob, 10));
1740 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1741 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1743 env.require(owners(alice, 10));
1744 env.require(owners(bob, 10));
1746 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1747 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1749 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1750 BEAST_EXPECT(env.seq(bob) == bobSeq);
1752 env(pay(gw, alice, USD(900)));
1758 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1761 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1764 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1767 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1771 env.require(owners(alice, 10));
1772 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1774 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1776 env.require(owners(bob, 10));
1777 BEAST_EXPECT(env.seq(bob) == bobSeq);
1780 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1781 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1784 env.require(owners(alice, 8));
1785 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1787 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1789 env.require(owners(bob, 8));
1790 BEAST_EXPECT(env.seq(bob) == bobSeq);
1793 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1794 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1797 env.require(owners(alice, 6));
1798 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1800 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1801 env.require(balance(alice, USD(700)));
1803 env.require(owners(bob, 6));
1804 BEAST_EXPECT(env.seq(bob) == bobSeq);
1805 env.require(balance(bob, USD(200)));
1816 using namespace test::jtx;
1818 Env env{*
this, features};
1831 suite.
expect(ownerCount(env, acct) == owners,
"Owner count mismatch", __FILE__, line);
1835 operator Account
const()
const
1852 AccountOwns alice{*
this, env,
"alice", 0};
1853 AccountOwns bob{*
this, env,
"bob", 0};
1856 env.fund(XRP(5000), noripple(alice, bob));
1862 AccountOwns gw1{*
this, env,
"gw1", 0};
1867 env.fund(XRP(5000), noripple(gw1));
1870 IOU
const CK8 = gw1[
"CK8"];
1871 gw1.verifyOwners(__LINE__);
1873 Account
const yui{
"yui"};
1878 env.fund(XRP(200), yui);
1882 env(check::create(gw1, yui, CK8(99)));
1887 alice.verifyOwners(__LINE__);
1891 env(pay(env.master, yui, XRP(51)));
1893 env(check::cash(yui, chkId, CK8(99)));
1896 BEAST_EXPECT(ownerCount(env, yui) == 1);
1900 gw1.verifyOwners(__LINE__);
1915 auto cmpTrustLines = [
this, &env](
1916 Account
const& acct1, Account
const& acct2, IOU
const& offerIou, IOU
const& checkIou) {
1917 auto const offerLine = env.le(
keylet::line(acct1, acct2, offerIou.currency));
1918 auto const checkLine = env.le(
keylet::line(acct1, acct2, checkIou.currency));
1919 if (offerLine ==
nullptr || checkLine ==
nullptr)
1921 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
1927 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
1931 auto cmpReqAmount = [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
1932 STAmount const offerAmount = offerLine->at(sfield);
1933 STAmount const checkAmount = checkLine->at(sfield);
1936 if (!BEAST_EXPECT(!offerAmount.
native() && !checkAmount.
native()))
1944 cmpReqAmount(sfBalance);
1945 cmpReqAmount(sfLowLimit);
1946 cmpReqAmount(sfHighLimit);
1950 auto cmpOptField = [
this, offerLine, checkLine](
auto const& sfield) {
1952 if (!BEAST_EXPECT(offerLine->isFieldPresent(sfield) == checkLine->isFieldPresent(sfield)))
1957 if (!offerLine->isFieldPresent(sfield))
1962 BEAST_EXPECT(offerLine->at(sfield) == checkLine->at(sfield));
1964 cmpOptField(sfLowNode);
1965 cmpOptField(sfLowQualityIn);
1966 cmpOptField(sfLowQualityOut);
1968 cmpOptField(sfHighNode);
1969 cmpOptField(sfHighQualityIn);
1970 cmpOptField(sfHighQualityOut);
1978 AccountOwns gw1{*
this, env,
"gw1", 0};
1980 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
1981 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
1982 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
1985 IOU
const OF1 = gw1[
"OF1"];
1986 env(offer(gw1, XRP(98), OF1(98)));
1988 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
1989 env(offer(alice, OF1(98), XRP(98)));
1996 gw1.verifyOwners(__LINE__);
1999 alice.verifyOwners(__LINE__);
2002 IOU
const CK1 = gw1[
"CK1"];
2004 env(check::create(gw1, alice, CK1(98)));
2006 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2007 env(check::cash(alice, chkId, CK1(98)));
2015 gw1.verifyOwners(__LINE__);
2018 alice.verifyOwners(__LINE__);
2020 cmpTrustLines(gw1, alice, OF1, CK1);
2031 AccountOwns gw1{*
this, env,
"gw1", 0};
2032 IOU
const OF1 = gw1[
"OF1"];
2033 env(offer(alice, XRP(97), OF1(97)));
2035 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2036 env(offer(bob, OF1(97), XRP(97)));
2041 env.require(balance(alice, OF1(1)));
2042 env.require(balance(bob, OF1(97)));
2045 gw1.verifyOwners(__LINE__);
2046 alice.verifyOwners(__LINE__);
2047 bob.verifyOwners(__LINE__);
2055 IOU
const CK1 = gw1[
"CK1"];
2057 env(check::create(alice, bob, CK1(97)));
2059 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2060 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2063 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2064 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2067 env(check::cancel(alice, chkId));
2071 gw1.verifyOwners(__LINE__);
2072 alice.verifyOwners(__LINE__);
2073 bob.verifyOwners(__LINE__);
2080 AccountOwns gw1{*
this, env,
"gw1", 0};
2085 IOU
const OF2 = gw1[
"OF2"];
2086 env(offer(gw1, XRP(96), OF2(96)));
2088 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2089 env(offer(alice, OF2(96), XRP(96)));
2096 gw1.verifyOwners(__LINE__);
2099 alice.verifyOwners(__LINE__);
2102 IOU
const CK2 = gw1[
"CK2"];
2104 env(check::create(gw1, alice, CK2(96)));
2106 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2107 env(check::cash(alice, chkId, CK2(96)));
2115 gw1.verifyOwners(__LINE__);
2118 alice.verifyOwners(__LINE__);
2120 cmpTrustLines(gw1, alice, OF2, CK2);
2128 AccountOwns gw1{*
this, env,
"gw1", 0};
2129 IOU
const OF2 = gw1[
"OF2"];
2130 env(offer(alice, XRP(95), OF2(95)));
2132 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2133 env(offer(bob, OF2(95), XRP(95)));
2138 gw1.verifyOwners(__LINE__);
2139 alice.verifyOwners(__LINE__);
2140 bob.verifyOwners(__LINE__);
2143 IOU
const CK2 = gw1[
"CK2"];
2145 env(check::create(alice, bob, CK2(95)));
2147 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2148 env(check::cash(bob, chkId, CK2(95)));
2154 gw1.verifyOwners(__LINE__);
2155 alice.verifyOwners(__LINE__);
2156 bob.verifyOwners(__LINE__);
2158 cmpTrustLines(alice, bob, OF2, CK2);
2169 AccountOwns gw1{*
this, env,
"gw1", 0};
2176 IOU
const OF3 = gw1[
"OF3"];
2177 env(offer(gw1, XRP(94), OF3(94)));
2179 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2180 env(offer(alice, OF3(94), XRP(94)));
2187 gw1.verifyOwners(__LINE__);
2190 alice.verifyOwners(__LINE__);
2193 IOU
const CK3 = gw1[
"CK3"];
2195 env(check::create(gw1, alice, CK3(94)));
2197 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2198 env(check::cash(alice, chkId, CK3(94)));
2206 gw1.verifyOwners(__LINE__);
2209 alice.verifyOwners(__LINE__);
2211 cmpTrustLines(gw1, alice, OF3, CK3);
2219 AccountOwns gw1{*
this, env,
"gw1", 0};
2220 IOU
const OF3 = gw1[
"OF3"];
2221 env(offer(alice, XRP(93), OF3(93)));
2223 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2224 env(offer(bob, OF3(93), XRP(93)));
2229 gw1.verifyOwners(__LINE__);
2230 alice.verifyOwners(__LINE__);
2231 bob.verifyOwners(__LINE__);
2234 IOU
const CK3 = gw1[
"CK3"];
2236 env(check::create(alice, bob, CK3(93)));
2238 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2239 env(check::cash(bob, chkId, CK3(93)));
2245 gw1.verifyOwners(__LINE__);
2246 alice.verifyOwners(__LINE__);
2247 bob.verifyOwners(__LINE__);
2249 cmpTrustLines(alice, bob, OF3, CK3);
2256 AccountOwns gw1{*
this, env,
"gw1", 0};
2261 IOU
const OF4 = gw1[
"OF4"];
2262 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2264 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2265 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2269 gw1.verifyOwners(__LINE__);
2270 alice.verifyOwners(__LINE__);
2271 bob.verifyOwners(__LINE__);
2274 IOU
const CK4 = gw1[
"CK4"];
2276 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2278 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2279 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2283 gw1.verifyOwners(__LINE__);
2284 alice.verifyOwners(__LINE__);
2285 bob.verifyOwners(__LINE__);
2289 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2290 BEAST_EXPECT(env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2298 AccountOwns gw1{*
this, env,
"gw1", 0};
2299 IOU
const OF4 = gw1[
"OF4"];
2300 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2302 BEAST_EXPECT(env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2303 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2307 gw1.verifyOwners(__LINE__);
2308 alice.verifyOwners(__LINE__);
2309 bob.verifyOwners(__LINE__);
2312 IOU
const CK4 = gw1[
"CK4"];
2314 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2316 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2317 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2321 gw1.verifyOwners(__LINE__);
2322 alice.verifyOwners(__LINE__);
2323 bob.verifyOwners(__LINE__);
2327 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2328 BEAST_EXPECT(env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2337 AccountOwns gw2{*
this, env,
"gw2", 0};
2338 env.fund(XRP(5000), gw2);
2347 IOU
const OF5 = gw2[
"OF5"];
2349 env(offer(gw2, XRP(92), OF5(92)));
2352 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2353 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2358 gw2.verifyOwners(__LINE__);
2359 alice.verifyOwners(__LINE__);
2360 bob.verifyOwners(__LINE__);
2363 env(offer_cancel(gw2, gw2OfferSeq));
2366 gw2.verifyOwners(__LINE__);
2369 IOU
const CK5 = gw2[
"CK5"];
2371 env(check::create(gw2, alice, CK5(92)));
2374 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2375 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2380 gw2.verifyOwners(__LINE__);
2381 alice.verifyOwners(__LINE__);
2382 bob.verifyOwners(__LINE__);
2386 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2387 BEAST_EXPECT(env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2390 env(check::cancel(gw2, chkId));
2393 gw2.verifyOwners(__LINE__);
2401 AccountOwns gw2{*
this, env,
"gw2", 0};
2402 IOU
const OF5 = gw2[
"OF5"];
2405 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2406 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2409 gw2.verifyOwners(__LINE__);
2410 alice.verifyOwners(__LINE__);
2411 bob.verifyOwners(__LINE__);
2414 IOU
const CK5 = gw2[
"CK5"];
2416 env(check::create(alice, bob, CK5(91)));
2418 BEAST_EXPECT(env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2423 env(check::cancel(alice, chkId));
2427 gw2.verifyOwners(__LINE__);
2428 alice.verifyOwners(__LINE__);
2429 bob.verifyOwners(__LINE__);
2433 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2434 BEAST_EXPECT(env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);