21#include <test/jtx/Oracle.h>
22#include <test/jtx/attester.h>
23#include <test/jtx/multisign.h>
24#include <test/jtx/xchain_bridge.h>
25#include <xrpld/app/misc/TxQ.h>
26#include <xrpl/beast/unit_test.h>
27#include <xrpl/json/json_value.h>
28#include <xrpl/protocol/AccountID.h>
29#include <xrpl/protocol/ErrorCodes.h>
30#include <xrpl/protocol/jss.h>
43 if (BEAST_EXPECT(jv.
isMember(jss::status)))
44 BEAST_EXPECT(jv[jss::status] ==
"error");
45 if (BEAST_EXPECT(jv.
isMember(jss::error)))
46 BEAST_EXPECT(jv[jss::error] == err);
51 jv[jss::error_message] ==
"");
53 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
54 BEAST_EXPECT(jv[jss::error_message] == msg);
61 using namespace test::jtx;
64 Env scEnv(*
this, envconfig(),
features);
75 jvParams[jss::bridge] =
jvb;
77 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
79 BEAST_EXPECT(jrr.
isMember(jss::node));
80 auto r = jrr[jss::node];
83 BEAST_EXPECT(r.isMember(jss::Account));
86 BEAST_EXPECT(r.isMember(jss::Flags));
88 BEAST_EXPECT(r.isMember(sfLedgerEntryType.jsonName));
89 BEAST_EXPECT(r[sfLedgerEntryType.jsonName] == jss::Bridge);
92 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
93 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 0);
96 BEAST_EXPECT(r.isMember(sfXChainAccountClaimCount.jsonName));
97 BEAST_EXPECT(r[sfXChainAccountClaimCount.jsonName].asInt() == 0);
99 BEAST_EXPECT(r.isMember(jss::index));
100 bridge_index = r[jss::index].asString();
106 jvParams[jss::index] = bridge_index;
108 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
110 BEAST_EXPECT(jrr.
isMember(jss::node));
111 BEAST_EXPECT(jrr[jss::node] == mcBridge);
117 jvParams[jss::bridge_account] = Account::master.human();
118 jvParams[jss::bridge] =
jvb;
119 jvParams[jss::ledger_hash] = ledgerHash;
121 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
136 jvParams[jss::bridge] =
jvb;
139 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
141 BEAST_EXPECT(jrr.
isMember(jss::node));
142 auto r = jrr[jss::node];
145 BEAST_EXPECT(r.isMember(sfXChainClaimID.jsonName));
146 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
153 testcase(
"ledger_entry: xchain_claim_id");
154 using namespace test::jtx;
157 Env scEnv(*
this, envconfig(),
features);
171 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
175 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
177 BEAST_EXPECT(jrr.
isMember(jss::node));
178 auto r = jrr[jss::node];
181 BEAST_EXPECT(r.isMember(jss::Account));
184 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
185 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 1);
186 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
193 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
196 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
198 BEAST_EXPECT(jrr.
isMember(jss::node));
199 auto r = jrr[jss::node];
202 BEAST_EXPECT(r.isMember(jss::Account));
203 BEAST_EXPECT(r[jss::Account] ==
scBob.
human());
205 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
206 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
207 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
214 testcase(
"ledger_entry: xchain_create_account_claim_id");
215 using namespace test::jtx;
218 Env scEnv(*
this, envconfig(),
features);
226 auto const amt = XRP(1000);
227 mcEnv(sidechain_xchain_account_create(
233 size_t constexpr num_attest = 3;
234 auto attestations = create_account_attestations(
245 UT_XCHAIN_DEFAULT_NUM_SIGNERS);
246 for (
size_t i = 0; i < num_attest; ++i)
248 scEnv(attestations[i]);
255 jvParams[jss::xchain_owned_create_account_claim_id] =
257 jvParams[jss::xchain_owned_create_account_claim_id]
258 [jss::xchain_owned_create_account_claim_id] = 1;
261 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
264 BEAST_EXPECT(jrr.
isMember(jss::node));
265 auto r = jrr[jss::node];
267 BEAST_EXPECT(r.isMember(jss::Account));
268 BEAST_EXPECT(r[jss::Account] == Account::master.human());
270 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
271 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 1);
274 r.isMember(sfXChainCreateAccountAttestations.jsonName));
275 auto attest = r[sfXChainCreateAccountAttestations.jsonName];
276 BEAST_EXPECT(attest.isArray());
277 BEAST_EXPECT(attest.size() == 3);
279 sfXChainCreateAccountProofSig.jsonName));
281 for (
size_t i = 0; i < num_attest; ++i)
284 [sfXChainCreateAccountProofSig.jsonName];
286 a[i].isMember(jss::Amount) &&
289 a[i].isMember(jss::Destination) &&
292 a[i].isMember(sfAttestationSignerAccount.jsonName) &&
295 return a[i][sfAttestationSignerAccount.jsonName] ==
299 a[i].isMember(sfAttestationRewardAccount.jsonName) &&
303 [&](Account
const& account) {
304 return a[i][sfAttestationRewardAccount.jsonName] ==
308 a[i].isMember(sfWasLockingChainSend.jsonName) &&
309 a[i][sfWasLockingChainSend.jsonName] == 1);
311 a[i].isMember(sfSignatureReward.jsonName) &&
312 a[i][sfSignatureReward.jsonName].
asInt() ==
319 for (
size_t i = num_attest; i < UT_XCHAIN_DEFAULT_NUM_SIGNERS; ++i)
321 scEnv(attestations[i]);
327 jvParams[jss::xchain_owned_create_account_claim_id] =
329 jvParams[jss::xchain_owned_create_account_claim_id]
330 [jss::xchain_owned_create_account_claim_id] = 1;
333 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
356 if (BEAST_EXPECT(jv.
isMember(jss::status)))
357 BEAST_EXPECT(jv[jss::status] ==
"error");
358 if (BEAST_EXPECT(jv.
isMember(jss::error)))
359 BEAST_EXPECT(jv[jss::error] == err);
364 jv[jss::error_message] ==
"");
366 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
367 BEAST_EXPECT(jv[jss::error_message] == msg);
384 using namespace test::jtx;
389 BEAST_EXPECT(env.current()->info().seq == 4);
394 jvParams[jss::ledger_index] = 1;
396 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
397 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
398 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
403 jvParams[jss::ledger_index] =
"1";
405 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
406 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
407 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
412 auto const jrr = env.rpc(
"ledger",
"current")[jss::result];
413 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
false);
415 jrr[jss::ledger][jss::ledger_index] ==
418 jrr[jss::ledger_current_index] == env.current()->info().seq);
426 using namespace test::jtx;
428 Account
const gw{
"gateway"};
429 auto const USD = gw[
"USD"];
430 Account
const bob{
"bob"};
432 env.fund(XRP(10000), gw, bob);
434 env.trust(USD(1000), bob);
440 jvParams[jss::ledger_index] =
"potato";
442 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
449 jvParams[jss::ledger_index] = -1;
451 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
458 jvParams[jss::ledger_index] = 10u;
460 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
466 auto const jrr = env.rpc(
"ledger",
"arbitrary_text")[jss::result];
473 jvParams[jss::ledger_index] =
"validated";
474 jvParams[jss::queue] =
true;
476 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
483 env.rpc(
"json",
"ledger",
"{ \"ledger_index\" : 2e15 }");
485 BEAST_EXPECT(ret[jss::error_message] ==
"Invalid parameters.");
490 auto const ret = env.rpc(
491 "json",
"ledger",
"{ \"ledger_index\" : 1000000000000000 }");
498 jvParams[jss::ledger_index] =
"validated";
499 jvParams[jss::index] =
500 "00000000000000000000000000000000000000000000000000000000000000"
502 auto const jrr = env.rpc(
503 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
512 using namespace test::jtx;
517 BEAST_EXPECT(env.current()->info().seq == 4);
520 auto const jrr = env.rpc(
"ledger_current")[jss::result];
522 jrr[jss::ledger_current_index] == env.current()->info().seq);
529 testcase(
"Missing ledger_entry ledger_hash");
530 using namespace test::jtx;
532 Account
const alice{
"alice"};
533 env.fund(XRP(10000), alice);
537 jvParams[jss::account_root] = alice.human();
538 jvParams[jss::ledger_hash] =
539 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
541 env.rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
548 testcase(
"Ledger Request, Full Option");
549 using namespace test::jtx;
556 jvParams[jss::ledger_index] = 3u;
557 jvParams[jss::full] =
true;
559 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
560 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
561 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
562 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 3u);
568 testcase(
"Ledger Request, Full Option Without Admin");
569 using namespace test::jtx;
571 Env env{*
this, envconfig(no_admin)};
576 jvParams[jss::ledger_index] = 1u;
577 jvParams[jss::full] =
true;
579 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
581 jrr,
"noPermission",
"You don't have permission for this command.");
587 testcase(
"Ledger Request, Accounts Option");
588 using namespace test::jtx;
595 jvParams[jss::ledger_index] = 3u;
596 jvParams[jss::accounts] =
true;
598 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
599 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
600 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
601 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 3u);
607 testcase(
"ledger_entry Request AccountRoot");
608 using namespace test::jtx;
610 Account
const alice{
"alice"};
611 env.fund(XRP(10000), alice);
617 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
618 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
619 BEAST_EXPECT(jrr[jss::ledger_index] == 3);
626 jvParams[jss::account_root] = alice.human();
627 jvParams[jss::ledger_hash] = ledgerHash;
629 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
630 BEAST_EXPECT(jrr.
isMember(jss::node));
631 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
632 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
633 accountRootIndex = jrr[jss::index].
asString();
636 constexpr char alicesAcctRootBinary[]{
637 "1100612200800000240000000425000000032D00000000559CE54C3B934E4"
638 "73A995B477E92EC229F99CED5B62BF4D2ACE4DC42719103AE2F6240000002"
639 "540BE4008114AE123A8556F3CF91154711376AFB0F894F832B3D"};
643 jvParams[jss::account_root] = alice.human();
644 jvParams[jss::binary] = 1;
645 jvParams[jss::ledger_hash] = ledgerHash;
647 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
648 BEAST_EXPECT(jrr.
isMember(jss::node_binary));
649 BEAST_EXPECT(jrr[jss::node_binary] == alicesAcctRootBinary);
654 jvParams[jss::index] = accountRootIndex;
656 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
657 BEAST_EXPECT(!jrr.
isMember(jss::node_binary));
658 BEAST_EXPECT(jrr.
isMember(jss::node));
659 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
660 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
665 jvParams[jss::index] = accountRootIndex;
666 jvParams[jss::binary] = 0;
668 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
669 BEAST_EXPECT(jrr.
isMember(jss::node));
670 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
671 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
677 jvParams[jss::ledger_hash] = ledgerHash;
679 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
685 jvParams[jss::account_root] = Account(
"bob").human();
686 jvParams[jss::ledger_hash] = ledgerHash;
688 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
696 testcase(
"ledger_entry Request Check");
697 using namespace test::jtx;
699 Account
const alice{
"alice"};
700 env.fund(XRP(10000), alice);
703 auto const checkId =
keylet::check(env.master, env.seq(env.master));
705 env(check::create(env.master, alice, XRP(100)));
712 jvParams[jss::check] =
to_string(checkId.key);
713 jvParams[jss::ledger_hash] = ledgerHash;
715 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
717 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
718 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
726 jvParams[jss::account_root] = alice.human();
728 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
729 accountRootIndex = jrr[jss::index].
asString();
732 jvParams[jss::check] = accountRootIndex;
733 jvParams[jss::ledger_hash] = ledgerHash;
735 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
743 testcase(
"ledger_entry credentials");
745 using namespace test::jtx;
748 Account
const issuer{
"issuer"};
749 Account
const alice{
"alice"};
750 Account
const bob{
"bob"};
751 const char credType[] =
"abcde";
753 env.fund(XRP(5000), issuer, alice, bob);
757 env(credentials::create(alice, issuer, credType));
762 auto jv = credentials::ledgerEntry(env, alice, issuer, credType);
764 jv.isObject() && jv.isMember(jss::result) &&
765 !jv[jss::result].isMember(jss::error) &&
766 jv[jss::result].isMember(jss::node) &&
767 jv[jss::result][jss::node].isMember(
768 sfLedgerEntryType.jsonName) &&
769 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
772 std::string const credIdx = jv[jss::result][jss::index].asString();
774 jv = credentials::ledgerEntry(env, credIdx);
776 jv.isObject() && jv.isMember(jss::result) &&
777 !jv[jss::result].isMember(jss::error) &&
778 jv[jss::result].isMember(jss::node) &&
779 jv[jss::result][jss::node].isMember(
780 sfLedgerEntryType.jsonName) &&
781 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
787 auto const jv = credentials::ledgerEntry(env,
"");
793 auto const jv = credentials::ledgerEntry(
795 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
803 jv[jss::ledger_index] = jss::validated;
804 jv[jss::credential][jss::subject] = 42;
805 jv[jss::credential][jss::issuer] = issuer.human();
806 jv[jss::credential][jss::credential_type] =
808 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
815 jv[jss::ledger_index] = jss::validated;
816 jv[jss::credential][jss::subject] = alice.human();
817 jv[jss::credential][jss::issuer] = 42;
818 jv[jss::credential][jss::credential_type] =
820 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
827 jv[jss::ledger_index] = jss::validated;
828 jv[jss::credential][jss::subject] = alice.human();
829 jv[jss::credential][jss::issuer] = issuer.human();
830 jv[jss::credential][jss::credential_type] = 42;
831 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
838 jv[jss::ledger_index] = jss::validated;
839 jv[jss::credential][jss::subject] =
"";
840 jv[jss::credential][jss::issuer] = issuer.human();
841 jv[jss::credential][jss::credential_type] =
843 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
850 jv[jss::ledger_index] = jss::validated;
851 jv[jss::credential][jss::subject] = alice.human();
852 jv[jss::credential][jss::issuer] =
"";
853 jv[jss::credential][jss::credential_type] =
855 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
862 jv[jss::ledger_index] = jss::validated;
863 jv[jss::credential][jss::subject] = alice.human();
864 jv[jss::credential][jss::issuer] = issuer.human();
865 jv[jss::credential][jss::credential_type] =
"";
866 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
873 jv[jss::ledger_index] = jss::validated;
874 jv[jss::credential][jss::issuer] = issuer.human();
875 jv[jss::credential][jss::credential_type] =
877 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
884 jv[jss::ledger_index] = jss::validated;
885 jv[jss::credential][jss::subject] = alice.human();
886 jv[jss::credential][jss::credential_type] =
888 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
895 jv[jss::ledger_index] = jss::validated;
896 jv[jss::credential][jss::subject] = alice.human();
897 jv[jss::credential][jss::issuer] = issuer.human();
898 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
905 jv[jss::ledger_index] = jss::validated;
906 jv[jss::credential][jss::subject] =
"wehsdbvasbdfvj";
907 jv[jss::credential][jss::issuer] = issuer.human();
908 jv[jss::credential][jss::credential_type] =
910 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
917 jv[jss::ledger_index] = jss::validated;
918 jv[jss::credential][jss::subject] = alice.human();
919 jv[jss::credential][jss::issuer] =
"c4p93ugndfbsiu";
920 jv[jss::credential][jss::credential_type] =
922 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
929 jv[jss::ledger_index] = jss::validated;
930 jv[jss::credential][jss::subject] = alice.human();
931 jv[jss::credential][jss::issuer] = issuer.human();
932 jv[jss::credential][jss::credential_type] =
"12KK";
933 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
941 testcase(
"ledger_entry Deposit Preauth");
943 using namespace test::jtx;
946 Account
const alice{
"alice"};
947 Account
const becky{
"becky"};
949 env.fund(XRP(10000), alice, becky);
952 env(deposit::auth(alice, becky));
960 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
961 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
962 jvParams[jss::ledger_hash] = ledgerHash;
964 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
967 jrr[jss::node][sfLedgerEntryType.jsonName] ==
968 jss::DepositPreauth);
969 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
970 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
971 depositPreauthIndex = jrr[jss::node][jss::index].
asString();
976 jvParams[jss::deposit_preauth] = depositPreauthIndex;
977 jvParams[jss::ledger_hash] = ledgerHash;
979 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
982 jrr[jss::node][sfLedgerEntryType.jsonName] ==
983 jss::DepositPreauth);
984 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
985 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
990 jvParams[jss::deposit_preauth] = -5;
991 jvParams[jss::ledger_hash] = ledgerHash;
993 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
999 jvParams[jss::deposit_preauth] =
"0123456789ABCDEFG";
1000 jvParams[jss::ledger_hash] = ledgerHash;
1002 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1008 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1009 jvParams[jss::ledger_hash] = ledgerHash;
1011 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1017 jvParams[jss::deposit_preauth][jss::owner] = 7;
1018 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1019 jvParams[jss::ledger_hash] = ledgerHash;
1021 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1027 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1028 jvParams[jss::ledger_hash] = ledgerHash;
1030 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1036 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1037 jvParams[jss::deposit_preauth][jss::authorized] = 47;
1038 jvParams[jss::ledger_hash] = ledgerHash;
1040 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1046 jvParams[jss::deposit_preauth][jss::owner] =
1047 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
1049 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1050 jvParams[jss::ledger_hash] = ledgerHash;
1052 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1058 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1059 jvParams[jss::deposit_preauth][jss::authorized] =
1060 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
1062 jvParams[jss::ledger_hash] = ledgerHash;
1064 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1072 testcase(
"ledger_entry Deposit Preauth with credentials");
1074 using namespace test::jtx;
1077 Account
const issuer{
"issuer"};
1078 Account
const alice{
"alice"};
1079 Account
const bob{
"bob"};
1080 const char credType[] =
"abcde";
1082 env.fund(XRP(5000), issuer, alice, bob);
1089 env(deposit::authCredentials(bob, {{issuer, credType}}));
1096 jvParams[jss::ledger_index] = jss::validated;
1097 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1099 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1102 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1105 jo[jss::issuer] = issuer.human();
1107 arr.append(std::move(jo));
1109 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1112 jrr.isObject() && jrr.isMember(jss::result) &&
1113 !jrr[jss::result].isMember(jss::error) &&
1114 jrr[jss::result].isMember(jss::node) &&
1115 jrr[jss::result][jss::node].isMember(
1116 sfLedgerEntryType.jsonName) &&
1117 jrr[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
1118 jss::DepositPreauth);
1124 jvParams[jss::ledger_index] = jss::validated;
1125 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1127 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1130 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1135 arr.append(std::move(jo));
1137 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1139 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1145 jvParams[jss::ledger_index] = jss::validated;
1146 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1148 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1151 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1154 jo[jss::issuer] = issuer.human();
1157 arr.append(std::move(jo));
1159 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1161 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1167 jvParams[jss::ledger_index] = jss::validated;
1168 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1170 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1173 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1176 jo[jss::issuer] = issuer.human();
1177 jo[jss::credential_type] =
"";
1178 arr.
append(std::move(jo));
1181 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1183 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1189 jvParams[jss::ledger_index] = jss::validated;
1190 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1191 jvParams[jss::deposit_preauth][jss::authorized] = alice.human();
1193 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1196 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1199 jo[jss::issuer] = issuer.human();
1201 arr.append(std::move(jo));
1204 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1211 jvParams[jss::ledger_index] = jss::validated;
1212 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1213 jvParams[jss::deposit_preauth][jss::authorized_credentials] = 42;
1216 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1223 jvParams[jss::ledger_index] = jss::validated;
1224 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1225 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1228 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1229 arr.append(
"foobar");
1232 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1234 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1240 jvParams[jss::ledger_index] = jss::validated;
1241 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1242 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1245 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1248 arr.
append(std::move(payload));
1251 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1253 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1259 jvParams[jss::ledger_index] = jss::validated;
1260 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1261 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1265 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1267 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1284 sizeof(credTypes) /
sizeof(credTypes[0]) >
1288 jvParams[jss::ledger_index] = jss::validated;
1289 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1290 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1294 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1296 for (
unsigned i = 0; i <
sizeof(credTypes) /
sizeof(credTypes[0]);
1300 jo[jss::issuer] = issuer.human();
1301 jo[jss::credential_type] =
1303 arr.append(std::move(jo));
1307 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1309 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1315 jvParams[jss::ledger_index] = jss::validated;
1316 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1318 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1321 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1325 arr.append(std::move(jo));
1328 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1330 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1336 jvParams[jss::ledger_index] = jss::validated;
1337 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1339 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1342 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1345 jo[jss::issuer] = 42;
1347 arr.append(std::move(jo));
1350 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1352 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1358 jvParams[jss::ledger_index] = jss::validated;
1359 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1361 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1364 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1369 jo[jss::issuer] = std::move(payload);
1371 arr.append(std::move(jo));
1374 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1376 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1382 jvParams[jss::ledger_index] = jss::validated;
1383 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1385 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1388 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1391 jo[jss::issuer] =
"invalid_account";
1393 arr.append(std::move(jo));
1396 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1398 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1404 jvParams[jss::ledger_index] = jss::validated;
1405 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1407 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1410 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1413 jo[jss::issuer] = issuer.human();
1414 arr.
append(std::move(jo));
1417 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1419 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1425 jvParams[jss::ledger_index] = jss::validated;
1426 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1428 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1431 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1434 jo[jss::issuer] = issuer.human();
1435 jo[jss::credential_type] = 42;
1436 arr.
append(std::move(jo));
1439 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1441 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1447 jvParams[jss::ledger_index] = jss::validated;
1448 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1450 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1453 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1456 jo[jss::issuer] = issuer.human();
1459 jo[jss::credential_type] = std::move(payload);
1460 arr.append(std::move(jo));
1463 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1465 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1471 jvParams[jss::ledger_index] = jss::validated;
1472 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1474 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1477 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1480 jo[jss::issuer] = issuer.human();
1481 jo[jss::credential_type] =
"12KK";
1482 arr.
append(std::move(jo));
1485 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1487 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1494 testcase(
"ledger_entry Request Directory");
1495 using namespace test::jtx;
1497 Account
const alice{
"alice"};
1498 Account
const gw{
"gateway"};
1499 auto const USD = gw[
"USD"];
1500 env.fund(XRP(10000), alice, gw);
1503 env.trust(USD(1000), alice);
1508 for (
int d = 1'000'032; d >= 1'000'000; --d)
1510 env(offer(alice, USD(1), drops(d)));
1517 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
1518 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
1519 BEAST_EXPECT(jrr[jss::ledger_index] == 5);
1523 "A33EC6BB85FB5674074C4A3A43373BB17645308F3EAE1933E3E35252162B217D";
1527 jvParams[jss::directory] = dirRootIndex;
1528 jvParams[jss::ledger_hash] = ledgerHash;
1530 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1531 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 32);
1537 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1539 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1540 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1546 jvParams[jss::directory][jss::owner] = alice.human();
1547 jvParams[jss::ledger_hash] = ledgerHash;
1549 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1550 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1556 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1557 jvParams[jss::directory][jss::sub_index] = 1;
1559 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1560 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1561 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1567 jvParams[jss::directory][jss::owner] = alice.human();
1568 jvParams[jss::directory][jss::sub_index] = 1;
1569 jvParams[jss::ledger_hash] = ledgerHash;
1571 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1572 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1573 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1579 jvParams[jss::ledger_hash] = ledgerHash;
1581 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1588 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1589 jvParams[jss::directory][jss::sub_index] = 1.5;
1590 jvParams[jss::ledger_hash] = ledgerHash;
1592 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1601 jvParams[jss::directory][jss::owner] = badAddress;
1602 jvParams[jss::ledger_hash] = ledgerHash;
1604 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1611 jvParams[jss::directory][jss::owner] = alice.human();
1612 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1613 jvParams[jss::ledger_hash] = ledgerHash;
1615 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1622 jvParams[jss::directory][jss::sub_index] = 1;
1623 jvParams[jss::ledger_hash] = ledgerHash;
1625 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1633 testcase(
"ledger_entry Request Escrow");
1634 using namespace test::jtx;
1636 Account
const alice{
"alice"};
1637 env.fund(XRP(10000), alice);
1646 jv[jss::TransactionType] = jss::EscrowCreate;
1648 jv[jss::Account] = account.human();
1649 jv[jss::Destination] = to.human();
1651 jv[sfFinishAfter.jsonName] =
1652 cancelAfter.time_since_epoch().count() + 2;
1656 using namespace std::chrono_literals;
1657 env(escrowCreate(alice, alice, XRP(333), env.now() + 2s));
1666 jvParams[jss::escrow][jss::owner] = alice.human();
1667 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1669 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1671 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1672 escrowIndex = jrr[jss::index].
asString();
1677 jvParams[jss::escrow] = escrowIndex;
1678 jvParams[jss::ledger_hash] = ledgerHash;
1680 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1682 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1690 jvParams[jss::escrow][jss::owner] = badAddress;
1691 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1692 jvParams[jss::ledger_hash] = ledgerHash;
1694 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1701 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1702 jvParams[jss::ledger_hash] = ledgerHash;
1704 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1711 jvParams[jss::escrow][jss::owner] = alice.human();
1712 jvParams[jss::ledger_hash] = ledgerHash;
1714 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1721 jvParams[jss::escrow][jss::owner] = alice.human();
1722 jvParams[jss::escrow][jss::seq] =
1724 jvParams[jss::ledger_hash] = ledgerHash;
1726 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1734 testcase(
"ledger_entry Request Offer");
1735 using namespace test::jtx;
1737 Account
const alice{
"alice"};
1738 Account
const gw{
"gateway"};
1739 auto const USD = gw[
"USD"];
1740 env.fund(XRP(10000), alice, gw);
1743 env(offer(alice, USD(321), XRP(322)));
1752 jvParams[jss::offer][jss::account] = alice.human();
1753 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1754 jvParams[jss::ledger_hash] = ledgerHash;
1756 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1757 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1758 offerIndex = jrr[jss::index].
asString();
1763 jvParams[jss::offer] = offerIndex;
1765 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1766 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1774 jvParams[jss::offer][jss::account] = badAddress;
1775 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1776 jvParams[jss::ledger_hash] = ledgerHash;
1778 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1785 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1786 jvParams[jss::ledger_hash] = ledgerHash;
1788 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1795 jvParams[jss::offer][jss::account] = alice.human();
1796 jvParams[jss::ledger_hash] = ledgerHash;
1798 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1805 jvParams[jss::offer][jss::account] = alice.human();
1806 jvParams[jss::offer][jss::seq] =
std::to_string(env.seq(alice) - 1);
1807 jvParams[jss::ledger_hash] = ledgerHash;
1809 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1817 testcase(
"ledger_entry Request Pay Chan");
1818 using namespace test::jtx;
1819 using namespace std::literals::chrono_literals;
1821 Account
const alice{
"alice"};
1823 env.fund(XRP(10000), alice);
1833 jv[jss::TransactionType] = jss::PaymentChannelCreate;
1834 jv[jss::Account] = account.human();
1835 jv[jss::Destination] = to.human();
1837 jv[sfSettleDelay.jsonName] = settleDelay.count();
1838 jv[sfPublicKey.jsonName] =
strHex(pk.slice());
1842 env(payChanCreate(alice, env.master, XRP(57), 18s, alice.pk()));
1852 jvParams[jss::payment_channel] =
to_string(payChanIndex);
1853 jvParams[jss::ledger_hash] = ledgerHash;
1855 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1856 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"57000000");
1857 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"0");
1858 BEAST_EXPECT(jrr[jss::node][sfSettleDelay.jsonName] == 18);
1863 jvParams[jss::payment_channel] = ledgerHash;
1864 jvParams[jss::ledger_hash] = ledgerHash;
1866 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1874 testcase(
"ledger_entry Request RippleState");
1875 using namespace test::jtx;
1877 Account
const alice{
"alice"};
1878 Account
const gw{
"gateway"};
1879 auto const USD = gw[
"USD"];
1880 env.fund(XRP(10000), alice, gw);
1883 env.trust(USD(999), alice);
1886 env(pay(gw, alice, USD(97)));
1890 for (
auto const& fieldName : {jss::ripple_state, jss::state})
1898 jvParams[fieldName][jss::accounts][0u] = alice.human();
1899 jvParams[fieldName][jss::accounts][1u] = gw.human();
1900 jvParams[fieldName][jss::currency] =
"USD";
1901 jvParams[jss::ledger_hash] = ledgerHash;
1903 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1905 jrr[jss::node][sfBalance.jsonName][jss::value] ==
"-97");
1907 jrr[jss::node][sfHighLimit.jsonName][jss::value] ==
"999");
1912 jvParams[fieldName] =
"ripple_state";
1913 jvParams[jss::ledger_hash] = ledgerHash;
1915 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1923 jvParams[fieldName][jss::accounts][0u] = alice.human();
1924 jvParams[fieldName][jss::accounts][1u] = gw.human();
1925 jvParams[jss::ledger_hash] = ledgerHash;
1927 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1934 jvParams[fieldName][jss::accounts] = 2;
1935 jvParams[fieldName][jss::currency] =
"USD";
1936 jvParams[jss::ledger_hash] = ledgerHash;
1938 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1946 jvParams[fieldName][jss::accounts][0u] = alice.human();
1947 jvParams[fieldName][jss::currency] =
"USD";
1948 jvParams[jss::ledger_hash] = ledgerHash;
1950 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1958 jvParams[fieldName][jss::accounts][0u] = alice.human();
1959 jvParams[fieldName][jss::accounts][1u] = gw.human();
1960 jvParams[fieldName][jss::accounts][2u] = alice.human();
1961 jvParams[fieldName][jss::currency] =
"USD";
1962 jvParams[jss::ledger_hash] = ledgerHash;
1964 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1972 jvParams[fieldName][jss::accounts][0u] = 44;
1973 jvParams[fieldName][jss::accounts][1u] = gw.human();
1974 jvParams[fieldName][jss::currency] =
"USD";
1975 jvParams[jss::ledger_hash] = ledgerHash;
1977 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1985 jvParams[fieldName][jss::accounts][0u] = alice.human();
1986 jvParams[fieldName][jss::accounts][1u] = 21;
1987 jvParams[fieldName][jss::currency] =
"USD";
1988 jvParams[jss::ledger_hash] = ledgerHash;
1990 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1998 jvParams[fieldName][jss::accounts][0u] = alice.human();
1999 jvParams[fieldName][jss::accounts][1u] = alice.human();
2000 jvParams[fieldName][jss::currency] =
"USD";
2001 jvParams[jss::ledger_hash] = ledgerHash;
2003 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2011 jvParams[fieldName][jss::accounts][0u] =
2013 jvParams[fieldName][jss::accounts][1u] = gw.human();
2014 jvParams[fieldName][jss::currency] =
"USD";
2015 jvParams[jss::ledger_hash] = ledgerHash;
2017 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2025 jvParams[fieldName][jss::accounts][0u] = alice.human();
2026 jvParams[fieldName][jss::accounts][1u] =
2028 jvParams[fieldName][jss::currency] =
"USD";
2029 jvParams[jss::ledger_hash] = ledgerHash;
2031 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2039 jvParams[fieldName][jss::accounts][0u] = alice.human();
2040 jvParams[fieldName][jss::accounts][1u] = gw.human();
2041 jvParams[fieldName][jss::currency] =
"USDollars";
2042 jvParams[jss::ledger_hash] = ledgerHash;
2044 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2053 testcase(
"ledger_entry Request Ticket");
2054 using namespace test::jtx;
2060 env(ticket::create(env.master, 2));
2070 jvParams[jss::ticket] =
2072 jvParams[jss::ledger_hash] = ledgerHash;
2074 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2081 jvParams[jss::ledger_hash] = ledgerHash;
2083 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2085 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Ticket);
2086 BEAST_EXPECT(jrr[jss::node][sfTicketSequence.jsonName] == tkt1);
2092 jvParams[jss::ticket][jss::account] = env.master.human();
2093 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 1;
2094 jvParams[jss::ledger_hash] = ledgerHash;
2096 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2098 jrr[jss::node][jss::index] ==
2105 jvParams[jss::ticket][jss::account] = env.master.human();
2106 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 2;
2107 jvParams[jss::ledger_hash] = ledgerHash;
2109 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2116 jvParams[jss::ledger_hash] = ledgerHash;
2118 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2127 jvParams[jss::ticket][jss::account] = badAddress;
2128 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
2129 jvParams[jss::ledger_hash] = ledgerHash;
2131 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2138 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
2139 jvParams[jss::ledger_hash] = ledgerHash;
2141 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2148 jvParams[jss::ticket][jss::account] = env.master.human();
2149 jvParams[jss::ledger_hash] = ledgerHash;
2151 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2158 jvParams[jss::ticket][jss::account] = env.master.human();
2159 jvParams[jss::ticket][jss::ticket_seq] =
2161 jvParams[jss::ledger_hash] = ledgerHash;
2163 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2171 testcase(
"ledger_entry Request DID");
2172 using namespace test::jtx;
2173 using namespace std::literals::chrono_literals;
2175 Account
const alice{
"alice"};
2177 env.fund(XRP(10000), alice);
2183 jv[jss::TransactionType] = jss::DIDSet;
2184 jv[jss::Account] = account.human();
2190 env(didCreate(alice));
2198 jvParams[jss::did] = alice.human();
2199 jvParams[jss::ledger_hash] = ledgerHash;
2201 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2203 jrr[jss::node][sfDIDDocument.jsonName] ==
2211 jvParams[jss::did] = env.master.human();
2212 jvParams[jss::ledger_hash] = ledgerHash;
2214 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2223 "ledger_entry Request With Invalid Parameters v" +
2225 using namespace test::jtx;
2232 params[jss::api_version] = apiVersion;
2238 auto const jvParams =
2240 jvParams[jss::features] = ledgerHash;
2241 jvParams[jss::ledger_hash] = ledgerHash;
2244 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2246 if (apiVersion < 2u)
2253 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2254 obj[jss::ledger_index] =
"validated";
2259 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2260 arr[1u] =
"validated";
2266 for (
auto const& field :
2267 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
2269 auto const jvParams =
2270 makeParams([&field, &injectArray](
Json::Value& jvParams) {
2271 jvParams[field] = injectArray;
2275 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2277 if (apiVersion < 2u)
2283 for (
auto const& field :
2284 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
2286 auto const jvParams =
2287 makeParams([&field, &injectObject](
Json::Value& jvParams) {
2288 jvParams[field] = injectObject;
2292 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2297 for (
auto const& inject : {injectObject, injectArray})
2300 for (
auto const& field :
2304 jss::payment_channel})
2306 auto const jvParams =
2307 makeParams([&field, &inject](
Json::Value& jvParams) {
2308 jvParams[field] = inject;
2312 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2314 if (apiVersion < 2u)
2320 for (
auto const& field : {jss::dir_root, jss::owner})
2322 auto const jvParams =
2323 makeParams([&field, &inject](
Json::Value& jvParams) {
2324 jvParams[jss::directory][field] = inject;
2328 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2330 if (apiVersion < 2u)
2337 auto const jvParams =
2339 jvParams[jss::escrow][jss::owner] = inject;
2340 jvParams[jss::escrow][jss::seq] = 99;
2344 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2346 if (apiVersion < 2u)
2353 auto const jvParams =
2355 jvParams[jss::offer][jss::account] = inject;
2356 jvParams[jss::offer][jss::seq] = 99;
2360 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2362 if (apiVersion < 2u)
2369 auto const jvParams =
2372 rs[jss::currency] =
"FOO";
2374 rs[jss::accounts][0u] =
2375 "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2376 rs[jss::accounts][1u] =
2377 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
2378 rs[jss::currency] = inject;
2379 jvParams[jss::ripple_state] = std::move(rs);
2383 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2385 if (apiVersion < 2u)
2392 auto const jvParams =
2394 jvParams[jss::ticket][jss::account] = inject;
2395 jvParams[jss::ticket][jss::ticket_seq] = 99;
2399 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2401 if (apiVersion < 2u)
2408 for (
auto const& field : {jss::nft_page, jss::deposit_preauth})
2410 auto const jvParams =
2411 makeParams([&field, &inject](
Json::Value& jvParams) {
2412 jvParams[field] = inject;
2416 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2422 for (
auto const& field : {jss::owner, jss::authorized})
2424 auto const jvParams =
2425 makeParams([&field, &inject](
Json::Value& jvParams) {
2427 pa[jss::owner] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2428 pa[jss::authorized] =
2429 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
2431 jvParams[jss::deposit_preauth] = std::move(pa);
2435 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2450 using namespace test::jtx;
2453 env.fund(XRP(10000),
"alice");
2455 env.fund(XRP(10000),
"bob");
2457 env.fund(XRP(10000),
"jim");
2459 env.fund(XRP(10000),
"jill");
2464 jvParams[jss::ledger] =
"closed";
2468 boost::lexical_cast<std::string>(jvParams))[jss::result];
2469 BEAST_EXPECT(jrr.isMember(jss::ledger));
2470 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2471 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2473 jvParams[jss::ledger] =
"validated";
2477 boost::lexical_cast<std::string>(jvParams))[jss::result];
2478 BEAST_EXPECT(jrr.isMember(jss::ledger));
2479 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2480 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2482 jvParams[jss::ledger] =
"current";
2486 boost::lexical_cast<std::string>(jvParams))[jss::result];
2487 BEAST_EXPECT(jrr.isMember(jss::ledger));
2488 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
2491 jvParams[jss::ledger] =
"invalid";
2495 boost::lexical_cast<std::string>(jvParams))[jss::result];
2496 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2497 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
2500 jvParams[jss::ledger] = 4;
2504 boost::lexical_cast<std::string>(jvParams))[jss::result];
2505 BEAST_EXPECT(jrr.isMember(jss::ledger));
2506 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2507 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
2510 jvParams[jss::ledger] = 20;
2514 boost::lexical_cast<std::string>(jvParams))[jss::result];
2515 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2516 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2521 "E86DE7F3D7A4D9CE17EF7C8BA08A8F4D"
2522 "8F643B9552F0D895A31CDA78F541DE4E"};
2525 jvParams[jss::ledger_hash] = hash3;
2529 boost::lexical_cast<std::string>(jvParams))[jss::result];
2530 BEAST_EXPECT(jrr.isMember(jss::ledger));
2531 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2532 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
2535 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
2539 boost::lexical_cast<std::string>(jvParams))[jss::result];
2540 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2541 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
2544 jvParams[jss::ledger_hash] = 2;
2548 boost::lexical_cast<std::string>(jvParams))[jss::result];
2549 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2550 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashNotString");
2553 jvParams[jss::ledger_hash] =
2554 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
2555 "7F2775F2F7485BB37307984C3C0F2340";
2559 boost::lexical_cast<std::string>(jvParams))[jss::result];
2560 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2561 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
2564 jvParams[jss::ledger_hash] =
2565 "8C3EEDB3124D92E49E75D81A8826A2E6"
2566 "5A75FD71FC3FD6F36FEB803C5F1D812D";
2570 boost::lexical_cast<std::string>(jvParams))[jss::result];
2571 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2572 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2578 jvParams[jss::ledger_index] =
"closed";
2582 boost::lexical_cast<std::string>(jvParams))[jss::result];
2583 BEAST_EXPECT(jrr.isMember(jss::ledger));
2584 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2585 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2586 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
2588 jvParams[jss::ledger_index] =
"validated";
2592 boost::lexical_cast<std::string>(jvParams))[jss::result];
2593 BEAST_EXPECT(jrr.isMember(jss::ledger));
2594 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2595 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2597 jvParams[jss::ledger_index] =
"current";
2601 boost::lexical_cast<std::string>(jvParams))[jss::result];
2602 BEAST_EXPECT(jrr.isMember(jss::ledger));
2603 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
2604 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
2607 jvParams[jss::ledger_index] =
"invalid";
2611 boost::lexical_cast<std::string>(jvParams))[jss::result];
2612 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2613 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
2616 for (
auto i : {1, 2, 3, 4, 5, 6})
2618 jvParams[jss::ledger_index] = i;
2622 boost::lexical_cast<std::string>(jvParams))[jss::result];
2623 BEAST_EXPECT(jrr.isMember(jss::ledger));
2625 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2631 jvParams[jss::ledger_index] = 7;
2635 boost::lexical_cast<std::string>(jvParams))[jss::result];
2636 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2637 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2644 testcase(
"Ledger with queueing disabled");
2645 using namespace test::jtx;
2649 jv[jss::ledger_index] =
"current";
2650 jv[jss::queue] =
true;
2651 jv[jss::expand] =
true;
2653 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2654 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2660 testcase(
"Ledger with Queued Transactions");
2661 using namespace test::jtx;
2663 auto& section = cfg->section(
"transaction_queue");
2664 section.set(
"minimum_txn_in_ledger_standalone",
"3");
2665 section.set(
"normal_consensus_increase_percent",
"0");
2670 jv[jss::ledger_index] =
"current";
2671 jv[jss::queue] =
true;
2672 jv[jss::expand] =
true;
2674 Account
const alice{
"alice"};
2675 Account
const bob{
"bob"};
2676 Account
const charlie{
"charlie"};
2677 Account
const daria{
"daria"};
2678 env.fund(XRP(10000), alice);
2679 env.fund(XRP(10000), bob);
2681 env.fund(XRP(10000), charlie);
2682 env.fund(XRP(10000), daria);
2685 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2686 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2691 auto metrics = env.app().getTxQ().getMetrics(*env.current());
2692 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
2697 BEAST_EXPECT(env.current()->info().seq == 5);
2700 auto aliceSeq = env.seq(alice);
2701 env(pay(alice,
"george", XRP(1000)),
2702 json(R
"({"LastLedgerSequence":7})"),
2704 env(offer(alice, XRP(50000), alice["USD"](5000)),
2707 env(noop(alice), seq(aliceSeq + 2), ter(
terQUEUED));
2709 auto batch = [&env](Account a) {
2710 auto aSeq = env.seq(a);
2712 for (
int i = 0; i < 10; ++i)
2714 env(noop(a), fee(1000 + i), seq(aSeq + i), ter(
terQUEUED));
2723 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2724 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
2730 BEAST_EXPECT(env.current()->info().seq == 8);
2732 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2733 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
2737 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2739 auto const& parentHash = env.current()->info().parentHash;
2740 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2743 auto const& txj = jrr[jss::queue_data][1u];
2744 BEAST_EXPECT(txj[jss::account] == alice.human());
2745 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2746 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2747 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2748 BEAST_EXPECT(txj.isMember(jss::tx));
2749 auto const& tx = txj[jss::tx];
2750 BEAST_EXPECT(tx[jss::Account] == alice.human());
2751 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2752 return tx[jss::hash].asString();
2755 auto const& txj = jrr[jss::queue_data][0u];
2756 BEAST_EXPECT(txj[jss::account] == alice.human());
2757 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2758 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2759 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2760 BEAST_EXPECT(txj.isMember(jss::tx));
2761 auto const& tx = txj[jss::tx];
2762 BEAST_EXPECT(tx[jss::Account] == alice.human());
2763 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
2764 const auto txid0 = tx[jss::hash].asString();
2768 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2776 jv[jss::expand] =
false;
2778 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2779 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2781 auto const& parentHash = env.current()->info().parentHash;
2782 auto const txid1 = [&]() {
2783 auto const& txj = jrr[jss::queue_data][1u];
2784 BEAST_EXPECT(txj[jss::account] == alice.human());
2785 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2786 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2787 BEAST_EXPECT(txj.isMember(jss::tx));
2788 return txj[jss::tx].asString();
2790 auto const& txj = jrr[jss::queue_data][0u];
2791 BEAST_EXPECT(txj[jss::account] == alice.human());
2792 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2793 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2794 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
2795 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2796 BEAST_EXPECT(txj.isMember(jss::tx));
2797 BEAST_EXPECT(txj[jss::tx] == txid0);
2801 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2806 jv[jss::expand] =
true;
2807 jv[jss::binary] =
true;
2809 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2810 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2812 auto const& txj = jrr[jss::queue_data][1u];
2813 BEAST_EXPECT(txj[jss::account] == alice.human());
2814 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2815 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2816 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
2817 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2818 BEAST_EXPECT(txj.isMember(jss::tx));
2819 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
2821 auto const& txj2 = jrr[jss::queue_data][0u];
2822 BEAST_EXPECT(txj2[jss::account] == alice.human());
2823 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
2824 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
2825 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
2826 BEAST_EXPECT(!txj2.isMember(
"last_result"));
2827 BEAST_EXPECT(txj2.isMember(jss::tx));
2828 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
2831 for (
int i = 0; i != 9; ++i)
2836 jv[jss::expand] =
false;
2837 jv[jss::binary] =
false;
2839 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2841 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2843 auto const& txj = jrr[jss::queue_data][0u];
2844 BEAST_EXPECT(txj[jss::account] == alice.human());
2845 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2846 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2847 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2848 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2849 BEAST_EXPECT(txj.isMember(jss::tx));
2850 BEAST_EXPECT(txj[jss::tx] != txid0);
2851 return txj[jss::tx].asString();
2856 jv[jss::full] =
true;
2858 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2859 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2861 auto const& txj = jrr[jss::queue_data][0u];
2862 BEAST_EXPECT(txj[jss::account] == alice.human());
2863 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2864 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2865 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2866 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2867 BEAST_EXPECT(txj.isMember(jss::tx));
2868 auto const& tx = txj[jss::tx];
2869 BEAST_EXPECT(tx[jss::Account] == alice.human());
2870 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2871 BEAST_EXPECT(tx[jss::hash] == txid2);
2878 testcase(
"Ledger Request, Accounts Hashes");
2879 using namespace test::jtx;
2888 jvParams[jss::ledger_index] = 3u;
2889 jvParams[jss::accounts] =
true;
2890 jvParams[jss::expand] =
true;
2891 jvParams[jss::type] =
"hashes";
2893 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2894 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2895 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2896 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2898 jrr[jss::ledger][jss::accountState][0u][
"LedgerEntryType"] ==
2900 index = jrr[jss::ledger][jss::accountState][0u][
"index"].asString();
2904 jvParams[jss::ledger_index] = 3u;
2905 jvParams[jss::accounts] =
true;
2906 jvParams[jss::expand] =
false;
2907 jvParams[jss::type] =
"hashes";
2909 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2910 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2911 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2912 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2913 BEAST_EXPECT(jrr[jss::ledger][jss::accountState][0u] == index);
2920 testcase(
"Invalid Oracle Ledger Entry");
2926 env.
fund(XRP(1'000), owner);
2927 Oracle oracle(env, {.owner = owner});
2930 auto res = Oracle::ledgerEntry(env, owner, NoneTag);
2931 BEAST_EXPECT(res[jss::error].asString() ==
"invalidParams");
2935 auto const res = Oracle::ledgerEntry(env, owner, v);
2936 BEAST_EXPECT(res[jss::error].asString() ==
"malformedDocumentID");
2939 res = Oracle::ledgerEntry(env, owner, std::nullopt);
2940 BEAST_EXPECT(res[jss::error].asString() ==
"malformedRequest");
2943 res = Oracle::ledgerEntry(env, std::nullopt, 1);
2944 BEAST_EXPECT(res[jss::error].asString() ==
"malformedRequest");
2948 malfAccount.
replace(10, 1, 1,
'!');
2949 res = Oracle::ledgerEntry(env, malfAccount, 1);
2950 BEAST_EXPECT(res[jss::error].asString() ==
"malformedAddress");
2963 for (
int i = 0; i < 10; ++i)
2966 env.
fund(XRP(1'000), owner);
2968 Oracle oracle(env, {.owner = owner, .documentID = i});
2972 Oracle oracle1(env, {.owner = owner, .documentID = i + 10});
2974 oracles.
push_back(oracle1.documentID());
2976 for (
int i = 0; i < accounts.
size(); ++i)
2978 auto const jv = [&]() {
2981 return Oracle::ledgerEntry(env, accounts[i], oracles[i]);
2983 return Oracle::ledgerEntry(
2989 jv[jss::node][jss::Owner] ==
to_string(accounts[i]));
3001 testcase(
"ledger_entry Request MPT");
3002 using namespace test::jtx;
3003 using namespace std::literals::chrono_literals;
3008 MPTTester mptAlice(env, alice, {.holders = {bob}});
3015 mptAlice.authorize({.account = bob, .holderCount = 1});
3020 "00000193B9DDCAF401B5B3B26875986043F82CD0D13B4315";
3024 jvParams[jss::mpt_issuance] =
strHex(mptAlice.issuanceID());
3025 jvParams[jss::ledger_hash] = ledgerHash;
3027 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3029 jrr[jss::node][sfMPTokenMetadata.jsonName] ==
3032 jrr[jss::node][jss::mpt_issuance_id] ==
3033 strHex(mptAlice.issuanceID()));
3038 jvParams[jss::mpt_issuance] = badMptID;
3039 jvParams[jss::ledger_hash] = ledgerHash;
3041 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3048 jvParams[jss::mptoken][jss::account] = bob.
human();
3049 jvParams[jss::mptoken][jss::mpt_issuance_id] =
3050 strHex(mptAlice.issuanceID());
3051 jvParams[jss::ledger_hash] = ledgerHash;
3053 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3055 jrr[jss::node][sfMPTokenIssuanceID.jsonName] ==
3056 strHex(mptAlice.issuanceID()));
3062 jvParams[jss::mptoken][jss::account] = bob.
human();
3063 jvParams[jss::mptoken][jss::mpt_issuance_id] = badMptID;
3064 jvParams[jss::ledger_hash] = ledgerHash;
3066 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3074 testcase(
"ledger_entry command-line");
3075 using namespace test::jtx;
3079 env.fund(XRP(10000), alice);
3082 auto const checkId =
keylet::check(env.master, env.seq(env.master));
3084 env(check::create(env.master, alice, XRP(100)));
3091 env.rpc(
"ledger_entry",
to_string(checkId.key))[jss::result];
3093 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
3094 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
3101 testcase(
"ledger_entry PermissionedDomain");
3103 using namespace test::jtx;
3105 Env env(*
this, supported_amendments() | featurePermissionedDomains);
3106 Account const issuer{
"issuer"};
3110 env.
fund(XRP(5000), issuer, alice, bob);
3113 auto const seq = env.
seq(alice);
3114 env(pdomain::setTx(alice, {{alice,
"first credential"}}));
3116 auto const objects = pdomain::getObjects(alice, env);
3117 if (!BEAST_EXPECT(objects.size() == 1))
3123 params[jss::ledger_index] = jss::validated;
3124 params[jss::permissioned_domain][jss::account] = alice.human();
3125 params[jss::permissioned_domain][jss::seq] =
seq;
3126 auto jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3128 jv.isObject() && jv.isMember(jss::result) &&
3129 !jv[jss::result].isMember(jss::error) &&
3130 jv[jss::result].isMember(jss::node) &&
3131 jv[jss::result][jss::node].isMember(
3132 sfLedgerEntryType.jsonName) &&
3133 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
3134 jss::PermissionedDomain);
3136 std::string const pdIdx = jv[jss::result][jss::index].asString();
3141 params[jss::ledger_index] = jss::validated;
3142 params[jss::permissioned_domain] = pdIdx;
3143 jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3145 jv.isObject() && jv.isMember(jss::result) &&
3146 !jv[jss::result].isMember(jss::error) &&
3147 jv[jss::result].isMember(jss::node) &&
3148 jv[jss::result][jss::node].isMember(
3149 sfLedgerEntryType.jsonName) &&
3150 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
3151 jss::PermissionedDomain);
3157 params[jss::ledger_index] = jss::validated;
3158 params[jss::permissioned_domain] =
3159 "12F1F1F1F180D67377B2FAB292A31C922470326268D2B9B74CD1E582645B9A"
3161 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3168 params[jss::ledger_index] = jss::validated;
3169 params[jss::permissioned_domain] =
"NotAHexString";
3170 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3177 params[jss::ledger_index] = jss::validated;
3178 params[jss::permissioned_domain] = 10;
3179 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3186 params[jss::ledger_index] = jss::validated;
3187 params[jss::permissioned_domain][jss::account] = 1;
3188 params[jss::permissioned_domain][jss::seq] =
seq;
3189 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3196 params[jss::ledger_index] = jss::validated;
3197 params[jss::permissioned_domain][jss::account] =
"";
3198 params[jss::permissioned_domain][jss::seq] =
seq;
3199 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3206 params[jss::ledger_index] = jss::validated;
3207 params[jss::permissioned_domain][jss::account] = alice.human();
3208 params[jss::permissioned_domain][jss::seq] =
"12g";
3209 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3252BEAST_DEFINE_TESTSUITE(LedgerRPC, app,
ripple);
3253BEAST_DEFINE_TESTSUITE(LedgerRPC_XChain, app,
ripple);
UInt size() const
Number of values in array or object.
void clear()
Remove all object members and array elements.
Value & append(const Value &value)
Append value to array at the end.
std::string asString() const
Returns the unquoted string value.
bool isMember(const char *key) const
Return true if the object has a member named key.
testcase_t testcase
Memberspace for declaring test cases.
void fail(String const &reason, char const *file, int line)
Record a failure.
void testLedgerEntryBridge()
void checkErrorValue(Json::Value const &jv, std::string const &err, std::string const &msg)
void run() override
Runs the suite.
void testLedgerEntryClaimID()
void testLedgerEntryCreateAccountClaimID()
void testOracleLedgerEntry()
void testLedgerEntryMPT()
void testLookupLedger()
ledger RPC requests as a way to drive input options to lookupLedger.
void testLedgerEntryCheck()
void testLedgerFullNonAdmin()
void testInvalidOracleLedgerEntry()
void testLedgerEntryDirectory()
void testLedgerAccountsOption()
void testLedgerEntryDID()
void testLedgerEntryEscrow()
void testLedgerEntryOffer()
void checkErrorValue(Json::Value const &jv, std::string const &err, std::string const &msg)
void testLedgerEntryDepositPreauth()
void testLedgerEntryCredentials()
void testLedgerEntryPayChan()
void testMissingLedgerEntryLedgerHash()
void testLedgerAccounts()
void testLedgerEntryDepositPreauthCred()
void run() override
Runs the suite.
void testLedgerEntryInvalidParams(unsigned int apiVersion)
void testLedgerEntryCLI()
void testLedgerEntryRippleState()
void testLedgerEntryAccountRoot()
std::string makeBadAddress(std::string good)
void testLedgerEntryTicket()
void testLedgerEntryPermissionedDomain()
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Immutable cryptographic account descriptor.
AccountID id() const
Returns the Account ID.
std::string const & human() const
Returns the human readable public key.
A transaction testing environment.
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
void create(MPTCreate const &arg=MPTCreate{})
Oracle class facilitates unit-testing of the Price Oracle feature.
@ arrayValue
array value (ordered list)
@ objectValue
object value (collection of name/value pairs).
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t asfDepositAuth
AccountID const & xrpAccount()
Compute AccountID from public key.
constexpr std::uint32_t const tfMPTCanTransfer
constexpr std::uint32_t const tfMPTCanTrade
std::string strHex(FwdIt begin, FwdIt end)
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
@ invalid
Timely, but invalid signature.
void forAllApiVersions(Fn const &fn, Args &&... args)
constexpr std::uint32_t tfUniversal
uint256 getTicketIndex(AccountID const &account, std::uint32_t uSequence)
std::string to_string(base_uint< Bits, Tag > const &a)
constexpr std::uint32_t const tfMPTCanEscrow
constexpr std::uint32_t const tfMPTRequireAuth
constexpr std::uint32_t const tfMPTCanLock
constexpr std::uint32_t const tfMPTCanClawback
std::vector< Account > const payee
static constexpr int drop_per_xrp
FeatureBitset const features
std::vector< signer > const signers
void createBridgeObjects(Env &mcEnv, Env &scEnv)
Json::Value const jvXRPBridgeRPC
Set the sequence number on a JTx.