22#include <xrpl/protocol/Feature.h>
23#include <xrpl/protocol/jss.h>
37 :
expry_{expiry.time_since_epoch().count()}
44 jt[sfExpiration.jsonName] =
expry_;
62 jt[sfSourceTag.jsonName] =
tag_;
80 jt[sfDestinationTag.jsonName] =
tag_;
106 if (sle && sle->getType() == ltCHECK)
107 result.push_back(sle);
125 Json::Value const meta = env.
rpc(
"tx", txHash)[jss::result][jss::meta];
128 if (!BEAST_EXPECT(meta.
isMember(sfDeliveredAmount.jsonName)))
134 meta[sfDeliveredAmount.jsonName] ==
145 using namespace test::jtx;
146 Account
const alice{
"alice"};
150 Env env{*
this, features - featureChecks};
152 env.fund(XRP(1000), alice);
157 env(check::create(env.master, alice, XRP(100)), ter(
temDISABLED));
160 env(check::cash(alice, checkId, XRP(100)), ter(
temDISABLED));
163 env(check::cancel(alice, checkId), ter(
temDISABLED));
169 Env env{*
this, features};
171 env.fund(XRP(1000), alice);
176 env(check::create(env.master, alice, XRP(100)));
179 env(check::cash(alice, checkId1, XRP(100)));
184 env(check::create(env.master, alice, XRP(100)));
187 env(check::cancel(alice, checkId2));
198 using namespace test::jtx;
200 Account
const gw{
"gateway"};
201 Account
const alice{
"alice"};
202 Account
const bob{
"bob"};
203 IOU
const USD{gw[
"USD"]};
205 Env env{*
this, features};
207 STAmount const startBalance{XRP(1000).value()};
208 env.fund(startBalance, gw, alice, bob);
214 auto writeTwoChecks = [&env, &USD,
this](
215 Account
const& from, Account
const& to) {
222 env(check::create(from, to, XRP(2000)));
225 env(check::create(from, to, USD(50)));
231 env.require(owners(from, fromOwnerCount + 2));
233 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
236 writeTwoChecks(alice, bob);
237 writeTwoChecks(gw, alice);
238 writeTwoChecks(alice, gw);
244 using namespace std::chrono_literals;
247 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
250 env(check::create(alice, bob, USD(50)), source_tag(2));
252 env(check::create(alice, bob, USD(50)), dest_tag(3));
254 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
256 env(check::create(alice, bob, USD(50)),
257 expiration(env.now() + 1s),
268 env(regkey(alice, alie));
273 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
277 env(check::create(alice, bob, USD(50)), sig(alie));
283 XRPAmount const baseFeeDrops{env.current()->fees().base};
284 env(check::create(alice, bob, USD(50)),
286 fee(3 * baseFeeDrops));
295 testcase(
"Create valid with disallow incoming");
297 using namespace test::jtx;
302 Account
const alice{
"alice"};
303 env.fund(XRP(10000), alice);
306 auto const sle = env.le(alice);
307 uint32_t flags = sle->getFlags();
311 Account
const gw{
"gateway"};
312 Account
const alice{
"alice"};
313 Account
const bob{
"bob"};
314 IOU
const USD{gw[
"USD"]};
318 STAmount const startBalance{XRP(1000).value()};
319 env.fund(startBalance, gw, alice, bob);
326 auto writeTwoChecksDI = [&env, &USD,
this](
336 env(check::create(from, to, XRP(2000)), ter(expected));
339 env(check::create(from, to, USD(50)), ter(expected));
348 env.require(owners(from, fromOwnerCount + 2));
350 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
357 env.require(owners(from, fromOwnerCount));
358 env.require(owners(to, to == from ? fromOwnerCount : toOwnerCount));
393 using namespace test::jtx;
395 Account
const gw1{
"gateway1"};
396 Account
const gwF{
"gatewayFrozen"};
397 Account
const alice{
"alice"};
398 Account
const bob{
"bob"};
399 IOU
const USD{gw1[
"USD"]};
401 Env env{*
this, features};
403 STAmount const startBalance{XRP(1000).value()};
404 env.fund(startBalance, gw1, gwF, alice, bob);
408 env(check::create(alice, bob, USD(50)),
414 env(check::create(alice, bob, USD(50)),
420 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
424 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
427 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
430 env(check::create(alice, bob, drops(1)));
439 env(check::create(alice, bob, USD(1)));
448 env(check::create(alice, bob, USD(50)),
454 Account
const bogie{
"bogie"};
455 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
465 env(check::create(alice, bob, USD(50)), dest_tag(11));
472 IOU
const USF{gwF[
"USF"]};
476 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
482 env(check::create(alice, bob, USF(50)));
488 env.trust(USD(1000), alice);
489 env.trust(USD(1000), bob);
491 env(pay(gw1, alice, USD(25)));
492 env(pay(gw1, bob, USD(25)));
500 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
504 env(check::create(bob, alice, USD(50)));
506 env(pay(bob, alice, USD(1)));
508 env(check::create(gw1, alice, USD(50)));
510 env(pay(gw1, alice, USD(1)));
516 env(check::create(alice, bob, USD(50)));
518 env(check::create(bob, alice, USD(50)));
520 env(check::create(gw1, alice, USD(50)));
528 env(check::create(alice, bob, USD(50)));
530 env(pay(alice, bob, USD(1)));
532 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
536 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
547 env(check::create(alice, bob, USD(50)),
548 expiration(env.now()),
552 using namespace std::chrono_literals;
553 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
557 Account
const cheri{
"cheri"};
558 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
561 env(check::create(cheri, bob, USD(50)),
562 fee(drops(env.current()->fees().base)),
566 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
569 env(check::create(cheri, bob, USD(50)));
579 using namespace test::jtx;
581 Account
const alice{
"alice"};
582 Account
const bob{
"bob"};
584 Env env{*
this, features};
586 XRPAmount const baseFeeDrops{env.current()->fees().base};
587 STAmount const startBalance{XRP(300).value()};
588 env.fund(startBalance, alice, bob);
593 env(check::create(alice, bob, XRP(10)));
595 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
596 env.require(balance(bob, startBalance));
599 BEAST_EXPECT(ownerCount(env, alice) == 1);
600 BEAST_EXPECT(ownerCount(env, bob) == 0);
602 env(check::cash(bob, chkId, XRP(10)));
605 balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
607 balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
610 BEAST_EXPECT(ownerCount(env, alice) == 0);
611 BEAST_EXPECT(ownerCount(env, bob) == 0);
614 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
615 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
617 env.require(balance(alice, startBalance));
618 env.require(balance(bob, startBalance));
622 STAmount const reserve{env.current()->fees().accountReserve(0)};
624 startBalance - reserve - drops(baseFeeDrops)};
626 env(check::create(alice, bob, checkAmount));
630 env(check::cash(bob, chkId, checkAmount + drops(1)),
634 bob, chkId, check::DeliverMin(checkAmount + drops(1))),
641 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
643 env.require(balance(alice, reserve));
645 bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
648 BEAST_EXPECT(ownerCount(env, alice) == 0);
649 BEAST_EXPECT(ownerCount(env, bob) == 0);
652 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
653 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
655 env.require(balance(alice, startBalance));
656 env.require(balance(bob, startBalance));
660 STAmount const reserve{env.current()->fees().accountReserve(0)};
662 startBalance - reserve - drops(baseFeeDrops - 1)};
664 env(check::create(alice, bob, checkAmount));
673 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
675 env.require(balance(alice, reserve));
677 bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
680 BEAST_EXPECT(ownerCount(env, alice) == 0);
681 BEAST_EXPECT(ownerCount(env, bob) == 0);
684 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
686 bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
688 env.require(balance(alice, startBalance));
689 env.require(balance(bob, startBalance));
699 using namespace test::jtx;
701 bool const cashCheckMakesTrustLine =
702 features[featureCheckCashMakesTrustLine];
704 Account
const gw{
"gateway"};
705 Account
const alice{
"alice"};
706 Account
const bob{
"bob"};
707 IOU
const USD{gw[
"USD"]};
710 Env env{*
this, features};
712 env.fund(XRP(1000), gw, alice, bob);
717 env(check::create(alice, bob, USD(10)));
725 env(trust(alice, USD(20)));
727 env(pay(gw, alice, USD(9.5)));
734 env(pay(gw, alice, USD(0.5)));
736 if (!cashCheckMakesTrustLine)
741 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_LINE));
746 env(trust(bob, USD(9.5)));
748 if (!cashCheckMakesTrustLine)
759 env(trust(bob, USD(10.5)));
765 env(check::cash(bob, chkId1, USD(10)));
767 env.require(balance(alice, USD(0)));
768 env.require(balance(bob, USD(10)));
771 BEAST_EXPECT(ownerCount(env, alice) == 1);
772 BEAST_EXPECT(ownerCount(env, bob) == 1);
775 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
779 env(pay(bob, alice, USD(7)));
783 env(check::create(alice, bob, USD(7)));
790 env(check::cash(bob, chkId2, USD(5)));
792 env.require(balance(alice, USD(2)));
793 env.require(balance(bob, USD(8)));
796 BEAST_EXPECT(ownerCount(env, alice) == 1);
797 BEAST_EXPECT(ownerCount(env, bob) == 1);
801 env(check::create(alice, bob, USD(2)));
804 env(check::create(alice, bob, USD(2)));
810 env(check::cash(bob, chkId4, USD(2)));
812 env.require(balance(alice, USD(0)));
813 env.require(balance(bob, USD(10)));
816 BEAST_EXPECT(ownerCount(env, alice) == 2);
817 BEAST_EXPECT(ownerCount(env, bob) == 1);
823 env.require(balance(alice, USD(0)));
824 env.require(balance(bob, USD(10)));
827 BEAST_EXPECT(ownerCount(env, alice) == 2);
828 BEAST_EXPECT(ownerCount(env, bob) == 1);
830 if (cashCheckMakesTrustLine)
846 env(check::create(gw, bob, USD(20)));
850 env(check::cash(bob, chkId20, USD(20)));
852 env.require(balance(bob, USD(30)));
856 env(pay(bob, gw, USD(20)));
860 env(check::cancel(bob, chkId3));
862 env.require(balance(alice, USD(0)));
863 env.require(balance(bob, USD(10)));
866 BEAST_EXPECT(ownerCount(env, alice) == 1);
867 BEAST_EXPECT(ownerCount(env, bob) == 1);
871 Env env{*
this, features};
873 env.fund(XRP(1000), gw, alice, bob);
876 env(trust(alice, USD(20)));
877 env(trust(bob, USD(20)));
879 env(pay(gw, alice, USD(8)));
884 env(check::create(alice, bob, USD(9)));
887 env(check::create(alice, bob, USD(8)));
890 env(check::create(alice, bob, USD(7)));
893 env(check::create(alice, bob, USD(6)));
898 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
903 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
905 env.require(balance(alice, USD(0)));
906 env.require(balance(bob, USD(8)));
909 BEAST_EXPECT(ownerCount(env, alice) == 4);
910 BEAST_EXPECT(ownerCount(env, bob) == 1);
913 env(pay(bob, alice, USD(7)));
918 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
920 env.require(balance(alice, USD(0)));
921 env.require(balance(bob, USD(8)));
924 BEAST_EXPECT(ownerCount(env, alice) == 3);
925 BEAST_EXPECT(ownerCount(env, bob) == 1);
928 env(pay(bob, alice, USD(8)));
933 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
935 env.require(balance(alice, USD(2)));
936 env.require(balance(bob, USD(6)));
939 BEAST_EXPECT(ownerCount(env, alice) == 2);
940 BEAST_EXPECT(ownerCount(env, bob) == 1);
944 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
946 env.require(balance(alice, USD(0)));
947 env.require(balance(bob, USD(8)));
950 BEAST_EXPECT(ownerCount(env, alice) == 1);
951 BEAST_EXPECT(ownerCount(env, bob) == 1);
955 Env env(*
this, features);
957 env.fund(XRP(1000), gw, alice, bob);
960 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
961 env(trust(alice, USD(20)));
963 env(pay(gw, alice, USD(8)));
969 env(check::create(alice, bob, USD(7)));
972 env(check::cash(bob, chkId, USD(7)),
978 env(trust(bob, USD(5)));
981 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
985 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
990 if (!cashCheckMakesTrustLine)
1006 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
1007 STAmount const bobGot = cashCheckMakesTrustLine ? USD(7) : USD(5);
1009 env.require(balance(alice, USD(8) - bobGot));
1010 env.require(balance(bob, bobGot));
1014 BEAST_EXPECT(ownerCount(env, alice) == 1);
1015 BEAST_EXPECT(ownerCount(env, bob) == 1);
1021 for (
auto const& testFeatures :
1022 {features - featureMultiSignReserve,
1023 features | featureMultiSignReserve})
1025 Env env{*
this, testFeatures};
1027 env.fund(XRP(1000), gw, alice, bob);
1032 env(check::create(alice, bob, USD(1)));
1036 env(check::create(alice, bob, USD(2)));
1039 env(trust(alice, USD(20)));
1040 env(trust(bob, USD(20)));
1042 env(pay(gw, alice, USD(8)));
1047 env(regkey(bob, bobby));
1052 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
1057 int const signersCount = {
1058 testFeatures[featureMultiSignReserve] ? 1 : 4};
1059 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1062 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
1064 env.require(balance(alice, USD(7)));
1065 env.require(balance(bob, USD(1)));
1068 BEAST_EXPECT(ownerCount(env, alice) == 2);
1069 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1072 XRPAmount const baseFeeDrops{env.current()->fees().base};
1073 env(check::cash(bob, chkId2, (USD(2))),
1075 fee(3 * baseFeeDrops));
1077 env.require(balance(alice, USD(5)));
1078 env.require(balance(bob, USD(3)));
1081 BEAST_EXPECT(ownerCount(env, alice) == 1);
1082 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1090 testcase(
"Cash with transfer fee");
1092 using namespace test::jtx;
1094 Account
const gw{
"gateway"};
1095 Account
const alice{
"alice"};
1096 Account
const bob{
"bob"};
1097 IOU
const USD{gw[
"USD"]};
1099 Env env{*
this, features};
1101 env.fund(XRP(1000), gw, alice, bob);
1104 env(trust(alice, USD(1000)));
1105 env(trust(bob, USD(1000)));
1107 env(pay(gw, alice, USD(1000)));
1111 env(rate(gw, 1.25));
1117 env(check::create(alice, bob, USD(125)));
1124 env(check::create(alice, bob, USD(120)));
1130 env(check::cash(bob, chkId125, check::DeliverMin(USD(101))),
1136 env(check::cash(bob, chkId125, check::DeliverMin(USD(75))));
1138 env.require(balance(alice, USD(1000 - 125)));
1139 env.require(balance(bob, USD(0 + 100)));
1149 env(check::cash(bob, chkId120, USD(50)));
1151 env.require(balance(alice, USD(1000 - 125 - 60)));
1152 env.require(balance(bob, USD(0 + 100 + 50)));
1163 using namespace test::jtx;
1165 Account
const gw{
"gateway"};
1166 Account
const alice{
"alice"};
1167 Account
const bob{
"bob"};
1168 IOU
const USD{gw[
"USD"]};
1170 Env env{*
this, features};
1172 env.fund(XRP(1000), gw, alice, bob);
1175 env(trust(alice, USD(1000)));
1176 env(trust(bob, USD(1000)));
1178 env(pay(gw, alice, USD(1000)));
1186 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1187 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1191 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1192 Account
const& truster,
1194 auto const& inOrOut,
1198 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1199 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1202 env(trust(truster, iou(1000)), inOrOut(pct));
1205 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1207 env.require(balance(alice, aliceStart - USD(10)));
1208 env.require(balance(bob, bobStart + USD(10)));
1212 env(trust(truster, iou(1000)), inOrOut(0));
1216 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1217 Account
const& truster,
1219 auto const& inOrOut,
1223 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1224 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1227 env(trust(truster, iou(1000)), inOrOut(pct));
1231 env(check::create(alice, bob, USD(10)));
1234 env(check::cash(bob, chkId, USD(amount)));
1236 env.require(balance(alice, aliceStart - USD(10)));
1237 env.require(balance(bob, bobStart + USD(10)));
1241 env(trust(truster, iou(1000)), inOrOut(0));
1246 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1247 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1250 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1251 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1253 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1254 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1256 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1257 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1259 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1260 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1262 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1263 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1265 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1266 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1268 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1269 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1276 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1277 Account
const& truster,
1279 auto const& inOrOut,
1287 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1290 env(trust(truster, iou(1000)), inOrOut(pct));
1294 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1296 env.require(balance(alice, aliceStart - USD(10)));
1299 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1301 env.require(balance(alice, aliceStart));
1305 env(trust(truster, iou(1000)), inOrOut(0));
1309 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1310 Account
const& truster,
1312 auto const& inOrOut,
1320 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1323 env(trust(truster, iou(1000)), inOrOut(pct));
1328 env(check::create(alice, gw, USD(max1)));
1331 env(check::cash(gw, chkAliceId, USD(amt1)));
1333 env.require(balance(alice, aliceStart - USD(10)));
1337 env(check::create(gw, alice, USD(max2)));
1340 env(check::cash(alice, chkGwId, USD(amt2)));
1342 env.require(balance(alice, aliceStart));
1346 env(trust(truster, iou(1000)), inOrOut(0));
1352 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1353 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1355 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1356 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1358 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1359 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1361 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1362 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1371 using namespace test::jtx;
1373 Account
const gw{
"gateway"};
1374 Account
const alice{
"alice"};
1375 Account
const bob{
"bob"};
1376 Account
const zoe{
"zoe"};
1377 IOU
const USD{gw[
"USD"]};
1379 Env env(*
this, features);
1381 env.fund(XRP(1000), gw, alice, bob, zoe);
1385 env(trust(alice, USD(20)));
1387 env(pay(gw, alice, USD(20)));
1394 env(check::create(alice, bob, USD(20)));
1397 if (!features[featureCheckCashMakesTrustLine])
1402 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_LINE));
1408 env(trust(bob, USD(20)));
1414 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1420 env(check::create(alice, bob, USD(20)));
1424 env(check::create(alice, bob, XRP(10)));
1427 using namespace std::chrono_literals;
1429 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1433 env(check::create(alice, bob, USD(1)));
1437 env(check::create(alice, bob, USD(2)));
1441 env(check::create(alice, bob, USD(3)));
1445 env(check::create(alice, bob, USD(4)));
1449 env(check::create(alice, bob, USD(1)));
1453 env(check::create(alice, bob, USD(2)), dest_tag(7));
1457 auto failingCases = [&env, &gw, &alice, &bob](
1460 env(check::cash(bob, chkId, amount),
1466 env(check::cash(bob, chkId, amount),
1492 env(check::cash(bob, chkId, amount.zeroed()),
1498 if (!amount.native())
1515 IOU
const wrongCurrency{gw[
"EUR"]};
1517 badAmount.
setIssue(wrongCurrency.issue());
1518 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1524 IOU
const wrongIssuer{alice[
"USD"]};
1526 badAmount.
setIssue(wrongIssuer.issue());
1527 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1536 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1541 failingCases(chkIdX, XRP(10));
1542 failingCases(chkIdU, USD(20));
1545 env(check::cash(bob, chkIdU, USD(20)));
1547 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1551 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1555 env(check::cancel(zoe, chkIdExp));
1560 env(pay(bob, alice, USD(20)));
1562 env.require(balance(alice, USD(20)));
1563 env.require(balance(bob, USD(0)));
1571 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1579 env(check::cash(bob, chkIdFroz1, USD(1)));
1581 env.require(balance(alice, USD(19)));
1582 env.require(balance(bob, USD(1)));
1589 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1596 env(check::cash(bob, chkIdFroz2, USD(2)));
1598 env.require(balance(alice, USD(17)));
1599 env.require(balance(bob, USD(3)));
1604 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1606 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1613 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1615 env.require(balance(alice, USD(14)));
1616 env.require(balance(bob, USD(6)));
1622 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1624 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1631 env(check::cash(bob, chkIdFroz4, USD(4)));
1633 env.require(balance(alice, USD(10)));
1634 env.require(balance(bob, USD(10)));
1643 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1648 env(check::cash(bob, chkIdHasDest2, USD(2)));
1650 env.require(balance(alice, USD(8)));
1651 env.require(balance(bob, USD(12)));
1657 env(check::cash(bob, chkIdNoDest1, USD(1)));
1659 env.require(balance(alice, USD(7)));
1660 env.require(balance(bob, USD(13)));
1670 using namespace test::jtx;
1672 Account
const gw{
"gateway"};
1673 Account
const alice{
"alice"};
1674 Account
const bob{
"bob"};
1675 Account
const zoe{
"zoe"};
1676 IOU
const USD{gw[
"USD"]};
1680 for (
auto const& testFeatures :
1681 {features - featureMultiSignReserve,
1682 features | featureMultiSignReserve})
1684 Env env{*
this, testFeatures};
1686 env.fund(XRP(1000), gw, alice, bob, zoe);
1692 env(check::create(alice, bob, USD(10)));
1696 env(check::create(alice, bob, XRP(10)));
1700 env(check::create(alice, bob, USD(10)));
1704 using namespace std::chrono_literals;
1706 env(check::create(alice, bob, XRP(10)),
1707 expiration(env.now() + 600s));
1711 env(check::create(alice, bob, USD(10)),
1712 expiration(env.now() + 600s));
1716 env(check::create(alice, bob, XRP(10)),
1717 expiration(env.now() + 600s));
1722 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1726 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1730 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1735 env(check::create(alice, bob, USD(10)));
1739 env(check::create(alice, bob, XRP(10)));
1742 BEAST_EXPECT(ownerCount(env, alice) == 11);
1745 env(check::cancel(alice, chkId1));
1748 BEAST_EXPECT(ownerCount(env, alice) == 10);
1750 env(check::cancel(bob, chkId2));
1753 BEAST_EXPECT(ownerCount(env, alice) == 9);
1758 BEAST_EXPECT(ownerCount(env, alice) == 9);
1761 env(check::cancel(alice, chkIdNotExp1));
1764 BEAST_EXPECT(ownerCount(env, alice) == 8);
1766 env(check::cancel(bob, chkIdNotExp2));
1769 BEAST_EXPECT(ownerCount(env, alice) == 7);
1774 BEAST_EXPECT(ownerCount(env, alice) == 7);
1777 env(check::cancel(alice, chkIdExp1));
1780 BEAST_EXPECT(ownerCount(env, alice) == 6);
1782 env(check::cancel(bob, chkIdExp2));
1785 BEAST_EXPECT(ownerCount(env, alice) == 5);
1787 env(check::cancel(zoe, chkIdExp3));
1790 BEAST_EXPECT(ownerCount(env, alice) == 4);
1794 env(regkey(alice, alie));
1799 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1804 int const signersCount{
1805 testFeatures[featureMultiSignReserve] ? 1 : 4};
1808 env(check::cancel(alice, chkIdReg), sig(alie));
1811 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 3);
1814 XRPAmount const baseFeeDrops{env.current()->fees().base};
1815 env(check::cancel(alice, chkIdMSig),
1817 fee(3 * baseFeeDrops));
1820 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 2);
1823 env(check::cancel(alice, chkId3), sig(alice));
1826 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 1);
1828 env(check::cancel(bob, chkIdNotExp3));
1831 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 0);
1841 using namespace test::jtx;
1843 Account
const alice{
"alice"};
1844 Account
const bob{
"bob"};
1846 Env env{*
this, features};
1848 env.fund(XRP(1000), alice, bob);
1852 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1858 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1864 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1874 using namespace test::jtx;
1876 auto testEnable = [
this](
1881 Account
const alice{
"alice"};
1882 Account
const bob{
"bob"};
1884 Env env{*
this, features};
1886 env.fund(XRP(1000), alice, bob);
1890 env(check::create(alice, bob, XRP(200)));
1893 env(check::cash(bob, chkId, check::DeliverMin(XRP(100))));
1903 env.rpc(
"tx", txHash)[jss::result][jss::meta];
1906 meta.
isMember(sfDeliveredAmount.jsonName) == hasFields);
1907 BEAST_EXPECT(meta.
isMember(jss::delivered_amount) == hasFields);
1911 testEnable(features - fix1623,
false);
1912 testEnable(features,
true);
1920 using namespace test::jtx;
1922 Account
const gw{
"gw"};
1923 Account
const alice{
"alice"};
1924 Account
const bob{
"bob"};
1925 IOU
const USD{gw[
"USD"]};
1927 Env env{*
this, features};
1928 env.fund(XRP(1000), gw, alice, bob);
1935 env(ticket::create(alice, 10));
1939 env(ticket::create(bob, 10));
1943 env.require(owners(alice, 10));
1944 env.require(owners(bob, 10));
1947 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1948 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1950 env.require(owners(alice, 10));
1951 env.require(owners(bob, 10));
1953 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1954 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1956 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1957 BEAST_EXPECT(env.seq(bob) == bobSeq);
1959 env(pay(gw, alice, USD(900)));
1965 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1968 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1971 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1974 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1978 env.require(owners(alice, 10));
1979 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1981 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1983 env.require(owners(bob, 10));
1984 BEAST_EXPECT(env.seq(bob) == bobSeq);
1987 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1988 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1991 env.require(owners(alice, 8));
1992 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1994 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1996 env.require(owners(bob, 8));
1997 BEAST_EXPECT(env.seq(bob) == bobSeq);
2000 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
2001 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
2004 env.require(owners(alice, 6));
2005 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
2007 BEAST_EXPECT(env.seq(alice) == aliceSeq);
2008 env.require(balance(alice, USD(700)));
2010 env.require(owners(bob, 6));
2011 BEAST_EXPECT(env.seq(bob) == bobSeq);
2012 env.require(balance(bob, USD(200)));
2023 assert(features[featureCheckCashMakesTrustLine]);
2027 using namespace test::jtx;
2029 Env env{*
this, features};
2043 ownerCount(env, acct) == owners,
2044 "Owner count mismatch",
2050 operator Account
const()
const
2067 AccountOwns alice{*
this, env,
"alice", 0};
2068 AccountOwns bob{*
this, env,
"bob", 0};
2071 env.fund(XRP(5000), noripple(alice, bob));
2077 AccountOwns gw1{*
this, env,
"gw1", 0};
2082 env.fund(XRP(5000), noripple(gw1));
2085 IOU
const CK8 = gw1[
"CK8"];
2086 gw1.verifyOwners(__LINE__);
2088 Account
const yui{
"yui"};
2093 env.fund(XRP(200), yui);
2097 env(check::create(gw1, yui, CK8(99)));
2100 env(check::cash(yui, chkId, CK8(99)),
2103 alice.verifyOwners(__LINE__);
2107 env(pay(env.master, yui, XRP(51)));
2109 env(check::cash(yui, chkId, CK8(99)));
2112 BEAST_EXPECT(ownerCount(env, yui) == 1);
2116 gw1.verifyOwners(__LINE__);
2131 auto cmpTrustLines = [
this, &env](
2132 Account
const& acct1,
2133 Account
const& acct2,
2134 IOU
const& offerIou,
2135 IOU
const& checkIou) {
2136 auto const offerLine =
2138 auto const checkLine =
2140 if (offerLine ==
nullptr || checkLine ==
nullptr)
2142 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
2148 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2153 [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
2154 STAmount const offerAmount = offerLine->at(sfield);
2155 STAmount const checkAmount = checkLine->at(sfield);
2172 cmpReqAmount(sfBalance);
2173 cmpReqAmount(sfLowLimit);
2174 cmpReqAmount(sfHighLimit);
2179 [
this, offerLine, checkLine](
auto const& sfield) {
2182 offerLine->isFieldPresent(sfield) ==
2183 checkLine->isFieldPresent(sfield)))
2188 if (!offerLine->isFieldPresent(sfield))
2194 offerLine->at(sfield) == checkLine->at(sfield));
2196 cmpOptField(sfLowNode);
2197 cmpOptField(sfLowQualityIn);
2198 cmpOptField(sfLowQualityOut);
2200 cmpOptField(sfHighNode);
2201 cmpOptField(sfHighQualityIn);
2202 cmpOptField(sfHighQualityOut);
2210 AccountOwns gw1{*
this, env,
"gw1", 0};
2212 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2213 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2214 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2217 IOU
const OF1 = gw1[
"OF1"];
2218 env(offer(gw1, XRP(98), OF1(98)));
2221 env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2222 env(offer(alice, OF1(98), XRP(98)));
2229 gw1.verifyOwners(__LINE__);
2232 alice.verifyOwners(__LINE__);
2235 IOU
const CK1 = gw1[
"CK1"];
2237 env(check::create(gw1, alice, CK1(98)));
2240 env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2241 env(check::cash(alice, chkId, CK1(98)));
2249 gw1.verifyOwners(__LINE__);
2252 alice.verifyOwners(__LINE__);
2254 cmpTrustLines(gw1, alice, OF1, CK1);
2265 AccountOwns gw1{*
this, env,
"gw1", 0};
2266 IOU
const OF1 = gw1[
"OF1"];
2267 env(offer(alice, XRP(97), OF1(97)));
2270 env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2271 env(offer(bob, OF1(97), XRP(97)));
2276 env.require(balance(alice, OF1(1)));
2277 env.require(balance(bob, OF1(97)));
2280 gw1.verifyOwners(__LINE__);
2281 alice.verifyOwners(__LINE__);
2282 bob.verifyOwners(__LINE__);
2290 IOU
const CK1 = gw1[
"CK1"];
2292 env(check::create(alice, bob, CK1(97)));
2295 env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2296 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2300 env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2302 env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2305 env(check::cancel(alice, chkId));
2309 gw1.verifyOwners(__LINE__);
2310 alice.verifyOwners(__LINE__);
2311 bob.verifyOwners(__LINE__);
2318 AccountOwns gw1{*
this, env,
"gw1", 0};
2323 IOU
const OF2 = gw1[
"OF2"];
2324 env(offer(gw1, XRP(96), OF2(96)));
2327 env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2328 env(offer(alice, OF2(96), XRP(96)));
2335 gw1.verifyOwners(__LINE__);
2338 alice.verifyOwners(__LINE__);
2341 IOU
const CK2 = gw1[
"CK2"];
2343 env(check::create(gw1, alice, CK2(96)));
2346 env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2347 env(check::cash(alice, chkId, CK2(96)));
2355 gw1.verifyOwners(__LINE__);
2358 alice.verifyOwners(__LINE__);
2360 cmpTrustLines(gw1, alice, OF2, CK2);
2368 AccountOwns gw1{*
this, env,
"gw1", 0};
2369 IOU
const OF2 = gw1[
"OF2"];
2370 env(offer(alice, XRP(95), OF2(95)));
2373 env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2374 env(offer(bob, OF2(95), XRP(95)));
2379 gw1.verifyOwners(__LINE__);
2380 alice.verifyOwners(__LINE__);
2381 bob.verifyOwners(__LINE__);
2384 IOU
const CK2 = gw1[
"CK2"];
2386 env(check::create(alice, bob, CK2(95)));
2389 env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2390 env(check::cash(bob, chkId, CK2(95)));
2396 gw1.verifyOwners(__LINE__);
2397 alice.verifyOwners(__LINE__);
2398 bob.verifyOwners(__LINE__);
2400 cmpTrustLines(alice, bob, OF2, CK2);
2411 AccountOwns gw1{*
this, env,
"gw1", 0};
2418 IOU
const OF3 = gw1[
"OF3"];
2419 env(offer(gw1, XRP(94), OF3(94)));
2422 env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2423 env(offer(alice, OF3(94), XRP(94)));
2430 gw1.verifyOwners(__LINE__);
2433 alice.verifyOwners(__LINE__);
2436 IOU
const CK3 = gw1[
"CK3"];
2438 env(check::create(gw1, alice, CK3(94)));
2441 env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2442 env(check::cash(alice, chkId, CK3(94)));
2450 gw1.verifyOwners(__LINE__);
2453 alice.verifyOwners(__LINE__);
2455 cmpTrustLines(gw1, alice, OF3, CK3);
2463 AccountOwns gw1{*
this, env,
"gw1", 0};
2464 IOU
const OF3 = gw1[
"OF3"];
2465 env(offer(alice, XRP(93), OF3(93)));
2468 env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2469 env(offer(bob, OF3(93), XRP(93)));
2474 gw1.verifyOwners(__LINE__);
2475 alice.verifyOwners(__LINE__);
2476 bob.verifyOwners(__LINE__);
2479 IOU
const CK3 = gw1[
"CK3"];
2481 env(check::create(alice, bob, CK3(93)));
2484 env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2485 env(check::cash(bob, chkId, CK3(93)));
2491 gw1.verifyOwners(__LINE__);
2492 alice.verifyOwners(__LINE__);
2493 bob.verifyOwners(__LINE__);
2495 cmpTrustLines(alice, bob, OF3, CK3);
2502 AccountOwns gw1{*
this, env,
"gw1", 0};
2507 IOU
const OF4 = gw1[
"OF4"];
2508 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2511 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2512 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2516 gw1.verifyOwners(__LINE__);
2517 alice.verifyOwners(__LINE__);
2518 bob.verifyOwners(__LINE__);
2521 IOU
const CK4 = gw1[
"CK4"];
2523 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2526 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2527 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2531 gw1.verifyOwners(__LINE__);
2532 alice.verifyOwners(__LINE__);
2533 bob.verifyOwners(__LINE__);
2538 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2540 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2548 AccountOwns gw1{*
this, env,
"gw1", 0};
2549 IOU
const OF4 = gw1[
"OF4"];
2550 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2553 env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2554 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2558 gw1.verifyOwners(__LINE__);
2559 alice.verifyOwners(__LINE__);
2560 bob.verifyOwners(__LINE__);
2563 IOU
const CK4 = gw1[
"CK4"];
2565 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2568 env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2569 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2573 gw1.verifyOwners(__LINE__);
2574 alice.verifyOwners(__LINE__);
2575 bob.verifyOwners(__LINE__);
2580 env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2582 env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2591 AccountOwns gw2{*
this, env,
"gw2", 0};
2592 env.fund(XRP(5000), gw2);
2601 IOU
const OF5 = gw2[
"OF5"];
2603 env(offer(gw2, XRP(92), OF5(92)));
2607 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2608 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2613 gw2.verifyOwners(__LINE__);
2614 alice.verifyOwners(__LINE__);
2615 bob.verifyOwners(__LINE__);
2618 env(offer_cancel(gw2, gw2OfferSeq));
2621 gw2.verifyOwners(__LINE__);
2624 IOU
const CK5 = gw2[
"CK5"];
2626 env(check::create(gw2, alice, CK5(92)));
2630 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2631 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2636 gw2.verifyOwners(__LINE__);
2637 alice.verifyOwners(__LINE__);
2638 bob.verifyOwners(__LINE__);
2643 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2645 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2648 env(check::cancel(gw2, chkId));
2651 gw2.verifyOwners(__LINE__);
2659 AccountOwns gw2{*
this, env,
"gw2", 0};
2660 IOU
const OF5 = gw2[
"OF5"];
2663 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2665 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2668 gw2.verifyOwners(__LINE__);
2669 alice.verifyOwners(__LINE__);
2670 bob.verifyOwners(__LINE__);
2673 IOU
const CK5 = gw2[
"CK5"];
2675 env(check::create(alice, bob, CK5(91)));
2678 env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2683 env(check::cancel(alice, chkId));
2687 gw2.verifyOwners(__LINE__);
2688 alice.verifyOwners(__LINE__);
2689 bob.verifyOwners(__LINE__);
2694 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2696 env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);
2722 using namespace test::jtx;
2723 auto const sa = testable_amendments();
Value removeMember(char const *key)
Remove and return the named member.
bool isMember(char const *key) const
Return true if the object has a member named key.
testcase_t testcase
Memberspace for declaring test cases.
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
void testCancelInvalid(FeatureBitset features)
void testCashXferFee(FeatureBitset features)
void testCashIOU(FeatureBitset features)
void testFix1623Enable(FeatureBitset features)
void testWithTickets(FeatureBitset features)
static std::vector< std::shared_ptr< SLE const > > checksOnAccount(test::jtx::Env &env, test::jtx::Account account)
void testCashXRP(FeatureBitset features)
void verifyDeliveredAmount(test::jtx::Env &env, STAmount const &amount)
void testEnabled(FeatureBitset features)
void testCashQuality(FeatureBitset features)
static uint256 getCheckIndex(AccountID const &account, std::uint32_t uSequence)
void testTrustLineCreation(FeatureBitset features)
FeatureBitset const disallowIncoming
void testCreateDisallowIncoming(FeatureBitset features)
void testCreateInvalid(FeatureBitset features)
void testCancelValid(FeatureBitset features)
void testCreateValid(FeatureBitset features)
void run() override
Runs the suite.
void testCashInvalid(FeatureBitset features)
void testWithFeats(FeatureBitset features)
A currency issued by an account.
Json::Value getJson(JsonOptions=JsonOptions::none) const override
int exponent() const noexcept
void setIssue(Asset const &asset)
Set the Issue for this amount.
bool negative() const noexcept
Issue const & issue() const
std::uint64_t mantissa() const noexcept
bool native() const noexcept
Immutable cryptographic account descriptor.
A transaction testing environment.
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Set DestinationTag on a JTx.
dest_tag(std::uint32_t tag)
void operator()(Env &, JTx &jt) const
void operator()(Env &, JTx &jt) const
expiration(NetClock::time_point const &expiry)
std::uint32_t const expry_
void operator()(Env &, JTx &jt) const
source_tag(std::uint32_t tag)
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
constexpr std::uint32_t asfGlobalFreeze
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
constexpr std::uint32_t asfDepositAuth
constexpr std::uint32_t asfRequireDest
@ lsfDisallowIncomingCheck
constexpr std::uint32_t tfImmediateOrCancel
constexpr std::uint32_t tfSetfAuth
constexpr std::uint32_t asfDefaultRipple
constexpr std::uint32_t asfDisallowIncomingCheck
constexpr std::uint32_t tfClearFreeze
@ tecNO_LINE_INSUF_RESERVE
@ tecINSUFFICIENT_RESERVE
void forEachItem(ReadView const &view, Keylet const &root, std::function< void(std::shared_ptr< SLE const > const &)> const &f)
Iterate all items in the given directory.
constexpr std::uint32_t asfRequireAuth
constexpr std::uint32_t tfSetFreeze
A field with a type known at compile time.
Execution context for applying a JSON transaction.