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];
1537 "ledger_entry Request With Invalid Parameters v" +
1539 using namespace test::jtx;
1546 params[jss::api_version] = apiVersion;
1552 auto const jvParams =
1554 jvParams[jss::features] = ledgerHash;
1555 jvParams[jss::ledger_hash] = ledgerHash;
1558 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1560 if (apiVersion < 2u)
1567 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
1568 obj[jss::ledger_index] =
"validated";
1573 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
1574 arr[1u] =
"validated";
1580 for (
auto const& field :
1581 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
1583 auto const jvParams =
1584 makeParams([&field, &injectArray](
Json::Value& jvParams) {
1585 jvParams[field] = injectArray;
1589 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1591 if (apiVersion < 2u)
1597 for (
auto const& field :
1598 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
1600 auto const jvParams =
1601 makeParams([&field, &injectObject](
Json::Value& jvParams) {
1602 jvParams[field] = injectObject;
1606 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1611 for (
auto const& inject : {injectObject, injectArray})
1614 for (
auto const& field :
1618 jss::payment_channel})
1620 auto const jvParams =
1621 makeParams([&field, &inject](
Json::Value& jvParams) {
1622 jvParams[field] = inject;
1626 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1628 if (apiVersion < 2u)
1634 for (
auto const& field : {jss::dir_root, jss::owner})
1636 auto const jvParams =
1637 makeParams([&field, &inject](
Json::Value& jvParams) {
1638 jvParams[jss::directory][field] = inject;
1642 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1644 if (apiVersion < 2u)
1651 auto const jvParams =
1653 jvParams[jss::escrow][jss::owner] = inject;
1654 jvParams[jss::escrow][jss::seq] = 99;
1658 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1660 if (apiVersion < 2u)
1667 auto const jvParams =
1669 jvParams[jss::offer][jss::account] = inject;
1670 jvParams[jss::offer][jss::seq] = 99;
1674 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1676 if (apiVersion < 2u)
1683 auto const jvParams =
1686 rs[jss::currency] =
"FOO";
1688 rs[jss::accounts][0u] =
1689 "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
1690 rs[jss::accounts][1u] =
1691 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
1692 rs[jss::currency] = inject;
1693 jvParams[jss::ripple_state] = std::move(rs);
1697 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1699 if (apiVersion < 2u)
1706 auto const jvParams =
1708 jvParams[jss::ticket][jss::account] = inject;
1709 jvParams[jss::ticket][jss::ticket_seq] = 99;
1713 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1715 if (apiVersion < 2u)
1722 for (
auto const& field : {jss::nft_page, jss::deposit_preauth})
1724 auto const jvParams =
1725 makeParams([&field, &inject](
Json::Value& jvParams) {
1726 jvParams[field] = inject;
1730 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1736 for (
auto const& field : {jss::owner, jss::authorized})
1738 auto const jvParams =
1739 makeParams([&field, &inject](
Json::Value& jvParams) {
1741 pa[jss::owner] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
1742 pa[jss::authorized] =
1743 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
1745 jvParams[jss::deposit_preauth] = std::move(pa);
1749 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1763 testcase(
"Lookup ledger");
1764 using namespace test::jtx;
1767 env.fund(XRP(10000),
"alice");
1769 env.fund(XRP(10000),
"bob");
1771 env.fund(XRP(10000),
"jim");
1773 env.fund(XRP(10000),
"jill");
1778 jvParams[jss::ledger] =
"closed";
1782 boost::lexical_cast<std::string>(jvParams))[jss::result];
1783 BEAST_EXPECT(jrr.isMember(jss::ledger));
1784 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1785 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
1787 jvParams[jss::ledger] =
"validated";
1791 boost::lexical_cast<std::string>(jvParams))[jss::result];
1792 BEAST_EXPECT(jrr.isMember(jss::ledger));
1793 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1794 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
1796 jvParams[jss::ledger] =
"current";
1800 boost::lexical_cast<std::string>(jvParams))[jss::result];
1801 BEAST_EXPECT(jrr.isMember(jss::ledger));
1802 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
1805 jvParams[jss::ledger] =
"invalid";
1809 boost::lexical_cast<std::string>(jvParams))[jss::result];
1810 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1811 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
1814 jvParams[jss::ledger] = 4;
1818 boost::lexical_cast<std::string>(jvParams))[jss::result];
1819 BEAST_EXPECT(jrr.isMember(jss::ledger));
1820 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1821 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
1824 jvParams[jss::ledger] = 20;
1828 boost::lexical_cast<std::string>(jvParams))[jss::result];
1829 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
1830 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
1835 "E86DE7F3D7A4D9CE17EF7C8BA08A8F4D"
1836 "8F643B9552F0D895A31CDA78F541DE4E"};
1839 jvParams[jss::ledger_hash] = hash3;
1843 boost::lexical_cast<std::string>(jvParams))[jss::result];
1844 BEAST_EXPECT(jrr.isMember(jss::ledger));
1845 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1846 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
1849 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
1853 boost::lexical_cast<std::string>(jvParams))[jss::result];
1854 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1855 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
1858 jvParams[jss::ledger_hash] = 2;
1862 boost::lexical_cast<std::string>(jvParams))[jss::result];
1863 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1864 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashNotString");
1867 jvParams[jss::ledger_hash] =
1868 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
1869 "7F2775F2F7485BB37307984C3C0F2340";
1873 boost::lexical_cast<std::string>(jvParams))[jss::result];
1874 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1875 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
1878 jvParams[jss::ledger_hash] =
1879 "8C3EEDB3124D92E49E75D81A8826A2E6"
1880 "5A75FD71FC3FD6F36FEB803C5F1D812D";
1884 boost::lexical_cast<std::string>(jvParams))[jss::result];
1885 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
1886 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
1892 jvParams[jss::ledger_index] =
"closed";
1896 boost::lexical_cast<std::string>(jvParams))[jss::result];
1897 BEAST_EXPECT(jrr.isMember(jss::ledger));
1898 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1899 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
1900 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
1902 jvParams[jss::ledger_index] =
"validated";
1906 boost::lexical_cast<std::string>(jvParams))[jss::result];
1907 BEAST_EXPECT(jrr.isMember(jss::ledger));
1908 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1909 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
1911 jvParams[jss::ledger_index] =
"current";
1915 boost::lexical_cast<std::string>(jvParams))[jss::result];
1916 BEAST_EXPECT(jrr.isMember(jss::ledger));
1917 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
1918 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
1921 jvParams[jss::ledger_index] =
"invalid";
1925 boost::lexical_cast<std::string>(jvParams))[jss::result];
1926 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
1927 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
1930 for (
auto i : {1, 2, 3, 4, 5, 6})
1932 jvParams[jss::ledger_index] = i;
1936 boost::lexical_cast<std::string>(jvParams))[jss::result];
1937 BEAST_EXPECT(jrr.isMember(jss::ledger));
1939 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
1945 jvParams[jss::ledger_index] = 7;
1949 boost::lexical_cast<std::string>(jvParams))[jss::result];
1950 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
1951 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
1958 testcase(
"Ledger with queueing disabled");
1959 using namespace test::jtx;
1963 jv[jss::ledger_index] =
"current";
1964 jv[jss::queue] =
true;
1965 jv[jss::expand] =
true;
1967 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
1968 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
1974 testcase(
"Ledger with Queued Transactions");
1975 using namespace test::jtx;
1977 auto& section = cfg->section(
"transaction_queue");
1978 section.set(
"minimum_txn_in_ledger_standalone",
"3");
1979 section.set(
"normal_consensus_increase_percent",
"0");
1984 jv[jss::ledger_index] =
"current";
1985 jv[jss::queue] =
true;
1986 jv[jss::expand] =
true;
1988 Account
const alice{
"alice"};
1989 Account
const bob{
"bob"};
1990 Account
const charlie{
"charlie"};
1991 Account
const daria{
"daria"};
1992 env.fund(XRP(10000), alice);
1993 env.fund(XRP(10000), bob);
1995 env.fund(XRP(10000), charlie);
1996 env.fund(XRP(10000), daria);
1999 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2000 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2005 auto metrics = env.app().getTxQ().getMetrics(*env.current());
2006 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
2011 BEAST_EXPECT(env.current()->info().seq == 5);
2014 auto aliceSeq = env.seq(alice);
2015 env(pay(alice,
"george", XRP(1000)),
2016 json(R
"({"LastLedgerSequence":7})"),
2018 env(offer(alice, XRP(50000), alice["USD"](5000)),
2021 env(noop(alice), seq(aliceSeq + 2), ter(
terQUEUED));
2023 auto batch = [&env](Account a) {
2024 auto aSeq = env.seq(a);
2026 for (
int i = 0; i < 10; ++i)
2028 env(noop(a), fee(1000 + i), seq(aSeq + i), ter(
terQUEUED));
2037 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2038 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
2044 BEAST_EXPECT(env.current()->info().seq == 8);
2046 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2047 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
2051 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2053 auto const& parentHash = env.current()->info().parentHash;
2054 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2057 auto const& txj = jrr[jss::queue_data][1u];
2058 BEAST_EXPECT(txj[jss::account] == alice.human());
2059 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2060 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2061 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2062 BEAST_EXPECT(txj.isMember(jss::tx));
2063 auto const& tx = txj[jss::tx];
2064 BEAST_EXPECT(tx[jss::Account] == alice.human());
2065 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2066 return tx[jss::hash].asString();
2069 auto const& txj = jrr[jss::queue_data][0u];
2070 BEAST_EXPECT(txj[jss::account] == alice.human());
2071 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2072 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2073 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2074 BEAST_EXPECT(txj.isMember(jss::tx));
2075 auto const& tx = txj[jss::tx];
2076 BEAST_EXPECT(tx[jss::Account] == alice.human());
2077 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
2078 const auto txid0 = tx[jss::hash].asString();
2082 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2090 jv[jss::expand] =
false;
2092 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2093 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2095 auto const& parentHash = env.current()->info().parentHash;
2096 auto const txid1 = [&]() {
2097 auto const& txj = jrr[jss::queue_data][1u];
2098 BEAST_EXPECT(txj[jss::account] == alice.human());
2099 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2100 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2101 BEAST_EXPECT(txj.isMember(jss::tx));
2102 return txj[jss::tx].asString();
2104 auto const& txj = jrr[jss::queue_data][0u];
2105 BEAST_EXPECT(txj[jss::account] == alice.human());
2106 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2107 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2108 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
2109 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2110 BEAST_EXPECT(txj.isMember(jss::tx));
2111 BEAST_EXPECT(txj[jss::tx] == txid0);
2115 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2120 jv[jss::expand] =
true;
2121 jv[jss::binary] =
true;
2123 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2124 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2126 auto const& txj = jrr[jss::queue_data][1u];
2127 BEAST_EXPECT(txj[jss::account] == alice.human());
2128 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2129 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2130 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
2131 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2132 BEAST_EXPECT(txj.isMember(jss::tx));
2133 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
2135 auto const& txj2 = jrr[jss::queue_data][0u];
2136 BEAST_EXPECT(txj2[jss::account] == alice.human());
2137 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
2138 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
2139 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
2140 BEAST_EXPECT(!txj2.isMember(
"last_result"));
2141 BEAST_EXPECT(txj2.isMember(jss::tx));
2142 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
2145 for (
int i = 0; i != 9; ++i)
2150 jv[jss::expand] =
false;
2151 jv[jss::binary] =
false;
2153 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2155 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2157 auto const& txj = jrr[jss::queue_data][0u];
2158 BEAST_EXPECT(txj[jss::account] == alice.human());
2159 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2160 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2161 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2162 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2163 BEAST_EXPECT(txj.isMember(jss::tx));
2164 BEAST_EXPECT(txj[jss::tx] != txid0);
2165 return txj[jss::tx].asString();
2170 jv[jss::full] =
true;
2172 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2173 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2175 auto const& txj = jrr[jss::queue_data][0u];
2176 BEAST_EXPECT(txj[jss::account] == alice.human());
2177 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2178 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2179 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2180 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2181 BEAST_EXPECT(txj.isMember(jss::tx));
2182 auto const& tx = txj[jss::tx];
2183 BEAST_EXPECT(tx[jss::Account] == alice.human());
2184 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2185 BEAST_EXPECT(tx[jss::hash] == txid2);
2192 testcase(
"Ledger Request, Accounts Hashes");
2193 using namespace test::jtx;
2202 jvParams[jss::ledger_index] = 3u;
2203 jvParams[jss::accounts] =
true;
2204 jvParams[jss::expand] =
true;
2205 jvParams[jss::type] =
"hashes";
2207 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2208 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2209 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2210 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2212 jrr[jss::ledger][jss::accountState][0u][
"LedgerEntryType"] ==
2214 index = jrr[jss::ledger][jss::accountState][0u][
"index"].asString();
2218 jvParams[jss::ledger_index] = 3u;
2219 jvParams[jss::accounts] =
true;
2220 jvParams[jss::expand] =
false;
2221 jvParams[jss::type] =
"hashes";
2223 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2224 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2225 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2226 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2227 BEAST_EXPECT(jrr[jss::ledger][jss::accountState][0u] == index);
2235 testLedgerRequest();
2237 testLedgerCurrent();
2238 testMissingLedgerEntryLedgerHash();
2240 testLedgerFullNonAdmin();
2241 testLedgerAccounts();
2242 testLedgerEntryAccountRoot();
2243 testLedgerEntryCheck();
2244 testLedgerEntryDepositPreauth();
2245 testLedgerEntryDirectory();
2246 testLedgerEntryEscrow();
2247 testLedgerEntryOffer();
2248 testLedgerEntryPayChan();
2249 testLedgerEntryRippleState();
2250 testLedgerEntryTicket();
2254 testLedgerAccountsOption();