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/Manifest.h>
26#include <xrpld/app/misc/TxQ.h>
27#include <xrpl/basics/StringUtilities.h>
28#include <xrpl/beast/unit_test.h>
29#include <xrpl/json/json_value.h>
30#include <xrpl/protocol/AccountID.h>
31#include <xrpl/protocol/ErrorCodes.h>
32#include <xrpl/protocol/STXChainBridge.h>
33#include <xrpl/protocol/jss.h>
46 if (BEAST_EXPECT(jv.
isMember(jss::status)))
47 BEAST_EXPECT(jv[jss::status] ==
"error");
48 if (BEAST_EXPECT(jv.
isMember(jss::error)))
49 BEAST_EXPECT(jv[jss::error] == err);
54 jv[jss::error_message] ==
"");
56 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
57 BEAST_EXPECT(jv[jss::error_message] == msg);
64 using namespace test::jtx;
67 Env scEnv(*
this, envconfig(),
features);
78 jvParams[jss::bridge] =
jvb;
80 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
82 BEAST_EXPECT(jrr.
isMember(jss::node));
83 auto r = jrr[jss::node];
86 BEAST_EXPECT(r.isMember(jss::Account));
89 BEAST_EXPECT(r.isMember(jss::Flags));
91 BEAST_EXPECT(r.isMember(sfLedgerEntryType.jsonName));
92 BEAST_EXPECT(r[sfLedgerEntryType.jsonName] == jss::Bridge);
95 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
96 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 0);
99 BEAST_EXPECT(r.isMember(sfXChainAccountClaimCount.jsonName));
100 BEAST_EXPECT(r[sfXChainAccountClaimCount.jsonName].asInt() == 0);
102 BEAST_EXPECT(r.isMember(jss::index));
103 bridge_index = r[jss::index].asString();
109 jvParams[jss::index] = bridge_index;
111 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
113 BEAST_EXPECT(jrr.
isMember(jss::node));
114 BEAST_EXPECT(jrr[jss::node] == mcBridge);
120 jvParams[jss::bridge_account] = Account::master.human();
121 jvParams[jss::bridge] =
jvb;
122 jvParams[jss::ledger_hash] = ledgerHash;
124 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
139 jvParams[jss::bridge] =
jvb;
142 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
144 BEAST_EXPECT(jrr.
isMember(jss::node));
145 auto r = jrr[jss::node];
148 BEAST_EXPECT(r.isMember(sfXChainClaimID.jsonName));
149 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
156 testcase(
"ledger_entry: xchain_claim_id");
157 using namespace test::jtx;
160 Env scEnv(*
this, envconfig(),
features);
174 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
178 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
180 BEAST_EXPECT(jrr.
isMember(jss::node));
181 auto r = jrr[jss::node];
184 BEAST_EXPECT(r.isMember(jss::Account));
187 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
188 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 1);
189 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
196 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
199 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
201 BEAST_EXPECT(jrr.
isMember(jss::node));
202 auto r = jrr[jss::node];
205 BEAST_EXPECT(r.isMember(jss::Account));
206 BEAST_EXPECT(r[jss::Account] ==
scBob.
human());
208 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
209 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
210 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
217 testcase(
"ledger_entry: xchain_create_account_claim_id");
218 using namespace test::jtx;
221 Env scEnv(*
this, envconfig(),
features);
229 auto const amt = XRP(1000);
230 mcEnv(sidechain_xchain_account_create(
236 size_t constexpr num_attest = 3;
237 auto attestations = create_account_attestations(
248 UT_XCHAIN_DEFAULT_NUM_SIGNERS);
249 for (
size_t i = 0; i < num_attest; ++i)
251 scEnv(attestations[i]);
258 jvParams[jss::xchain_owned_create_account_claim_id] =
260 jvParams[jss::xchain_owned_create_account_claim_id]
261 [jss::xchain_owned_create_account_claim_id] = 1;
264 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
267 BEAST_EXPECT(jrr.
isMember(jss::node));
268 auto r = jrr[jss::node];
270 BEAST_EXPECT(r.isMember(jss::Account));
271 BEAST_EXPECT(r[jss::Account] == Account::master.human());
273 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
274 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 1);
277 r.isMember(sfXChainCreateAccountAttestations.jsonName));
278 auto attest = r[sfXChainCreateAccountAttestations.jsonName];
279 BEAST_EXPECT(attest.isArray());
280 BEAST_EXPECT(attest.size() == 3);
282 sfXChainCreateAccountProofSig.jsonName));
284 for (
size_t i = 0; i < num_attest; ++i)
287 [sfXChainCreateAccountProofSig.jsonName];
289 a[i].isMember(jss::Amount) &&
292 a[i].isMember(jss::Destination) &&
295 a[i].isMember(sfAttestationSignerAccount.jsonName) &&
298 return a[i][sfAttestationSignerAccount.jsonName] ==
302 a[i].isMember(sfAttestationRewardAccount.jsonName) &&
306 [&](Account
const& account) {
307 return a[i][sfAttestationRewardAccount.jsonName] ==
311 a[i].isMember(sfWasLockingChainSend.jsonName) &&
312 a[i][sfWasLockingChainSend.jsonName] == 1);
314 a[i].isMember(sfSignatureReward.jsonName) &&
315 a[i][sfSignatureReward.jsonName].
asInt() ==
322 for (
size_t i = num_attest; i < UT_XCHAIN_DEFAULT_NUM_SIGNERS; ++i)
324 scEnv(attestations[i]);
330 jvParams[jss::xchain_owned_create_account_claim_id] =
332 jvParams[jss::xchain_owned_create_account_claim_id]
333 [jss::xchain_owned_create_account_claim_id] = 1;
336 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
359 if (BEAST_EXPECT(jv.
isMember(jss::status)))
360 BEAST_EXPECT(jv[jss::status] ==
"error");
361 if (BEAST_EXPECT(jv.
isMember(jss::error)))
362 BEAST_EXPECT(jv[jss::error] == err);
367 jv[jss::error_message] ==
"");
369 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
370 BEAST_EXPECT(jv[jss::error_message] == msg);
387 using namespace test::jtx;
392 BEAST_EXPECT(env.current()->info().seq == 4);
397 jvParams[jss::ledger_index] = 1;
399 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
400 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
401 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
406 jvParams[jss::ledger_index] =
"1";
408 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
409 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
410 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
415 auto const jrr = env.rpc(
"ledger",
"current")[jss::result];
416 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
false);
418 jrr[jss::ledger][jss::ledger_index] ==
421 jrr[jss::ledger_current_index] == env.current()->info().seq);
429 using namespace test::jtx;
431 Account
const gw{
"gateway"};
432 auto const USD = gw[
"USD"];
433 Account
const bob{
"bob"};
435 env.fund(XRP(10000), gw, bob);
437 env.trust(USD(1000), bob);
443 jvParams[jss::ledger_index] =
"potato";
445 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
452 jvParams[jss::ledger_index] = -1;
454 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
461 jvParams[jss::ledger_index] = 10u;
463 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
469 auto const jrr = env.rpc(
"ledger",
"arbitrary_text")[jss::result];
476 jvParams[jss::ledger_index] =
"validated";
477 jvParams[jss::queue] =
true;
479 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
486 env.rpc(
"json",
"ledger",
"{ \"ledger_index\" : 2e15 }");
488 BEAST_EXPECT(ret[jss::error_message] ==
"Invalid parameters.");
493 auto const ret = env.rpc(
494 "json",
"ledger",
"{ \"ledger_index\" : 1000000000000000 }");
501 jvParams[jss::ledger_index] =
"validated";
502 jvParams[jss::index] =
503 "00000000000000000000000000000000000000000000000000000000000000"
505 auto const jrr = env.rpc(
506 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
515 using namespace test::jtx;
520 BEAST_EXPECT(env.current()->info().seq == 4);
523 auto const jrr = env.rpc(
"ledger_current")[jss::result];
525 jrr[jss::ledger_current_index] == env.current()->info().seq);
532 testcase(
"Missing ledger_entry ledger_hash");
533 using namespace test::jtx;
535 Account
const alice{
"alice"};
536 env.fund(XRP(10000), alice);
540 jvParams[jss::account_root] = alice.human();
541 jvParams[jss::ledger_hash] =
542 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
544 env.rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
551 testcase(
"Ledger Request, Full Option");
552 using namespace test::jtx;
559 jvParams[jss::ledger_index] = 3u;
560 jvParams[jss::full] =
true;
562 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
563 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
564 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
565 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 3u);
571 testcase(
"Ledger Request, Full Option Without Admin");
572 using namespace test::jtx;
574 Env env{*
this, envconfig(no_admin)};
579 jvParams[jss::ledger_index] = 1u;
580 jvParams[jss::full] =
true;
582 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
584 jrr,
"noPermission",
"You don't have permission for this command.");
590 testcase(
"Ledger Request, Accounts Option");
591 using namespace test::jtx;
598 jvParams[jss::ledger_index] = 3u;
599 jvParams[jss::accounts] =
true;
601 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
602 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
603 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
604 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 3u);
610 testcase(
"ledger_entry Request AccountRoot");
611 using namespace test::jtx;
613 Account
const alice{
"alice"};
614 env.fund(XRP(10000), alice);
620 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
621 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
622 BEAST_EXPECT(jrr[jss::ledger_index] == 3);
629 jvParams[jss::account_root] = alice.human();
630 jvParams[jss::ledger_hash] = ledgerHash;
632 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
633 BEAST_EXPECT(jrr.
isMember(jss::node));
634 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
635 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
636 accountRootIndex = jrr[jss::index].
asString();
639 constexpr char alicesAcctRootBinary[]{
640 "1100612200800000240000000425000000032D00000000559CE54C3B934E4"
641 "73A995B477E92EC229F99CED5B62BF4D2ACE4DC42719103AE2F6240000002"
642 "540BE4008114AE123A8556F3CF91154711376AFB0F894F832B3D"};
646 jvParams[jss::account_root] = alice.human();
647 jvParams[jss::binary] = 1;
648 jvParams[jss::ledger_hash] = ledgerHash;
650 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
651 BEAST_EXPECT(jrr.
isMember(jss::node_binary));
652 BEAST_EXPECT(jrr[jss::node_binary] == alicesAcctRootBinary);
657 jvParams[jss::index] = accountRootIndex;
659 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
660 BEAST_EXPECT(!jrr.
isMember(jss::node_binary));
661 BEAST_EXPECT(jrr.
isMember(jss::node));
662 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
663 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
668 jvParams[jss::index] = accountRootIndex;
669 jvParams[jss::binary] = 0;
671 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
672 BEAST_EXPECT(jrr.
isMember(jss::node));
673 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
674 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
680 jvParams[jss::ledger_hash] = ledgerHash;
682 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
688 jvParams[jss::account_root] = Account(
"bob").human();
689 jvParams[jss::ledger_hash] = ledgerHash;
691 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
699 testcase(
"ledger_entry Request Check");
700 using namespace test::jtx;
702 Account
const alice{
"alice"};
703 env.fund(XRP(10000), alice);
706 auto const checkId =
keylet::check(env.master, env.seq(env.master));
708 env(check::create(env.master, alice, XRP(100)));
715 jvParams[jss::check] =
to_string(checkId.key);
716 jvParams[jss::ledger_hash] = ledgerHash;
718 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
720 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
721 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
729 jvParams[jss::account_root] = alice.human();
731 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
732 accountRootIndex = jrr[jss::index].
asString();
735 jvParams[jss::check] = accountRootIndex;
736 jvParams[jss::ledger_hash] = ledgerHash;
738 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
746 testcase(
"ledger_entry credentials");
748 using namespace test::jtx;
751 Account
const issuer{
"issuer"};
752 Account
const alice{
"alice"};
753 Account
const bob{
"bob"};
754 const char credType[] =
"abcde";
756 env.fund(XRP(5000), issuer, alice, bob);
760 env(credentials::create(alice, issuer, credType));
765 auto jv = credentials::ledgerEntry(env, alice, issuer, credType);
767 jv.isObject() && jv.isMember(jss::result) &&
768 !jv[jss::result].isMember(jss::error) &&
769 jv[jss::result].isMember(jss::node) &&
770 jv[jss::result][jss::node].isMember(
771 sfLedgerEntryType.jsonName) &&
772 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
775 std::string const credIdx = jv[jss::result][jss::index].asString();
777 jv = credentials::ledgerEntry(env, credIdx);
779 jv.isObject() && jv.isMember(jss::result) &&
780 !jv[jss::result].isMember(jss::error) &&
781 jv[jss::result].isMember(jss::node) &&
782 jv[jss::result][jss::node].isMember(
783 sfLedgerEntryType.jsonName) &&
784 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
790 auto const jv = credentials::ledgerEntry(env,
"");
796 auto const jv = credentials::ledgerEntry(
798 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
806 jv[jss::ledger_index] = jss::validated;
807 jv[jss::credential][jss::subject] = 42;
808 jv[jss::credential][jss::issuer] = issuer.human();
809 jv[jss::credential][jss::credential_type] =
811 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
818 jv[jss::ledger_index] = jss::validated;
819 jv[jss::credential][jss::subject] = alice.human();
820 jv[jss::credential][jss::issuer] = 42;
821 jv[jss::credential][jss::credential_type] =
823 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
830 jv[jss::ledger_index] = jss::validated;
831 jv[jss::credential][jss::subject] = alice.human();
832 jv[jss::credential][jss::issuer] = issuer.human();
833 jv[jss::credential][jss::credential_type] = 42;
834 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
841 jv[jss::ledger_index] = jss::validated;
842 jv[jss::credential][jss::subject] =
"";
843 jv[jss::credential][jss::issuer] = issuer.human();
844 jv[jss::credential][jss::credential_type] =
846 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
853 jv[jss::ledger_index] = jss::validated;
854 jv[jss::credential][jss::subject] = alice.human();
855 jv[jss::credential][jss::issuer] =
"";
856 jv[jss::credential][jss::credential_type] =
858 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
865 jv[jss::ledger_index] = jss::validated;
866 jv[jss::credential][jss::subject] = alice.human();
867 jv[jss::credential][jss::issuer] = issuer.human();
868 jv[jss::credential][jss::credential_type] =
"";
869 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
876 jv[jss::ledger_index] = jss::validated;
877 jv[jss::credential][jss::issuer] = issuer.human();
878 jv[jss::credential][jss::credential_type] =
880 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
887 jv[jss::ledger_index] = jss::validated;
888 jv[jss::credential][jss::subject] = alice.human();
889 jv[jss::credential][jss::credential_type] =
891 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
898 jv[jss::ledger_index] = jss::validated;
899 jv[jss::credential][jss::subject] = alice.human();
900 jv[jss::credential][jss::issuer] = issuer.human();
901 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
908 jv[jss::ledger_index] = jss::validated;
909 jv[jss::credential][jss::subject] =
"wehsdbvasbdfvj";
910 jv[jss::credential][jss::issuer] = issuer.human();
911 jv[jss::credential][jss::credential_type] =
913 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
920 jv[jss::ledger_index] = jss::validated;
921 jv[jss::credential][jss::subject] = alice.human();
922 jv[jss::credential][jss::issuer] =
"c4p93ugndfbsiu";
923 jv[jss::credential][jss::credential_type] =
925 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
932 jv[jss::ledger_index] = jss::validated;
933 jv[jss::credential][jss::subject] = alice.human();
934 jv[jss::credential][jss::issuer] = issuer.human();
935 jv[jss::credential][jss::credential_type] =
"12KK";
936 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
944 testcase(
"ledger_entry Deposit Preauth");
946 using namespace test::jtx;
949 Account
const alice{
"alice"};
950 Account
const becky{
"becky"};
952 env.fund(XRP(10000), alice, becky);
955 env(deposit::auth(alice, becky));
963 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
964 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
965 jvParams[jss::ledger_hash] = ledgerHash;
967 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
970 jrr[jss::node][sfLedgerEntryType.jsonName] ==
971 jss::DepositPreauth);
972 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
973 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
974 depositPreauthIndex = jrr[jss::node][jss::index].
asString();
979 jvParams[jss::deposit_preauth] = depositPreauthIndex;
980 jvParams[jss::ledger_hash] = ledgerHash;
982 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
985 jrr[jss::node][sfLedgerEntryType.jsonName] ==
986 jss::DepositPreauth);
987 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
988 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
993 jvParams[jss::deposit_preauth] = -5;
994 jvParams[jss::ledger_hash] = ledgerHash;
996 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1002 jvParams[jss::deposit_preauth] =
"0123456789ABCDEFG";
1003 jvParams[jss::ledger_hash] = ledgerHash;
1005 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1011 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1012 jvParams[jss::ledger_hash] = ledgerHash;
1014 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1020 jvParams[jss::deposit_preauth][jss::owner] = 7;
1021 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1022 jvParams[jss::ledger_hash] = ledgerHash;
1024 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1030 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1031 jvParams[jss::ledger_hash] = ledgerHash;
1033 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1039 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1040 jvParams[jss::deposit_preauth][jss::authorized] = 47;
1041 jvParams[jss::ledger_hash] = ledgerHash;
1043 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1049 jvParams[jss::deposit_preauth][jss::owner] =
1050 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
1052 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1053 jvParams[jss::ledger_hash] = ledgerHash;
1055 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1061 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1062 jvParams[jss::deposit_preauth][jss::authorized] =
1063 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
1065 jvParams[jss::ledger_hash] = ledgerHash;
1067 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1075 testcase(
"ledger_entry Deposit Preauth with credentials");
1077 using namespace test::jtx;
1080 Account
const issuer{
"issuer"};
1081 Account
const alice{
"alice"};
1082 Account
const bob{
"bob"};
1083 const char credType[] =
"abcde";
1085 env.fund(XRP(5000), issuer, alice, bob);
1092 env(deposit::authCredentials(bob, {{issuer, credType}}));
1099 jvParams[jss::ledger_index] = jss::validated;
1100 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1102 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1105 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1108 jo[jss::issuer] = issuer.human();
1110 arr.append(std::move(jo));
1112 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1115 jrr.isObject() && jrr.isMember(jss::result) &&
1116 !jrr[jss::result].isMember(jss::error) &&
1117 jrr[jss::result].isMember(jss::node) &&
1118 jrr[jss::result][jss::node].isMember(
1119 sfLedgerEntryType.jsonName) &&
1120 jrr[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
1121 jss::DepositPreauth);
1127 jvParams[jss::ledger_index] = jss::validated;
1128 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1130 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1133 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1138 arr.append(std::move(jo));
1140 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1142 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1148 jvParams[jss::ledger_index] = jss::validated;
1149 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1151 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1154 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1157 jo[jss::issuer] = issuer.human();
1160 arr.append(std::move(jo));
1162 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1164 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1170 jvParams[jss::ledger_index] = jss::validated;
1171 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1173 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1176 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1179 jo[jss::issuer] = issuer.human();
1180 jo[jss::credential_type] =
"";
1181 arr.
append(std::move(jo));
1184 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1186 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1192 jvParams[jss::ledger_index] = jss::validated;
1193 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1194 jvParams[jss::deposit_preauth][jss::authorized] = alice.human();
1196 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1199 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1202 jo[jss::issuer] = issuer.human();
1204 arr.append(std::move(jo));
1207 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1214 jvParams[jss::ledger_index] = jss::validated;
1215 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1216 jvParams[jss::deposit_preauth][jss::authorized_credentials] = 42;
1219 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1226 jvParams[jss::ledger_index] = jss::validated;
1227 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1228 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1231 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1232 arr.append(
"foobar");
1235 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1237 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1243 jvParams[jss::ledger_index] = jss::validated;
1244 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1245 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1248 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1251 arr.
append(std::move(payload));
1254 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1256 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1262 jvParams[jss::ledger_index] = jss::validated;
1263 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1264 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1268 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1270 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1287 sizeof(credTypes) /
sizeof(credTypes[0]) >
1291 jvParams[jss::ledger_index] = jss::validated;
1292 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1293 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1297 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1299 for (
unsigned i = 0; i <
sizeof(credTypes) /
sizeof(credTypes[0]);
1303 jo[jss::issuer] = issuer.human();
1304 jo[jss::credential_type] =
1306 arr.append(std::move(jo));
1310 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1312 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1318 jvParams[jss::ledger_index] = jss::validated;
1319 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1321 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1324 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1328 arr.append(std::move(jo));
1331 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1333 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1339 jvParams[jss::ledger_index] = jss::validated;
1340 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1342 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1345 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1348 jo[jss::issuer] = 42;
1350 arr.append(std::move(jo));
1353 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1355 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1361 jvParams[jss::ledger_index] = jss::validated;
1362 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1364 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1367 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1372 jo[jss::issuer] = std::move(payload);
1374 arr.append(std::move(jo));
1377 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1379 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1385 jvParams[jss::ledger_index] = jss::validated;
1386 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1388 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1391 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1394 jo[jss::issuer] =
"invalid_account";
1396 arr.append(std::move(jo));
1399 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1401 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1407 jvParams[jss::ledger_index] = jss::validated;
1408 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1410 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1413 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1416 jo[jss::issuer] = issuer.human();
1417 arr.
append(std::move(jo));
1420 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1422 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1428 jvParams[jss::ledger_index] = jss::validated;
1429 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1431 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1434 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1437 jo[jss::issuer] = issuer.human();
1438 jo[jss::credential_type] = 42;
1439 arr.
append(std::move(jo));
1442 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1444 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1450 jvParams[jss::ledger_index] = jss::validated;
1451 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1453 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1456 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1459 jo[jss::issuer] = issuer.human();
1462 jo[jss::credential_type] = std::move(payload);
1463 arr.append(std::move(jo));
1466 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1468 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1474 jvParams[jss::ledger_index] = jss::validated;
1475 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1477 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1480 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1483 jo[jss::issuer] = issuer.human();
1484 jo[jss::credential_type] =
"12KK";
1485 arr.
append(std::move(jo));
1488 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1490 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1497 testcase(
"ledger_entry Request Directory");
1498 using namespace test::jtx;
1500 Account
const alice{
"alice"};
1501 Account
const gw{
"gateway"};
1502 auto const USD = gw[
"USD"];
1503 env.fund(XRP(10000), alice, gw);
1506 env.trust(USD(1000), alice);
1511 for (
int d = 1'000'032; d >= 1'000'000; --d)
1513 env(offer(alice, USD(1), drops(d)));
1520 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
1521 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
1522 BEAST_EXPECT(jrr[jss::ledger_index] == 5);
1526 "A33EC6BB85FB5674074C4A3A43373BB17645308F3EAE1933E3E35252162B217D";
1530 jvParams[jss::directory] = dirRootIndex;
1531 jvParams[jss::ledger_hash] = ledgerHash;
1533 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1534 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 32);
1540 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1542 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1543 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1549 jvParams[jss::directory][jss::owner] = alice.human();
1550 jvParams[jss::ledger_hash] = ledgerHash;
1552 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1553 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1559 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1560 jvParams[jss::directory][jss::sub_index] = 1;
1562 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1563 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1564 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1570 jvParams[jss::directory][jss::owner] = alice.human();
1571 jvParams[jss::directory][jss::sub_index] = 1;
1572 jvParams[jss::ledger_hash] = ledgerHash;
1574 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1575 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1576 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1582 jvParams[jss::ledger_hash] = ledgerHash;
1584 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1591 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1592 jvParams[jss::directory][jss::sub_index] = 1.5;
1593 jvParams[jss::ledger_hash] = ledgerHash;
1595 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1604 jvParams[jss::directory][jss::owner] = badAddress;
1605 jvParams[jss::ledger_hash] = ledgerHash;
1607 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1614 jvParams[jss::directory][jss::owner] = alice.human();
1615 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1616 jvParams[jss::ledger_hash] = ledgerHash;
1618 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1625 jvParams[jss::directory][jss::sub_index] = 1;
1626 jvParams[jss::ledger_hash] = ledgerHash;
1628 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1636 testcase(
"ledger_entry Request Escrow");
1637 using namespace test::jtx;
1639 Account
const alice{
"alice"};
1640 env.fund(XRP(10000), alice);
1649 jv[jss::TransactionType] = jss::EscrowCreate;
1651 jv[jss::Account] = account.human();
1652 jv[jss::Destination] = to.human();
1654 jv[sfFinishAfter.jsonName] =
1655 cancelAfter.time_since_epoch().count() + 2;
1659 using namespace std::chrono_literals;
1660 env(escrowCreate(alice, alice, XRP(333), env.now() + 2s));
1669 jvParams[jss::escrow][jss::owner] = alice.human();
1670 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1672 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1674 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1675 escrowIndex = jrr[jss::index].
asString();
1680 jvParams[jss::escrow] = escrowIndex;
1681 jvParams[jss::ledger_hash] = ledgerHash;
1683 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1685 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1693 jvParams[jss::escrow][jss::owner] = badAddress;
1694 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1695 jvParams[jss::ledger_hash] = ledgerHash;
1697 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1704 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1705 jvParams[jss::ledger_hash] = ledgerHash;
1707 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1714 jvParams[jss::escrow][jss::owner] = alice.human();
1715 jvParams[jss::ledger_hash] = ledgerHash;
1717 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1724 jvParams[jss::escrow][jss::owner] = alice.human();
1725 jvParams[jss::escrow][jss::seq] =
1727 jvParams[jss::ledger_hash] = ledgerHash;
1729 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1737 testcase(
"ledger_entry Request Offer");
1738 using namespace test::jtx;
1740 Account
const alice{
"alice"};
1741 Account
const gw{
"gateway"};
1742 auto const USD = gw[
"USD"];
1743 env.fund(XRP(10000), alice, gw);
1746 env(offer(alice, USD(321), XRP(322)));
1755 jvParams[jss::offer][jss::account] = alice.human();
1756 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1757 jvParams[jss::ledger_hash] = ledgerHash;
1759 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1760 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1761 offerIndex = jrr[jss::index].
asString();
1766 jvParams[jss::offer] = offerIndex;
1768 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1769 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1777 jvParams[jss::offer][jss::account] = badAddress;
1778 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1779 jvParams[jss::ledger_hash] = ledgerHash;
1781 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1788 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1789 jvParams[jss::ledger_hash] = ledgerHash;
1791 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1798 jvParams[jss::offer][jss::account] = alice.human();
1799 jvParams[jss::ledger_hash] = ledgerHash;
1801 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1808 jvParams[jss::offer][jss::account] = alice.human();
1809 jvParams[jss::offer][jss::seq] =
std::to_string(env.seq(alice) - 1);
1810 jvParams[jss::ledger_hash] = ledgerHash;
1812 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1820 testcase(
"ledger_entry Request Pay Chan");
1821 using namespace test::jtx;
1822 using namespace std::literals::chrono_literals;
1824 Account
const alice{
"alice"};
1826 env.fund(XRP(10000), alice);
1836 jv[jss::TransactionType] = jss::PaymentChannelCreate;
1837 jv[jss::Account] = account.human();
1838 jv[jss::Destination] = to.human();
1840 jv[sfSettleDelay.jsonName] = settleDelay.count();
1841 jv[sfPublicKey.jsonName] =
strHex(pk.slice());
1845 env(payChanCreate(alice, env.master, XRP(57), 18s, alice.pk()));
1855 jvParams[jss::payment_channel] =
to_string(payChanIndex);
1856 jvParams[jss::ledger_hash] = ledgerHash;
1858 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1859 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"57000000");
1860 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"0");
1861 BEAST_EXPECT(jrr[jss::node][sfSettleDelay.jsonName] == 18);
1866 jvParams[jss::payment_channel] = ledgerHash;
1867 jvParams[jss::ledger_hash] = ledgerHash;
1869 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1877 testcase(
"ledger_entry Request RippleState");
1878 using namespace test::jtx;
1880 Account
const alice{
"alice"};
1881 Account
const gw{
"gateway"};
1882 auto const USD = gw[
"USD"];
1883 env.fund(XRP(10000), alice, gw);
1886 env.trust(USD(999), alice);
1889 env(pay(gw, alice, USD(97)));
1893 for (
auto const& fieldName : {jss::ripple_state, jss::state})
1901 jvParams[fieldName][jss::accounts][0u] = alice.human();
1902 jvParams[fieldName][jss::accounts][1u] = gw.human();
1903 jvParams[fieldName][jss::currency] =
"USD";
1904 jvParams[jss::ledger_hash] = ledgerHash;
1906 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1908 jrr[jss::node][sfBalance.jsonName][jss::value] ==
"-97");
1910 jrr[jss::node][sfHighLimit.jsonName][jss::value] ==
"999");
1915 jvParams[fieldName] =
"ripple_state";
1916 jvParams[jss::ledger_hash] = ledgerHash;
1918 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1926 jvParams[fieldName][jss::accounts][0u] = alice.human();
1927 jvParams[fieldName][jss::accounts][1u] = gw.human();
1928 jvParams[jss::ledger_hash] = ledgerHash;
1930 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1937 jvParams[fieldName][jss::accounts] = 2;
1938 jvParams[fieldName][jss::currency] =
"USD";
1939 jvParams[jss::ledger_hash] = ledgerHash;
1941 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1949 jvParams[fieldName][jss::accounts][0u] = alice.human();
1950 jvParams[fieldName][jss::currency] =
"USD";
1951 jvParams[jss::ledger_hash] = ledgerHash;
1953 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1961 jvParams[fieldName][jss::accounts][0u] = alice.human();
1962 jvParams[fieldName][jss::accounts][1u] = gw.human();
1963 jvParams[fieldName][jss::accounts][2u] = alice.human();
1964 jvParams[fieldName][jss::currency] =
"USD";
1965 jvParams[jss::ledger_hash] = ledgerHash;
1967 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1975 jvParams[fieldName][jss::accounts][0u] = 44;
1976 jvParams[fieldName][jss::accounts][1u] = gw.human();
1977 jvParams[fieldName][jss::currency] =
"USD";
1978 jvParams[jss::ledger_hash] = ledgerHash;
1980 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1988 jvParams[fieldName][jss::accounts][0u] = alice.human();
1989 jvParams[fieldName][jss::accounts][1u] = 21;
1990 jvParams[fieldName][jss::currency] =
"USD";
1991 jvParams[jss::ledger_hash] = ledgerHash;
1993 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2001 jvParams[fieldName][jss::accounts][0u] = alice.human();
2002 jvParams[fieldName][jss::accounts][1u] = alice.human();
2003 jvParams[fieldName][jss::currency] =
"USD";
2004 jvParams[jss::ledger_hash] = ledgerHash;
2006 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2014 jvParams[fieldName][jss::accounts][0u] =
2016 jvParams[fieldName][jss::accounts][1u] = gw.human();
2017 jvParams[fieldName][jss::currency] =
"USD";
2018 jvParams[jss::ledger_hash] = ledgerHash;
2020 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2028 jvParams[fieldName][jss::accounts][0u] = alice.human();
2029 jvParams[fieldName][jss::accounts][1u] =
2031 jvParams[fieldName][jss::currency] =
"USD";
2032 jvParams[jss::ledger_hash] = ledgerHash;
2034 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2042 jvParams[fieldName][jss::accounts][0u] = alice.human();
2043 jvParams[fieldName][jss::accounts][1u] = gw.human();
2044 jvParams[fieldName][jss::currency] =
"USDollars";
2045 jvParams[jss::ledger_hash] = ledgerHash;
2047 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2056 testcase(
"ledger_entry Request Ticket");
2057 using namespace test::jtx;
2063 env(ticket::create(env.master, 2));
2073 jvParams[jss::ticket] =
2075 jvParams[jss::ledger_hash] = ledgerHash;
2077 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2084 jvParams[jss::ledger_hash] = ledgerHash;
2086 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2088 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Ticket);
2089 BEAST_EXPECT(jrr[jss::node][sfTicketSequence.jsonName] == tkt1);
2095 jvParams[jss::ticket][jss::account] = env.master.human();
2096 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 1;
2097 jvParams[jss::ledger_hash] = ledgerHash;
2099 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2101 jrr[jss::node][jss::index] ==
2108 jvParams[jss::ticket][jss::account] = env.master.human();
2109 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 2;
2110 jvParams[jss::ledger_hash] = ledgerHash;
2112 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2119 jvParams[jss::ledger_hash] = ledgerHash;
2121 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2130 jvParams[jss::ticket][jss::account] = badAddress;
2131 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
2132 jvParams[jss::ledger_hash] = ledgerHash;
2134 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2141 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
2142 jvParams[jss::ledger_hash] = ledgerHash;
2144 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2151 jvParams[jss::ticket][jss::account] = env.master.human();
2152 jvParams[jss::ledger_hash] = ledgerHash;
2154 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2161 jvParams[jss::ticket][jss::account] = env.master.human();
2162 jvParams[jss::ticket][jss::ticket_seq] =
2164 jvParams[jss::ledger_hash] = ledgerHash;
2166 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2174 testcase(
"ledger_entry Request DID");
2175 using namespace test::jtx;
2176 using namespace std::literals::chrono_literals;
2178 Account
const alice{
"alice"};
2180 env.fund(XRP(10000), alice);
2186 jv[jss::TransactionType] = jss::DIDSet;
2187 jv[jss::Account] = account.human();
2193 env(didCreate(alice));
2201 jvParams[jss::did] = alice.human();
2202 jvParams[jss::ledger_hash] = ledgerHash;
2204 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2206 jrr[jss::node][sfDIDDocument.jsonName] ==
2214 jvParams[jss::did] = env.master.human();
2215 jvParams[jss::ledger_hash] = ledgerHash;
2217 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2226 "ledger_entry Request With Invalid Parameters v" +
2228 using namespace test::jtx;
2235 params[jss::api_version] = apiVersion;
2241 auto const jvParams =
2243 jvParams[jss::features] = ledgerHash;
2244 jvParams[jss::ledger_hash] = ledgerHash;
2247 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2249 if (apiVersion < 2u)
2256 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2257 obj[jss::ledger_index] =
"validated";
2262 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2263 arr[1u] =
"validated";
2269 for (
auto const& field :
2270 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
2272 auto const jvParams =
2273 makeParams([&field, &injectArray](
Json::Value& jvParams) {
2274 jvParams[field] = injectArray;
2278 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2280 if (apiVersion < 2u)
2286 for (
auto const& field :
2287 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
2289 auto const jvParams =
2290 makeParams([&field, &injectObject](
Json::Value& jvParams) {
2291 jvParams[field] = injectObject;
2295 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2300 for (
auto const& inject : {injectObject, injectArray})
2303 for (
auto const& field :
2307 jss::payment_channel})
2309 auto const jvParams =
2310 makeParams([&field, &inject](
Json::Value& jvParams) {
2311 jvParams[field] = inject;
2315 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2317 if (apiVersion < 2u)
2323 for (
auto const& field : {jss::dir_root, jss::owner})
2325 auto const jvParams =
2326 makeParams([&field, &inject](
Json::Value& jvParams) {
2327 jvParams[jss::directory][field] = inject;
2331 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2333 if (apiVersion < 2u)
2340 auto const jvParams =
2342 jvParams[jss::escrow][jss::owner] = inject;
2343 jvParams[jss::escrow][jss::seq] = 99;
2347 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2349 if (apiVersion < 2u)
2356 auto const jvParams =
2358 jvParams[jss::offer][jss::account] = inject;
2359 jvParams[jss::offer][jss::seq] = 99;
2363 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2365 if (apiVersion < 2u)
2372 auto const jvParams =
2375 rs[jss::currency] =
"FOO";
2377 rs[jss::accounts][0u] =
2378 "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2379 rs[jss::accounts][1u] =
2380 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
2381 rs[jss::currency] = inject;
2382 jvParams[jss::ripple_state] = std::move(rs);
2386 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2388 if (apiVersion < 2u)
2395 auto const jvParams =
2397 jvParams[jss::ticket][jss::account] = inject;
2398 jvParams[jss::ticket][jss::ticket_seq] = 99;
2402 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2404 if (apiVersion < 2u)
2411 for (
auto const& field : {jss::nft_page, jss::deposit_preauth})
2413 auto const jvParams =
2414 makeParams([&field, &inject](
Json::Value& jvParams) {
2415 jvParams[field] = inject;
2419 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2425 for (
auto const& field : {jss::owner, jss::authorized})
2427 auto const jvParams =
2428 makeParams([&field, &inject](
Json::Value& jvParams) {
2430 pa[jss::owner] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2431 pa[jss::authorized] =
2432 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
2434 jvParams[jss::deposit_preauth] = std::move(pa);
2438 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2453 using namespace test::jtx;
2456 env.fund(XRP(10000),
"alice");
2458 env.fund(XRP(10000),
"bob");
2460 env.fund(XRP(10000),
"jim");
2462 env.fund(XRP(10000),
"jill");
2467 jvParams[jss::ledger] =
"closed";
2471 boost::lexical_cast<std::string>(jvParams))[jss::result];
2472 BEAST_EXPECT(jrr.isMember(jss::ledger));
2473 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2474 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2476 jvParams[jss::ledger] =
"validated";
2480 boost::lexical_cast<std::string>(jvParams))[jss::result];
2481 BEAST_EXPECT(jrr.isMember(jss::ledger));
2482 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2483 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2485 jvParams[jss::ledger] =
"current";
2489 boost::lexical_cast<std::string>(jvParams))[jss::result];
2490 BEAST_EXPECT(jrr.isMember(jss::ledger));
2491 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
2494 jvParams[jss::ledger] =
"invalid";
2498 boost::lexical_cast<std::string>(jvParams))[jss::result];
2499 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2500 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
2503 jvParams[jss::ledger] = 4;
2507 boost::lexical_cast<std::string>(jvParams))[jss::result];
2508 BEAST_EXPECT(jrr.isMember(jss::ledger));
2509 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2510 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
2513 jvParams[jss::ledger] = 20;
2517 boost::lexical_cast<std::string>(jvParams))[jss::result];
2518 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2519 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2524 "E86DE7F3D7A4D9CE17EF7C8BA08A8F4D"
2525 "8F643B9552F0D895A31CDA78F541DE4E"};
2528 jvParams[jss::ledger_hash] = hash3;
2532 boost::lexical_cast<std::string>(jvParams))[jss::result];
2533 BEAST_EXPECT(jrr.isMember(jss::ledger));
2534 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2535 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
2538 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
2542 boost::lexical_cast<std::string>(jvParams))[jss::result];
2543 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2544 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
2547 jvParams[jss::ledger_hash] = 2;
2551 boost::lexical_cast<std::string>(jvParams))[jss::result];
2552 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2553 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashNotString");
2556 jvParams[jss::ledger_hash] =
2557 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
2558 "7F2775F2F7485BB37307984C3C0F2340";
2562 boost::lexical_cast<std::string>(jvParams))[jss::result];
2563 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2564 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
2567 jvParams[jss::ledger_hash] =
2568 "8C3EEDB3124D92E49E75D81A8826A2E6"
2569 "5A75FD71FC3FD6F36FEB803C5F1D812D";
2573 boost::lexical_cast<std::string>(jvParams))[jss::result];
2574 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2575 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2581 jvParams[jss::ledger_index] =
"closed";
2585 boost::lexical_cast<std::string>(jvParams))[jss::result];
2586 BEAST_EXPECT(jrr.isMember(jss::ledger));
2587 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2588 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2589 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
2591 jvParams[jss::ledger_index] =
"validated";
2595 boost::lexical_cast<std::string>(jvParams))[jss::result];
2596 BEAST_EXPECT(jrr.isMember(jss::ledger));
2597 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2598 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2600 jvParams[jss::ledger_index] =
"current";
2604 boost::lexical_cast<std::string>(jvParams))[jss::result];
2605 BEAST_EXPECT(jrr.isMember(jss::ledger));
2606 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
2607 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
2610 jvParams[jss::ledger_index] =
"invalid";
2614 boost::lexical_cast<std::string>(jvParams))[jss::result];
2615 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2616 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
2619 for (
auto i : {1, 2, 3, 4, 5, 6})
2621 jvParams[jss::ledger_index] = i;
2625 boost::lexical_cast<std::string>(jvParams))[jss::result];
2626 BEAST_EXPECT(jrr.isMember(jss::ledger));
2628 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2634 jvParams[jss::ledger_index] = 7;
2638 boost::lexical_cast<std::string>(jvParams))[jss::result];
2639 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2640 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2647 testcase(
"Ledger with queueing disabled");
2648 using namespace test::jtx;
2652 jv[jss::ledger_index] =
"current";
2653 jv[jss::queue] =
true;
2654 jv[jss::expand] =
true;
2656 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2657 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2663 testcase(
"Ledger with Queued Transactions");
2664 using namespace test::jtx;
2666 auto& section = cfg->section(
"transaction_queue");
2667 section.set(
"minimum_txn_in_ledger_standalone",
"3");
2668 section.set(
"normal_consensus_increase_percent",
"0");
2673 jv[jss::ledger_index] =
"current";
2674 jv[jss::queue] =
true;
2675 jv[jss::expand] =
true;
2677 Account
const alice{
"alice"};
2678 Account
const bob{
"bob"};
2679 Account
const charlie{
"charlie"};
2680 Account
const daria{
"daria"};
2681 env.fund(XRP(10000), alice);
2682 env.fund(XRP(10000), bob);
2684 env.fund(XRP(10000), charlie);
2685 env.fund(XRP(10000), daria);
2688 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2689 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2694 auto metrics = env.app().getTxQ().getMetrics(*env.current());
2695 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
2700 BEAST_EXPECT(env.current()->info().seq == 5);
2703 auto aliceSeq = env.seq(alice);
2704 env(pay(alice,
"george", XRP(1000)),
2705 json(R
"({"LastLedgerSequence":7})"),
2707 env(offer(alice, XRP(50000), alice["USD"](5000)),
2710 env(noop(alice), seq(aliceSeq + 2), ter(
terQUEUED));
2712 auto batch = [&env](Account a) {
2713 auto aSeq = env.seq(a);
2715 for (
int i = 0; i < 10; ++i)
2717 env(noop(a), fee(1000 + i), seq(aSeq + i), ter(
terQUEUED));
2726 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2727 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
2733 BEAST_EXPECT(env.current()->info().seq == 8);
2735 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2736 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
2740 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2742 auto const& parentHash = env.current()->info().parentHash;
2743 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2746 auto const& txj = jrr[jss::queue_data][1u];
2747 BEAST_EXPECT(txj[jss::account] == alice.human());
2748 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2749 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2750 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2751 BEAST_EXPECT(txj.isMember(jss::tx));
2752 auto const& tx = txj[jss::tx];
2753 BEAST_EXPECT(tx[jss::Account] == alice.human());
2754 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2755 return tx[jss::hash].asString();
2758 auto const& txj = jrr[jss::queue_data][0u];
2759 BEAST_EXPECT(txj[jss::account] == alice.human());
2760 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2761 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2762 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2763 BEAST_EXPECT(txj.isMember(jss::tx));
2764 auto const& tx = txj[jss::tx];
2765 BEAST_EXPECT(tx[jss::Account] == alice.human());
2766 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
2767 const auto txid0 = tx[jss::hash].asString();
2771 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2779 jv[jss::expand] =
false;
2781 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2782 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2784 auto const& parentHash = env.current()->info().parentHash;
2785 auto const txid1 = [&]() {
2786 auto const& txj = jrr[jss::queue_data][1u];
2787 BEAST_EXPECT(txj[jss::account] == alice.human());
2788 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2789 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2790 BEAST_EXPECT(txj.isMember(jss::tx));
2791 return txj[jss::tx].asString();
2793 auto const& txj = jrr[jss::queue_data][0u];
2794 BEAST_EXPECT(txj[jss::account] == alice.human());
2795 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2796 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2797 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
2798 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2799 BEAST_EXPECT(txj.isMember(jss::tx));
2800 BEAST_EXPECT(txj[jss::tx] == txid0);
2804 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2809 jv[jss::expand] =
true;
2810 jv[jss::binary] =
true;
2812 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2813 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2815 auto const& txj = jrr[jss::queue_data][1u];
2816 BEAST_EXPECT(txj[jss::account] == alice.human());
2817 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2818 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2819 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
2820 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2821 BEAST_EXPECT(txj.isMember(jss::tx));
2822 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
2824 auto const& txj2 = jrr[jss::queue_data][0u];
2825 BEAST_EXPECT(txj2[jss::account] == alice.human());
2826 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
2827 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
2828 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
2829 BEAST_EXPECT(!txj2.isMember(
"last_result"));
2830 BEAST_EXPECT(txj2.isMember(jss::tx));
2831 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
2834 for (
int i = 0; i != 9; ++i)
2839 jv[jss::expand] =
false;
2840 jv[jss::binary] =
false;
2842 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2844 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2846 auto const& txj = jrr[jss::queue_data][0u];
2847 BEAST_EXPECT(txj[jss::account] == alice.human());
2848 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2849 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2850 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2851 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2852 BEAST_EXPECT(txj.isMember(jss::tx));
2853 BEAST_EXPECT(txj[jss::tx] != txid0);
2854 return txj[jss::tx].asString();
2859 jv[jss::full] =
true;
2861 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2862 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2864 auto const& txj = jrr[jss::queue_data][0u];
2865 BEAST_EXPECT(txj[jss::account] == alice.human());
2866 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2867 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2868 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2869 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2870 BEAST_EXPECT(txj.isMember(jss::tx));
2871 auto const& tx = txj[jss::tx];
2872 BEAST_EXPECT(tx[jss::Account] == alice.human());
2873 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2874 BEAST_EXPECT(tx[jss::hash] == txid2);
2881 testcase(
"Ledger Request, Accounts Hashes");
2882 using namespace test::jtx;
2891 jvParams[jss::ledger_index] = 3u;
2892 jvParams[jss::accounts] =
true;
2893 jvParams[jss::expand] =
true;
2894 jvParams[jss::type] =
"hashes";
2896 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2897 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2898 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2899 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2901 jrr[jss::ledger][jss::accountState][0u][
"LedgerEntryType"] ==
2903 index = jrr[jss::ledger][jss::accountState][0u][
"index"].asString();
2907 jvParams[jss::ledger_index] = 3u;
2908 jvParams[jss::accounts] =
true;
2909 jvParams[jss::expand] =
false;
2910 jvParams[jss::type] =
"hashes";
2912 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2913 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2914 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2915 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2916 BEAST_EXPECT(jrr[jss::ledger][jss::accountState][0u] == index);
2923 testcase(
"Invalid Oracle Ledger Entry");
2929 env.
fund(XRP(1'000), owner);
2930 Oracle oracle(env, {.owner = owner});
2933 auto res = Oracle::ledgerEntry(env, owner, NoneTag);
2934 BEAST_EXPECT(res[jss::error].asString() ==
"invalidParams");
2938 auto const res = Oracle::ledgerEntry(env, owner, v);
2939 BEAST_EXPECT(res[jss::error].asString() ==
"malformedDocumentID");
2942 res = Oracle::ledgerEntry(env, owner, std::nullopt);
2943 BEAST_EXPECT(res[jss::error].asString() ==
"malformedRequest");
2946 res = Oracle::ledgerEntry(env, std::nullopt, 1);
2947 BEAST_EXPECT(res[jss::error].asString() ==
"malformedRequest");
2951 malfAccount.
replace(10, 1, 1,
'!');
2952 res = Oracle::ledgerEntry(env, malfAccount, 1);
2953 BEAST_EXPECT(res[jss::error].asString() ==
"malformedAddress");
2966 for (
int i = 0; i < 10; ++i)
2969 env.
fund(XRP(1'000), owner);
2971 Oracle oracle(env, {.owner = owner, .documentID = i});
2975 Oracle oracle1(env, {.owner = owner, .documentID = i + 10});
2977 oracles.
push_back(oracle1.documentID());
2979 for (
int i = 0; i < accounts.
size(); ++i)
2981 auto const jv = [&]() {
2984 return Oracle::ledgerEntry(env, accounts[i], oracles[i]);
2986 return Oracle::ledgerEntry(
2992 jv[jss::node][jss::Owner] ==
to_string(accounts[i]));
3004 testcase(
"ledger_entry Request MPT");
3005 using namespace test::jtx;
3006 using namespace std::literals::chrono_literals;
3011 MPTTester mptAlice(env, alice, {.holders = {bob}});
3018 mptAlice.authorize({.account = bob, .holderCount = 1});
3023 "00000193B9DDCAF401B5B3B26875986043F82CD0D13B4315";
3027 jvParams[jss::mpt_issuance] =
strHex(mptAlice.issuanceID());
3028 jvParams[jss::ledger_hash] = ledgerHash;
3030 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3032 jrr[jss::node][sfMPTokenMetadata.jsonName] ==
3035 jrr[jss::node][jss::mpt_issuance_id] ==
3036 strHex(mptAlice.issuanceID()));
3041 jvParams[jss::mpt_issuance] = badMptID;
3042 jvParams[jss::ledger_hash] = ledgerHash;
3044 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3051 jvParams[jss::mptoken][jss::account] = bob.
human();
3052 jvParams[jss::mptoken][jss::mpt_issuance_id] =
3053 strHex(mptAlice.issuanceID());
3054 jvParams[jss::ledger_hash] = ledgerHash;
3056 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3058 jrr[jss::node][sfMPTokenIssuanceID.jsonName] ==
3059 strHex(mptAlice.issuanceID()));
3065 jvParams[jss::mptoken][jss::account] = bob.
human();
3066 jvParams[jss::mptoken][jss::mpt_issuance_id] = badMptID;
3067 jvParams[jss::ledger_hash] = ledgerHash;
3069 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3077 testcase(
"ledger_entry command-line");
3078 using namespace test::jtx;
3082 env.fund(XRP(10000), alice);
3085 auto const checkId =
keylet::check(env.master, env.seq(env.master));
3087 env(check::create(env.master, alice, XRP(100)));
3094 env.rpc(
"ledger_entry",
to_string(checkId.key))[jss::result];
3096 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
3097 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
3104 testcase(
"ledger_entry PermissionedDomain");
3106 using namespace test::jtx;
3108 Env env(*
this, supported_amendments() | featurePermissionedDomains);
3109 Account const issuer{
"issuer"};
3113 env.
fund(XRP(5000), issuer, alice, bob);
3116 auto const seq = env.
seq(alice);
3117 env(pdomain::setTx(alice, {{alice,
"first credential"}}));
3119 auto const objects = pdomain::getObjects(alice, env);
3120 if (!BEAST_EXPECT(objects.size() == 1))
3126 params[jss::ledger_index] = jss::validated;
3127 params[jss::permissioned_domain][jss::account] = alice.human();
3128 params[jss::permissioned_domain][jss::seq] =
seq;
3129 auto jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3131 jv.isObject() && jv.isMember(jss::result) &&
3132 !jv[jss::result].isMember(jss::error) &&
3133 jv[jss::result].isMember(jss::node) &&
3134 jv[jss::result][jss::node].isMember(
3135 sfLedgerEntryType.jsonName) &&
3136 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
3137 jss::PermissionedDomain);
3139 std::string const pdIdx = jv[jss::result][jss::index].asString();
3144 params[jss::ledger_index] = jss::validated;
3145 params[jss::permissioned_domain] = pdIdx;
3146 jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3148 jv.isObject() && jv.isMember(jss::result) &&
3149 !jv[jss::result].isMember(jss::error) &&
3150 jv[jss::result].isMember(jss::node) &&
3151 jv[jss::result][jss::node].isMember(
3152 sfLedgerEntryType.jsonName) &&
3153 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
3154 jss::PermissionedDomain);
3160 params[jss::ledger_index] = jss::validated;
3161 params[jss::permissioned_domain] =
3162 "12F1F1F1F180D67377B2FAB292A31C922470326268D2B9B74CD1E582645B9A"
3164 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3171 params[jss::ledger_index] = jss::validated;
3172 params[jss::permissioned_domain] =
"NotAHexString";
3173 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3180 params[jss::ledger_index] = jss::validated;
3181 params[jss::permissioned_domain] = 10;
3182 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3189 params[jss::ledger_index] = jss::validated;
3190 params[jss::permissioned_domain][jss::account] = 1;
3191 params[jss::permissioned_domain][jss::seq] =
seq;
3192 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3199 params[jss::ledger_index] = jss::validated;
3200 params[jss::permissioned_domain][jss::account] =
"";
3201 params[jss::permissioned_domain][jss::seq] =
seq;
3202 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3209 params[jss::ledger_index] = jss::validated;
3210 params[jss::permissioned_domain][jss::account] = alice.human();
3211 params[jss::permissioned_domain][jss::seq] =
"12g";
3212 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3255BEAST_DEFINE_TESTSUITE(LedgerRPC, app,
ripple);
3256BEAST_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.