20 #include <ripple/beast/unit_test.h>
21 #include <ripple/protocol/ErrorCodes.h>
22 #include <ripple/protocol/TxFlags.h>
23 #include <ripple/protocol/jss.h>
36 testcase(
"acccount_lines");
38 using namespace test::jtx;
42 auto const lines = env.rpc(
"json",
"account_lines",
"{ }");
44 lines[jss::result][jss::error_message] ==
49 auto const lines = env.rpc(
53 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"})");
55 lines[jss::result][jss::error_message] ==
58 Account const alice{
"alice"};
61 auto const lines = env.rpc(
64 R
"({"account": ")" + alice.human() + R"("})");
66 lines[jss::result][jss::error_message] ==
69 env.fund(XRP(10000), alice);
71 LedgerInfo const ledger3Info = env.closed()->info();
72 BEAST_EXPECT(ledger3Info.
seq == 3);
76 auto const lines = env.rpc(
79 R
"({"account": ")" + alice.human() + R"("})");
80 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
81 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 0);
85 auto const lines = env.rpc(
88 R
"({"account": ")" + alice.human() +
90 R"("ledger_index": "nonsense"})");
92 lines[jss::result][jss::error_message] ==
93 "ledgerIndexMalformed");
97 auto const lines = env.rpc(
100 R
"({"account": ")" + alice.human() +
102 R"("ledger_index": 50000})");
104 lines[jss::result][jss::error_message] == "ledgerNotFound");
107 Account
const gw1{
"gw1"};
108 env.fund(XRP(10000), gw1);
111 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
115 gw1[
std::string(
"YA") +
static_cast<char>(
'A' + c)]);
116 IOU
const& gw1Currency = gw1Currencies.
back();
119 env(trust(alice, gw1Currency(100 + c)));
120 env(pay(gw1, alice, gw1Currency(50 + c)));
123 LedgerInfo const ledger4Info = env.closed()->info();
124 BEAST_EXPECT(ledger4Info.
seq == 4);
128 Account
const gw2{
"gw2"};
129 env.fund(XRP(10000), gw2);
136 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
140 gw2[
std::string(
"ZA") +
static_cast<char>(
'A' + c)]);
141 IOU
const& gw2Currency = gw2Currencies.
back();
144 env(trust(alice, gw2Currency(200 + c)));
145 env(trust(gw2, gw2Currency(0), alice,
tfSetfAuth));
147 env(pay(gw2, alice, gw2Currency(100 + c)));
154 LedgerInfo const ledger58Info = env.closed()->info();
155 BEAST_EXPECT(ledger58Info.
seq == 58);
158 auto testAccountLinesHistory = [
this, &env](
159 Account
const& account,
163 auto const linesSeq = env.rpc(
166 R
"({"account": ")" + account.human() +
168 R"("ledger_index": )" +
170 BEAST_EXPECT(linesSeq[jss::result][jss::lines].isArray());
171 BEAST_EXPECT(linesSeq[jss::result][jss::lines].size() == count);
174 auto const linesHash = env.rpc(
177 R
"({"account": ")" + account.human() +
179 R"("ledger_hash": ")" +
181 BEAST_EXPECT(linesHash[jss::result][jss::lines].isArray());
182 BEAST_EXPECT(linesHash[jss::result][jss::lines].size() == count);
186 testAccountLinesHistory(alice, ledger3Info, 0);
189 testAccountLinesHistory(alice, ledger4Info, 26);
192 testAccountLinesHistory(alice, ledger58Info, 52);
197 auto const lines = env.rpc(
200 R
"({"account": ")" + alice.human() +
202 R"("ledger_hash": ")" +
205 R"("ledger_index": )" +
207 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
208 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 26);
212 auto const lines = env.rpc(
215 R
"({"account": ")" + alice.human() + R"("})");
216 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
217 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 52);
221 auto const lines = env.rpc(
224 R
"({"account": ")" + alice.human() +
227 gw1.human() + R"("})");
228 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
229 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 26);
233 auto const lines = env.rpc(
236 R
"({"account": ")" + alice.human() +
239 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"})");
241 lines[jss::result][jss::error_message] ==
246 auto const lines = env.rpc(
249 R
"({"account": ")" + alice.human() +
253 lines[jss::result][jss::error_message] ==
258 auto const linesA = env.rpc(
261 R
"({"account": ")" + alice.human() +
264 BEAST_EXPECT(linesA[jss::result][jss::lines].isArray());
265 BEAST_EXPECT(linesA[jss::result][jss::lines].size() == 1);
268 auto marker = linesA[jss::result][jss::marker].asString();
269 auto const linesB = env.rpc(
272 R
"({"account": ")" + alice.human() +
276 BEAST_EXPECT(linesB[jss::result][jss::lines].isArray());
277 BEAST_EXPECT(linesB[jss::result][jss::lines].size() == 51);
280 auto const linesC = env.rpc(
283 R
"({"account": ")" + alice.human() +
288 BEAST_EXPECT(linesC[jss::result][jss::lines].isArray());
289 BEAST_EXPECT(linesC[jss::result][jss::lines].size() == 3);
292 marker[5] = marker[5] ==
'7' ?
'8' :
'7';
293 auto const linesD = env.rpc(
296 R
"({"account": ")" + alice.human() +
301 linesD[jss::result][jss::error_message] ==
306 auto const lines = env.rpc(
309 R
"({"account": ")" + alice.human() +
311 R"("marker": true})");
313 lines[jss::result][jss::error_message] ==
318 auto const lines = env.rpc(
321 R
"({"account": ")" + alice.human() +
325 gw2.human() + R"("})");
326 auto const& line = lines[jss::result][jss::lines][0u];
327 BEAST_EXPECT(line[jss::freeze].asBool() ==
true);
328 BEAST_EXPECT(line[jss::no_ripple].asBool() ==
true);
329 BEAST_EXPECT(line[jss::peer_authorized].asBool() ==
true);
333 auto const linesA = env.rpc(
336 R
"({"account": ")" + gw2.human() +
340 alice.human() + R"("})");
341 auto const& lineA = linesA[jss::result][jss::lines][0u];
342 BEAST_EXPECT(lineA[jss::freeze_peer].asBool() ==
true);
343 BEAST_EXPECT(lineA[jss::no_ripple_peer].asBool() ==
true);
344 BEAST_EXPECT(lineA[jss::authorized].asBool() ==
true);
347 BEAST_EXPECT(linesA[jss::result].isMember(jss::marker));
348 auto const marker = linesA[jss::result][jss::marker].asString();
349 auto const linesB = env.rpc(
352 R
"({"account": ")" + gw2.human() +
359 alice.human() + R"("})");
360 BEAST_EXPECT(linesB[jss::result][jss::lines].isArray());
361 BEAST_EXPECT(linesB[jss::result][jss::lines].size() == 25);
362 BEAST_EXPECT(!linesB[jss::result].isMember(jss::marker));
367 testAccountLinesMarker()
369 testcase(
"Entry pointed to by marker is not owned by account");
370 using namespace test::jtx;
379 Account
const alice{
"alice"};
380 Account
const becky{
"becky"};
381 Account
const gw1{
"gw1"};
382 env.fund(
XRP(10000), alice, becky, gw1);
386 Account
const bogie{
"bogie"};
387 env(
signers(alice, 2, {{bogie, 3}}));
390 auto const EUR = gw1[
"EUR"];
391 env(
trust(alice, EUR(200)));
392 env(
trust(becky, EUR(200)));
402 R
"({"account": ")" + alice.human() +
406 aliceObjects[jss::result][jss::account_objects][0u];
410 "alice's account objects are misordered. "
411 "Please reorder the objects so the SignerList is first.",
419 auto const aliceLines1 = env.rpc(
422 R
"({"account": ")" + alice.human() + R"(", "limit": 1})");
423 BEAST_EXPECT(aliceLines1[jss::result].isMember(jss::marker));
427 aliceLines1[jss::result][jss::marker].asString();
430 BEAST_EXPECT(markerIndex == aliceSignerList[jss::index].asString());
433 auto const aliceLines2 = env.rpc(
436 R
"({"account": ")" + alice.human() + R"(", "marker": ")" +
437 aliceMarker + R"("})");
438 BEAST_EXPECT(aliceLines2[jss::result][jss::lines].size() == 1);
439 BEAST_EXPECT(!aliceLines2[jss::result].isMember(jss::marker));
443 auto const beckyLines = env.rpc(
446 R
"({"account": ")" + becky.human() + R"(", "marker": ")" +
447 aliceMarker + R"("})");
448 BEAST_EXPECT(beckyLines[jss::result].isMember(jss::error_message));
452 testAccountLineDelete()
454 testcase(
"Entry pointed to by marker is removed");
455 using namespace test::jtx;
469 Account
const alice{
"alice"};
470 Account
const becky{
"becky"};
471 Account
const cheri{
"cheri"};
472 Account
const gw1{
"gw1"};
473 Account
const gw2{
"gw2"};
474 env.fund(
XRP(10000), alice, becky, cheri, gw1, gw2);
477 auto const USD = gw1[
"USD"];
478 auto const AUD = gw1[
"AUD"];
479 auto const EUR = gw2[
"EUR"];
480 env(
trust(alice, USD(200)));
481 env(
trust(alice, AUD(200)));
482 env(
trust(becky, EUR(200)));
483 env(
trust(cheri, EUR(200)));
487 env(
pay(gw2, becky, EUR(100)));
491 env(
offer(alice, EUR(100),
XRP(100)));
495 env(
offer(becky,
XRP(100), EUR(100)));
499 auto const linesBeg = env.rpc(
502 R
"({"account": ")" + alice.human() +
506 linesBeg[jss::result][jss::lines][0u][jss::currency] == "USD");
507 BEAST_EXPECT(linesBeg[jss::result].isMember(jss::marker));
510 env(
pay(alice, cheri, EUR(100)));
515 auto const linesEnd = env.rpc(
518 R
"({"account": ")" + alice.human() +
521 linesBeg[jss::result][jss::marker].asString() + R"("})");
523 linesEnd[jss::result][jss::error_message] ==
531 testcase(
"V2: acccount_lines");
533 using namespace test::jtx;
537 auto const lines = env.rpc(
540 R
"("method" : "account_lines",)"
541 R"("jsonrpc" : "2.0",)"
542 R"("ripplerpc" : "2.0")"
545 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
547 lines.isMember(jss::ripplerpc) &&
548 lines[jss::ripplerpc] ==
"2.0");
552 auto const lines = env.rpc(
555 R
"("method" : "account_lines",)"
556 R"("jsonrpc" : "2.0",)"
557 R"("ripplerpc" : "2.0",)"
561 lines[jss::error][jss::message] ==
564 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
566 lines.isMember(jss::ripplerpc) &&
567 lines[jss::ripplerpc] ==
"2.0");
568 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
572 auto const lines = env.rpc(
575 R
"("method" : "account_lines",)"
576 R"("jsonrpc" : "2.0",)"
577 R"("ripplerpc" : "2.0",)"
581 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"}})");
583 lines[jss::error][jss::message] ==
586 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
588 lines.isMember(jss::ripplerpc) &&
589 lines[jss::ripplerpc] ==
"2.0");
590 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
592 Account
const alice{
"alice"};
595 auto const lines = env.rpc(
598 R
"("method" : "account_lines",)"
599 R"("jsonrpc" : "2.0",)"
600 R"("ripplerpc" : "2.0",)"
604 alice.human() + R"("}})");
606 lines[jss::error][jss::message] ==
609 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
611 lines.isMember(jss::ripplerpc) &&
612 lines[jss::ripplerpc] ==
"2.0");
613 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
615 env.fund(
XRP(10000), alice);
617 LedgerInfo
const ledger3Info = env.closed()->info();
618 BEAST_EXPECT(ledger3Info.seq == 3);
622 auto const lines = env.rpc(
625 R
"("method" : "account_lines",)"
626 R"("jsonrpc" : "2.0",)"
627 R"("ripplerpc" : "2.0",)"
631 alice.human() + R"("}})");
632 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
633 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 0);
635 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
637 lines.isMember(jss::ripplerpc) &&
638 lines[jss::ripplerpc] ==
"2.0");
639 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
643 auto const lines = env.rpc(
646 R
"("method" : "account_lines",)"
647 R"("jsonrpc" : "2.0",)"
648 R"("ripplerpc" : "2.0",)"
654 R"("ledger_index": "nonsense"}})");
656 lines[jss::error][jss::message] == "ledgerIndexMalformed");
658 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
660 lines.isMember(jss::ripplerpc) &&
661 lines[jss::ripplerpc] ==
"2.0");
662 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
666 auto const lines = env.rpc(
669 R
"("method" : "account_lines",)"
670 R"("jsonrpc" : "2.0",)"
671 R"("ripplerpc" : "2.0",)"
677 R"("ledger_index": 50000}})");
678 BEAST_EXPECT(lines[jss::error][jss::message] == "ledgerNotFound");
680 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
682 lines.isMember(jss::ripplerpc) &&
683 lines[jss::ripplerpc] ==
"2.0");
684 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
687 Account
const gw1{
"gw1"};
688 env.fund(
XRP(10000), gw1);
691 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
695 gw1[
std::string(
"YA") +
static_cast<char>(
'A' + c)]);
696 IOU
const& gw1Currency = gw1Currencies.
back();
699 env(
trust(alice, gw1Currency(100 + c)));
700 env(
pay(gw1, alice, gw1Currency(50 + c)));
703 LedgerInfo
const ledger4Info = env.closed()->info();
704 BEAST_EXPECT(ledger4Info.seq == 4);
708 Account
const gw2{
"gw2"};
709 env.fund(
XRP(10000), gw2);
716 for (
char c = 0; c <= (
'Z' -
'A'); ++c)
720 gw2[
std::string(
"ZA") +
static_cast<char>(
'A' + c)]);
721 IOU
const& gw2Currency = gw2Currencies.
back();
724 env(
trust(alice, gw2Currency(200 + c)));
727 env(
pay(gw2, alice, gw2Currency(100 + c)));
734 LedgerInfo
const ledger58Info = env.closed()->info();
735 BEAST_EXPECT(ledger58Info.seq == 58);
738 auto testAccountLinesHistory = [
this, &env](
739 Account
const& account,
740 LedgerInfo
const& info,
743 auto const linesSeq = env.rpc(
746 R
"("method" : "account_lines",)"
747 R"("jsonrpc" : "2.0",)"
748 R"("ripplerpc" : "2.0",)"
754 R"("ledger_index": )" +
756 BEAST_EXPECT(linesSeq[jss::result][jss::lines].isArray());
757 BEAST_EXPECT(linesSeq[jss::result][jss::lines].
size() == count);
759 linesSeq.isMember(jss::jsonrpc) &&
760 linesSeq[jss::jsonrpc] ==
"2.0");
762 linesSeq.isMember(jss::ripplerpc) &&
763 linesSeq[jss::ripplerpc] ==
"2.0");
764 BEAST_EXPECT(linesSeq.isMember(jss::id) && linesSeq[jss::id] == 5);
767 auto const linesHash = env.rpc(
770 R
"("method" : "account_lines",)"
771 R"("jsonrpc" : "2.0",)"
772 R"("ripplerpc" : "2.0",)"
778 R"("ledger_hash": ")" +
780 BEAST_EXPECT(linesHash[jss::result][jss::lines].isArray());
781 BEAST_EXPECT(linesHash[jss::result][jss::lines].size() == count);
783 linesHash.isMember(jss::jsonrpc) &&
784 linesHash[jss::jsonrpc] == "2.0");
786 linesHash.isMember(jss::ripplerpc) &&
787 linesHash[jss::ripplerpc] ==
"2.0");
789 linesHash.isMember(jss::id) && linesHash[jss::id] == 5);
793 testAccountLinesHistory(alice, ledger3Info, 0);
796 testAccountLinesHistory(alice, ledger4Info, 26);
799 testAccountLinesHistory(alice, ledger58Info, 52);
804 auto const lines = env.rpc(
807 R
"("method" : "account_lines",)"
808 R"("jsonrpc" : "2.0",)"
809 R"("ripplerpc" : "2.0",)"
815 R"("ledger_hash": ")" +
818 R"("ledger_index": )" +
820 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
821 BEAST_EXPECT(lines[jss::result][jss::lines].
size() == 26);
823 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
825 lines.isMember(jss::ripplerpc) &&
826 lines[jss::ripplerpc] ==
"2.0");
827 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
831 auto const lines = env.rpc(
834 R
"("method" : "account_lines",)"
835 R"("jsonrpc" : "2.0",)"
836 R"("ripplerpc" : "2.0",)"
840 alice.human() + R"("}})");
841 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
842 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 52);
844 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
846 lines.isMember(jss::ripplerpc) &&
847 lines[jss::ripplerpc] ==
"2.0");
848 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
852 auto const lines = env.rpc(
855 R
"("method" : "account_lines",)"
856 R"("jsonrpc" : "2.0",)"
857 R"("ripplerpc" : "2.0",)"
864 gw1.human() + R"("}})");
865 BEAST_EXPECT(lines[jss::result][jss::lines].isArray());
866 BEAST_EXPECT(lines[jss::result][jss::lines].size() == 26);
868 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
870 lines.isMember(jss::ripplerpc) &&
871 lines[jss::ripplerpc] ==
"2.0");
872 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
876 auto const lines = env.rpc(
879 R
"("method" : "account_lines",)"
880 R"("jsonrpc" : "2.0",)"
881 R"("ripplerpc" : "2.0",)"
888 R"("n9MJkEKHDhy5eTLuHUQeAAjo382frHNbFK4C8hcwN4nwM2SrLdBj"}})");
890 lines[jss::error][jss::message] ==
893 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] == "2.0");
895 lines.isMember(jss::ripplerpc) &&
896 lines[jss::ripplerpc] ==
"2.0");
897 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
901 auto const lines = env.rpc(
904 R
"("method" : "account_lines",)"
905 R"("jsonrpc" : "2.0",)"
906 R"("ripplerpc" : "2.0",)"
914 lines[jss::error][jss::message] ==
917 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
919 lines.isMember(jss::ripplerpc) &&
920 lines[jss::ripplerpc] ==
"2.0");
921 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
925 auto const linesA = env.rpc(
928 R
"("method" : "account_lines",)"
929 R"("jsonrpc" : "2.0",)"
930 R"("ripplerpc" : "2.0",)"
937 BEAST_EXPECT(linesA[jss::result][jss::lines].isArray());
938 BEAST_EXPECT(linesA[jss::result][jss::lines].size() == 1);
940 linesA.isMember(jss::jsonrpc) && linesA[jss::jsonrpc] == "2.0");
942 linesA.isMember(jss::ripplerpc) &&
943 linesA[jss::ripplerpc] ==
"2.0");
944 BEAST_EXPECT(linesA.isMember(jss::id) && linesA[jss::id] == 5);
947 auto marker = linesA[jss::result][jss::marker].asString();
948 auto const linesB = env.rpc(
951 R
"("method" : "account_lines",)"
952 R"("jsonrpc" : "2.0",)"
953 R"("ripplerpc" : "2.0",)"
961 BEAST_EXPECT(linesB[jss::result][jss::lines].isArray());
962 BEAST_EXPECT(linesB[jss::result][jss::lines].size() == 51);
964 linesB.isMember(jss::jsonrpc) && linesB[jss::jsonrpc] == "2.0");
966 linesB.isMember(jss::ripplerpc) &&
967 linesB[jss::ripplerpc] ==
"2.0");
968 BEAST_EXPECT(linesB.isMember(jss::id) && linesB[jss::id] == 5);
971 auto const linesC = env.rpc(
974 R
"("method" : "account_lines",)"
975 R"("jsonrpc" : "2.0",)"
976 R"("ripplerpc" : "2.0",)"
985 BEAST_EXPECT(linesC[jss::result][jss::lines].isArray());
986 BEAST_EXPECT(linesC[jss::result][jss::lines].size() == 3);
988 linesC.isMember(jss::jsonrpc) && linesC[jss::jsonrpc] == "2.0");
990 linesC.isMember(jss::ripplerpc) &&
991 linesC[jss::ripplerpc] ==
"2.0");
992 BEAST_EXPECT(linesC.isMember(jss::id) && linesC[jss::id] == 5);
995 marker[5] = marker[5] ==
'7' ?
'8' :
'7';
996 auto const linesD = env.rpc(
999 R
"("method" : "account_lines",)"
1000 R"("jsonrpc" : "2.0",)"
1001 R"("ripplerpc" : "2.0",)"
1004 R"({"account": ")" +
1010 linesD[jss::error][jss::message] ==
1013 linesD.isMember(jss::jsonrpc) && linesD[jss::jsonrpc] == "2.0");
1015 linesD.isMember(jss::ripplerpc) &&
1016 linesD[jss::ripplerpc] ==
"2.0");
1017 BEAST_EXPECT(linesD.isMember(jss::id) && linesD[jss::id] == 5);
1021 auto const lines = env.rpc(
1024 R
"("method" : "account_lines",)"
1025 R"("jsonrpc" : "2.0",)"
1026 R"("ripplerpc" : "2.0",)"
1029 R"({"account": ")" +
1032 R"("marker": true}})");
1034 lines[jss::error][jss::message] ==
1037 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
1039 lines.isMember(jss::ripplerpc) &&
1040 lines[jss::ripplerpc] ==
"2.0");
1041 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
1045 auto const lines = env.rpc(
1048 R
"("method" : "account_lines",)"
1049 R"("jsonrpc" : "2.0",)"
1050 R"("ripplerpc" : "2.0",)"
1053 R"({"account": ")" +
1058 gw2.human() + R"("}})");
1059 auto const&
line =
lines[jss::result][jss::lines][0u];
1060 BEAST_EXPECT(line[jss::freeze].asBool() ==
true);
1061 BEAST_EXPECT(line[jss::no_ripple].asBool() ==
true);
1062 BEAST_EXPECT(line[jss::peer_authorized].asBool() ==
true);
1064 lines.isMember(jss::jsonrpc) && lines[jss::jsonrpc] ==
"2.0");
1066 lines.isMember(jss::ripplerpc) &&
1067 lines[jss::ripplerpc] ==
"2.0");
1068 BEAST_EXPECT(
lines.isMember(jss::id) && lines[jss::id] == 5);
1072 auto const linesA = env.rpc(
1075 R
"("method" : "account_lines",)"
1076 R"("jsonrpc" : "2.0",)"
1077 R"("ripplerpc" : "2.0",)"
1080 R"({"account": ")" +
1085 alice.human() + R"("}})");
1086 auto const& lineA = linesA[jss::result][jss::lines][0u];
1087 BEAST_EXPECT(lineA[jss::freeze_peer].asBool() ==
true);
1088 BEAST_EXPECT(lineA[jss::no_ripple_peer].asBool() ==
true);
1089 BEAST_EXPECT(lineA[jss::authorized].asBool() ==
true);
1091 linesA.isMember(jss::jsonrpc) && linesA[jss::jsonrpc] ==
"2.0");
1093 linesA.isMember(jss::ripplerpc) &&
1094 linesA[jss::ripplerpc] ==
"2.0");
1095 BEAST_EXPECT(linesA.isMember(jss::id) && linesA[jss::id] == 5);
1098 BEAST_EXPECT(linesA[jss::result].isMember(jss::marker));
1099 auto const marker = linesA[jss::result][jss::marker].asString();
1100 auto const linesB = env.rpc(
1103 R
"("method" : "account_lines",)"
1104 R"("jsonrpc" : "2.0",)"
1105 R"("ripplerpc" : "2.0",)"
1108 R"({"account": ")" +
1116 alice.human() + R"("}})");
1117 BEAST_EXPECT(linesB[jss::result][jss::lines].isArray());
1118 BEAST_EXPECT(linesB[jss::result][jss::lines].size() == 25);
1119 BEAST_EXPECT(!linesB[jss::result].isMember(jss::marker));
1121 linesB.isMember(jss::jsonrpc) && linesB[jss::jsonrpc] == "2.0");
1123 linesB.isMember(jss::ripplerpc) &&
1124 linesB[jss::ripplerpc] ==
"2.0");
1125 BEAST_EXPECT(linesB.isMember(jss::id) && linesB[jss::id] == 5);
1131 testAccountLineDelete2()
1133 testcase(
"V2: account_lines with removed marker");
1135 using namespace test::jtx;
1149 Account
const alice{
"alice"};
1150 Account
const becky{
"becky"};
1151 Account
const cheri{
"cheri"};
1152 Account
const gw1{
"gw1"};
1153 Account
const gw2{
"gw2"};
1154 env.fund(
XRP(10000), alice, becky, cheri, gw1, gw2);
1157 auto const USD = gw1[
"USD"];
1158 auto const AUD = gw1[
"AUD"];
1159 auto const EUR = gw2[
"EUR"];
1160 env(
trust(alice, USD(200)));
1161 env(
trust(alice, AUD(200)));
1162 env(
trust(becky, EUR(200)));
1163 env(
trust(cheri, EUR(200)));
1167 env(
pay(gw2, becky, EUR(100)));
1171 env(
offer(alice, EUR(100),
XRP(100)));
1175 env(
offer(becky,
XRP(100), EUR(100)));
1179 auto const linesBeg = env.rpc(
1182 R
"("method" : "account_lines",)"
1183 R"("jsonrpc" : "2.0",)"
1184 R"("ripplerpc" : "2.0",)"
1187 R"({"account": ")" +
1192 linesBeg[jss::result][jss::lines][0u][jss::currency] == "USD");
1193 BEAST_EXPECT(linesBeg[jss::result].isMember(jss::marker));
1195 linesBeg.isMember(jss::jsonrpc) && linesBeg[jss::jsonrpc] ==
"2.0");
1197 linesBeg.isMember(jss::ripplerpc) &&
1198 linesBeg[jss::ripplerpc] ==
"2.0");
1199 BEAST_EXPECT(linesBeg.isMember(jss::id) && linesBeg[jss::id] == 5);
1202 env(
pay(alice, cheri, EUR(100)));
1207 auto const linesEnd = env.rpc(
1210 R
"("method" : "account_lines",)"
1211 R"("jsonrpc" : "2.0",)"
1212 R"("ripplerpc" : "2.0",)"
1215 R"({"account": ")" +
1219 linesBeg[jss::result][jss::marker].asString() + R"("}})");
1221 linesEnd[jss::error][jss::message] ==
1224 linesEnd.isMember(jss::jsonrpc) && linesEnd[jss::jsonrpc] == "2.0");
1226 linesEnd.isMember(jss::ripplerpc) &&
1227 linesEnd[jss::ripplerpc] ==
"2.0");
1228 BEAST_EXPECT(linesEnd.isMember(jss::id) && linesEnd[jss::id] == 5);
1235 testAccountLinesMarker();
1236 testAccountLineDelete();
1237 testAccountLines2();
1238 testAccountLineDelete2();