22#include <xrpl/beast/unit_test.h>
23#include <xrpl/protocol/ErrorCodes.h>
24#include <xrpl/protocol/TxFlags.h>
25#include <xrpl/protocol/jss.h>
38 using namespace test::jtx;
42 auto const lines =
env.rpc(
"json",
"account_lines",
"{ }");
44 lines[jss::result][jss::error_message] ==
53 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"})");
55 lines[jss::result][jss::error_message] ==
60 auto testInvalidAccountParam = [&](
auto const& param) {
62 params[jss::account] = param;
64 "json",
"account_lines",
to_string(params))[jss::result];
67 jrr[jss::error_message] ==
"Invalid field 'account'.");
70 testInvalidAccountParam(1);
71 testInvalidAccountParam(1.1);
72 testInvalidAccountParam(
true);
83 R
"({"account": ")" + alice.human() + R"("})");
85 lines[jss::result][jss::error_message] ==
88 env.fund(XRP(10000), alice);
98 R
"({"account": ")" + alice.human() + R"("})");
107 R
"({"account": ")" + alice.human() +
109 R"("ledger_index": "nonsense"})");
111 lines[jss::result][jss::error_message] ==
112 "ledgerIndexMalformed");
119 R
"({"account": ")" + alice.human() +
121 R"("ledger_index": 50000})");
123 lines[jss::result][jss::error_message] == "ledgerNotFound");
130 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
138 env(
trust(alice, gw1Currency(100 + c)));
139 env(
pay(
gw1, alice, gw1Currency(50 + c)));
155 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
163 env(
trust(alice, gw2Currency(200 + c)));
166 env(
pay(
gw2, alice, gw2Currency(100 + c)));
186 auto const linesSeq =
env.rpc(
189 R
"({"account": ")" + account.human() +
191 R"("ledger_index": )" +
193 BEAST_EXPECT(linesSeq[jss::result][jss::lines].isArray());
194 BEAST_EXPECT(linesSeq[jss::result][jss::lines].size() == count);
197 auto const linesHash =
env.rpc(
200 R
"({"account": ")" + account.human() +
202 R"("ledger_hash": ")" +
204 BEAST_EXPECT(linesHash[jss::result][jss::lines].isArray());
205 BEAST_EXPECT(linesHash[jss::result][jss::lines].size() == count);
223 R
"({"account": ")" + alice.human() +
225 R"("ledger_hash": ")" +
228 R"("ledger_index": )" +
238 R
"({"account": ")" + alice.human() + R"("})");
247 R
"({"account": ")" + alice.human() +
255 auto const&
line =
lines[jss::result][jss::lines][0u];
263 R
"({"account": ")" + alice.human() +
266 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"})");
268 lines[jss::result][jss::error_message] ==
276 R
"({"account": ")" + alice.human() +
280 lines[jss::result][jss::error_message] ==
285 auto const linesA =
env.rpc(
288 R
"({"account": ")" + alice.human() +
291 BEAST_EXPECT(linesA[jss::result][jss::lines].isArray());
292 BEAST_EXPECT(linesA[jss::result][jss::lines].size() == 1);
295 auto marker = linesA[jss::result][jss::marker].asString();
299 R
"({"account": ")" + alice.human() +
310 R
"({"account": ")" + alice.human() +
323 R
"({"account": ")" + alice.human() +
328 linesD[jss::result][jss::error_message] ==
336 R
"({"account": ")" + alice.human() +
338 R"("marker": true})");
340 lines[jss::result][jss::error_message] ==
348 R
"({"account": ")" + alice.human() +
353 auto const&
line =
lines[jss::result][jss::lines][0u];
361 auto const linesA =
env.rpc(
368 alice.human() + R"("})");
369 auto const&
lineA = linesA[jss::result][jss::lines][0u];
376 BEAST_EXPECT(linesA[jss::result].isMember(jss::marker));
377 auto const marker = linesA[jss::result][jss::marker].asString();
388 alice.human() + R"("})");
396 testAccountLinesMarker()
398 testcase(
"Entry pointed to by marker is not owned by account");
399 using namespace test::jtx;
410 Account
const gw1{
"gw1"};
415 Account
const bogie{
"bogie"};
419 auto const EUR =
gw1[
"EUR"];
431 R
"({"account": ")" + alice.human() +
435 aliceObjects[jss::result][jss::account_objects][0u];
436 if (!(aliceSignerList[sfLedgerEntryType.jsonName] == jss::SignerList))
439 "alice's account objects are misordered. "
440 "Please reorder the objects so the SignerList is first.",
448 auto const aliceLines1 =
env.rpc(
451 R
"({"account": ")" + alice.human() + R"(", "limit": 1})");
452 BEAST_EXPECT(aliceLines1[jss::result].isMember(jss::marker));
456 aliceLines1[jss::result][jss::marker].asString();
459 BEAST_EXPECT(markerIndex == aliceSignerList[jss::index].asString());
462 auto const aliceLines2 =
env.rpc(
465 R
"({"account": ")" + alice.human() + R"(", "marker": ")" +
466 aliceMarker + R"("})");
468 BEAST_EXPECT(!aliceLines2[jss::result].isMember(jss::marker));
472 auto const beckyLines =
env.rpc(
475 R
"({"account": ")" + becky.human() + R"(", "marker": ")" +
476 aliceMarker + R"("})");
477 BEAST_EXPECT(beckyLines[jss::result].isMember(jss::error_message));
481 testAccountLineDelete()
483 testcase(
"Entry pointed to by marker is removed");
484 using namespace test::jtx;
498 Account
const alice{
"alice"};
499 Account
const becky{
"becky"};
500 Account
const cheri{
"cheri"};
501 Account
const gw1{
"gw1"};
502 Account
const gw2{
"gw2"};
506 auto const USD =
gw1[
"USD"];
507 auto const AUD =
gw1[
"AUD"];
508 auto const EUR =
gw2[
"EUR"];
528 auto const linesBeg =
env.rpc(
531 R
"({"account": ")" + alice.human() +
535 linesBeg[jss::result][jss::lines][0u][jss::currency] == "USD");
536 BEAST_EXPECT(linesBeg[jss::result].isMember(jss::marker));
539 env(
pay(alice, cheri, EUR(100)));
544 auto const linesEnd =
env.rpc(
547 R
"({"account": ")" + alice.human() +
550 linesBeg[jss::result][jss::marker].asString() + R"("})");
552 linesEnd[jss::result][jss::error_message] ==
557 testAccountLinesWalkMarkers()
559 testcase(
"Marker can point to any appropriate ledger entry type");
560 using namespace test::jtx;
561 using namespace std::chrono_literals;
570 Account
const alice{
"alice"};
571 Account
const becky{
"becky"};
572 Account
const gw1{
"gw1"};
578 Account
const& account,
580 STAmount
const& amount) {
582 jv[jss::TransactionType] = jss::EscrowCreate;
584 jv[jss::Account] = account.human();
585 jv[jss::Destination] = to.human();
588 jv[sfFinishAfter.jsonName] =
finish.time_since_epoch().count();
592 auto payChan = [](Account
const& account,
594 STAmount
const& amount,
596 PublicKey
const& pk) {
598 jv[jss::TransactionType] = jss::PaymentChannelCreate;
600 jv[jss::Account] = account.human();
601 jv[jss::Destination] = to.human();
603 jv[
"SettleDelay"] = settleDelay.count();
604 jv[
"PublicKey"] =
strHex(pk.slice());
613 Account
const bogie{
"bogie"};
622 auto const EUR =
gw1[
"EUR"];
646 token::owner(becky));
648 token::owner(alice));
652 token::destination(alice));
655 token::destination(becky));
659 token::destination(alice));
662 token::destination(becky));
679 auto const USDalice = alice[
"USD"];
687 auto const BTCbecky = becky[
"BTC"];
696 auto getNextLine = [](Env&
env,
697 Account
const& alice,
700 params[jss::account] = alice.human();
701 params[jss::limit] = 1;
703 params[jss::marker] = *
marker;
705 return env.rpc(
"json",
"account_lines",
to_string(params));
708 auto aliceLines = getNextLine(
env, alice, std::nullopt);
714 auto hasMarker = [](
auto const& aliceLines) {
715 return aliceLines[jss::result].isMember(jss::marker);
717 auto marker = [](
auto const& aliceLines) {
718 return aliceLines[jss::result][jss::marker].asString();
720 auto checkLines = [](
auto const& aliceLines) {
721 return aliceLines.isMember(jss::result) &&
722 !aliceLines[jss::result].isMember(jss::error_message) &&
723 aliceLines[jss::result].isMember(jss::lines) &&
724 aliceLines[jss::result][jss::lines].isArray() &&
725 aliceLines[jss::result][jss::lines].size() <= 1;
734 while (hasMarker(aliceLines))
737 aliceLines = getNextLine(
env, alice,
marker(aliceLines));
739 foundLines += aliceLines[jss::result][jss::lines].size();
747 R
"({"account": ")" + alice.human() +
752 !aliceObjects[jss::result].isMember(jss::error_message));
754 aliceObjects[jss::result].isMember(jss::account_objects));
756 aliceObjects[jss::result][jss::account_objects].isArray());
761 aliceObjects[jss::result][jss::account_objects].
size() ==
762 iterations + expectedNFTs);
772 R
"({"account": ")" + becky.human() +
777 !beckyObjects[jss::result].isMember(jss::error_message));
779 beckyObjects[jss::result].isMember(jss::account_objects));
781 beckyObjects[jss::result][jss::account_objects].isArray());
785 beckyObjects[jss::result][jss::account_objects].
size() ==
786 aliceObjects[jss::result][jss::account_objects].
size() - 2);
796 using namespace test::jtx;
803 R
"("method" : "account_lines",)"
804 R"("jsonrpc" : "2.0",)"
805 R"("ripplerpc" : "2.0")"
808 lines.isMember(jss::jsonrpc) &&
lines[jss::jsonrpc] ==
"2.0");
810 lines.isMember(jss::ripplerpc) &&
811 lines[jss::ripplerpc] ==
"2.0");
818 R
"("method" : "account_lines",)"
819 R"("jsonrpc" : "2.0",)"
820 R"("ripplerpc" : "2.0",)"
824 lines[jss::error][jss::message] ==
827 lines.isMember(jss::jsonrpc) &&
lines[jss::jsonrpc] ==
"2.0");
829 lines.isMember(jss::ripplerpc) &&
830 lines[jss::ripplerpc] ==
"2.0");
838 R
"("method" : "account_lines",)"
839 R"("jsonrpc" : "2.0",)"
840 R"("ripplerpc" : "2.0",)"
844 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"}})");
846 lines[jss::error][jss::message] ==
849 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
851 lines.isMember(jss::ripplerpc) &&
852 lines[jss::ripplerpc] ==
"2.0");
861 R
"("method" : "account_lines",)"
862 R"("jsonrpc" : "2.0",)"
863 R"("ripplerpc" : "2.0",)"
867 alice.human() + R"("}})");
869 lines[jss::error][jss::message] ==
872 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
874 lines.isMember(jss::ripplerpc) &&
875 lines[jss::ripplerpc] ==
"2.0");
888 R
"("method" : "account_lines",)"
889 R"("jsonrpc" : "2.0",)"
890 R"("ripplerpc" : "2.0",)"
894 alice.human() + R"("}})");
898 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
900 lines.isMember(jss::ripplerpc) &&
901 lines[jss::ripplerpc] ==
"2.0");
909 R
"("method" : "account_lines",)"
910 R"("jsonrpc" : "2.0",)"
911 R"("ripplerpc" : "2.0",)"
917 R"("ledger_index": "nonsense"}})");
919 lines[jss::error][jss::message] == "ledgerIndexMalformed");
921 lines.isMember(jss::jsonrpc) &&
lines[jss::jsonrpc] ==
"2.0");
923 lines.isMember(jss::ripplerpc) &&
924 lines[jss::ripplerpc] ==
"2.0");
932 R
"("method" : "account_lines",)"
933 R"("jsonrpc" : "2.0",)"
934 R"("ripplerpc" : "2.0",)"
940 R"("ledger_index": 50000}})");
943 lines.isMember(jss::jsonrpc) &&
lines[jss::jsonrpc] ==
"2.0");
945 lines.isMember(jss::ripplerpc) &&
946 lines[jss::ripplerpc] ==
"2.0");
954 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
962 env(
trust(alice, gw1Currency(100 + c)));
963 env(
pay(
gw1, alice, gw1Currency(50 + c)));
979 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
987 env(
trust(alice, gw2Currency(200 + c)));
990 env(
pay(
gw2, alice, gw2Currency(100 + c)));
1010 auto const linesSeq =
env.rpc(
1013 R
"("method" : "account_lines",)"
1014 R"("jsonrpc" : "2.0",)"
1015 R"("ripplerpc" : "2.0",)"
1018 R"({"account": ")" +
1021 R"("ledger_index": )" +
1023 BEAST_EXPECT(linesSeq[jss::result][jss::lines].isArray());
1024 BEAST_EXPECT(linesSeq[jss::result][jss::lines].size() == count);
1026 linesSeq.isMember(jss::jsonrpc) &&
1027 linesSeq[jss::jsonrpc] ==
"2.0");
1029 linesSeq.isMember(jss::ripplerpc) &&
1030 linesSeq[jss::ripplerpc] ==
"2.0");
1031 BEAST_EXPECT(linesSeq.isMember(jss::id) && linesSeq[jss::id] == 5);
1034 auto const linesHash =
env.rpc(
1037 R
"("method" : "account_lines",)"
1038 R"("jsonrpc" : "2.0",)"
1039 R"("ripplerpc" : "2.0",)"
1042 R"({"account": ")" +
1045 R"("ledger_hash": ")" +
1047 BEAST_EXPECT(linesHash[jss::result][jss::lines].isArray());
1048 BEAST_EXPECT(linesHash[jss::result][jss::lines].size() == count);
1050 linesHash.isMember(jss::jsonrpc) &&
1051 linesHash[jss::jsonrpc] == "2.0");
1053 linesHash.isMember(jss::ripplerpc) &&
1054 linesHash[jss::ripplerpc] ==
"2.0");
1056 linesHash.isMember(jss::id) && linesHash[jss::id] == 5);
1074 R
"("method" : "account_lines",)"
1075 R"("jsonrpc" : "2.0",)"
1076 R"("ripplerpc" : "2.0",)"
1079 R"({"account": ")" +
1082 R"("ledger_hash": ")" +
1085 R"("ledger_index": )" +
1090 lines.isMember(jss::jsonrpc) &&
lines[jss::jsonrpc] ==
"2.0");
1092 lines.isMember(jss::ripplerpc) &&
1093 lines[jss::ripplerpc] ==
"2.0");
1101 R
"("method" : "account_lines",)"
1102 R"("jsonrpc" : "2.0",)"
1103 R"("ripplerpc" : "2.0",)"
1106 R"({"account": ")" +
1107 alice.human() + R"("}})");
1111 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
1113 lines.isMember(jss::ripplerpc) &&
1114 lines[jss::ripplerpc] ==
"2.0");
1122 R
"("method" : "account_lines",)"
1123 R"("jsonrpc" : "2.0",)"
1124 R"("ripplerpc" : "2.0",)"
1127 R"({"account": ")" +
1135 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
1137 lines.isMember(jss::ripplerpc) &&
1138 lines[jss::ripplerpc] ==
"2.0");
1146 R
"("method" : "account_lines",)"
1147 R"("jsonrpc" : "2.0",)"
1148 R"("ripplerpc" : "2.0",)"
1151 R"({"account": ")" +
1155 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"}})");
1157 lines[jss::error][jss::message] ==
1160 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
1162 lines.isMember(jss::ripplerpc) &&
1163 lines[jss::ripplerpc] ==
"2.0");
1171 R
"("method" : "account_lines",)"
1172 R"("jsonrpc" : "2.0",)"
1173 R"("ripplerpc" : "2.0",)"
1176 R"({"account": ")" +
1179 R"("limit": -1}})");
1181 lines[jss::error][jss::message] ==
1184 lines.isMember(jss::jsonrpc) &&
lines[jss::jsonrpc] ==
"2.0");
1186 lines.isMember(jss::ripplerpc) &&
1187 lines[jss::ripplerpc] ==
"2.0");
1192 auto const linesA =
env.rpc(
1195 R
"("method" : "account_lines",)"
1196 R"("jsonrpc" : "2.0",)"
1197 R"("ripplerpc" : "2.0",)"
1200 R"({"account": ")" +
1207 linesA.isMember(jss::jsonrpc) && linesA[jss::jsonrpc] == "2.0");
1209 linesA.isMember(jss::ripplerpc) &&
1210 linesA[jss::ripplerpc] ==
"2.0");
1214 auto marker = linesA[jss::result][jss::marker].asString();
1218 R
"("method" : "account_lines",)"
1219 R"("jsonrpc" : "2.0",)"
1220 R"("ripplerpc" : "2.0",)"
1223 R"({"account": ")" +
1231 linesB.isMember(jss::jsonrpc) && linesB[jss::jsonrpc] == "2.0");
1233 linesB.isMember(jss::ripplerpc) &&
1234 linesB[jss::ripplerpc] ==
"2.0");
1241 R
"("method" : "account_lines",)"
1242 R"("jsonrpc" : "2.0",)"
1243 R"("ripplerpc" : "2.0",)"
1246 R"({"account": ")" +
1255 linesC.isMember(jss::jsonrpc) && linesC[jss::jsonrpc] == "2.0");
1257 linesC.isMember(jss::ripplerpc) &&
1258 linesC[jss::ripplerpc] ==
"2.0");
1266 R
"("method" : "account_lines",)"
1267 R"("jsonrpc" : "2.0",)"
1268 R"("ripplerpc" : "2.0",)"
1271 R"({"account": ")" +
1277 linesD[jss::error][jss::message] ==
1280 linesD.isMember(jss::jsonrpc) && linesD[jss::jsonrpc] == "2.0");
1282 linesD.isMember(jss::ripplerpc) &&
1283 linesD[jss::ripplerpc] ==
"2.0");
1291 R
"("method" : "account_lines",)"
1292 R"("jsonrpc" : "2.0",)"
1293 R"("ripplerpc" : "2.0",)"
1296 R"({"account": ")" +
1299 R"("marker": true}})");
1301 lines[jss::error][jss::message] ==
1304 lines.isMember(jss::jsonrpc) &&
lines[jss::jsonrpc] ==
"2.0");
1306 lines.isMember(jss::ripplerpc) &&
1307 lines[jss::ripplerpc] ==
"2.0");
1315 R
"("method" : "account_lines",)"
1316 R"("jsonrpc" : "2.0",)"
1317 R"("ripplerpc" : "2.0",)"
1320 R"({"account": ")" +
1332 lines.isMember(jss::jsonrpc) &&
lines[jss::jsonrpc] ==
"2.0");
1334 lines.isMember(jss::ripplerpc) &&
1335 lines[jss::ripplerpc] ==
"2.0");
1340 auto const linesA =
env.rpc(
1343 R
"("method" : "account_lines",)"
1344 R"("jsonrpc" : "2.0",)"
1345 R"("ripplerpc" : "2.0",)"
1348 R"({"account": ")" +
1353 alice.human() + R"("}})");
1354 auto const&
lineA = linesA[jss::result][jss::lines][0u];
1360 linesA.isMember(jss::jsonrpc) && linesA[jss::jsonrpc] ==
"2.0");
1362 linesA.isMember(jss::ripplerpc) &&
1363 linesA[jss::ripplerpc] ==
"2.0");
1368 auto const marker = linesA[jss::result][jss::marker].asString();
1372 R
"("method" : "account_lines",)"
1373 R"("jsonrpc" : "2.0",)"
1374 R"("ripplerpc" : "2.0",)"
1377 R"({"account": ")" +
1385 alice.human() + R"("}})");
1390 linesB.isMember(jss::jsonrpc) && linesB[jss::jsonrpc] == "2.0");
1392 linesB.isMember(jss::ripplerpc) &&
1393 linesB[jss::ripplerpc] ==
"2.0");
1402 testcase(
"V2: account_lines with removed marker");
1404 using namespace test::jtx;
1426 auto const USD =
gw1[
"USD"];
1427 auto const AUD =
gw1[
"AUD"];
1428 auto const EUR =
gw2[
"EUR"];
1448 auto const linesBeg =
env.rpc(
1451 R
"("method" : "account_lines",)"
1452 R"("jsonrpc" : "2.0",)"
1453 R"("ripplerpc" : "2.0",)"
1456 R"({"account": ")" +
1461 linesBeg[jss::result][jss::lines][0u][jss::currency] == "USD");
1462 BEAST_EXPECT(linesBeg[jss::result].isMember(jss::marker));
1464 linesBeg.isMember(jss::jsonrpc) && linesBeg[jss::jsonrpc] ==
"2.0");
1466 linesBeg.isMember(jss::ripplerpc) &&
1467 linesBeg[jss::ripplerpc] ==
"2.0");
1468 BEAST_EXPECT(linesBeg.isMember(jss::id) && linesBeg[jss::id] == 5);
1471 env(
pay(alice, cheri, EUR(100)));
1476 auto const linesEnd =
env.rpc(
1479 R
"("method" : "account_lines",)"
1480 R"("jsonrpc" : "2.0",)"
1481 R"("ripplerpc" : "2.0",)"
1484 R"({"account": ")" +
1488 linesBeg[jss::result][jss::marker].asString() + R"("}})");
1490 linesEnd[jss::error][jss::message] ==
1493 linesEnd.isMember(jss::jsonrpc) && linesEnd[jss::jsonrpc] == "2.0");
1495 linesEnd.isMember(jss::ripplerpc) &&
1496 linesEnd[jss::ripplerpc] ==
"2.0");
1504 testAccountLinesMarker();
1505 testAccountLineDelete();
1506 testAccountLinesWalkMarkers();
bool isMember(char const *key) const
Return true if the object has a member named key.
testcase_t testcase
Memberspace for declaring test cases.
void fail(String const &reason, char const *file, int line)
Record a failure.
std::chrono::time_point< NetClock > time_point
std::chrono::duration< rep, period > duration
BEAST_EXPECT(lineA[jss::deep_freeze_peer].asBool()==true)
BEAST_EXPECT(linesB[jss::result][jss::lines].isArray())
BEAST_EXPECT(ledger3Info.seq==3)
BEAST_EXPECT(linesEnd.isMember(jss::ripplerpc) &&linesEnd[jss::ripplerpc]=="2.0")
BEAST_EXPECT(line[jss::peer_authorized].asBool()==true)
BEAST_EXPECT(linesD.isMember(jss::id) &&linesD[jss::id]==5)
BEAST_EXPECT(line[jss::no_ripple].asBool()==true)
BEAST_EXPECT(linesD[jss::error][jss::message]==RPC::make_error(rpcINVALID_PARAMS)[jss::error_message])
testAccountLinesHistory(alice, ledger4Info, 26)
auto testAccountLinesHistory
BEAST_EXPECT(linesB.isMember(jss::ripplerpc) &&linesB[jss::ripplerpc]=="2.0")
BEAST_EXPECT(linesC.isMember(jss::jsonrpc) &&linesC[jss::jsonrpc]=="2.0")
void testAccountLineDelete2()
BEAST_EXPECT(ledger4Info.seq==4)
BEAST_EXPECT(lines[jss::result][jss::lines].size()==26)
BEAST_EXPECT(linesA.isMember(jss::ripplerpc) &&linesA[jss::ripplerpc]=="2.0")
BEAST_EXPECT(linesB.isMember(jss::jsonrpc) &&linesB[jss::jsonrpc]=="2.0")
BEAST_EXPECT(linesD.isMember(jss::ripplerpc) &&linesD[jss::ripplerpc]=="2.0")
LedgerInfo const ledger3Info
BEAST_EXPECT(lineA[jss::no_ripple_peer].asBool()==true)
BEAST_EXPECT(lineA[jss::freeze_peer].asBool()==true)
BEAST_EXPECT(linesC[jss::result][jss::lines].size()==3)
BEAST_EXPECT(linesC.isMember(jss::ripplerpc) &&linesC[jss::ripplerpc]=="2.0")
BEAST_EXPECT(linesC[jss::result][jss::lines].isArray())
BEAST_EXPECT(ledger58Info.seq==58)
BEAST_EXPECT(linesA[jss::result].isMember(jss::marker))
BEAST_EXPECT(linesEnd[jss::error][jss::message]==RPC::make_error(rpcINVALID_PARAMS)[jss::error_message])
env(fset(gw2, asfRequireAuth))
LedgerInfo const ledger4Info
std::vector< IOU > gw1Currencies
BEAST_EXPECT(lines[jss::result][jss::lines].size()==0)
BEAST_EXPECT(lines.isMember(jss::id) &&lines[jss::id]==5)
BEAST_EXPECT(lines[jss::error][jss::message]=="ledgerIndexMalformed")
BEAST_EXPECT(lines.isMember(jss::jsonrpc) &&lines[jss::jsonrpc]=="2.0")
BEAST_EXPECT(linesA[jss::result][jss::lines].isArray())
BEAST_EXPECT(lines[jss::error][jss::message]==RPC::expected_field_message(jss::limit, "unsigned integer"))
BEAST_EXPECT(lines.isMember(jss::ripplerpc) &&lines[jss::ripplerpc]=="2.0")
BEAST_EXPECT(linesB.isMember(jss::id) &&linesB[jss::id]==5)
BEAST_EXPECT(linesB[jss::result][jss::lines].size()==25)
BEAST_EXPECT(!linesB[jss::result].isMember(jss::marker))
LedgerInfo const ledger58Info
BEAST_EXPECT(linesC.isMember(jss::id) &&linesC[jss::id]==5)
testAccountLinesHistory(alice, ledger58Info, 52)
BEAST_EXPECT(linesD.isMember(jss::jsonrpc) &&linesD[jss::jsonrpc]=="2.0")
BEAST_EXPECT(lines[jss::result][jss::lines].isArray())
BEAST_EXPECT(linesEnd.isMember(jss::id) &&linesEnd[jss::id]==5)
BEAST_EXPECT(linesB[jss::result][jss::lines].size()==51)
BEAST_EXPECT(lines[jss::error][jss::message]==RPC::expected_field_message(jss::marker, "string"))
BEAST_EXPECT(linesEnd.isMember(jss::jsonrpc) &&linesEnd[jss::jsonrpc]=="2.0")
BEAST_EXPECT(linesA.isMember(jss::id) &&linesA[jss::id]==5)
void run() override
Runs the suite.
BEAST_EXPECT(lines[jss::error][jss::message]=="ledgerNotFound")
BEAST_EXPECT(lineA[jss::authorized].asBool()==true)
BEAST_EXPECT(lines[jss::error][jss::message]==RPC::make_error(rpcACT_NOT_FOUND)[jss::error_message])
BEAST_EXPECT(lines[jss::result][jss::lines].size()==52)
BEAST_EXPECT(linesA.isMember(jss::jsonrpc) &&linesA[jss::jsonrpc]=="2.0")
BEAST_EXPECT(line[jss::deep_freeze].asBool()==true)
testAccountLinesHistory(alice, ledger3Info, 0)
BEAST_EXPECT(lines[jss::error][jss::message]==RPC::make_error(rpcACT_MALFORMED)[jss::error_message])
std::vector< IOU > gw2Currencies
BEAST_EXPECT(line[jss::freeze].asBool()==true)
BEAST_EXPECT(linesA[jss::result][jss::lines].size()==1)
Immutable cryptographic account descriptor.
std::string const & human() const
Returns the human readable public key.
A transaction testing environment.
Converts to IOU Issue or STAmount.
Set the expected result code for a JTx The test will fail if the code doesn't match.
@ arrayValue
array value (ordered list)
@ objectValue
object value (collection of name/value pairs).
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
std::string expected_field_message(std::string const &name, std::string const &type)
Json::Value missing_field_error(std::string const &name)
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
Json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
uint256 getNextID(jtx::Env const &env, jtx::Account const &issuer, std::uint32_t nfTokenTaxon, std::uint16_t flags, std::uint16_t xferFee)
Get the next NFTokenID that will be issued.
Json::Value createOffer(jtx::Account const &account, uint256 const &nftokenID, STAmount const &amount)
Create an NFTokenOffer.
Json::Value mint(jtx::Account const &account, std::uint32_t nfTokenTaxon)
Mint an NFToken.
Json::Value escrow(AccountID const &account, AccountID const &to, STAmount const &amount)
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Json::Value finish(AccountID const &account, AccountID const &from, std::uint32_t seq)
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
XRP_t const XRP
Converts to XRP Issue or STAmount.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t tfSetDeepFreeze
constexpr std::uint32_t const tfSellNFToken
std::string strHex(FwdIt begin, FwdIt end)
constexpr std::uint32_t tfSetfAuth
constexpr std::uint32_t tfUniversal
std::string to_string(base_uint< Bits, Tag > const &a)
constexpr std::uint32_t asfRequireAuth
constexpr std::uint32_t tfSetFreeze
constexpr std::uint32_t tfSetNoRipple
constexpr std::uint32_t const tfTransferable