21#include <xrpl/protocol/Feature.h>
22#include <xrpl/protocol/jss.h>
36 :
expry_{expiry.time_since_epoch().count()}
43 jt[sfExpiration.jsonName] =
expry_;
61 jt[sfSourceTag.jsonName] =
tag_;
79 jt[sfDestinationTag.jsonName] =
tag_;
105 if (sle && sle->getType() == ltCHECK)
106 result.push_back(sle);
124 Json::Value const meta = env.
rpc(
"tx", txHash)[jss::result][jss::meta];
127 if (!BEAST_EXPECT(meta.
isMember(sfDeliveredAmount.jsonName)))
133 meta[sfDeliveredAmount.jsonName] ==
144 using namespace test::jtx;
145 Account
const alice{
"alice"};
149 Env env{*
this, features - featureChecks};
151 env.fund(XRP(1000), alice);
155 env(check::create(env.master, alice, XRP(100)), ter(
temDISABLED));
158 env(check::cash(alice, checkId, XRP(100)), ter(
temDISABLED));
161 env(check::cancel(alice, checkId), ter(
temDISABLED));
167 Env env{*
this, features};
169 env.fund(XRP(1000), alice);
173 env(check::create(env.master, alice, XRP(100)));
176 env(check::cash(alice, checkId1, XRP(100)));
181 env(check::create(env.master, alice, XRP(100)));
184 env(check::cancel(alice, checkId2));
195 using namespace test::jtx;
197 Account
const gw{
"gateway"};
198 Account
const alice{
"alice"};
199 Account
const bob{
"bob"};
200 IOU
const USD{gw[
"USD"]};
202 Env env{*
this, features};
204 STAmount const startBalance{XRP(1000).value()};
205 env.fund(startBalance, gw, alice, bob);
210 auto writeTwoChecks = [&env, &USD,
this](
211 Account
const& from, Account
const& to) {
218 env(check::create(from, to, XRP(2000)));
221 env(check::create(from, to, USD(50)));
227 env.require(owners(from, fromOwnerCount + 2));
229 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
232 writeTwoChecks(alice, bob);
233 writeTwoChecks(gw, alice);
234 writeTwoChecks(alice, gw);
240 using namespace std::chrono_literals;
243 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
246 env(check::create(alice, bob, USD(50)), source_tag(2));
248 env(check::create(alice, bob, USD(50)), dest_tag(3));
250 env(check::create(alice, bob, USD(50)), invoice_id(
uint256{4}));
252 env(check::create(alice, bob, USD(50)),
253 expiration(env.now() + 1s),
264 env(regkey(alice, alie));
269 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
273 env(check::create(alice, bob, USD(50)), sig(alie));
279 XRPAmount const baseFeeDrops{env.current()->fees().base};
280 env(check::create(alice, bob, USD(50)),
282 fee(3 * baseFeeDrops));
291 testcase(
"Create valid with disallow incoming");
293 using namespace test::jtx;
298 Account
const alice{
"alice"};
299 env.fund(XRP(10000), alice);
302 auto const sle = env.le(alice);
303 uint32_t flags = sle->getFlags();
307 Account
const gw{
"gateway"};
308 Account
const alice{
"alice"};
309 Account
const bob{
"bob"};
310 IOU
const USD{gw[
"USD"]};
314 STAmount const startBalance{XRP(1000).value()};
315 env.fund(startBalance, gw, alice, bob);
321 auto writeTwoChecksDI = [&env, &USD,
this](
331 env(check::create(from, to, XRP(2000)), ter(expected));
334 env(check::create(from, to, USD(50)), ter(expected));
343 env.require(owners(from, fromOwnerCount + 2));
345 owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
352 env.require(owners(from, fromOwnerCount));
353 env.require(owners(to, to == from ? fromOwnerCount : toOwnerCount));
388 using namespace test::jtx;
390 Account
const gw1{
"gateway1"};
391 Account
const gwF{
"gatewayFrozen"};
392 Account
const alice{
"alice"};
393 Account
const bob{
"bob"};
394 IOU
const USD{gw1[
"USD"]};
396 Env env{*
this, features};
398 STAmount const startBalance{XRP(1000).value()};
399 env.fund(startBalance, gw1, gwF, alice, bob);
402 env(check::create(alice, bob, USD(50)),
408 env(check::create(alice, bob, USD(50)),
414 env(check::create(alice, alice, XRP(10)), ter(
temREDUNDANT));
418 env(check::create(alice, bob, drops(-1)), ter(
temBAD_AMOUNT));
421 env(check::create(alice, bob, drops(0)), ter(
temBAD_AMOUNT));
424 env(check::create(alice, bob, drops(1)));
433 env(check::create(alice, bob, USD(1)));
442 env(check::create(alice, bob, USD(50)),
448 Account
const bogie{
"bogie"};
449 env(check::create(alice, bogie, USD(50)), ter(
tecNO_DST));
459 env(check::create(alice, bob, USD(50)), dest_tag(11));
466 IOU
const USF{gwF[
"USF"]};
470 env(check::create(alice, bob, USF(50)), ter(
tecFROZEN));
476 env(check::create(alice, bob, USF(50)));
482 env.trust(USD(1000), alice);
483 env.trust(USD(1000), bob);
485 env(pay(gw1, alice, USD(25)));
486 env(pay(gw1, bob, USD(25)));
494 env(check::create(alice, bob, USD(50)), ter(
tecFROZEN));
498 env(check::create(bob, alice, USD(50)));
500 env(pay(bob, alice, USD(1)));
502 env(check::create(gw1, alice, USD(50)));
504 env(pay(gw1, alice, USD(1)));
510 env(check::create(alice, bob, USD(50)));
512 env(check::create(bob, alice, USD(50)));
514 env(check::create(gw1, alice, USD(50)));
522 env(check::create(alice, bob, USD(50)));
524 env(pay(alice, bob, USD(1)));
526 env(check::create(bob, alice, USD(50)), ter(
tecFROZEN));
530 env(check::create(gw1, alice, USD(50)), ter(
tecFROZEN));
541 env(check::create(alice, bob, USD(50)),
542 expiration(env.now()),
546 using namespace std::chrono_literals;
547 env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
551 Account
const cheri{
"cheri"};
552 env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
554 env(check::create(cheri, bob, USD(50)),
555 fee(drops(env.current()->fees().base)),
559 env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
562 env(check::create(cheri, bob, USD(50)));
572 using namespace test::jtx;
574 Account
const alice{
"alice"};
575 Account
const bob{
"bob"};
577 Env env{*
this, features};
579 XRPAmount const baseFeeDrops{env.current()->fees().base};
580 STAmount const startBalance{XRP(300).value()};
581 env.fund(startBalance, alice, bob);
585 env(check::create(alice, bob, XRP(10)));
587 env.require(balance(alice, startBalance - drops(baseFeeDrops)));
588 env.require(balance(bob, startBalance));
591 BEAST_EXPECT(ownerCount(env, alice) == 1);
592 BEAST_EXPECT(ownerCount(env, bob) == 0);
594 env(check::cash(bob, chkId, XRP(10)));
597 balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
599 balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
602 BEAST_EXPECT(ownerCount(env, alice) == 0);
603 BEAST_EXPECT(ownerCount(env, bob) == 0);
606 env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
607 env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
609 env.require(balance(alice, startBalance));
610 env.require(balance(bob, startBalance));
614 STAmount const reserve{env.current()->fees().accountReserve(0)};
616 startBalance - reserve - drops(baseFeeDrops)};
618 env(check::create(alice, bob, checkAmount));
622 env(check::cash(bob, chkId, checkAmount + drops(1)),
626 bob, chkId, check::DeliverMin(checkAmount + drops(1))),
633 env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
635 env.require(balance(alice, reserve));
637 bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
640 BEAST_EXPECT(ownerCount(env, alice) == 0);
641 BEAST_EXPECT(ownerCount(env, bob) == 0);
644 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
645 env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
647 env.require(balance(alice, startBalance));
648 env.require(balance(bob, startBalance));
652 STAmount const reserve{env.current()->fees().accountReserve(0)};
654 startBalance - reserve - drops(baseFeeDrops - 1)};
656 env(check::create(alice, bob, checkAmount));
665 env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
667 env.require(balance(alice, reserve));
669 bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
672 BEAST_EXPECT(ownerCount(env, alice) == 0);
673 BEAST_EXPECT(ownerCount(env, bob) == 0);
676 env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
678 bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
680 env.require(balance(alice, startBalance));
681 env.require(balance(bob, startBalance));
691 using namespace test::jtx;
693 bool const cashCheckMakesTrustLine =
694 features[featureCheckCashMakesTrustLine];
696 Account
const gw{
"gateway"};
697 Account
const alice{
"alice"};
698 Account
const bob{
"bob"};
699 IOU
const USD{gw[
"USD"]};
702 Env env{*
this, features};
704 env.fund(XRP(1000), gw, alice, bob);
708 env(check::create(alice, bob, USD(10)));
716 env(trust(alice, USD(20)));
718 env(pay(gw, alice, USD(9.5)));
725 env(pay(gw, alice, USD(0.5)));
727 if (!cashCheckMakesTrustLine)
732 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_LINE));
737 env(trust(bob, USD(9.5)));
739 if (!cashCheckMakesTrustLine)
750 env(trust(bob, USD(10.5)));
756 env(check::cash(bob, chkId1, USD(10)));
758 env.require(balance(alice, USD(0)));
759 env.require(balance(bob, USD(10)));
762 BEAST_EXPECT(ownerCount(env, alice) == 1);
763 BEAST_EXPECT(ownerCount(env, bob) == 1);
766 env(check::cash(bob, chkId1, USD(10)), ter(
tecNO_ENTRY));
770 env(pay(bob, alice, USD(7)));
774 env(check::create(alice, bob, USD(7)));
781 env(check::cash(bob, chkId2, USD(5)));
783 env.require(balance(alice, USD(2)));
784 env.require(balance(bob, USD(8)));
787 BEAST_EXPECT(ownerCount(env, alice) == 1);
788 BEAST_EXPECT(ownerCount(env, bob) == 1);
792 env(check::create(alice, bob, USD(2)));
795 env(check::create(alice, bob, USD(2)));
801 env(check::cash(bob, chkId4, USD(2)));
803 env.require(balance(alice, USD(0)));
804 env.require(balance(bob, USD(10)));
807 BEAST_EXPECT(ownerCount(env, alice) == 2);
808 BEAST_EXPECT(ownerCount(env, bob) == 1);
814 env.require(balance(alice, USD(0)));
815 env.require(balance(bob, USD(10)));
818 BEAST_EXPECT(ownerCount(env, alice) == 2);
819 BEAST_EXPECT(ownerCount(env, bob) == 1);
821 if (cashCheckMakesTrustLine)
837 env(check::create(gw, bob, USD(20)));
841 env(check::cash(bob, chkId20, USD(20)));
843 env.require(balance(bob, USD(30)));
847 env(pay(bob, gw, USD(20)));
851 env(check::cancel(bob, chkId3));
853 env.require(balance(alice, USD(0)));
854 env.require(balance(bob, USD(10)));
857 BEAST_EXPECT(ownerCount(env, alice) == 1);
858 BEAST_EXPECT(ownerCount(env, bob) == 1);
862 Env env{*
this, features};
864 env.fund(XRP(1000), gw, alice, bob);
866 env(trust(alice, USD(20)));
867 env(trust(bob, USD(20)));
869 env(pay(gw, alice, USD(8)));
874 env(check::create(alice, bob, USD(9)));
877 env(check::create(alice, bob, USD(8)));
880 env(check::create(alice, bob, USD(7)));
883 env(check::create(alice, bob, USD(6)));
888 env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
893 env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
895 env.require(balance(alice, USD(0)));
896 env.require(balance(bob, USD(8)));
899 BEAST_EXPECT(ownerCount(env, alice) == 4);
900 BEAST_EXPECT(ownerCount(env, bob) == 1);
903 env(pay(bob, alice, USD(7)));
908 env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
910 env.require(balance(alice, USD(0)));
911 env.require(balance(bob, USD(8)));
914 BEAST_EXPECT(ownerCount(env, alice) == 3);
915 BEAST_EXPECT(ownerCount(env, bob) == 1);
918 env(pay(bob, alice, USD(8)));
923 env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
925 env.require(balance(alice, USD(2)));
926 env.require(balance(bob, USD(6)));
929 BEAST_EXPECT(ownerCount(env, alice) == 2);
930 BEAST_EXPECT(ownerCount(env, bob) == 1);
934 env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
936 env.require(balance(alice, USD(0)));
937 env.require(balance(bob, USD(8)));
940 BEAST_EXPECT(ownerCount(env, alice) == 1);
941 BEAST_EXPECT(ownerCount(env, bob) == 1);
945 Env env(*
this, features);
947 env.fund(XRP(1000), gw, alice, bob);
950 env(trust(gw, alice[
"USD"](100)), txflags(
tfSetfAuth));
951 env(trust(alice, USD(20)));
953 env(pay(gw, alice, USD(8)));
959 env(check::create(alice, bob, USD(7)));
962 env(check::cash(bob, chkId, USD(7)),
968 env(trust(bob, USD(5)));
971 env(check::cash(bob, chkId, USD(7)), ter(
tecNO_AUTH));
975 env(trust(gw, bob[
"USD"](1)), txflags(
tfSetfAuth));
980 if (!cashCheckMakesTrustLine)
996 env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
997 STAmount const bobGot = cashCheckMakesTrustLine ? USD(7) : USD(5);
999 env.require(balance(alice, USD(8) - bobGot));
1000 env.require(balance(bob, bobGot));
1004 BEAST_EXPECT(ownerCount(env, alice) == 1);
1005 BEAST_EXPECT(ownerCount(env, bob) == 1);
1011 for (
auto const& testFeatures :
1012 {features - featureMultiSignReserve,
1013 features | featureMultiSignReserve})
1015 Env env{*
this, testFeatures};
1017 env.fund(XRP(1000), gw, alice, bob);
1021 env(check::create(alice, bob, USD(1)));
1025 env(check::create(alice, bob, USD(2)));
1028 env(trust(alice, USD(20)));
1029 env(trust(bob, USD(20)));
1031 env(pay(gw, alice, USD(8)));
1036 env(regkey(bob, bobby));
1041 env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
1046 int const signersCount = {
1047 testFeatures[featureMultiSignReserve] ? 1 : 4};
1048 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1051 env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
1053 env.require(balance(alice, USD(7)));
1054 env.require(balance(bob, USD(1)));
1057 BEAST_EXPECT(ownerCount(env, alice) == 2);
1058 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1061 XRPAmount const baseFeeDrops{env.current()->fees().base};
1062 env(check::cash(bob, chkId2, (USD(2))),
1064 fee(3 * baseFeeDrops));
1066 env.require(balance(alice, USD(5)));
1067 env.require(balance(bob, USD(3)));
1070 BEAST_EXPECT(ownerCount(env, alice) == 1);
1071 BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1079 testcase(
"Cash with transfer fee");
1081 using namespace test::jtx;
1083 Account
const gw{
"gateway"};
1084 Account
const alice{
"alice"};
1085 Account
const bob{
"bob"};
1086 IOU
const USD{gw[
"USD"]};
1088 Env env{*
this, features};
1090 env.fund(XRP(1000), gw, alice, bob);
1092 env(trust(alice, USD(1000)));
1093 env(trust(bob, USD(1000)));
1095 env(pay(gw, alice, USD(1000)));
1099 env(rate(gw, 1.25));
1105 env(check::create(alice, bob, USD(125)));
1112 env(check::create(alice, bob, USD(120)));
1118 env(check::cash(bob, chkId125, check::DeliverMin(USD(101))),
1124 env(check::cash(bob, chkId125, check::DeliverMin(USD(75))));
1126 env.require(balance(alice, USD(1000 - 125)));
1127 env.require(balance(bob, USD(0 + 100)));
1137 env(check::cash(bob, chkId120, USD(50)));
1139 env.require(balance(alice, USD(1000 - 125 - 60)));
1140 env.require(balance(bob, USD(0 + 100 + 50)));
1151 using namespace test::jtx;
1153 Account
const gw{
"gateway"};
1154 Account
const alice{
"alice"};
1155 Account
const bob{
"bob"};
1156 IOU
const USD{gw[
"USD"]};
1158 Env env{*
this, features};
1160 env.fund(XRP(1000), gw, alice, bob);
1162 env(trust(alice, USD(1000)));
1163 env(trust(bob, USD(1000)));
1165 env(pay(gw, alice, USD(1000)));
1173 auto qIn = [](
double percent) {
return qualityInPercent(percent); };
1174 auto qOut = [](
double percent) {
return qualityOutPercent(percent); };
1178 auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1179 Account
const& truster,
1181 auto const& inOrOut,
1185 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1186 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1189 env(trust(truster, iou(1000)), inOrOut(pct));
1192 env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1194 env.require(balance(alice, aliceStart - USD(10)));
1195 env.require(balance(bob, bobStart + USD(10)));
1199 env(trust(truster, iou(1000)), inOrOut(0));
1203 auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1204 Account
const& truster,
1206 auto const& inOrOut,
1210 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1211 STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1214 env(trust(truster, iou(1000)), inOrOut(pct));
1218 env(check::create(alice, bob, USD(10)));
1221 env(check::cash(bob, chkId, USD(amount)));
1223 env.require(balance(alice, aliceStart - USD(10)));
1224 env.require(balance(bob, bobStart + USD(10)));
1228 env(trust(truster, iou(1000)), inOrOut(0));
1233 testNonIssuerQPay(alice, gw[
"USD"], qIn, 50, 10);
1234 testNonIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10);
1237 testNonIssuerQPay(bob, gw[
"USD"], qIn, 50, 5);
1238 testNonIssuerQCheck(bob, gw[
"USD"], qIn, 50, 5);
1240 testNonIssuerQPay(gw, alice[
"USD"], qIn, 50, 10);
1241 testNonIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10);
1243 testNonIssuerQPay(gw, bob[
"USD"], qIn, 50, 10);
1244 testNonIssuerQCheck(gw, bob[
"USD"], qIn, 50, 10);
1246 testNonIssuerQPay(alice, gw[
"USD"], qOut, 200, 10);
1247 testNonIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10);
1249 testNonIssuerQPay(bob, gw[
"USD"], qOut, 200, 10);
1250 testNonIssuerQCheck(bob, gw[
"USD"], qOut, 200, 10);
1252 testNonIssuerQPay(gw, alice[
"USD"], qOut, 200, 10);
1253 testNonIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10);
1255 testNonIssuerQPay(gw, bob[
"USD"], qOut, 200, 10);
1256 testNonIssuerQCheck(gw, bob[
"USD"], qOut, 200, 10);
1263 auto testIssuerQPay = [&env, &gw, &alice, &USD](
1264 Account
const& truster,
1266 auto const& inOrOut,
1274 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1277 env(trust(truster, iou(1000)), inOrOut(pct));
1281 env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1283 env.require(balance(alice, aliceStart - USD(10)));
1286 env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1288 env.require(balance(alice, aliceStart));
1292 env(trust(truster, iou(1000)), inOrOut(0));
1296 auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1297 Account
const& truster,
1299 auto const& inOrOut,
1307 STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1310 env(trust(truster, iou(1000)), inOrOut(pct));
1315 env(check::create(alice, gw, USD(max1)));
1318 env(check::cash(gw, chkAliceId, USD(amt1)));
1320 env.require(balance(alice, aliceStart - USD(10)));
1324 env(check::create(gw, alice, USD(max2)));
1327 env(check::cash(alice, chkGwId, USD(amt2)));
1329 env.require(balance(alice, aliceStart));
1333 env(trust(truster, iou(1000)), inOrOut(0));
1339 testIssuerQPay(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1340 testIssuerQCheck(alice, gw[
"USD"], qIn, 50, 10, 10, 5, 10);
1342 testIssuerQPay(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1343 testIssuerQCheck(gw, alice[
"USD"], qIn, 50, 10, 10, 10, 10);
1345 testIssuerQPay(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1346 testIssuerQCheck(alice, gw[
"USD"], qOut, 200, 10, 10, 10, 10);
1348 testIssuerQPay(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1349 testIssuerQCheck(gw, alice[
"USD"], qOut, 200, 10, 10, 10, 10);
1358 using namespace test::jtx;
1360 Account
const gw{
"gateway"};
1361 Account
const alice{
"alice"};
1362 Account
const bob{
"bob"};
1363 Account
const zoe{
"zoe"};
1364 IOU
const USD{gw[
"USD"]};
1366 Env env(*
this, features);
1368 env.fund(XRP(1000), gw, alice, bob, zoe);
1371 env(trust(alice, USD(20)));
1373 env(pay(gw, alice, USD(20)));
1380 env(check::create(alice, bob, USD(20)));
1383 if (!features[featureCheckCashMakesTrustLine])
1388 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_LINE));
1394 env(trust(bob, USD(20)));
1400 env(check::cash(bob, chkId, USD(20)), ter(
tecNO_ENTRY));
1406 env(check::create(alice, bob, USD(20)));
1410 env(check::create(alice, bob, XRP(10)));
1413 using namespace std::chrono_literals;
1415 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1419 env(check::create(alice, bob, USD(1)));
1423 env(check::create(alice, bob, USD(2)));
1427 env(check::create(alice, bob, USD(3)));
1431 env(check::create(alice, bob, USD(4)));
1435 env(check::create(alice, bob, USD(1)));
1439 env(check::create(alice, bob, USD(2)), dest_tag(7));
1443 auto failingCases = [&env, &gw, &alice, &bob](
1446 env(check::cash(bob, chkId, amount),
1452 env(check::cash(bob, chkId, amount),
1478 env(check::cash(bob, chkId, amount.zeroed()),
1484 if (!amount.native())
1501 IOU
const wrongCurrency{gw[
"EUR"]};
1503 badAmount.
setIssue(wrongCurrency.issue());
1504 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1510 IOU
const wrongIssuer{alice[
"USD"]};
1512 badAmount.
setIssue(wrongIssuer.issue());
1513 env(check::cash(bob, chkId, badAmount), ter(
temMALFORMED));
1522 env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1527 failingCases(chkIdX, XRP(10));
1528 failingCases(chkIdU, USD(20));
1531 env(check::cash(bob, chkIdU, USD(20)));
1533 env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1537 env(check::cash(bob, chkIdExp, XRP(10)), ter(
tecEXPIRED));
1541 env(check::cancel(zoe, chkIdExp));
1546 env(pay(bob, alice, USD(20)));
1548 env.require(balance(alice, USD(20)));
1549 env.require(balance(bob, USD(0)));
1557 env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1565 env(check::cash(bob, chkIdFroz1, USD(1)));
1567 env.require(balance(alice, USD(19)));
1568 env.require(balance(bob, USD(1)));
1575 env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1582 env(check::cash(bob, chkIdFroz2, USD(2)));
1584 env.require(balance(alice, USD(17)));
1585 env.require(balance(bob, USD(3)));
1590 env(check::cash(bob, chkIdFroz3, USD(3)), ter(
tecFROZEN));
1592 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1599 env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1601 env.require(balance(alice, USD(14)));
1602 env.require(balance(bob, USD(6)));
1608 env(check::cash(bob, chkIdFroz4, USD(4)), ter(
terNO_LINE));
1610 env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1617 env(check::cash(bob, chkIdFroz4, USD(4)));
1619 env.require(balance(alice, USD(10)));
1620 env.require(balance(bob, USD(10)));
1629 env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1634 env(check::cash(bob, chkIdHasDest2, USD(2)));
1636 env.require(balance(alice, USD(8)));
1637 env.require(balance(bob, USD(12)));
1643 env(check::cash(bob, chkIdNoDest1, USD(1)));
1645 env.require(balance(alice, USD(7)));
1646 env.require(balance(bob, USD(13)));
1656 using namespace test::jtx;
1658 Account
const gw{
"gateway"};
1659 Account
const alice{
"alice"};
1660 Account
const bob{
"bob"};
1661 Account
const zoe{
"zoe"};
1662 IOU
const USD{gw[
"USD"]};
1666 for (
auto const& testFeatures :
1667 {features - featureMultiSignReserve,
1668 features | featureMultiSignReserve})
1670 Env env{*
this, testFeatures};
1672 env.fund(XRP(1000), gw, alice, bob, zoe);
1677 env(check::create(alice, bob, USD(10)));
1681 env(check::create(alice, bob, XRP(10)));
1685 env(check::create(alice, bob, USD(10)));
1689 using namespace std::chrono_literals;
1691 env(check::create(alice, bob, XRP(10)),
1692 expiration(env.now() + 600s));
1696 env(check::create(alice, bob, USD(10)),
1697 expiration(env.now() + 600s));
1701 env(check::create(alice, bob, XRP(10)),
1702 expiration(env.now() + 600s));
1707 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1711 env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1715 env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1720 env(check::create(alice, bob, USD(10)));
1724 env(check::create(alice, bob, XRP(10)));
1727 BEAST_EXPECT(ownerCount(env, alice) == 11);
1730 env(check::cancel(alice, chkId1));
1733 BEAST_EXPECT(ownerCount(env, alice) == 10);
1735 env(check::cancel(bob, chkId2));
1738 BEAST_EXPECT(ownerCount(env, alice) == 9);
1743 BEAST_EXPECT(ownerCount(env, alice) == 9);
1746 env(check::cancel(alice, chkIdNotExp1));
1749 BEAST_EXPECT(ownerCount(env, alice) == 8);
1751 env(check::cancel(bob, chkIdNotExp2));
1754 BEAST_EXPECT(ownerCount(env, alice) == 7);
1759 BEAST_EXPECT(ownerCount(env, alice) == 7);
1762 env(check::cancel(alice, chkIdExp1));
1765 BEAST_EXPECT(ownerCount(env, alice) == 6);
1767 env(check::cancel(bob, chkIdExp2));
1770 BEAST_EXPECT(ownerCount(env, alice) == 5);
1772 env(check::cancel(zoe, chkIdExp3));
1775 BEAST_EXPECT(ownerCount(env, alice) == 4);
1779 env(regkey(alice, alie));
1784 env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1789 int const signersCount{
1790 testFeatures[featureMultiSignReserve] ? 1 : 4};
1793 env(check::cancel(alice, chkIdReg), sig(alie));
1796 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 3);
1799 XRPAmount const baseFeeDrops{env.current()->fees().base};
1800 env(check::cancel(alice, chkIdMSig),
1802 fee(3 * baseFeeDrops));
1805 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 2);
1808 env(check::cancel(alice, chkId3), sig(alice));
1811 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 1);
1813 env(check::cancel(bob, chkIdNotExp3));
1816 BEAST_EXPECT(ownerCount(env, alice) == signersCount + 0);
1826 using namespace test::jtx;
1828 Account
const alice{
"alice"};
1829 Account
const bob{
"bob"};
1831 Env env{*
this, features};
1833 env.fund(XRP(1000), alice, bob);
1836 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1842 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1848 env(check::cancel(bob,
getCheckIndex(alice, env.seq(alice))),
1858 using namespace test::jtx;
1860 auto testEnable = [
this](
1865 Account
const alice{
"alice"};
1866 Account
const bob{
"bob"};
1868 Env env{*
this, features};
1870 env.fund(XRP(1000), alice, bob);
1874 env(check::create(alice, bob, XRP(200)));
1877 env(check::cash(bob, chkId, check::DeliverMin(XRP(100))));
1887 env.rpc(
"tx", txHash)[jss::result][jss::meta];
1890 meta.
isMember(sfDeliveredAmount.jsonName) == hasFields);
1891 BEAST_EXPECT(meta.
isMember(jss::delivered_amount) == hasFields);
1895 testEnable(features - fix1623,
false);
1896 testEnable(features,
true);
1904 using namespace test::jtx;
1906 Account
const gw{
"gw"};
1907 Account
const alice{
"alice"};
1908 Account
const bob{
"bob"};
1909 IOU
const USD{gw[
"USD"]};
1911 Env env{*
this, features};
1912 env.fund(XRP(1000), gw, alice, bob);
1919 env(ticket::create(alice, 10));
1923 env(ticket::create(bob, 10));
1927 env.require(owners(alice, 10));
1928 env.require(owners(bob, 10));
1931 env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1932 env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1934 env.require(owners(alice, 10));
1935 env.require(owners(bob, 10));
1937 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1938 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1940 env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1941 BEAST_EXPECT(env.seq(bob) == bobSeq);
1943 env(pay(gw, alice, USD(900)));
1949 env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1952 env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1955 env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1958 env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1962 env.require(owners(alice, 10));
1963 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1965 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1967 env.require(owners(bob, 10));
1968 BEAST_EXPECT(env.seq(bob) == bobSeq);
1971 env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1972 env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1975 env.require(owners(alice, 8));
1976 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1978 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1980 env.require(owners(bob, 8));
1981 BEAST_EXPECT(env.seq(bob) == bobSeq);
1984 env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1985 env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1988 env.require(owners(alice, 6));
1989 env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1991 BEAST_EXPECT(env.seq(alice) == aliceSeq);
1992 env.require(balance(alice, USD(700)));
1993 env.require(balance(alice, drops(699'999'940)));
1995 env.require(owners(bob, 6));
1996 BEAST_EXPECT(env.seq(bob) == bobSeq);
1997 env.require(balance(bob, USD(200)));
1998 env.require(balance(bob, drops(1'299'999'940)));
2009 assert(features[featureCheckCashMakesTrustLine]);
2013 using namespace test::jtx;
2015 Env env{*
this, features};
2029 ownerCount(env, acct) == owners,
2030 "Owner count mismatch",
2036 operator Account
const()
const
2053 AccountOwns alice{*
this, env,
"alice", 0};
2054 AccountOwns bob{*
this, env,
"bob", 0};
2057 env.fund(XRP(5000), noripple(alice, bob));
2063 AccountOwns gw1{*
this, env,
"gw1", 0};
2068 env.fund(XRP(5000), noripple(gw1));
2071 IOU
const CK8 = gw1[
"CK8"];
2072 gw1.verifyOwners(__LINE__);
2074 Account
const yui{
"yui"};
2079 env.fund(XRP(200), yui);
2083 env(check::create(gw1, yui, CK8(99)));
2086 env(check::cash(yui, chkId, CK8(99)),
2089 alice.verifyOwners(__LINE__);
2093 env(pay(env.master, yui, XRP(51)));
2095 env(check::cash(yui, chkId, CK8(99)));
2098 BEAST_EXPECT(ownerCount(env, yui) == 1);
2102 gw1.verifyOwners(__LINE__);
2117 auto cmpTrustLines = [
this, &env](
2118 Account
const& acct1,
2119 Account
const& acct2,
2120 IOU
const& offerIou,
2121 IOU
const& checkIou) {
2122 auto const offerLine =
2124 auto const checkLine =
2126 if (offerLine ==
nullptr || checkLine ==
nullptr)
2128 BEAST_EXPECT(offerLine ==
nullptr && checkLine ==
nullptr);
2134 BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2139 [
this, offerLine, checkLine](
SF_AMOUNT const& sfield) {
2140 STAmount const offerAmount = offerLine->at(sfield);
2141 STAmount const checkAmount = checkLine->at(sfield);
2158 cmpReqAmount(sfBalance);
2159 cmpReqAmount(sfLowLimit);
2160 cmpReqAmount(sfHighLimit);
2165 [
this, offerLine, checkLine](
auto const& sfield) {
2168 offerLine->isFieldPresent(sfield) ==
2169 checkLine->isFieldPresent(sfield)))
2174 if (!offerLine->isFieldPresent(sfield))
2180 offerLine->at(sfield) == checkLine->at(sfield));
2182 cmpOptField(sfLowNode);
2183 cmpOptField(sfLowQualityIn);
2184 cmpOptField(sfLowQualityOut);
2186 cmpOptField(sfHighNode);
2187 cmpOptField(sfHighQualityIn);
2188 cmpOptField(sfHighQualityOut);
2196 AccountOwns gw1{*
this, env,
"gw1", 0};
2198 BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2199 BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2200 BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2203 IOU
const OF1 = gw1[
"OF1"];
2204 env(offer(gw1, XRP(98), OF1(98)));
2207 env.le(
keylet::line(gw1, alice, OF1.currency)) ==
nullptr);
2208 env(offer(alice, OF1(98), XRP(98)));
2215 gw1.verifyOwners(__LINE__);
2218 alice.verifyOwners(__LINE__);
2221 IOU
const CK1 = gw1[
"CK1"];
2223 env(check::create(gw1, alice, CK1(98)));
2226 env.le(
keylet::line(gw1, alice, CK1.currency)) ==
nullptr);
2227 env(check::cash(alice, chkId, CK1(98)));
2235 gw1.verifyOwners(__LINE__);
2238 alice.verifyOwners(__LINE__);
2240 cmpTrustLines(gw1, alice, OF1, CK1);
2251 AccountOwns gw1{*
this, env,
"gw1", 0};
2252 IOU
const OF1 = gw1[
"OF1"];
2253 env(offer(alice, XRP(97), OF1(97)));
2256 env.le(
keylet::line(alice, bob, OF1.currency)) ==
nullptr);
2257 env(offer(bob, OF1(97), XRP(97)));
2262 env.require(balance(alice, OF1(1)));
2263 env.require(balance(bob, OF1(97)));
2266 gw1.verifyOwners(__LINE__);
2267 alice.verifyOwners(__LINE__);
2268 bob.verifyOwners(__LINE__);
2276 IOU
const CK1 = gw1[
"CK1"];
2278 env(check::create(alice, bob, CK1(97)));
2281 env.le(
keylet::line(alice, bob, CK1.currency)) ==
nullptr);
2282 env(check::cash(bob, chkId, CK1(97)), ter(
terNO_RIPPLE));
2286 env.le(
keylet::line(gw1, bob, OF1.currency)) !=
nullptr);
2288 env.le(
keylet::line(gw1, bob, CK1.currency)) ==
nullptr);
2291 env(check::cancel(alice, chkId));
2295 gw1.verifyOwners(__LINE__);
2296 alice.verifyOwners(__LINE__);
2297 bob.verifyOwners(__LINE__);
2304 AccountOwns gw1{*
this, env,
"gw1", 0};
2309 IOU
const OF2 = gw1[
"OF2"];
2310 env(offer(gw1, XRP(96), OF2(96)));
2313 env.le(
keylet::line(gw1, alice, OF2.currency)) ==
nullptr);
2314 env(offer(alice, OF2(96), XRP(96)));
2321 gw1.verifyOwners(__LINE__);
2324 alice.verifyOwners(__LINE__);
2327 IOU
const CK2 = gw1[
"CK2"];
2329 env(check::create(gw1, alice, CK2(96)));
2332 env.le(
keylet::line(gw1, alice, CK2.currency)) ==
nullptr);
2333 env(check::cash(alice, chkId, CK2(96)));
2341 gw1.verifyOwners(__LINE__);
2344 alice.verifyOwners(__LINE__);
2346 cmpTrustLines(gw1, alice, OF2, CK2);
2354 AccountOwns gw1{*
this, env,
"gw1", 0};
2355 IOU
const OF2 = gw1[
"OF2"];
2356 env(offer(alice, XRP(95), OF2(95)));
2359 env.le(
keylet::line(alice, bob, OF2.currency)) ==
nullptr);
2360 env(offer(bob, OF2(95), XRP(95)));
2365 gw1.verifyOwners(__LINE__);
2366 alice.verifyOwners(__LINE__);
2367 bob.verifyOwners(__LINE__);
2370 IOU
const CK2 = gw1[
"CK2"];
2372 env(check::create(alice, bob, CK2(95)));
2375 env.le(
keylet::line(alice, bob, CK2.currency)) ==
nullptr);
2376 env(check::cash(bob, chkId, CK2(95)));
2382 gw1.verifyOwners(__LINE__);
2383 alice.verifyOwners(__LINE__);
2384 bob.verifyOwners(__LINE__);
2386 cmpTrustLines(alice, bob, OF2, CK2);
2397 AccountOwns gw1{*
this, env,
"gw1", 0};
2404 IOU
const OF3 = gw1[
"OF3"];
2405 env(offer(gw1, XRP(94), OF3(94)));
2408 env.le(
keylet::line(gw1, alice, OF3.currency)) ==
nullptr);
2409 env(offer(alice, OF3(94), XRP(94)));
2416 gw1.verifyOwners(__LINE__);
2419 alice.verifyOwners(__LINE__);
2422 IOU
const CK3 = gw1[
"CK3"];
2424 env(check::create(gw1, alice, CK3(94)));
2427 env.le(
keylet::line(gw1, alice, CK3.currency)) ==
nullptr);
2428 env(check::cash(alice, chkId, CK3(94)));
2436 gw1.verifyOwners(__LINE__);
2439 alice.verifyOwners(__LINE__);
2441 cmpTrustLines(gw1, alice, OF3, CK3);
2449 AccountOwns gw1{*
this, env,
"gw1", 0};
2450 IOU
const OF3 = gw1[
"OF3"];
2451 env(offer(alice, XRP(93), OF3(93)));
2454 env.le(
keylet::line(alice, bob, OF3.currency)) ==
nullptr);
2455 env(offer(bob, OF3(93), XRP(93)));
2460 gw1.verifyOwners(__LINE__);
2461 alice.verifyOwners(__LINE__);
2462 bob.verifyOwners(__LINE__);
2465 IOU
const CK3 = gw1[
"CK3"];
2467 env(check::create(alice, bob, CK3(93)));
2470 env.le(
keylet::line(alice, bob, CK3.currency)) ==
nullptr);
2471 env(check::cash(bob, chkId, CK3(93)));
2477 gw1.verifyOwners(__LINE__);
2478 alice.verifyOwners(__LINE__);
2479 bob.verifyOwners(__LINE__);
2481 cmpTrustLines(alice, bob, OF3, CK3);
2488 AccountOwns gw1{*
this, env,
"gw1", 0};
2493 IOU
const OF4 = gw1[
"OF4"];
2494 env(offer(gw1, XRP(92), OF4(92)), ter(
tecFROZEN));
2497 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2498 env(offer(alice, OF4(92), XRP(92)), ter(
tecFROZEN));
2502 gw1.verifyOwners(__LINE__);
2503 alice.verifyOwners(__LINE__);
2504 bob.verifyOwners(__LINE__);
2507 IOU
const CK4 = gw1[
"CK4"];
2509 env(check::create(gw1, alice, CK4(92)), ter(
tecFROZEN));
2512 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2513 env(check::cash(alice, chkId, CK4(92)), ter(
tecNO_ENTRY));
2517 gw1.verifyOwners(__LINE__);
2518 alice.verifyOwners(__LINE__);
2519 bob.verifyOwners(__LINE__);
2524 env.le(
keylet::line(gw1, alice, OF4.currency)) ==
nullptr);
2526 env.le(
keylet::line(gw1, alice, CK4.currency)) ==
nullptr);
2534 AccountOwns gw1{*
this, env,
"gw1", 0};
2535 IOU
const OF4 = gw1[
"OF4"];
2536 env(offer(alice, XRP(91), OF4(91)), ter(
tecFROZEN));
2539 env.le(
keylet::line(alice, bob, OF4.currency)) ==
nullptr);
2540 env(offer(bob, OF4(91), XRP(91)), ter(
tecFROZEN));
2544 gw1.verifyOwners(__LINE__);
2545 alice.verifyOwners(__LINE__);
2546 bob.verifyOwners(__LINE__);
2549 IOU
const CK4 = gw1[
"CK4"];
2551 env(check::create(alice, bob, CK4(91)), ter(
tecFROZEN));
2554 env.le(
keylet::line(alice, bob, CK4.currency)) ==
nullptr);
2555 env(check::cash(bob, chkId, CK4(91)), ter(
tecNO_ENTRY));
2559 gw1.verifyOwners(__LINE__);
2560 alice.verifyOwners(__LINE__);
2561 bob.verifyOwners(__LINE__);
2566 env.le(
keylet::line(gw1, bob, OF4.currency)) ==
nullptr);
2568 env.le(
keylet::line(gw1, bob, CK4.currency)) ==
nullptr);
2577 AccountOwns gw2{*
this, env,
"gw2", 0};
2578 env.fund(XRP(5000), gw2);
2587 IOU
const OF5 = gw2[
"OF5"];
2589 env(offer(gw2, XRP(92), OF5(92)));
2593 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2594 env(offer(alice, OF5(92), XRP(92)), ter(
tecNO_LINE));
2599 gw2.verifyOwners(__LINE__);
2600 alice.verifyOwners(__LINE__);
2601 bob.verifyOwners(__LINE__);
2604 env(offer_cancel(gw2, gw2OfferSeq));
2607 gw2.verifyOwners(__LINE__);
2610 IOU
const CK5 = gw2[
"CK5"];
2612 env(check::create(gw2, alice, CK5(92)));
2616 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2617 env(check::cash(alice, chkId, CK5(92)), ter(
tecNO_AUTH));
2622 gw2.verifyOwners(__LINE__);
2623 alice.verifyOwners(__LINE__);
2624 bob.verifyOwners(__LINE__);
2629 env.le(
keylet::line(gw2, alice, OF5.currency)) ==
nullptr);
2631 env.le(
keylet::line(gw2, alice, CK5.currency)) ==
nullptr);
2634 env(check::cancel(gw2, chkId));
2637 gw2.verifyOwners(__LINE__);
2645 AccountOwns gw2{*
this, env,
"gw2", 0};
2646 IOU
const OF5 = gw2[
"OF5"];
2649 env(offer(bob, OF5(91), XRP(91)), ter(
tecNO_LINE));
2651 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2654 gw2.verifyOwners(__LINE__);
2655 alice.verifyOwners(__LINE__);
2656 bob.verifyOwners(__LINE__);
2659 IOU
const CK5 = gw2[
"CK5"];
2661 env(check::create(alice, bob, CK5(91)));
2664 env.le(
keylet::line(alice, bob, CK5.currency)) ==
nullptr);
2669 env(check::cancel(alice, chkId));
2673 gw2.verifyOwners(__LINE__);
2674 alice.verifyOwners(__LINE__);
2675 bob.verifyOwners(__LINE__);
2680 env.le(
keylet::line(gw2, bob, OF5.currency)) ==
nullptr);
2682 env.le(
keylet::line(gw2, bob, CK5.currency)) ==
nullptr);
2708 using namespace test::jtx;
2709 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.