20 #include <ripple/app/misc/Manifest.h>
21 #include <ripple/app/misc/TxQ.h>
22 #include <ripple/basics/StringUtilities.h>
23 #include <ripple/beast/unit_test.h>
24 #include <ripple/protocol/AccountID.h>
25 #include <ripple/protocol/ErrorCodes.h>
26 #include <ripple/protocol/STXChainBridge.h>
27 #include <ripple/protocol/jss.h>
29 #include <test/jtx/attester.h>
30 #include <test/jtx/multisign.h>
31 #include <test/jtx/xchain_bridge.h>
44 if (BEAST_EXPECT(jv.
isMember(jss::status)))
45 BEAST_EXPECT(jv[jss::status] ==
"error");
46 if (BEAST_EXPECT(jv.
isMember(jss::error)))
47 BEAST_EXPECT(jv[jss::error] == err);
52 jv[jss::error_message] ==
"");
54 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
55 BEAST_EXPECT(jv[jss::error_message] == msg);
61 testcase(
"ledger_entry: bridge");
62 using namespace test::jtx;
65 Env scEnv(*
this, envconfig(port_increment, 3),
features);
76 jvParams[jss::bridge] =
jvb;
78 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
80 BEAST_EXPECT(jrr.
isMember(jss::node));
81 auto r = jrr[jss::node];
84 BEAST_EXPECT(r.isMember(jss::Account));
87 BEAST_EXPECT(r.isMember(jss::Flags));
100 BEAST_EXPECT(r.isMember(jss::index));
101 bridge_index = r[jss::index].asString();
107 jvParams[jss::index] = bridge_index;
109 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
111 BEAST_EXPECT(jrr.
isMember(jss::node));
112 BEAST_EXPECT(jrr[jss::node] == mcBridge);
118 jvParams[jss::bridge_account] = Account::master.human();
119 jvParams[jss::bridge] =
jvb;
120 jvParams[jss::ledger_hash] = ledgerHash;
122 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
137 jvParams[jss::bridge] =
jvb;
140 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
142 BEAST_EXPECT(jrr.
isMember(jss::node));
143 auto r = jrr[jss::node];
154 testcase(
"ledger_entry: xchain_claim_id");
155 using namespace test::jtx;
158 Env scEnv(*
this, envconfig(port_increment, 3),
features);
172 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
176 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
178 BEAST_EXPECT(jrr.
isMember(jss::node));
179 auto r = jrr[jss::node];
182 BEAST_EXPECT(r.isMember(jss::Account));
194 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
197 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
199 BEAST_EXPECT(jrr.
isMember(jss::node));
200 auto r = jrr[jss::node];
203 BEAST_EXPECT(r.isMember(jss::Account));
204 BEAST_EXPECT(r[jss::Account] ==
scBob.
human());
215 testcase(
"ledger_entry: xchain_create_account_claim_id");
216 using namespace test::jtx;
219 Env scEnv(*
this, envconfig(port_increment, 3),
features);
227 auto const amt = XRP(1000);
228 mcEnv(sidechain_xchain_account_create(
234 size_t constexpr num_attest = 3;
235 auto attestations = create_account_attestations(
246 UT_XCHAIN_DEFAULT_NUM_SIGNERS);
247 for (
size_t i = 0; i < num_attest; ++i)
249 scEnv(attestations[i]);
256 jvParams[jss::xchain_owned_create_account_claim_id] =
258 jvParams[jss::xchain_owned_create_account_claim_id]
259 [jss::xchain_owned_create_account_claim_id] = 1;
262 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
265 BEAST_EXPECT(jrr.
isMember(jss::node));
266 auto r = jrr[jss::node];
268 BEAST_EXPECT(r.isMember(jss::Account));
269 BEAST_EXPECT(r[jss::Account] == Account::master.human());
277 BEAST_EXPECT(attest.isArray());
278 BEAST_EXPECT(attest.size() == 3);
282 for (
size_t i = 0; i < num_attest; ++i)
287 a[i].isMember(jss::Amount) &&
290 a[i].isMember(jss::Destination) &&
296 return a[i][sfAttestationSignerAccount.jsonName] ==
304 [&](Account
const& account) {
305 return a[i][sfAttestationRewardAccount.jsonName] ==
320 for (
size_t i = num_attest; i < UT_XCHAIN_DEFAULT_NUM_SIGNERS; ++i)
322 scEnv(attestations[i]);
328 jvParams[jss::xchain_owned_create_account_claim_id] =
330 jvParams[jss::xchain_owned_create_account_claim_id]
331 [jss::xchain_owned_create_account_claim_id] = 1;
334 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
357 if (BEAST_EXPECT(jv.
isMember(jss::status)))
358 BEAST_EXPECT(jv[jss::status] ==
"error");
359 if (BEAST_EXPECT(jv.
isMember(jss::error)))
360 BEAST_EXPECT(jv[jss::error] == err);
365 jv[jss::error_message] ==
"");
367 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
368 BEAST_EXPECT(jv[jss::error_message] == msg);
384 testcase(
"Basic Request");
385 using namespace test::jtx;
390 BEAST_EXPECT(env.current()->info().seq == 4);
395 jvParams[jss::ledger_index] = 1;
397 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
398 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
399 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
404 jvParams[jss::ledger_index] =
"1";
406 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
407 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
408 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
413 auto const jrr = env.rpc(
"ledger",
"current")[jss::result];
414 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
false);
416 jrr[jss::ledger][jss::ledger_index] ==
419 jrr[jss::ledger_current_index] == env.current()->info().seq);
426 testcase(
"Bad Input");
427 using namespace test::jtx;
429 Account
const gw{
"gateway"};
430 auto const USD = gw[
"USD"];
431 Account
const bob{
"bob"};
433 env.fund(XRP(10000), gw, bob);
435 env.trust(USD(1000), bob);
441 jvParams[jss::ledger_index] =
"potato";
443 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
450 jvParams[jss::ledger_index] = -1;
452 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
459 jvParams[jss::ledger_index] = 10u;
461 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
467 auto const jrr = env.rpc(
"ledger",
"arbitrary_text")[jss::result];
474 jvParams[jss::ledger_index] =
"validated";
475 jvParams[jss::queue] =
true;
477 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
484 env.rpc(
"json",
"ledger",
"{ \"ledger_index\" : 2e15 }");
486 BEAST_EXPECT(ret[jss::error_message] ==
"Invalid parameters.");
491 auto const ret = env.rpc(
492 "json",
"ledger",
"{ \"ledger_index\" : 1000000000000000 }");
500 testcase(
"ledger_current Request");
501 using namespace test::jtx;
506 BEAST_EXPECT(env.current()->info().seq == 4);
509 auto const jrr = env.rpc(
"ledger_current")[jss::result];
511 jrr[jss::ledger_current_index] == env.current()->info().seq);
518 testcase(
"Missing ledger_entry ledger_hash");
519 using namespace test::jtx;
521 Account
const alice{
"alice"};
522 env.fund(XRP(10000), alice);
526 jvParams[jss::account_root] = alice.human();
527 jvParams[jss::ledger_hash] =
528 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
530 env.rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
537 testcase(
"Ledger Request, Full Option");
538 using namespace test::jtx;
545 jvParams[jss::ledger_index] = 3u;
546 jvParams[jss::full] =
true;
548 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
549 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
550 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
551 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 3u);
557 testcase(
"Ledger Request, Full Option Without Admin");
558 using namespace test::jtx;
560 Env env{*
this, envconfig(no_admin)};
565 jvParams[jss::ledger_index] = 1u;
566 jvParams[jss::full] =
true;
568 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
570 jrr,
"noPermission",
"You don't have permission for this command.");
576 testcase(
"Ledger Request, Accounts Option");
577 using namespace test::jtx;
584 jvParams[jss::ledger_index] = 3u;
585 jvParams[jss::accounts] =
true;
587 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
588 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
589 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
590 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 3u);
596 testcase(
"ledger_entry Request AccountRoot");
597 using namespace test::jtx;
599 Account
const alice{
"alice"};
600 env.fund(XRP(10000), alice);
606 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
607 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
608 BEAST_EXPECT(jrr[jss::ledger_index] == 3);
615 jvParams[jss::account_root] = alice.human();
616 jvParams[jss::ledger_hash] = ledgerHash;
618 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
619 BEAST_EXPECT(jrr.
isMember(jss::node));
620 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
622 accountRootIndex = jrr[jss::index].
asString();
625 constexpr
char alicesAcctRootBinary[]{
626 "1100612200800000240000000425000000032D00000000559CE54C3B934E4"
627 "73A995B477E92EC229F99CED5B62BF4D2ACE4DC42719103AE2F6240000002"
628 "540BE4008114AE123A8556F3CF91154711376AFB0F894F832B3D"};
632 jvParams[jss::account_root] = alice.human();
633 jvParams[jss::binary] = 1;
634 jvParams[jss::ledger_hash] = ledgerHash;
636 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
637 BEAST_EXPECT(jrr.
isMember(jss::node_binary));
638 BEAST_EXPECT(jrr[jss::node_binary] == alicesAcctRootBinary);
643 jvParams[jss::index] = accountRootIndex;
645 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
646 BEAST_EXPECT(!jrr.
isMember(jss::node_binary));
647 BEAST_EXPECT(jrr.
isMember(jss::node));
648 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
654 jvParams[jss::index] = accountRootIndex;
655 jvParams[jss::binary] = 0;
657 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
658 BEAST_EXPECT(jrr.
isMember(jss::node));
659 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
665 jvParams[jss::account_root] = makeBadAddress(alice.human());
666 jvParams[jss::ledger_hash] = ledgerHash;
668 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
674 jvParams[jss::account_root] = Account(
"bob").human();
675 jvParams[jss::ledger_hash] = ledgerHash;
677 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
685 testcase(
"ledger_entry Request Check");
686 using namespace test::jtx;
688 Account
const alice{
"alice"};
689 env.fund(XRP(10000), alice);
692 auto const checkId =
keylet::check(env.master, env.seq(env.master));
694 env(check::create(env.master, alice, XRP(100)));
701 jvParams[jss::check] =
to_string(checkId.key);
702 jvParams[jss::ledger_hash] = ledgerHash;
704 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
715 jvParams[jss::account_root] = alice.human();
717 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
718 accountRootIndex = jrr[jss::index].
asString();
721 jvParams[jss::check] = accountRootIndex;
722 jvParams[jss::ledger_hash] = ledgerHash;
724 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
732 testcase(
"ledger_entry Deposit Preauth");
734 using namespace test::jtx;
737 Account
const alice{
"alice"};
738 Account
const becky{
"becky"};
740 env.fund(XRP(10000), alice, becky);
743 env(deposit::auth(alice, becky));
751 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
752 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
753 jvParams[jss::ledger_hash] = ledgerHash;
755 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
759 jss::DepositPreauth);
762 depositPreauthIndex = jrr[jss::node][jss::index].
asString();
767 jvParams[jss::deposit_preauth] = depositPreauthIndex;
768 jvParams[jss::ledger_hash] = ledgerHash;
770 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
774 jss::DepositPreauth);
781 jvParams[jss::deposit_preauth] = -5;
782 jvParams[jss::ledger_hash] = ledgerHash;
784 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
790 jvParams[jss::deposit_preauth] =
"0123456789ABCDEFG";
791 jvParams[jss::ledger_hash] = ledgerHash;
793 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
799 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
800 jvParams[jss::ledger_hash] = ledgerHash;
802 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
808 jvParams[jss::deposit_preauth][jss::owner] = 7;
809 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
810 jvParams[jss::ledger_hash] = ledgerHash;
812 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
818 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
819 jvParams[jss::ledger_hash] = ledgerHash;
821 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
827 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
828 jvParams[jss::deposit_preauth][jss::authorized] = 47;
829 jvParams[jss::ledger_hash] = ledgerHash;
831 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
837 jvParams[jss::deposit_preauth][jss::owner] =
838 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
840 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
841 jvParams[jss::ledger_hash] = ledgerHash;
843 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
849 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
850 jvParams[jss::deposit_preauth][jss::authorized] =
851 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
853 jvParams[jss::ledger_hash] = ledgerHash;
855 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
863 testcase(
"ledger_entry Request Directory");
864 using namespace test::jtx;
866 Account
const alice{
"alice"};
867 Account
const gw{
"gateway"};
868 auto const USD = gw[
"USD"];
869 env.fund(XRP(10000), alice, gw);
872 env.trust(USD(1000), alice);
877 for (
int d = 1
'000'032; d >= 1
'000'000; --d)
879 env(offer(alice, USD(1), drops(d)));
886 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
887 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
888 BEAST_EXPECT(jrr[jss::ledger_index] == 5);
892 "A33EC6BB85FB5674074C4A3A43373BB17645308F3EAE1933E3E35252162B217D";
896 jvParams[jss::directory] = dirRootIndex;
897 jvParams[jss::ledger_hash] = ledgerHash;
899 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
906 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
908 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
909 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
915 jvParams[jss::directory][jss::owner] = alice.human();
916 jvParams[jss::ledger_hash] = ledgerHash;
918 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
919 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
925 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
926 jvParams[jss::directory][jss::sub_index] = 1;
928 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
929 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
936 jvParams[jss::directory][jss::owner] = alice.human();
937 jvParams[jss::directory][jss::sub_index] = 1;
938 jvParams[jss::ledger_hash] = ledgerHash;
940 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
941 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
948 jvParams[jss::ledger_hash] = ledgerHash;
950 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
957 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
958 jvParams[jss::directory][jss::sub_index] = 1.5;
959 jvParams[jss::ledger_hash] = ledgerHash;
961 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
969 std::string const badAddress = makeBadAddress(alice.human());
970 jvParams[jss::directory][jss::owner] = badAddress;
971 jvParams[jss::ledger_hash] = ledgerHash;
973 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
980 jvParams[jss::directory][jss::owner] = alice.human();
981 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
982 jvParams[jss::ledger_hash] = ledgerHash;
984 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
991 jvParams[jss::directory][jss::sub_index] = 1;
992 jvParams[jss::ledger_hash] = ledgerHash;
994 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1002 testcase(
"ledger_entry Request Escrow");
1003 using namespace test::jtx;
1005 Account
const alice{
"alice"};
1006 env.fund(XRP(10000), alice);
1015 jv[jss::TransactionType] = jss::EscrowCreate;
1017 jv[jss::Account] = account.human();
1018 jv[jss::Destination] = to.human();
1021 cancelAfter.time_since_epoch().count() + 2;
1025 using namespace std::chrono_literals;
1026 env(escrowCreate(alice, alice, XRP(333), env.now() + 2s));
1035 jvParams[jss::escrow][jss::owner] = alice.human();
1036 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1038 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1040 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1041 escrowIndex = jrr[jss::index].
asString();
1046 jvParams[jss::escrow] = escrowIndex;
1047 jvParams[jss::ledger_hash] = ledgerHash;
1049 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1051 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1058 std::string const badAddress = makeBadAddress(alice.human());
1059 jvParams[jss::escrow][jss::owner] = badAddress;
1060 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1061 jvParams[jss::ledger_hash] = ledgerHash;
1063 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1070 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1071 jvParams[jss::ledger_hash] = ledgerHash;
1073 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1080 jvParams[jss::escrow][jss::owner] = alice.human();
1081 jvParams[jss::ledger_hash] = ledgerHash;
1083 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1090 jvParams[jss::escrow][jss::owner] = alice.human();
1091 jvParams[jss::escrow][jss::seq] =
1093 jvParams[jss::ledger_hash] = ledgerHash;
1095 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1103 testcase(
"ledger_entry Request Offer");
1104 using namespace test::jtx;
1106 Account
const alice{
"alice"};
1107 Account
const gw{
"gateway"};
1108 auto const USD = gw[
"USD"];
1109 env.fund(XRP(10000), alice, gw);
1112 env(offer(alice, USD(321), XRP(322)));
1121 jvParams[jss::offer][jss::account] = alice.human();
1122 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1123 jvParams[jss::ledger_hash] = ledgerHash;
1125 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1126 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1127 offerIndex = jrr[jss::index].
asString();
1132 jvParams[jss::offer] = offerIndex;
1134 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1135 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1142 std::string const badAddress = makeBadAddress(alice.human());
1143 jvParams[jss::offer][jss::account] = badAddress;
1144 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1145 jvParams[jss::ledger_hash] = ledgerHash;
1147 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1154 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1155 jvParams[jss::ledger_hash] = ledgerHash;
1157 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1164 jvParams[jss::offer][jss::account] = alice.human();
1165 jvParams[jss::ledger_hash] = ledgerHash;
1167 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1174 jvParams[jss::offer][jss::account] = alice.human();
1175 jvParams[jss::offer][jss::seq] =
std::to_string(env.seq(alice) - 1);
1176 jvParams[jss::ledger_hash] = ledgerHash;
1178 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1186 testcase(
"ledger_entry Request Pay Chan");
1187 using namespace test::jtx;
1188 using namespace std::literals::chrono_literals;
1190 Account
const alice{
"alice"};
1192 env.fund(XRP(10000), alice);
1202 jv[jss::TransactionType] = jss::PaymentChannelCreate;
1203 jv[jss::Account] = account.human();
1204 jv[jss::Destination] = to.human();
1211 env(payChanCreate(alice, env.master, XRP(57), 18s, alice.pk()));
1221 jvParams[jss::payment_channel] =
to_string(payChanIndex);
1222 jvParams[jss::ledger_hash] = ledgerHash;
1224 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1232 jvParams[jss::payment_channel] = ledgerHash;
1233 jvParams[jss::ledger_hash] = ledgerHash;
1235 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1243 testcase(
"ledger_entry Request RippleState");
1244 using namespace test::jtx;
1246 Account
const alice{
"alice"};
1247 Account
const gw{
"gateway"};
1248 auto const USD = gw[
"USD"];
1249 env.fund(XRP(10000), alice, gw);
1252 env.trust(USD(999), alice);
1255 env(pay(gw, alice, USD(97)));
1264 jvParams[jss::ripple_state][jss::accounts][0u] = alice.human();
1265 jvParams[jss::ripple_state][jss::accounts][1u] = gw.human();
1266 jvParams[jss::ripple_state][jss::currency] =
"USD";
1267 jvParams[jss::ledger_hash] = ledgerHash;
1269 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1278 jvParams[jss::ripple_state] =
"ripple_state";
1279 jvParams[jss::ledger_hash] = ledgerHash;
1281 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1289 jvParams[jss::ripple_state][jss::accounts][0u] = alice.human();
1290 jvParams[jss::ripple_state][jss::accounts][1u] = gw.human();
1291 jvParams[jss::ledger_hash] = ledgerHash;
1293 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1300 jvParams[jss::ripple_state][jss::accounts] = 2;
1301 jvParams[jss::ripple_state][jss::currency] =
"USD";
1302 jvParams[jss::ledger_hash] = ledgerHash;
1304 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1312 jvParams[jss::ripple_state][jss::accounts][0u] = alice.human();
1313 jvParams[jss::ripple_state][jss::currency] =
"USD";
1314 jvParams[jss::ledger_hash] = ledgerHash;
1316 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1324 jvParams[jss::ripple_state][jss::accounts][0u] = alice.human();
1325 jvParams[jss::ripple_state][jss::accounts][1u] = gw.human();
1326 jvParams[jss::ripple_state][jss::accounts][2u] = alice.human();
1327 jvParams[jss::ripple_state][jss::currency] =
"USD";
1328 jvParams[jss::ledger_hash] = ledgerHash;
1330 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1338 jvParams[jss::ripple_state][jss::accounts][0u] = 44;
1339 jvParams[jss::ripple_state][jss::accounts][1u] = gw.human();
1340 jvParams[jss::ripple_state][jss::currency] =
"USD";
1341 jvParams[jss::ledger_hash] = ledgerHash;
1343 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1351 jvParams[jss::ripple_state][jss::accounts][0u] = alice.human();
1352 jvParams[jss::ripple_state][jss::accounts][1u] = 21;
1353 jvParams[jss::ripple_state][jss::currency] =
"USD";
1354 jvParams[jss::ledger_hash] = ledgerHash;
1356 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1364 jvParams[jss::ripple_state][jss::accounts][0u] = alice.human();
1365 jvParams[jss::ripple_state][jss::accounts][1u] = alice.human();
1366 jvParams[jss::ripple_state][jss::currency] =
"USD";
1367 jvParams[jss::ledger_hash] = ledgerHash;
1369 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1377 jvParams[jss::ripple_state][jss::accounts][0u] =
1378 makeBadAddress(alice.human());
1379 jvParams[jss::ripple_state][jss::accounts][1u] = gw.human();
1380 jvParams[jss::ripple_state][jss::currency] =
"USD";
1381 jvParams[jss::ledger_hash] = ledgerHash;
1383 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1391 jvParams[jss::ripple_state][jss::accounts][0u] = alice.human();
1392 jvParams[jss::ripple_state][jss::accounts][1u] =
1393 makeBadAddress(gw.human());
1394 jvParams[jss::ripple_state][jss::currency] =
"USD";
1395 jvParams[jss::ledger_hash] = ledgerHash;
1397 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1405 jvParams[jss::ripple_state][jss::accounts][0u] = alice.human();
1406 jvParams[jss::ripple_state][jss::accounts][1u] = gw.human();
1407 jvParams[jss::ripple_state][jss::currency] =
"USDollars";
1408 jvParams[jss::ledger_hash] = ledgerHash;
1410 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1418 testcase(
"ledger_entry Request Ticket");
1419 using namespace test::jtx;
1425 env(ticket::create(env.master, 2));
1435 jvParams[jss::ticket] =
1437 jvParams[jss::ledger_hash] = ledgerHash;
1439 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1446 jvParams[jss::ledger_hash] = ledgerHash;
1448 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1457 jvParams[jss::ticket][jss::account] = env.master.human();
1458 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 1;
1459 jvParams[jss::ledger_hash] = ledgerHash;
1461 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1463 jrr[jss::node][jss::index] ==
1470 jvParams[jss::ticket][jss::account] = env.master.human();
1471 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 2;
1472 jvParams[jss::ledger_hash] = ledgerHash;
1474 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1481 jvParams[jss::ledger_hash] = ledgerHash;
1483 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1491 std::string const badAddress = makeBadAddress(env.master.human());
1492 jvParams[jss::ticket][jss::account] = badAddress;
1493 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
1494 jvParams[jss::ledger_hash] = ledgerHash;
1496 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1503 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
1504 jvParams[jss::ledger_hash] = ledgerHash;
1506 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1513 jvParams[jss::ticket][jss::account] = env.master.human();
1514 jvParams[jss::ledger_hash] = ledgerHash;
1516 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1523 jvParams[jss::ticket][jss::account] = env.master.human();
1524 jvParams[jss::ticket][jss::ticket_seq] =
1526 jvParams[jss::ledger_hash] = ledgerHash;
1528 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1536 testcase(
"ledger_entry Request DID");
1537 using namespace test::jtx;
1538 using namespace std::literals::chrono_literals;
1540 Account
const alice{
"alice"};
1542 env.fund(XRP(10000), alice);
1548 jv[jss::TransactionType] = jss::DIDSet;
1549 jv[jss::Account] = account.human();
1555 env(didCreate(alice));
1563 jvParams[jss::did] = alice.human();
1564 jvParams[jss::ledger_hash] = ledgerHash;
1566 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1576 jvParams[jss::did] = env.master.human();
1577 jvParams[jss::ledger_hash] = ledgerHash;
1579 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1588 "ledger_entry Request With Invalid Parameters v" +
1590 using namespace test::jtx;
1597 params[jss::api_version] = apiVersion;
1603 auto const jvParams =
1605 jvParams[jss::features] = ledgerHash;
1606 jvParams[jss::ledger_hash] = ledgerHash;
1609 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1611 if (apiVersion < 2u)
1618 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
1619 obj[jss::ledger_index] =
"validated";
1624 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
1625 arr[1u] =
"validated";
1631 for (
auto const& field :
1632 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
1634 auto const jvParams =
1635 makeParams([&field, &injectArray](
Json::Value& jvParams) {
1636 jvParams[field] = injectArray;
1640 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1642 if (apiVersion < 2u)
1648 for (
auto const& field :
1649 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
1651 auto const jvParams =
1652 makeParams([&field, &injectObject](
Json::Value& jvParams) {
1653 jvParams[field] = injectObject;
1657 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1662 for (
auto const& inject : {injectObject, injectArray})
1665 for (
auto const& field :
1669 jss::payment_channel})
1671 auto const jvParams =
1672 makeParams([&field, &inject](
Json::Value& jvParams) {
1673 jvParams[field] = inject;
1677 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1679 if (apiVersion < 2u)
1685 for (
auto const& field : {jss::dir_root, jss::owner})
1687 auto const jvParams =
1688 makeParams([&field, &inject](
Json::Value& jvParams) {
1689 jvParams[jss::directory][field] = inject;
1693 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1695 if (apiVersion < 2u)
1702 auto const jvParams =
1704 jvParams[jss::escrow][jss::owner] = inject;
1705 jvParams[jss::escrow][jss::seq] = 99;
1709 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1711 if (apiVersion < 2u)
1718 auto const jvParams =
1720 jvParams[jss::offer][jss::account] = inject;
1721 jvParams[jss::offer][jss::seq] = 99;
1725 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1727 if (apiVersion < 2u)
1734 auto const jvParams =
1737 rs[jss::currency] =
"FOO";
1739 rs[jss::accounts][0u] =
1740 "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
1741 rs[jss::accounts][1u] =
1742 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
1743 rs[jss::currency] = inject;
1744 jvParams[jss::ripple_state] = std::move(rs);
1748 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1750 if (apiVersion < 2u)
1757 auto const jvParams =
1759 jvParams[jss::ticket][jss::account] = inject;
1760 jvParams[jss::ticket][jss::ticket_seq] = 99;
1764 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1766 if (apiVersion < 2u)
1773 for (
auto const& field : {jss::nft_page, jss::deposit_preauth})
1775 auto const jvParams =
1776 makeParams([&field, &inject](
Json::Value& jvParams) {
1777 jvParams[field] = inject;
1781 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1787 for (
auto const& field : {jss::owner, jss::authorized})
1789 auto const jvParams =
1790 makeParams([&field, &inject](
Json::Value& jvParams) {
1792 pa[jss::owner] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
1793 pa[jss::authorized] =
1794 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
1796 jvParams[jss::deposit_preauth] = std::move(pa);
1800 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1814 testcase(
"Lookup ledger");
1815 using namespace test::jtx;
1818 env.fund(XRP(10000),
"alice");
1820 env.fund(XRP(10000),
"bob");
1822 env.fund(XRP(10000),
"jim");
1824 env.fund(XRP(10000),
"jill");
1829 jvParams[jss::ledger] =
"closed";
1833 boost::lexical_cast<std::string>(jvParams))[jss::result];
1834 BEAST_EXPECT(jrr.isMember(jss::ledger));
1835 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1836 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
1838 jvParams[jss::ledger] =
"validated";
1842 boost::lexical_cast<std::string>(jvParams))[jss::result];
1843 BEAST_EXPECT(jrr.isMember(jss::ledger));
1844 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1845 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
1847 jvParams[jss::ledger] =
"current";
1851 boost::lexical_cast<std::string>(jvParams))[jss::result];
1852 BEAST_EXPECT(jrr.isMember(jss::ledger));
1853 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
1856 jvParams[jss::ledger] =
"invalid";
1860 boost::lexical_cast<std::string>(jvParams))[jss::result];
1861 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1862 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
1865 jvParams[jss::ledger] = 4;
1869 boost::lexical_cast<std::string>(jvParams))[jss::result];
1870 BEAST_EXPECT(jrr.isMember(jss::ledger));
1871 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1872 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
1875 jvParams[jss::ledger] = 20;
1879 boost::lexical_cast<std::string>(jvParams))[jss::result];
1880 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
1881 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
1886 "E86DE7F3D7A4D9CE17EF7C8BA08A8F4D"
1887 "8F643B9552F0D895A31CDA78F541DE4E"};
1890 jvParams[jss::ledger_hash] = hash3;
1894 boost::lexical_cast<std::string>(jvParams))[jss::result];
1895 BEAST_EXPECT(jrr.isMember(jss::ledger));
1896 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1897 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
1900 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
1904 boost::lexical_cast<std::string>(jvParams))[jss::result];
1905 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1906 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
1909 jvParams[jss::ledger_hash] = 2;
1913 boost::lexical_cast<std::string>(jvParams))[jss::result];
1914 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1915 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashNotString");
1918 jvParams[jss::ledger_hash] =
1919 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
1920 "7F2775F2F7485BB37307984C3C0F2340";
1924 boost::lexical_cast<std::string>(jvParams))[jss::result];
1925 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1926 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
1929 jvParams[jss::ledger_hash] =
1930 "8C3EEDB3124D92E49E75D81A8826A2E6"
1931 "5A75FD71FC3FD6F36FEB803C5F1D812D";
1935 boost::lexical_cast<std::string>(jvParams))[jss::result];
1936 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
1937 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
1943 jvParams[jss::ledger_index] =
"closed";
1947 boost::lexical_cast<std::string>(jvParams))[jss::result];
1948 BEAST_EXPECT(jrr.isMember(jss::ledger));
1949 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1950 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
1951 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
1953 jvParams[jss::ledger_index] =
"validated";
1957 boost::lexical_cast<std::string>(jvParams))[jss::result];
1958 BEAST_EXPECT(jrr.isMember(jss::ledger));
1959 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1960 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
1962 jvParams[jss::ledger_index] =
"current";
1966 boost::lexical_cast<std::string>(jvParams))[jss::result];
1967 BEAST_EXPECT(jrr.isMember(jss::ledger));
1968 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
1969 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
1972 jvParams[jss::ledger_index] =
"invalid";
1976 boost::lexical_cast<std::string>(jvParams))[jss::result];
1977 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1978 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
1981 for (
auto i : {1, 2, 3, 4, 5, 6})
1983 jvParams[jss::ledger_index] = i;
1987 boost::lexical_cast<std::string>(jvParams))[jss::result];
1988 BEAST_EXPECT(jrr.isMember(jss::ledger));
1990 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1996 jvParams[jss::ledger_index] = 7;
2000 boost::lexical_cast<std::string>(jvParams))[jss::result];
2001 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2002 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2009 testcase(
"Ledger with queueing disabled");
2010 using namespace test::jtx;
2014 jv[jss::ledger_index] =
"current";
2015 jv[jss::queue] =
true;
2016 jv[jss::expand] =
true;
2018 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2019 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2025 testcase(
"Ledger with Queued Transactions");
2026 using namespace test::jtx;
2028 auto& section = cfg->section(
"transaction_queue");
2029 section.set(
"minimum_txn_in_ledger_standalone",
"3");
2030 section.set(
"normal_consensus_increase_percent",
"0");
2035 jv[jss::ledger_index] =
"current";
2036 jv[jss::queue] =
true;
2037 jv[jss::expand] =
true;
2039 Account
const alice{
"alice"};
2040 Account
const bob{
"bob"};
2041 Account
const charlie{
"charlie"};
2042 Account
const daria{
"daria"};
2043 env.fund(XRP(10000), alice);
2044 env.fund(XRP(10000), bob);
2046 env.fund(XRP(10000), charlie);
2047 env.fund(XRP(10000), daria);
2050 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2051 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2056 auto metrics = env.app().getTxQ().getMetrics(*env.current());
2057 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
2062 BEAST_EXPECT(env.current()->info().seq == 5);
2065 auto aliceSeq = env.seq(alice);
2066 env(pay(alice,
"george", XRP(1000)),
2067 json(R
"({"LastLedgerSequence":7})"),
2069 env(offer(alice, XRP(50000), alice["USD"](5000)),
2072 env(noop(alice), seq(aliceSeq + 2), ter(
terQUEUED));
2074 auto batch = [&env](Account a) {
2075 auto aSeq = env.seq(a);
2077 for (
int i = 0; i < 10; ++i)
2079 env(noop(a), fee(1000 + i), seq(aSeq + i), ter(
terQUEUED));
2088 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2089 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
2095 BEAST_EXPECT(env.current()->info().seq == 8);
2097 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2098 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
2102 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2104 auto const& parentHash = env.current()->info().parentHash;
2105 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2108 auto const& txj = jrr[jss::queue_data][1u];
2109 BEAST_EXPECT(txj[jss::account] == alice.human());
2110 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2111 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2112 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2113 BEAST_EXPECT(txj.isMember(jss::tx));
2114 auto const& tx = txj[jss::tx];
2115 BEAST_EXPECT(tx[jss::Account] == alice.human());
2116 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2117 return tx[jss::hash].asString();
2120 auto const& txj = jrr[jss::queue_data][0u];
2121 BEAST_EXPECT(txj[jss::account] == alice.human());
2122 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2123 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2124 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2125 BEAST_EXPECT(txj.isMember(jss::tx));
2126 auto const& tx = txj[jss::tx];
2127 BEAST_EXPECT(tx[jss::Account] == alice.human());
2128 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
2129 const auto txid0 = tx[jss::hash].asString();
2133 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2141 jv[jss::expand] =
false;
2143 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2144 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2146 auto const& parentHash = env.current()->info().parentHash;
2147 auto const txid1 = [&]() {
2148 auto const& txj = jrr[jss::queue_data][1u];
2149 BEAST_EXPECT(txj[jss::account] == alice.human());
2150 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2151 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2152 BEAST_EXPECT(txj.isMember(jss::tx));
2153 return txj[jss::tx].asString();
2155 auto const& txj = jrr[jss::queue_data][0u];
2156 BEAST_EXPECT(txj[jss::account] == alice.human());
2157 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2158 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2159 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
2160 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2161 BEAST_EXPECT(txj.isMember(jss::tx));
2162 BEAST_EXPECT(txj[jss::tx] == txid0);
2166 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2171 jv[jss::expand] =
true;
2172 jv[jss::binary] =
true;
2174 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2175 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2177 auto const& txj = jrr[jss::queue_data][1u];
2178 BEAST_EXPECT(txj[jss::account] == alice.human());
2179 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2180 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2181 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
2182 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2183 BEAST_EXPECT(txj.isMember(jss::tx));
2184 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
2186 auto const& txj2 = jrr[jss::queue_data][0u];
2187 BEAST_EXPECT(txj2[jss::account] == alice.human());
2188 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
2189 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
2190 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
2191 BEAST_EXPECT(!txj2.isMember(
"last_result"));
2192 BEAST_EXPECT(txj2.isMember(jss::tx));
2193 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
2196 for (
int i = 0; i != 9; ++i)
2201 jv[jss::expand] =
false;
2202 jv[jss::binary] =
false;
2204 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2206 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2208 auto const& txj = jrr[jss::queue_data][0u];
2209 BEAST_EXPECT(txj[jss::account] == alice.human());
2210 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2211 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2212 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2213 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2214 BEAST_EXPECT(txj.isMember(jss::tx));
2215 BEAST_EXPECT(txj[jss::tx] != txid0);
2216 return txj[jss::tx].asString();
2221 jv[jss::full] =
true;
2223 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2224 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2226 auto const& txj = jrr[jss::queue_data][0u];
2227 BEAST_EXPECT(txj[jss::account] == alice.human());
2228 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2229 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2230 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2231 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2232 BEAST_EXPECT(txj.isMember(jss::tx));
2233 auto const& tx = txj[jss::tx];
2234 BEAST_EXPECT(tx[jss::Account] == alice.human());
2235 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2236 BEAST_EXPECT(tx[jss::hash] == txid2);
2243 testcase(
"Ledger Request, Accounts Hashes");
2244 using namespace test::jtx;
2253 jvParams[jss::ledger_index] = 3u;
2254 jvParams[jss::accounts] =
true;
2255 jvParams[jss::expand] =
true;
2256 jvParams[jss::type] =
"hashes";
2258 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2259 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2260 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2261 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2263 jrr[jss::ledger][jss::accountState][0u][
"LedgerEntryType"] ==
2265 index = jrr[jss::ledger][jss::accountState][0u][
"index"].asString();
2269 jvParams[jss::ledger_index] = 3u;
2270 jvParams[jss::accounts] =
true;
2271 jvParams[jss::expand] =
false;
2272 jvParams[jss::type] =
"hashes";
2274 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2275 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2276 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2277 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2278 BEAST_EXPECT(jrr[jss::ledger][jss::accountState][0u] == index);
2286 testLedgerRequest();
2288 testLedgerCurrent();
2289 testMissingLedgerEntryLedgerHash();
2291 testLedgerFullNonAdmin();
2292 testLedgerAccounts();
2293 testLedgerEntryAccountRoot();
2294 testLedgerEntryCheck();
2295 testLedgerEntryDepositPreauth();
2296 testLedgerEntryDirectory();
2297 testLedgerEntryEscrow();
2298 testLedgerEntryOffer();
2299 testLedgerEntryPayChan();
2300 testLedgerEntryRippleState();
2301 testLedgerEntryTicket();
2305 testLedgerAccountsOption();
2306 testLedgerEntryDID();