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);
156 env(check::create(env.master, alice, XRP(100)), ter(
temDISABLED));
159 env(check::cash(alice, checkId, XRP(100)), ter(
temDISABLED));
162 env(check::cancel(alice, checkId), ter(
temDISABLED));
168 Env env{*
this, features};
170 env.fund(XRP(1000), alice);
174 env(check::create(env.master, alice, XRP(100)));
177 env(check::cash(alice, checkId1, XRP(100)));
182 env(check::create(env.master, alice, XRP(100)));
185 env(check::cancel(alice, checkId2));
196 using namespace test::jtx;
198 Account
const gw{
"gateway"};
199 Account
const alice{
"alice"};
200 Account
const bob{
"bob"};
201 IOU
const USD{gw[
"USD"]};
203 Env env{*
this, features};
205 STAmount const startBalance{XRP(1000).value()};
206 env.fund(startBalance, gw, alice, bob);
211 auto writeTwoChecks = [&env, &USD,
this](
212 Account
const& from, Account
const& to) {
219 env(check::create(from, to, XRP(2000)));
222 env(check::create(from, to, USD(50)));
228 env.require(owners(from, fromOwnerCount + 2));
230 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
233 writeTwoChecks(alice, bob);
234 writeTwoChecks(gw, alice);
235 writeTwoChecks(alice, gw);
241 using namespace std::chrono_literals;
244 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
247 env(check::create(alice, bob, USD(50)), source_tag(2));
249 env(check::create(alice, bob, USD(50)), dest_tag(3));
251 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
253 env(check::create(alice, bob, USD(50)),
254 expiration(env.now() + 1s),
265 env(regkey(alice, alie));
270 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
274 env(check::create(alice, bob, USD(50)), sig(alie));
280 XRPAmount const baseFeeDrops{env.current()->fees().base};
281 env(check::create(alice, bob, USD(50)),
283 fee(3 * baseFeeDrops));
292 testcase(
"Create valid with disallow incoming");
294 using namespace test::jtx;
299 Account
const alice{
"alice"};
300 env.fund(XRP(10000), alice);
303 auto const sle = env.le(alice);
304 uint32_t flags = sle->getFlags();
308 Account
const gw{
"gateway"};
309 Account
const alice{
"alice"};
310 Account
const bob{
"bob"};
311 IOU
const USD{gw[
"USD"]};
315 STAmount const startBalance{XRP(1000).value()};
316 env.fund(startBalance, gw, alice, bob);
322 auto writeTwoChecksDI = [&env, &USD,
this](
332 env(check::create(from, to, XRP(2000)), ter(expected));
335 env(check::create(from, to, USD(50)), ter(expected));
344 env.require(owners(from, fromOwnerCount + 2));
346 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
353 env.require(owners(from, fromOwnerCount));
354 env.require(owners(to, to == from ? fromOwnerCount : toOwnerCount));
389 using namespace test::jtx;
391 Account
const gw1{
"gateway1"};
392 Account
const gwF{
"gatewayFrozen"};
393 Account
const alice{
"alice"};
394 Account
const bob{
"bob"};
395 IOU
const USD{gw1[
"USD"]};
397 Env env{*
this, features};
399 STAmount const startBalance{XRP(1000).value()};
400 env.fund(startBalance, gw1, gwF, alice, bob);
403 env(check::create(alice, bob, USD(50)),
409 env(check::create(alice, bob, USD(50)),
415 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
419 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
422 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
425 env(check::create(alice, bob, drops(1)));
434 env(check::create(alice, bob, USD(1)));
443 env(check::create(alice, bob, USD(50)),
449 Account
const bogie{
"bogie"};
450 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
460 env(check::create(alice, bob, USD(50)), dest_tag(11));
467 IOU
const USF{gwF[
"USF"]};
471 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
477 env(check::create(alice, bob, USF(50)));
483 env.trust(USD(1000), alice);
484 env.trust(USD(1000), bob);
486 env(pay(gw1, alice, USD(25)));
487 env(pay(gw1, bob, USD(25)));
495 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
499 env(check::create(bob, alice, USD(50)));
501 env(pay(bob, alice, USD(1)));
503 env(check::create(gw1, alice, USD(50)));
505 env(pay(gw1, alice, USD(1)));
511 env(check::create(alice, bob, USD(50)));
513 env(check::create(bob, alice, USD(50)));
515 env(check::create(gw1, alice, USD(50)));
523 env(check::create(alice, bob, USD(50)));
525 env(pay(alice, bob, USD(1)));
527 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
531 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
542 env(check::create(alice, bob, USD(50)),
543 expiration(env.now()),
547 using namespace std::chrono_literals;
548 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
552 Account
const cheri{
"cheri"};
553 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
555 env(check::create(cheri, bob, USD(50)),
556 fee(drops(env.current()->fees().base)),
560 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
563 env(check::create(cheri, bob, USD(50)));
573 using namespace test::jtx;
575 Account
const alice{
"alice"};
576 Account
const bob{
"bob"};
578 Env env{*
this, features};
580 XRPAmount const baseFeeDrops{env.current()->fees().base};
581 STAmount const startBalance{XRP(300).value()};
582 env.fund(startBalance, alice, bob);
586 env(check::create(alice, bob, XRP(10)));
588 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
589 env.require(balance(bob, startBalance));
592 BEAST_EXPECT(ownerCount(env, alice) == 1);
593 BEAST_EXPECT(ownerCount(env, bob) == 0);
595 env(check::cash(bob, chkId, XRP(10)));
598 balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
600 balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
603 BEAST_EXPECT(ownerCount(env, alice) == 0);
604 BEAST_EXPECT(ownerCount(env, bob) == 0);
607 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
608 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
610 env.require(balance(alice, startBalance));
611 env.require(balance(bob, startBalance));
615 STAmount const reserve{env.current()->fees().accountReserve(0)};
617 startBalance - reserve - drops(baseFeeDrops)};
619 env(check::create(alice, bob, checkAmount));
623 env(check::cash(bob, chkId, checkAmount + drops(1)),
627 bob, chkId, check::DeliverMin(checkAmount + drops(1))),
634 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
636 env.require(balance(alice, reserve));
638 bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
641 BEAST_EXPECT(ownerCount(env, alice) == 0);
642 BEAST_EXPECT(ownerCount(env, bob) == 0);
645 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
646 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
648 env.require(balance(alice, startBalance));
649 env.require(balance(bob, startBalance));
653 STAmount const reserve{env.current()->fees().accountReserve(0)};
655 startBalance - reserve - drops(baseFeeDrops - 1)};
657 env(check::create(alice, bob, checkAmount));
666 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
668 env.require(balance(alice, reserve));
670 bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
673 BEAST_EXPECT(ownerCount(env, alice) == 0);
674 BEAST_EXPECT(ownerCount(env, bob) == 0);
677 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
679 bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
681 env.require(balance(alice, startBalance));
682 env.require(balance(bob, startBalance));
692 using namespace test::jtx;
694 bool const cashCheckMakesTrustLine =
695 features[featureCheckCashMakesTrustLine];
697 Account
const gw{
"gateway"};
698 Account
const alice{
"alice"};
699 Account
const bob{
"bob"};
700 IOU
const USD{gw[
"USD"]};
703 Env env{*
this, features};
705 env.fund(XRP(1000), gw, alice, bob);
709 env(check::create(alice, bob, USD(10)));
717 env(trust(alice, USD(20)));
719 env(pay(gw, alice, USD(9.5)));
726 env(pay(gw, alice, USD(0.5)));
728 if (!cashCheckMakesTrustLine)
733 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_LINE));
738 env(trust(bob, USD(9.5)));
740 if (!cashCheckMakesTrustLine)
751 env(trust(bob, USD(10.5)));
757 env(check::cash(bob, chkId1, USD(10)));
759 env.require(balance(alice, USD(0)));
760 env.require(balance(bob, USD(10)));
763 BEAST_EXPECT(ownerCount(env, alice) == 1);
764 BEAST_EXPECT(ownerCount(env, bob) == 1);
767 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
771 env(pay(bob, alice, USD(7)));
775 env(check::create(alice, bob, USD(7)));
782 env(check::cash(bob, chkId2, USD(5)));
784 env.require(balance(alice, USD(2)));
785 env.require(balance(bob, USD(8)));
788 BEAST_EXPECT(ownerCount(env, alice) == 1);
789 BEAST_EXPECT(ownerCount(env, bob) == 1);
793 env(check::create(alice, bob, USD(2)));
796 env(check::create(alice, bob, USD(2)));
802 env(check::cash(bob, chkId4, USD(2)));
804 env.require(balance(alice, USD(0)));
805 env.require(balance(bob, USD(10)));
808 BEAST_EXPECT(ownerCount(env, alice) == 2);
809 BEAST_EXPECT(ownerCount(env, bob) == 1);
815 env.require(balance(alice, USD(0)));
816 env.require(balance(bob, USD(10)));
819 BEAST_EXPECT(ownerCount(env, alice) == 2);
820 BEAST_EXPECT(ownerCount(env, bob) == 1);
822 if (cashCheckMakesTrustLine)
838 env(check::create(gw, bob, USD(20)));
842 env(check::cash(bob, chkId20, USD(20)));
844 env.require(balance(bob, USD(30)));
848 env(pay(bob, gw, USD(20)));
852 env(check::cancel(bob, chkId3));
854 env.require(balance(alice, USD(0)));
855 env.require(balance(bob, USD(10)));
858 BEAST_EXPECT(ownerCount(env, alice) == 1);
859 BEAST_EXPECT(ownerCount(env, bob) == 1);
863 Env env{*
this, features};
865 env.fund(XRP(1000), gw, alice, bob);
867 env(trust(alice, USD(20)));
868 env(trust(bob, USD(20)));
870 env(pay(gw, alice, USD(8)));
875 env(check::create(alice, bob, USD(9)));
878 env(check::create(alice, bob, USD(8)));
881 env(check::create(alice, bob, USD(7)));
884 env(check::create(alice, bob, USD(6)));
889 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
894 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
896 env.require(balance(alice, USD(0)));
897 env.require(balance(bob, USD(8)));
900 BEAST_EXPECT(ownerCount(env, alice) == 4);
901 BEAST_EXPECT(ownerCount(env, bob) == 1);
904 env(pay(bob, alice, USD(7)));
909 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
911 env.require(balance(alice, USD(0)));
912 env.require(balance(bob, USD(8)));
915 BEAST_EXPECT(ownerCount(env, alice) == 3);
916 BEAST_EXPECT(ownerCount(env, bob) == 1);
919 env(pay(bob, alice, USD(8)));
924 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
926 env.require(balance(alice, USD(2)));
927 env.require(balance(bob, USD(6)));
930 BEAST_EXPECT(ownerCount(env, alice) == 2);
931 BEAST_EXPECT(ownerCount(env, bob) == 1);
935 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
937 env.require(balance(alice, USD(0)));
938 env.require(balance(bob, USD(8)));
941 BEAST_EXPECT(ownerCount(env, alice) == 1);
942 BEAST_EXPECT(ownerCount(env, bob) == 1);
946 Env env(*
this, features);
948 env.fund(XRP(1000), gw, alice, bob);
951 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
952 env(trust(alice, USD(20)));
954 env(pay(gw, alice, USD(8)));
960 env(check::create(alice, bob, USD(7)));
963 env(check::cash(bob, chkId, USD(7)),
969 env(trust(bob, USD(5)));
972 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
976 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
981 if (!cashCheckMakesTrustLine)
997 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
998 STAmount const bobGot = cashCheckMakesTrustLine ? USD(7) : USD(5);
1000 env.require(balance(alice, USD(8) - bobGot));
1001 env.require(balance(bob, bobGot));
1005 BEAST_EXPECT(ownerCount(env, alice) == 1);
1006 BEAST_EXPECT(ownerCount(env, bob) == 1);
1012 for (
auto const& testFeatures :
1013 {features - featureMultiSignReserve,
1014 features | featureMultiSignReserve})
1016 Env env{*
this, testFeatures};
1018 env.fund(XRP(1000), gw, alice, bob);
1022 env(check::create(alice, bob, USD(1)));
1026 env(check::create(alice, bob, USD(2)));
1029 env(trust(alice, USD(20)));
1030 env(trust(bob, USD(20)));
1032 env(pay(gw, alice, USD(8)));
1037 env(regkey(bob, bobby));
1042 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
1047 int const signersCount = {
1048 testFeatures[featureMultiSignReserve] ? 1 : 4};
1049 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1052 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
1054 env.require(balance(alice, USD(7)));
1055 env.require(balance(bob, USD(1)));
1058 BEAST_EXPECT(ownerCount(env, alice) == 2);
1059 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1062 XRPAmount const baseFeeDrops{env.current()->fees().base};
1063 env(check::cash(bob, chkId2, (USD(2))),
1065 fee(3 * baseFeeDrops));
1067 env.require(balance(alice, USD(5)));
1068 env.require(balance(bob, USD(3)));
1071 BEAST_EXPECT(ownerCount(env, alice) == 1);
1072 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1080 testcase(
"Cash with transfer fee");
1082 using namespace test::jtx;
1084 Account
const gw{
"gateway"};
1085 Account
const alice{
"alice"};
1086 Account
const bob{
"bob"};
1087 IOU
const USD{gw[
"USD"]};
1089 Env env{*
this, features};
1091 env.fund(XRP(1000), gw, alice, bob);
1093 env(trust(alice, USD(1000)));
1094 env(trust(bob, USD(1000)));
1096 env(pay(gw, alice, USD(1000)));
1100 env(rate(gw, 1.25));
1106 env(check::create(alice, bob, USD(125)));
1113 env(check::create(alice, bob, USD(120)));
1119 env(check::cash(bob, chkId125, check::DeliverMin(USD(101))),
1125 env(check::cash(bob, chkId125, check::DeliverMin(USD(75))));
1127 env.require(balance(alice, USD(1000 - 125)));
1128 env.require(balance(bob, USD(0 + 100)));
1138 env(check::cash(bob, chkId120, USD(50)));
1140 env.require(balance(alice, USD(1000 - 125 - 60)));
1141 env.require(balance(bob, USD(0 + 100 + 50)));
1152 using namespace test::jtx;
1154 Account
const gw{
"gateway"};
1155 Account
const alice{
"alice"};
1156 Account
const bob{
"bob"};
1157 IOU
const USD{gw[
"USD"]};
1159 Env env{*
this, features};
1161 env.fund(XRP(1000), gw, alice, bob);
1163 env(trust(alice, USD(1000)));
1164 env(trust(bob, USD(1000)));
1166 env(pay(gw, alice, USD(1000)));
1174 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1175 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1179 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1180 Account
const& truster,
1182 auto const& inOrOut,
1186 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1187 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1190 env(trust(truster, iou(1000)), inOrOut(pct));
1193 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1195 env.require(balance(alice, aliceStart - USD(10)));
1196 env.require(balance(bob, bobStart + USD(10)));
1200 env(trust(truster, iou(1000)), inOrOut(0));
1204 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1205 Account
const& truster,
1207 auto const& inOrOut,
1211 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1212 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1215 env(trust(truster, iou(1000)), inOrOut(pct));
1219 env(check::create(alice, bob, USD(10)));
1222 env(check::cash(bob, chkId, USD(amount)));
1224 env.require(balance(alice, aliceStart - USD(10)));
1225 env.require(balance(bob, bobStart + USD(10)));
1229 env(trust(truster, iou(1000)), inOrOut(0));
1234 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1235 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1238 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1239 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1241 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1242 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1244 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1245 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1247 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1248 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1250 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1251 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1253 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1254 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1256 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1257 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1264 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1265 Account
const& truster,
1267 auto const& inOrOut,
1275 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1278 env(trust(truster, iou(1000)), inOrOut(pct));
1282 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1284 env.require(balance(alice, aliceStart - USD(10)));
1287 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1289 env.require(balance(alice, aliceStart));
1293 env(trust(truster, iou(1000)), inOrOut(0));
1297 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1298 Account
const& truster,
1300 auto const& inOrOut,
1308 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1311 env(trust(truster, iou(1000)), inOrOut(pct));
1316 env(check::create(alice, gw, USD(max1)));
1319 env(check::cash(gw, chkAliceId, USD(amt1)));
1321 env.require(balance(alice, aliceStart - USD(10)));
1325 env(check::create(gw, alice, USD(max2)));
1328 env(check::cash(alice, chkGwId, USD(amt2)));
1330 env.require(balance(alice, aliceStart));
1334 env(trust(truster, iou(1000)), inOrOut(0));
1340 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1341 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1343 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1344 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1346 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1347 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1349 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1350 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1359 using namespace test::jtx;
1361 Account
const gw{
"gateway"};
1362 Account
const alice{
"alice"};
1363 Account
const bob{
"bob"};
1364 Account
const zoe{
"zoe"};
1365 IOU
const USD{gw[
"USD"]};
1367 Env env(*
this, features);
1369 env.fund(XRP(1000), gw, alice, bob, zoe);
1372 env(trust(alice, USD(20)));
1374 env(pay(gw, alice, USD(20)));
1381 env(check::create(alice, bob, USD(20)));
1384 if (!features[featureCheckCashMakesTrustLine])
1389 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_LINE));
1395 env(trust(bob, USD(20)));
1401 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1407 env(check::create(alice, bob, USD(20)));
1411 env(check::create(alice, bob, XRP(10)));
1414 using namespace std::chrono_literals;
1416 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1420 env(check::create(alice, bob, USD(1)));
1424 env(check::create(alice, bob, USD(2)));
1428 env(check::create(alice, bob, USD(3)));
1432 env(check::create(alice, bob, USD(4)));
1436 env(check::create(alice, bob, USD(1)));
1440 env(check::create(alice, bob, USD(2)), dest_tag(7));
1444 auto failingCases = [&env, &gw, &alice, &bob](
1447 env(check::cash(bob, chkId, amount),
1453 env(check::cash(bob, chkId, amount),
1479 env(check::cash(bob, chkId, amount.zeroed()),
1485 if (!amount.native())
1502 IOU
const wrongCurrency{gw[
"EUR"]};
1504 badAmount.
setIssue(wrongCurrency.issue());
1505 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1511 IOU
const wrongIssuer{alice[
"USD"]};
1513 badAmount.
setIssue(wrongIssuer.issue());
1514 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1523 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1528 failingCases(chkIdX, XRP(10));
1529 failingCases(chkIdU, USD(20));
1532 env(check::cash(bob, chkIdU, USD(20)));
1534 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1538 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1542 env(check::cancel(zoe, chkIdExp));
1547 env(pay(bob, alice, USD(20)));
1549 env.require(balance(alice, USD(20)));
1550 env.require(balance(bob, USD(0)));
1558 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1566 env(check::cash(bob, chkIdFroz1, USD(1)));
1568 env.require(balance(alice, USD(19)));
1569 env.require(balance(bob, USD(1)));
1576 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1583 env(check::cash(bob, chkIdFroz2, USD(2)));
1585 env.require(balance(alice, USD(17)));
1586 env.require(balance(bob, USD(3)));
1591 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1593 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1600 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1602 env.require(balance(alice, USD(14)));
1603 env.require(balance(bob, USD(6)));
1609 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1611 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1618 env(check::cash(bob, chkIdFroz4, USD(4)));
1620 env.require(balance(alice, USD(10)));
1621 env.require(balance(bob, USD(10)));
1630 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1635 env(check::cash(bob, chkIdHasDest2, USD(2)));
1637 env.require(balance(alice, USD(8)));
1638 env.require(balance(bob, USD(12)));
1644 env(check::cash(bob, chkIdNoDest1, USD(1)));
1646 env.require(balance(alice, USD(7)));
1647 env.require(balance(bob, USD(13)));
1657 using namespace test::jtx;
1659 Account
const gw{
"gateway"};
1660 Account
const alice{
"alice"};
1661 Account
const bob{
"bob"};
1662 Account
const zoe{
"zoe"};
1663 IOU
const USD{gw[
"USD"]};
1667 for (
auto const& testFeatures :
1668 {features - featureMultiSignReserve,
1669 features | featureMultiSignReserve})
1671 Env env{*
this, testFeatures};
1673 env.fund(XRP(1000), gw, alice, bob, zoe);
1678 env(check::create(alice, bob, USD(10)));
1682 env(check::create(alice, bob, XRP(10)));
1686 env(check::create(alice, bob, USD(10)));
1690 using namespace std::chrono_literals;
1692 env(check::create(alice, bob, XRP(10)),
1693 expiration(env.now() + 600s));
1697 env(check::create(alice, bob, USD(10)),
1698 expiration(env.now() + 600s));
1702 env(check::create(alice, bob, XRP(10)),
1703 expiration(env.now() + 600s));
1708 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1712 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1716 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1721 env(check::create(alice, bob, USD(10)));
1725 env(check::create(alice, bob, XRP(10)));
1728 BEAST_EXPECT(ownerCount(env, alice) == 11);
1731 env(check::cancel(alice, chkId1));
1734 BEAST_EXPECT(ownerCount(env, alice) == 10);
1736 env(check::cancel(bob, chkId2));
1739 BEAST_EXPECT(ownerCount(env, alice) == 9);
1744 BEAST_EXPECT(ownerCount(env, alice) == 9);
1747 env(check::cancel(alice, chkIdNotExp1));
1750 BEAST_EXPECT(ownerCount(env, alice) == 8);
1752 env(check::cancel(bob, chkIdNotExp2));
1755 BEAST_EXPECT(ownerCount(env, alice) == 7);
1760 BEAST_EXPECT(ownerCount(env, alice) == 7);
1763 env(check::cancel(alice, chkIdExp1));
1766 BEAST_EXPECT(ownerCount(env, alice) == 6);
1768 env(check::cancel(bob, chkIdExp2));
1771 BEAST_EXPECT(ownerCount(env, alice) == 5);
1773 env(check::cancel(zoe, chkIdExp3));
1776 BEAST_EXPECT(ownerCount(env, alice) == 4);
1780 env(regkey(alice, alie));
1785 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1790 int const signersCount{
1791 testFeatures[featureMultiSignReserve] ? 1 : 4};
1794 env(check::cancel(alice, chkIdReg), sig(alie));
1797 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 3);
1800 XRPAmount const baseFeeDrops{env.current()->fees().base};
1801 env(check::cancel(alice, chkIdMSig),
1803 fee(3 * baseFeeDrops));
1806 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 2);
1809 env(check::cancel(alice, chkId3), sig(alice));
1812 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 1);
1814 env(check::cancel(bob, chkIdNotExp3));
1817 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 0);
1827 using namespace test::jtx;
1829 Account
const alice{
"alice"};
1830 Account
const bob{
"bob"};
1832 Env env{*
this, features};
1834 env.fund(XRP(1000), alice, bob);
1837 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1843 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1849 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1859 using namespace test::jtx;
1861 auto testEnable = [
this](
1866 Account
const alice{
"alice"};
1867 Account
const bob{
"bob"};
1869 Env env{*
this, features};
1871 env.fund(XRP(1000), alice, bob);
1875 env(check::create(alice, bob, XRP(200)));
1878 env(check::cash(bob, chkId, check::DeliverMin(XRP(100))));
1888 env.rpc(
"tx", txHash)[jss::result][jss::meta];
1891 meta.
isMember(sfDeliveredAmount.jsonName) == hasFields);
1892 BEAST_EXPECT(meta.
isMember(jss::delivered_amount) == hasFields);
1896 testEnable(features - fix1623,
false);
1897 testEnable(features,
true);
1905 using namespace test::jtx;
1907 Account
const gw{
"gw"};
1908 Account
const alice{
"alice"};
1909 Account
const bob{
"bob"};
1910 IOU
const USD{gw[
"USD"]};
1912 Env env{*
this, features};
1913 env.fund(XRP(1000), gw, alice, bob);
1920 env(ticket::create(alice, 10));
1924 env(ticket::create(bob, 10));
1928 env.require(owners(alice, 10));
1929 env.require(owners(bob, 10));
1932 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1933 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1935 env.require(owners(alice, 10));
1936 env.require(owners(bob, 10));
1938 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1939 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1941 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1942 BEAST_EXPECT(env.seq(bob) == bobSeq);
1944 env(pay(gw, alice, USD(900)));
1950 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1953 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1956 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1959 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1963 env.require(owners(alice, 10));
1964 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1966 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1968 env.require(owners(bob, 10));
1969 BEAST_EXPECT(env.seq(bob) == bobSeq);
1972 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1973 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1976 env.require(owners(alice, 8));
1977 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1979 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1981 env.require(owners(bob, 8));
1982 BEAST_EXPECT(env.seq(bob) == bobSeq);
1985 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1986 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1989 env.require(owners(alice, 6));
1990 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1992 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1993 env.require(balance(alice, USD(700)));
1994 env.require(balance(alice, drops(699'999'940)));
1996 env.require(owners(bob, 6));
1997 BEAST_EXPECT(env.seq(bob) == bobSeq);
1998 env.require(balance(bob, USD(200)));
1999 env.require(balance(bob, drops(1'299'999'940)));
2010 assert(features[featureCheckCashMakesTrustLine]);
2014 using namespace test::jtx;
2016 Env env{*
this, features};
2030 ownerCount(env, acct) == owners,
2031 "Owner count mismatch",
2037 operator Account
const()
const
2054 AccountOwns alice{*
this, env,
"alice", 0};
2055 AccountOwns bob{*
this, env,
"bob", 0};
2058 env.fund(XRP(5000), noripple(alice, bob));
2064 AccountOwns gw1{*
this, env,
"gw1", 0};
2069 env.fund(XRP(5000), noripple(gw1));
2072 IOU
const CK8 = gw1[
"CK8"];
2073 gw1.verifyOwners(__LINE__);
2075 Account
const yui{
"yui"};
2080 env.fund(XRP(200), yui);
2084 env(check::create(gw1, yui, CK8(99)));
2087 env(check::cash(yui, chkId, CK8(99)),
2090 alice.verifyOwners(__LINE__);
2094 env(pay(env.master, yui, XRP(51)));
2096 env(check::cash(yui, chkId, CK8(99)));
2099 BEAST_EXPECT(ownerCount(env, yui) == 1);
2103 gw1.verifyOwners(__LINE__);
2118 auto cmpTrustLines = [
this, &env](
2119 Account
const& acct1,
2120 Account
const& acct2,
2121 IOU
const& offerIou,
2122 IOU
const& checkIou) {
2123 auto const offerLine =
2125 auto const checkLine =
2127 if (offerLine ==
nullptr || checkLine ==
nullptr)
2129 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
2135 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2140 [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
2141 STAmount const offerAmount = offerLine->at(sfield);
2142 STAmount const checkAmount = checkLine->at(sfield);
2159 cmpReqAmount(sfBalance);
2160 cmpReqAmount(sfLowLimit);
2161 cmpReqAmount(sfHighLimit);
2166 [
this, offerLine, checkLine](
auto const& sfield) {
2169 offerLine->isFieldPresent(sfield) ==
2170 checkLine->isFieldPresent(sfield)))
2175 if (!offerLine->isFieldPresent(sfield))
2181 offerLine->at(sfield) == checkLine->at(sfield));
2183 cmpOptField(sfLowNode);
2184 cmpOptField(sfLowQualityIn);
2185 cmpOptField(sfLowQualityOut);
2187 cmpOptField(sfHighNode);
2188 cmpOptField(sfHighQualityIn);
2189 cmpOptField(sfHighQualityOut);
2197 AccountOwns gw1{*
this, env,
"gw1", 0};
2199 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2200 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2201 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2204 IOU
const OF1 = gw1[
"OF1"];
2205 env(offer(gw1, XRP(98), OF1(98)));
2208 env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2209 env(offer(alice, OF1(98), XRP(98)));
2216 gw1.verifyOwners(__LINE__);
2219 alice.verifyOwners(__LINE__);
2222 IOU
const CK1 = gw1[
"CK1"];
2224 env(check::create(gw1, alice, CK1(98)));
2227 env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2228 env(check::cash(alice, chkId, CK1(98)));
2236 gw1.verifyOwners(__LINE__);
2239 alice.verifyOwners(__LINE__);
2241 cmpTrustLines(gw1, alice, OF1, CK1);
2252 AccountOwns gw1{*
this, env,
"gw1", 0};
2253 IOU
const OF1 = gw1[
"OF1"];
2254 env(offer(alice, XRP(97), OF1(97)));
2257 env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2258 env(offer(bob, OF1(97), XRP(97)));
2263 env.require(balance(alice, OF1(1)));
2264 env.require(balance(bob, OF1(97)));
2267 gw1.verifyOwners(__LINE__);
2268 alice.verifyOwners(__LINE__);
2269 bob.verifyOwners(__LINE__);
2277 IOU
const CK1 = gw1[
"CK1"];
2279 env(check::create(alice, bob, CK1(97)));
2282 env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2283 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2287 env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2289 env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2292 env(check::cancel(alice, chkId));
2296 gw1.verifyOwners(__LINE__);
2297 alice.verifyOwners(__LINE__);
2298 bob.verifyOwners(__LINE__);
2305 AccountOwns gw1{*
this, env,
"gw1", 0};
2310 IOU
const OF2 = gw1[
"OF2"];
2311 env(offer(gw1, XRP(96), OF2(96)));
2314 env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2315 env(offer(alice, OF2(96), XRP(96)));
2322 gw1.verifyOwners(__LINE__);
2325 alice.verifyOwners(__LINE__);
2328 IOU
const CK2 = gw1[
"CK2"];
2330 env(check::create(gw1, alice, CK2(96)));
2333 env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2334 env(check::cash(alice, chkId, CK2(96)));
2342 gw1.verifyOwners(__LINE__);
2345 alice.verifyOwners(__LINE__);
2347 cmpTrustLines(gw1, alice, OF2, CK2);
2355 AccountOwns gw1{*
this, env,
"gw1", 0};
2356 IOU
const OF2 = gw1[
"OF2"];
2357 env(offer(alice, XRP(95), OF2(95)));
2360 env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2361 env(offer(bob, OF2(95), XRP(95)));
2366 gw1.verifyOwners(__LINE__);
2367 alice.verifyOwners(__LINE__);
2368 bob.verifyOwners(__LINE__);
2371 IOU
const CK2 = gw1[
"CK2"];
2373 env(check::create(alice, bob, CK2(95)));
2376 env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2377 env(check::cash(bob, chkId, CK2(95)));
2383 gw1.verifyOwners(__LINE__);
2384 alice.verifyOwners(__LINE__);
2385 bob.verifyOwners(__LINE__);
2387 cmpTrustLines(alice, bob, OF2, CK2);
2398 AccountOwns gw1{*
this, env,
"gw1", 0};
2405 IOU
const OF3 = gw1[
"OF3"];
2406 env(offer(gw1, XRP(94), OF3(94)));
2409 env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2410 env(offer(alice, OF3(94), XRP(94)));
2417 gw1.verifyOwners(__LINE__);
2420 alice.verifyOwners(__LINE__);
2423 IOU
const CK3 = gw1[
"CK3"];
2425 env(check::create(gw1, alice, CK3(94)));
2428 env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2429 env(check::cash(alice, chkId, CK3(94)));
2437 gw1.verifyOwners(__LINE__);
2440 alice.verifyOwners(__LINE__);
2442 cmpTrustLines(gw1, alice, OF3, CK3);
2450 AccountOwns gw1{*
this, env,
"gw1", 0};
2451 IOU
const OF3 = gw1[
"OF3"];
2452 env(offer(alice, XRP(93), OF3(93)));
2455 env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2456 env(offer(bob, OF3(93), XRP(93)));
2461 gw1.verifyOwners(__LINE__);
2462 alice.verifyOwners(__LINE__);
2463 bob.verifyOwners(__LINE__);
2466 IOU
const CK3 = gw1[
"CK3"];
2468 env(check::create(alice, bob, CK3(93)));
2471 env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2472 env(check::cash(bob, chkId, CK3(93)));
2478 gw1.verifyOwners(__LINE__);
2479 alice.verifyOwners(__LINE__);
2480 bob.verifyOwners(__LINE__);
2482 cmpTrustLines(alice, bob, OF3, CK3);
2489 AccountOwns gw1{*
this, env,
"gw1", 0};
2494 IOU
const OF4 = gw1[
"OF4"];
2495 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2498 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2499 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2503 gw1.verifyOwners(__LINE__);
2504 alice.verifyOwners(__LINE__);
2505 bob.verifyOwners(__LINE__);
2508 IOU
const CK4 = gw1[
"CK4"];
2510 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2513 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2514 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2518 gw1.verifyOwners(__LINE__);
2519 alice.verifyOwners(__LINE__);
2520 bob.verifyOwners(__LINE__);
2525 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2527 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2535 AccountOwns gw1{*
this, env,
"gw1", 0};
2536 IOU
const OF4 = gw1[
"OF4"];
2537 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2540 env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2541 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2545 gw1.verifyOwners(__LINE__);
2546 alice.verifyOwners(__LINE__);
2547 bob.verifyOwners(__LINE__);
2550 IOU
const CK4 = gw1[
"CK4"];
2552 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2555 env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2556 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2560 gw1.verifyOwners(__LINE__);
2561 alice.verifyOwners(__LINE__);
2562 bob.verifyOwners(__LINE__);
2567 env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2569 env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2578 AccountOwns gw2{*
this, env,
"gw2", 0};
2579 env.fund(XRP(5000), gw2);
2588 IOU
const OF5 = gw2[
"OF5"];
2590 env(offer(gw2, XRP(92), OF5(92)));
2594 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2595 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2600 gw2.verifyOwners(__LINE__);
2601 alice.verifyOwners(__LINE__);
2602 bob.verifyOwners(__LINE__);
2605 env(offer_cancel(gw2, gw2OfferSeq));
2608 gw2.verifyOwners(__LINE__);
2611 IOU
const CK5 = gw2[
"CK5"];
2613 env(check::create(gw2, alice, CK5(92)));
2617 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2618 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2623 gw2.verifyOwners(__LINE__);
2624 alice.verifyOwners(__LINE__);
2625 bob.verifyOwners(__LINE__);
2630 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2632 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2635 env(check::cancel(gw2, chkId));
2638 gw2.verifyOwners(__LINE__);
2646 AccountOwns gw2{*
this, env,
"gw2", 0};
2647 IOU
const OF5 = gw2[
"OF5"];
2650 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2652 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2655 gw2.verifyOwners(__LINE__);
2656 alice.verifyOwners(__LINE__);
2657 bob.verifyOwners(__LINE__);
2660 IOU
const CK5 = gw2[
"CK5"];
2662 env(check::create(alice, bob, CK5(91)));
2665 env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2670 env(check::cancel(alice, chkId));
2674 gw2.verifyOwners(__LINE__);
2675 alice.verifyOwners(__LINE__);
2676 bob.verifyOwners(__LINE__);
2681 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2683 env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);
2709 using namespace test::jtx;
2710 auto const sa = supported_amendments();
Value removeMember(const char *key)
Remove and return the named member.
bool isMember(const char *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) 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.