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>
26#include <xrpld/app/misc/TxQ.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/jss.h>
45 if (BEAST_EXPECT(jv.
isMember(jss::status)))
46 BEAST_EXPECT(jv[jss::status] ==
"error");
47 if (BEAST_EXPECT(jv.
isMember(jss::error)))
48 BEAST_EXPECT(jv[jss::error] == err);
53 jv[jss::error_message] ==
"");
55 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
56 BEAST_EXPECT(jv[jss::error_message] == msg);
63 using namespace test::jtx;
66 Env scEnv(*
this, envconfig(),
features);
77 jvParams[jss::bridge] =
jvb;
79 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
81 BEAST_EXPECT(jrr.
isMember(jss::node));
82 auto r = jrr[jss::node];
85 BEAST_EXPECT(r.isMember(jss::Account));
88 BEAST_EXPECT(r.isMember(jss::Flags));
90 BEAST_EXPECT(r.isMember(sfLedgerEntryType.jsonName));
91 BEAST_EXPECT(r[sfLedgerEntryType.jsonName] == jss::Bridge);
94 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
95 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 0);
98 BEAST_EXPECT(r.isMember(sfXChainAccountClaimCount.jsonName));
99 BEAST_EXPECT(r[sfXChainAccountClaimCount.jsonName].asInt() == 0);
101 BEAST_EXPECT(r.isMember(jss::index));
102 bridge_index = r[jss::index].asString();
108 jvParams[jss::index] = bridge_index;
110 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
112 BEAST_EXPECT(jrr.
isMember(jss::node));
113 BEAST_EXPECT(jrr[jss::node] == mcBridge);
119 jvParams[jss::bridge_account] = Account::master.human();
120 jvParams[jss::bridge] =
jvb;
121 jvParams[jss::ledger_hash] = ledgerHash;
123 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
138 jvParams[jss::bridge] =
jvb;
141 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
143 BEAST_EXPECT(jrr.
isMember(jss::node));
144 auto r = jrr[jss::node];
147 BEAST_EXPECT(r.isMember(sfXChainClaimID.jsonName));
148 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
155 testcase(
"ledger_entry: xchain_claim_id");
156 using namespace test::jtx;
159 Env scEnv(*
this, envconfig(),
features);
173 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
177 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
179 BEAST_EXPECT(jrr.
isMember(jss::node));
180 auto r = jrr[jss::node];
183 BEAST_EXPECT(r.isMember(jss::Account));
186 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
187 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 1);
188 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
195 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
198 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
200 BEAST_EXPECT(jrr.
isMember(jss::node));
201 auto r = jrr[jss::node];
204 BEAST_EXPECT(r.isMember(jss::Account));
205 BEAST_EXPECT(r[jss::Account] ==
scBob.
human());
207 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
208 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
209 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
216 testcase(
"ledger_entry: xchain_create_account_claim_id");
217 using namespace test::jtx;
220 Env scEnv(*
this, envconfig(),
features);
228 auto const amt = XRP(1000);
229 mcEnv(sidechain_xchain_account_create(
235 size_t constexpr num_attest = 3;
236 auto attestations = create_account_attestations(
247 UT_XCHAIN_DEFAULT_NUM_SIGNERS);
248 for (
size_t i = 0; i < num_attest; ++i)
250 scEnv(attestations[i]);
257 jvParams[jss::xchain_owned_create_account_claim_id] =
259 jvParams[jss::xchain_owned_create_account_claim_id]
260 [jss::xchain_owned_create_account_claim_id] = 1;
263 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
266 BEAST_EXPECT(jrr.
isMember(jss::node));
267 auto r = jrr[jss::node];
269 BEAST_EXPECT(r.isMember(jss::Account));
270 BEAST_EXPECT(r[jss::Account] == Account::master.human());
272 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
273 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 1);
276 r.isMember(sfXChainCreateAccountAttestations.jsonName));
277 auto attest = r[sfXChainCreateAccountAttestations.jsonName];
278 BEAST_EXPECT(attest.isArray());
279 BEAST_EXPECT(attest.size() == 3);
281 sfXChainCreateAccountProofSig.jsonName));
283 for (
size_t i = 0; i < num_attest; ++i)
286 [sfXChainCreateAccountProofSig.jsonName];
288 a[i].isMember(jss::Amount) &&
291 a[i].isMember(jss::Destination) &&
294 a[i].isMember(sfAttestationSignerAccount.jsonName) &&
297 return a[i][sfAttestationSignerAccount.jsonName] ==
301 a[i].isMember(sfAttestationRewardAccount.jsonName) &&
305 [&](Account
const& account) {
306 return a[i][sfAttestationRewardAccount.jsonName] ==
310 a[i].isMember(sfWasLockingChainSend.jsonName) &&
311 a[i][sfWasLockingChainSend.jsonName] == 1);
313 a[i].isMember(sfSignatureReward.jsonName) &&
314 a[i][sfSignatureReward.jsonName].
asInt() ==
321 for (
size_t i = num_attest; i < UT_XCHAIN_DEFAULT_NUM_SIGNERS; ++i)
323 scEnv(attestations[i]);
329 jvParams[jss::xchain_owned_create_account_claim_id] =
331 jvParams[jss::xchain_owned_create_account_claim_id]
332 [jss::xchain_owned_create_account_claim_id] = 1;
335 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
358 if (BEAST_EXPECT(jv.
isMember(jss::status)))
359 BEAST_EXPECT(jv[jss::status] ==
"error");
360 if (BEAST_EXPECT(jv.
isMember(jss::error)))
361 BEAST_EXPECT(jv[jss::error] == err);
366 jv[jss::error_message] ==
"");
368 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
369 BEAST_EXPECT(jv[jss::error_message] == msg);
386 using namespace test::jtx;
391 BEAST_EXPECT(env.current()->info().seq == 4);
396 jvParams[jss::ledger_index] = 1;
398 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
399 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
400 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
405 jvParams[jss::ledger_index] =
"1";
407 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
408 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
true);
409 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"1");
414 auto const jrr = env.rpc(
"ledger",
"current")[jss::result];
415 BEAST_EXPECT(jrr[jss::ledger][jss::closed] ==
false);
417 jrr[jss::ledger][jss::ledger_index] ==
420 jrr[jss::ledger_current_index] == env.current()->info().seq);
428 using namespace test::jtx;
430 Account
const gw{
"gateway"};
431 auto const USD = gw[
"USD"];
432 Account
const bob{
"bob"};
434 env.fund(XRP(10000), gw, bob);
436 env.trust(USD(1000), bob);
442 jvParams[jss::ledger_index] =
"potato";
444 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
451 jvParams[jss::ledger_index] = -1;
453 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
460 jvParams[jss::ledger_index] = 10u;
462 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
468 auto const jrr = env.rpc(
"ledger",
"arbitrary_text")[jss::result];
475 jvParams[jss::ledger_index] =
"validated";
476 jvParams[jss::queue] =
true;
478 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
485 env.rpc(
"json",
"ledger",
"{ \"ledger_index\" : 2e15 }");
487 BEAST_EXPECT(ret[jss::error_message] ==
"Invalid parameters.");
492 auto const ret = env.rpc(
493 "json",
"ledger",
"{ \"ledger_index\" : 1000000000000000 }");
500 jvParams[jss::ledger_index] =
"validated";
501 jvParams[jss::index] =
502 "00000000000000000000000000000000000000000000000000000000000000"
504 auto const jrr = env.rpc(
505 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
514 using namespace test::jtx;
519 BEAST_EXPECT(env.current()->info().seq == 4);
522 auto const jrr = env.rpc(
"ledger_current")[jss::result];
524 jrr[jss::ledger_current_index] == env.current()->info().seq);
531 testcase(
"Missing ledger_entry ledger_hash");
532 using namespace test::jtx;
534 Account
const alice{
"alice"};
535 env.fund(XRP(10000), alice);
539 jvParams[jss::account_root] = alice.human();
540 jvParams[jss::ledger_hash] =
541 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
543 env.rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
550 testcase(
"Ledger Request, Full Option");
551 using namespace test::jtx;
558 jvParams[jss::ledger_index] = 3u;
559 jvParams[jss::full] =
true;
561 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
562 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
563 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
564 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 3u);
570 testcase(
"Ledger Request, Full Option Without Admin");
571 using namespace test::jtx;
573 Env env{*
this, envconfig(no_admin)};
578 jvParams[jss::ledger_index] = 1u;
579 jvParams[jss::full] =
true;
581 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
583 jrr,
"noPermission",
"You don't have permission for this command.");
589 testcase(
"Ledger Request, Accounts Option");
590 using namespace test::jtx;
597 jvParams[jss::ledger_index] = 3u;
598 jvParams[jss::accounts] =
true;
600 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
601 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
602 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
603 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 3u);
609 testcase(
"ledger_entry Request AccountRoot");
610 using namespace test::jtx;
612 Account
const alice{
"alice"};
613 env.fund(XRP(10000), alice);
619 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
620 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
621 BEAST_EXPECT(jrr[jss::ledger_index] == 3);
628 jvParams[jss::account_root] = alice.human();
629 jvParams[jss::ledger_hash] = ledgerHash;
631 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
632 BEAST_EXPECT(jrr.
isMember(jss::node));
633 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
634 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
635 accountRootIndex = jrr[jss::index].
asString();
638 constexpr char alicesAcctRootBinary[]{
639 "1100612200800000240000000425000000032D00000000559CE54C3B934E4"
640 "73A995B477E92EC229F99CED5B62BF4D2ACE4DC42719103AE2F6240000002"
641 "540BE4008114AE123A8556F3CF91154711376AFB0F894F832B3D"};
645 jvParams[jss::account_root] = alice.human();
646 jvParams[jss::binary] = 1;
647 jvParams[jss::ledger_hash] = ledgerHash;
649 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
650 BEAST_EXPECT(jrr.
isMember(jss::node_binary));
651 BEAST_EXPECT(jrr[jss::node_binary] == alicesAcctRootBinary);
656 jvParams[jss::index] = accountRootIndex;
658 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
659 BEAST_EXPECT(!jrr.
isMember(jss::node_binary));
660 BEAST_EXPECT(jrr.
isMember(jss::node));
661 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
662 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
667 jvParams[jss::index] = accountRootIndex;
668 jvParams[jss::binary] = 0;
670 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
671 BEAST_EXPECT(jrr.
isMember(jss::node));
672 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
673 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
679 jvParams[jss::ledger_hash] = ledgerHash;
681 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
687 jvParams[jss::account_root] = Account(
"bob").human();
688 jvParams[jss::ledger_hash] = ledgerHash;
690 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
698 testcase(
"ledger_entry Request Check");
699 using namespace test::jtx;
701 Account
const alice{
"alice"};
702 env.fund(XRP(10000), alice);
705 auto const checkId =
keylet::check(env.master, env.seq(env.master));
707 env(check::create(env.master, alice, XRP(100)));
714 jvParams[jss::check] =
to_string(checkId.key);
715 jvParams[jss::ledger_hash] = ledgerHash;
717 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
719 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
720 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
728 jvParams[jss::account_root] = alice.human();
730 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
731 accountRootIndex = jrr[jss::index].
asString();
734 jvParams[jss::check] = accountRootIndex;
735 jvParams[jss::ledger_hash] = ledgerHash;
737 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
745 testcase(
"ledger_entry credentials");
747 using namespace test::jtx;
750 Account
const issuer{
"issuer"};
751 Account
const alice{
"alice"};
752 Account
const bob{
"bob"};
753 const char credType[] =
"abcde";
755 env.fund(XRP(5000), issuer, alice, bob);
759 env(credentials::create(alice, issuer, credType));
764 auto jv = credentials::ledgerEntry(env, alice, issuer, credType);
766 jv.isObject() && jv.isMember(jss::result) &&
767 !jv[jss::result].isMember(jss::error) &&
768 jv[jss::result].isMember(jss::node) &&
769 jv[jss::result][jss::node].isMember(
770 sfLedgerEntryType.jsonName) &&
771 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
774 std::string const credIdx = jv[jss::result][jss::index].asString();
776 jv = credentials::ledgerEntry(env, credIdx);
778 jv.isObject() && jv.isMember(jss::result) &&
779 !jv[jss::result].isMember(jss::error) &&
780 jv[jss::result].isMember(jss::node) &&
781 jv[jss::result][jss::node].isMember(
782 sfLedgerEntryType.jsonName) &&
783 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
789 auto const jv = credentials::ledgerEntry(env,
"");
795 auto const jv = credentials::ledgerEntry(
797 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
805 jv[jss::ledger_index] = jss::validated;
806 jv[jss::credential][jss::subject] = 42;
807 jv[jss::credential][jss::issuer] = issuer.human();
808 jv[jss::credential][jss::credential_type] =
810 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
817 jv[jss::ledger_index] = jss::validated;
818 jv[jss::credential][jss::subject] = alice.human();
819 jv[jss::credential][jss::issuer] = 42;
820 jv[jss::credential][jss::credential_type] =
822 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
829 jv[jss::ledger_index] = jss::validated;
830 jv[jss::credential][jss::subject] = alice.human();
831 jv[jss::credential][jss::issuer] = issuer.human();
832 jv[jss::credential][jss::credential_type] = 42;
833 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
840 jv[jss::ledger_index] = jss::validated;
841 jv[jss::credential][jss::subject] =
"";
842 jv[jss::credential][jss::issuer] = issuer.human();
843 jv[jss::credential][jss::credential_type] =
845 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
852 jv[jss::ledger_index] = jss::validated;
853 jv[jss::credential][jss::subject] = alice.human();
854 jv[jss::credential][jss::issuer] =
"";
855 jv[jss::credential][jss::credential_type] =
857 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
864 jv[jss::ledger_index] = jss::validated;
865 jv[jss::credential][jss::subject] = alice.human();
866 jv[jss::credential][jss::issuer] = issuer.human();
867 jv[jss::credential][jss::credential_type] =
"";
868 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
875 jv[jss::ledger_index] = jss::validated;
876 jv[jss::credential][jss::issuer] = issuer.human();
877 jv[jss::credential][jss::credential_type] =
879 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
886 jv[jss::ledger_index] = jss::validated;
887 jv[jss::credential][jss::subject] = alice.human();
888 jv[jss::credential][jss::credential_type] =
890 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
897 jv[jss::ledger_index] = jss::validated;
898 jv[jss::credential][jss::subject] = alice.human();
899 jv[jss::credential][jss::issuer] = issuer.human();
900 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
907 jv[jss::ledger_index] = jss::validated;
908 jv[jss::credential][jss::subject] =
"wehsdbvasbdfvj";
909 jv[jss::credential][jss::issuer] = issuer.human();
910 jv[jss::credential][jss::credential_type] =
912 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
919 jv[jss::ledger_index] = jss::validated;
920 jv[jss::credential][jss::subject] = alice.human();
921 jv[jss::credential][jss::issuer] =
"c4p93ugndfbsiu";
922 jv[jss::credential][jss::credential_type] =
924 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
931 jv[jss::ledger_index] = jss::validated;
932 jv[jss::credential][jss::subject] = alice.human();
933 jv[jss::credential][jss::issuer] = issuer.human();
934 jv[jss::credential][jss::credential_type] =
"12KK";
935 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
943 testcase(
"ledger_entry Deposit Preauth");
945 using namespace test::jtx;
948 Account
const alice{
"alice"};
949 Account
const becky{
"becky"};
951 env.fund(XRP(10000), alice, becky);
954 env(deposit::auth(alice, becky));
962 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
963 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
964 jvParams[jss::ledger_hash] = ledgerHash;
966 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
969 jrr[jss::node][sfLedgerEntryType.jsonName] ==
970 jss::DepositPreauth);
971 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
972 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
973 depositPreauthIndex = jrr[jss::node][jss::index].
asString();
978 jvParams[jss::deposit_preauth] = depositPreauthIndex;
979 jvParams[jss::ledger_hash] = ledgerHash;
981 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
984 jrr[jss::node][sfLedgerEntryType.jsonName] ==
985 jss::DepositPreauth);
986 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
987 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
992 jvParams[jss::deposit_preauth] = -5;
993 jvParams[jss::ledger_hash] = ledgerHash;
995 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1001 jvParams[jss::deposit_preauth] =
"0123456789ABCDEFG";
1002 jvParams[jss::ledger_hash] = ledgerHash;
1004 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1010 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1011 jvParams[jss::ledger_hash] = ledgerHash;
1013 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1019 jvParams[jss::deposit_preauth][jss::owner] = 7;
1020 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1021 jvParams[jss::ledger_hash] = ledgerHash;
1023 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1029 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1030 jvParams[jss::ledger_hash] = ledgerHash;
1032 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1038 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1039 jvParams[jss::deposit_preauth][jss::authorized] = 47;
1040 jvParams[jss::ledger_hash] = ledgerHash;
1042 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1048 jvParams[jss::deposit_preauth][jss::owner] =
1049 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
1051 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1052 jvParams[jss::ledger_hash] = ledgerHash;
1054 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1060 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1061 jvParams[jss::deposit_preauth][jss::authorized] =
1062 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
1064 jvParams[jss::ledger_hash] = ledgerHash;
1066 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1074 testcase(
"ledger_entry Deposit Preauth with credentials");
1076 using namespace test::jtx;
1079 Account
const issuer{
"issuer"};
1080 Account
const alice{
"alice"};
1081 Account
const bob{
"bob"};
1082 const char credType[] =
"abcde";
1084 env.fund(XRP(5000), issuer, alice, bob);
1091 env(deposit::authCredentials(bob, {{issuer, credType}}));
1098 jvParams[jss::ledger_index] = jss::validated;
1099 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1101 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1104 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1107 jo[jss::issuer] = issuer.human();
1109 arr.append(std::move(jo));
1111 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1114 jrr.isObject() && jrr.isMember(jss::result) &&
1115 !jrr[jss::result].isMember(jss::error) &&
1116 jrr[jss::result].isMember(jss::node) &&
1117 jrr[jss::result][jss::node].isMember(
1118 sfLedgerEntryType.jsonName) &&
1119 jrr[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
1120 jss::DepositPreauth);
1126 jvParams[jss::ledger_index] = jss::validated;
1127 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1129 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1132 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1137 arr.append(std::move(jo));
1139 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1141 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1147 jvParams[jss::ledger_index] = jss::validated;
1148 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1150 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1153 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1156 jo[jss::issuer] = issuer.human();
1159 arr.append(std::move(jo));
1161 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1163 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1169 jvParams[jss::ledger_index] = jss::validated;
1170 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1172 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1175 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1178 jo[jss::issuer] = issuer.human();
1179 jo[jss::credential_type] =
"";
1180 arr.
append(std::move(jo));
1183 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1185 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1191 jvParams[jss::ledger_index] = jss::validated;
1192 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1193 jvParams[jss::deposit_preauth][jss::authorized] = alice.human();
1195 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1198 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1201 jo[jss::issuer] = issuer.human();
1203 arr.append(std::move(jo));
1206 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1213 jvParams[jss::ledger_index] = jss::validated;
1214 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1215 jvParams[jss::deposit_preauth][jss::authorized_credentials] = 42;
1218 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1225 jvParams[jss::ledger_index] = jss::validated;
1226 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1227 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1230 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1231 arr.append(
"foobar");
1234 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1236 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1242 jvParams[jss::ledger_index] = jss::validated;
1243 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1244 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1247 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1250 arr.
append(std::move(payload));
1253 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1255 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1261 jvParams[jss::ledger_index] = jss::validated;
1262 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1263 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1267 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1269 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1286 sizeof(credTypes) /
sizeof(credTypes[0]) >
1290 jvParams[jss::ledger_index] = jss::validated;
1291 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1292 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1296 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1298 for (
unsigned i = 0; i <
sizeof(credTypes) /
sizeof(credTypes[0]);
1302 jo[jss::issuer] = issuer.human();
1303 jo[jss::credential_type] =
1305 arr.append(std::move(jo));
1309 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1311 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1317 jvParams[jss::ledger_index] = jss::validated;
1318 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1320 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1323 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1327 arr.append(std::move(jo));
1330 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1332 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1338 jvParams[jss::ledger_index] = jss::validated;
1339 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1341 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1344 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1347 jo[jss::issuer] = 42;
1349 arr.append(std::move(jo));
1352 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1354 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1360 jvParams[jss::ledger_index] = jss::validated;
1361 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1363 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1366 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1371 jo[jss::issuer] = std::move(payload);
1373 arr.append(std::move(jo));
1376 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1378 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1384 jvParams[jss::ledger_index] = jss::validated;
1385 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1387 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1390 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1393 jo[jss::issuer] =
"invalid_account";
1395 arr.append(std::move(jo));
1398 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1400 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1406 jvParams[jss::ledger_index] = jss::validated;
1407 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1409 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1412 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1415 jo[jss::issuer] = issuer.human();
1416 arr.
append(std::move(jo));
1419 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1421 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1427 jvParams[jss::ledger_index] = jss::validated;
1428 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1430 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1433 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1436 jo[jss::issuer] = issuer.human();
1437 jo[jss::credential_type] = 42;
1438 arr.
append(std::move(jo));
1441 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1443 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1449 jvParams[jss::ledger_index] = jss::validated;
1450 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1452 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1455 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1458 jo[jss::issuer] = issuer.human();
1461 jo[jss::credential_type] = std::move(payload);
1462 arr.append(std::move(jo));
1465 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1467 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1473 jvParams[jss::ledger_index] = jss::validated;
1474 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1476 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1479 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1482 jo[jss::issuer] = issuer.human();
1483 jo[jss::credential_type] =
"12KK";
1484 arr.
append(std::move(jo));
1487 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1489 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1496 testcase(
"ledger_entry Request Directory");
1497 using namespace test::jtx;
1499 Account
const alice{
"alice"};
1500 Account
const gw{
"gateway"};
1501 auto const USD = gw[
"USD"];
1502 env.fund(XRP(10000), alice, gw);
1505 env.trust(USD(1000), alice);
1510 for (
int d = 1'000'032; d >= 1'000'000; --d)
1512 env(offer(alice, USD(1), drops(d)));
1519 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
1520 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
1521 BEAST_EXPECT(jrr[jss::ledger_index] == 5);
1525 "A33EC6BB85FB5674074C4A3A43373BB17645308F3EAE1933E3E35252162B217D";
1529 jvParams[jss::directory] = dirRootIndex;
1530 jvParams[jss::ledger_hash] = ledgerHash;
1532 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1533 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 32);
1539 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1541 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1542 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1548 jvParams[jss::directory][jss::owner] = alice.human();
1549 jvParams[jss::ledger_hash] = ledgerHash;
1551 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1552 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1558 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1559 jvParams[jss::directory][jss::sub_index] = 1;
1561 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1562 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1563 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1569 jvParams[jss::directory][jss::owner] = alice.human();
1570 jvParams[jss::directory][jss::sub_index] = 1;
1571 jvParams[jss::ledger_hash] = ledgerHash;
1573 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1574 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1575 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1581 jvParams[jss::ledger_hash] = ledgerHash;
1583 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1590 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1591 jvParams[jss::directory][jss::sub_index] = 1.5;
1592 jvParams[jss::ledger_hash] = ledgerHash;
1594 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1603 jvParams[jss::directory][jss::owner] = badAddress;
1604 jvParams[jss::ledger_hash] = ledgerHash;
1606 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1613 jvParams[jss::directory][jss::owner] = alice.human();
1614 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1615 jvParams[jss::ledger_hash] = ledgerHash;
1617 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1624 jvParams[jss::directory][jss::sub_index] = 1;
1625 jvParams[jss::ledger_hash] = ledgerHash;
1627 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1635 testcase(
"ledger_entry Request Escrow");
1636 using namespace test::jtx;
1638 Account
const alice{
"alice"};
1639 env.fund(XRP(10000), alice);
1648 jv[jss::TransactionType] = jss::EscrowCreate;
1650 jv[jss::Account] = account.human();
1651 jv[jss::Destination] = to.human();
1653 jv[sfFinishAfter.jsonName] =
1654 cancelAfter.time_since_epoch().count() + 2;
1658 using namespace std::chrono_literals;
1659 env(escrowCreate(alice, alice, XRP(333), env.now() + 2s));
1668 jvParams[jss::escrow][jss::owner] = alice.human();
1669 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1671 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1673 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1674 escrowIndex = jrr[jss::index].
asString();
1679 jvParams[jss::escrow] = escrowIndex;
1680 jvParams[jss::ledger_hash] = ledgerHash;
1682 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1684 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1692 jvParams[jss::escrow][jss::owner] = badAddress;
1693 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1694 jvParams[jss::ledger_hash] = ledgerHash;
1696 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1703 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1704 jvParams[jss::ledger_hash] = ledgerHash;
1706 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1713 jvParams[jss::escrow][jss::owner] = alice.human();
1714 jvParams[jss::ledger_hash] = ledgerHash;
1716 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1723 jvParams[jss::escrow][jss::owner] = alice.human();
1724 jvParams[jss::escrow][jss::seq] =
1726 jvParams[jss::ledger_hash] = ledgerHash;
1728 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1736 testcase(
"ledger_entry Request Offer");
1737 using namespace test::jtx;
1739 Account
const alice{
"alice"};
1740 Account
const gw{
"gateway"};
1741 auto const USD = gw[
"USD"];
1742 env.fund(XRP(10000), alice, gw);
1745 env(offer(alice, USD(321), XRP(322)));
1754 jvParams[jss::offer][jss::account] = alice.human();
1755 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1756 jvParams[jss::ledger_hash] = ledgerHash;
1758 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1759 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1760 offerIndex = jrr[jss::index].
asString();
1765 jvParams[jss::offer] = offerIndex;
1767 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1768 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1776 jvParams[jss::offer][jss::account] = badAddress;
1777 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1778 jvParams[jss::ledger_hash] = ledgerHash;
1780 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1787 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1788 jvParams[jss::ledger_hash] = ledgerHash;
1790 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1797 jvParams[jss::offer][jss::account] = alice.human();
1798 jvParams[jss::ledger_hash] = ledgerHash;
1800 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1807 jvParams[jss::offer][jss::account] = alice.human();
1808 jvParams[jss::offer][jss::seq] =
std::to_string(env.seq(alice) - 1);
1809 jvParams[jss::ledger_hash] = ledgerHash;
1811 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1819 testcase(
"ledger_entry Request Pay Chan");
1820 using namespace test::jtx;
1821 using namespace std::literals::chrono_literals;
1823 Account
const alice{
"alice"};
1825 env.fund(XRP(10000), alice);
1835 jv[jss::TransactionType] = jss::PaymentChannelCreate;
1836 jv[jss::Account] = account.human();
1837 jv[jss::Destination] = to.human();
1839 jv[sfSettleDelay.jsonName] = settleDelay.count();
1840 jv[sfPublicKey.jsonName] =
strHex(pk.slice());
1844 env(payChanCreate(alice, env.master, XRP(57), 18s, alice.pk()));
1854 jvParams[jss::payment_channel] =
to_string(payChanIndex);
1855 jvParams[jss::ledger_hash] = ledgerHash;
1857 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1858 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"57000000");
1859 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"0");
1860 BEAST_EXPECT(jrr[jss::node][sfSettleDelay.jsonName] == 18);
1865 jvParams[jss::payment_channel] = ledgerHash;
1866 jvParams[jss::ledger_hash] = ledgerHash;
1868 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1876 testcase(
"ledger_entry Request RippleState");
1877 using namespace test::jtx;
1879 Account
const alice{
"alice"};
1880 Account
const gw{
"gateway"};
1881 auto const USD = gw[
"USD"];
1882 env.fund(XRP(10000), alice, gw);
1885 env.trust(USD(999), alice);
1888 env(pay(gw, alice, USD(97)));
1892 for (
auto const& fieldName : {jss::ripple_state, jss::state})
1900 jvParams[fieldName][jss::accounts][0u] = alice.human();
1901 jvParams[fieldName][jss::accounts][1u] = gw.human();
1902 jvParams[fieldName][jss::currency] =
"USD";
1903 jvParams[jss::ledger_hash] = ledgerHash;
1905 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1907 jrr[jss::node][sfBalance.jsonName][jss::value] ==
"-97");
1909 jrr[jss::node][sfHighLimit.jsonName][jss::value] ==
"999");
1914 jvParams[fieldName] =
"ripple_state";
1915 jvParams[jss::ledger_hash] = ledgerHash;
1917 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1925 jvParams[fieldName][jss::accounts][0u] = alice.human();
1926 jvParams[fieldName][jss::accounts][1u] = gw.human();
1927 jvParams[jss::ledger_hash] = ledgerHash;
1929 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1936 jvParams[fieldName][jss::accounts] = 2;
1937 jvParams[fieldName][jss::currency] =
"USD";
1938 jvParams[jss::ledger_hash] = ledgerHash;
1940 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1948 jvParams[fieldName][jss::accounts][0u] = alice.human();
1949 jvParams[fieldName][jss::currency] =
"USD";
1950 jvParams[jss::ledger_hash] = ledgerHash;
1952 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1960 jvParams[fieldName][jss::accounts][0u] = alice.human();
1961 jvParams[fieldName][jss::accounts][1u] = gw.human();
1962 jvParams[fieldName][jss::accounts][2u] = alice.human();
1963 jvParams[fieldName][jss::currency] =
"USD";
1964 jvParams[jss::ledger_hash] = ledgerHash;
1966 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1974 jvParams[fieldName][jss::accounts][0u] = 44;
1975 jvParams[fieldName][jss::accounts][1u] = gw.human();
1976 jvParams[fieldName][jss::currency] =
"USD";
1977 jvParams[jss::ledger_hash] = ledgerHash;
1979 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1987 jvParams[fieldName][jss::accounts][0u] = alice.human();
1988 jvParams[fieldName][jss::accounts][1u] = 21;
1989 jvParams[fieldName][jss::currency] =
"USD";
1990 jvParams[jss::ledger_hash] = ledgerHash;
1992 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2000 jvParams[fieldName][jss::accounts][0u] = alice.human();
2001 jvParams[fieldName][jss::accounts][1u] = alice.human();
2002 jvParams[fieldName][jss::currency] =
"USD";
2003 jvParams[jss::ledger_hash] = ledgerHash;
2005 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2013 jvParams[fieldName][jss::accounts][0u] =
2015 jvParams[fieldName][jss::accounts][1u] = gw.human();
2016 jvParams[fieldName][jss::currency] =
"USD";
2017 jvParams[jss::ledger_hash] = ledgerHash;
2019 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2027 jvParams[fieldName][jss::accounts][0u] = alice.human();
2028 jvParams[fieldName][jss::accounts][1u] =
2030 jvParams[fieldName][jss::currency] =
"USD";
2031 jvParams[jss::ledger_hash] = ledgerHash;
2033 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2041 jvParams[fieldName][jss::accounts][0u] = alice.human();
2042 jvParams[fieldName][jss::accounts][1u] = gw.human();
2043 jvParams[fieldName][jss::currency] =
"USDollars";
2044 jvParams[jss::ledger_hash] = ledgerHash;
2046 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2055 testcase(
"ledger_entry Request Ticket");
2056 using namespace test::jtx;
2062 env(ticket::create(env.master, 2));
2072 jvParams[jss::ticket] =
2074 jvParams[jss::ledger_hash] = ledgerHash;
2076 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2083 jvParams[jss::ledger_hash] = ledgerHash;
2085 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2087 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Ticket);
2088 BEAST_EXPECT(jrr[jss::node][sfTicketSequence.jsonName] == tkt1);
2094 jvParams[jss::ticket][jss::account] = env.master.human();
2095 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 1;
2096 jvParams[jss::ledger_hash] = ledgerHash;
2098 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2100 jrr[jss::node][jss::index] ==
2107 jvParams[jss::ticket][jss::account] = env.master.human();
2108 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 2;
2109 jvParams[jss::ledger_hash] = ledgerHash;
2111 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2118 jvParams[jss::ledger_hash] = ledgerHash;
2120 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2129 jvParams[jss::ticket][jss::account] = badAddress;
2130 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
2131 jvParams[jss::ledger_hash] = ledgerHash;
2133 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2140 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
2141 jvParams[jss::ledger_hash] = ledgerHash;
2143 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2150 jvParams[jss::ticket][jss::account] = env.master.human();
2151 jvParams[jss::ledger_hash] = ledgerHash;
2153 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2160 jvParams[jss::ticket][jss::account] = env.master.human();
2161 jvParams[jss::ticket][jss::ticket_seq] =
2163 jvParams[jss::ledger_hash] = ledgerHash;
2165 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2173 testcase(
"ledger_entry Request DID");
2174 using namespace test::jtx;
2175 using namespace std::literals::chrono_literals;
2177 Account
const alice{
"alice"};
2179 env.fund(XRP(10000), alice);
2185 jv[jss::TransactionType] = jss::DIDSet;
2186 jv[jss::Account] = account.human();
2192 env(didCreate(alice));
2200 jvParams[jss::did] = alice.human();
2201 jvParams[jss::ledger_hash] = ledgerHash;
2203 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2205 jrr[jss::node][sfDIDDocument.jsonName] ==
2213 jvParams[jss::did] = env.master.human();
2214 jvParams[jss::ledger_hash] = ledgerHash;
2216 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2225 "ledger_entry Request With Invalid Parameters v" +
2227 using namespace test::jtx;
2234 params[jss::api_version] = apiVersion;
2240 auto const jvParams =
2242 jvParams[jss::features] = ledgerHash;
2243 jvParams[jss::ledger_hash] = ledgerHash;
2246 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2248 if (apiVersion < 2u)
2255 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2256 obj[jss::ledger_index] =
"validated";
2261 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2262 arr[1u] =
"validated";
2268 for (
auto const& field :
2269 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
2271 auto const jvParams =
2272 makeParams([&field, &injectArray](
Json::Value& jvParams) {
2273 jvParams[field] = injectArray;
2277 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2279 if (apiVersion < 2u)
2285 for (
auto const& field :
2286 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
2288 auto const jvParams =
2289 makeParams([&field, &injectObject](
Json::Value& jvParams) {
2290 jvParams[field] = injectObject;
2294 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2299 for (
auto const& inject : {injectObject, injectArray})
2302 for (
auto const& field :
2306 jss::payment_channel})
2308 auto const jvParams =
2309 makeParams([&field, &inject](
Json::Value& jvParams) {
2310 jvParams[field] = inject;
2314 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2316 if (apiVersion < 2u)
2322 for (
auto const& field : {jss::dir_root, jss::owner})
2324 auto const jvParams =
2325 makeParams([&field, &inject](
Json::Value& jvParams) {
2326 jvParams[jss::directory][field] = inject;
2330 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2332 if (apiVersion < 2u)
2339 auto const jvParams =
2341 jvParams[jss::escrow][jss::owner] = inject;
2342 jvParams[jss::escrow][jss::seq] = 99;
2346 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2348 if (apiVersion < 2u)
2355 auto const jvParams =
2357 jvParams[jss::offer][jss::account] = inject;
2358 jvParams[jss::offer][jss::seq] = 99;
2362 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2364 if (apiVersion < 2u)
2371 auto const jvParams =
2374 rs[jss::currency] =
"FOO";
2376 rs[jss::accounts][0u] =
2377 "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2378 rs[jss::accounts][1u] =
2379 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
2380 rs[jss::currency] = inject;
2381 jvParams[jss::ripple_state] = std::move(rs);
2385 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2387 if (apiVersion < 2u)
2394 auto const jvParams =
2396 jvParams[jss::ticket][jss::account] = inject;
2397 jvParams[jss::ticket][jss::ticket_seq] = 99;
2401 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2403 if (apiVersion < 2u)
2410 for (
auto const& field : {jss::nft_page, jss::deposit_preauth})
2412 auto const jvParams =
2413 makeParams([&field, &inject](
Json::Value& jvParams) {
2414 jvParams[field] = inject;
2418 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2424 for (
auto const& field : {jss::owner, jss::authorized})
2426 auto const jvParams =
2427 makeParams([&field, &inject](
Json::Value& jvParams) {
2429 pa[jss::owner] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2430 pa[jss::authorized] =
2431 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
2433 jvParams[jss::deposit_preauth] = std::move(pa);
2437 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2452 using namespace test::jtx;
2455 env.fund(XRP(10000),
"alice");
2457 env.fund(XRP(10000),
"bob");
2459 env.fund(XRP(10000),
"jim");
2461 env.fund(XRP(10000),
"jill");
2466 jvParams[jss::ledger] =
"closed";
2470 boost::lexical_cast<std::string>(jvParams))[jss::result];
2471 BEAST_EXPECT(jrr.isMember(jss::ledger));
2472 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2473 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2475 jvParams[jss::ledger] =
"validated";
2479 boost::lexical_cast<std::string>(jvParams))[jss::result];
2480 BEAST_EXPECT(jrr.isMember(jss::ledger));
2481 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2482 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2484 jvParams[jss::ledger] =
"current";
2488 boost::lexical_cast<std::string>(jvParams))[jss::result];
2489 BEAST_EXPECT(jrr.isMember(jss::ledger));
2490 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
2493 jvParams[jss::ledger] =
"invalid";
2497 boost::lexical_cast<std::string>(jvParams))[jss::result];
2498 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2499 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
2502 jvParams[jss::ledger] = 4;
2506 boost::lexical_cast<std::string>(jvParams))[jss::result];
2507 BEAST_EXPECT(jrr.isMember(jss::ledger));
2508 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2509 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
2512 jvParams[jss::ledger] = 20;
2516 boost::lexical_cast<std::string>(jvParams))[jss::result];
2517 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2518 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2523 "E86DE7F3D7A4D9CE17EF7C8BA08A8F4D"
2524 "8F643B9552F0D895A31CDA78F541DE4E"};
2527 jvParams[jss::ledger_hash] = hash3;
2531 boost::lexical_cast<std::string>(jvParams))[jss::result];
2532 BEAST_EXPECT(jrr.isMember(jss::ledger));
2533 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2534 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
2537 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
2541 boost::lexical_cast<std::string>(jvParams))[jss::result];
2542 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2543 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
2546 jvParams[jss::ledger_hash] = 2;
2550 boost::lexical_cast<std::string>(jvParams))[jss::result];
2551 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2552 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashNotString");
2555 jvParams[jss::ledger_hash] =
2556 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
2557 "7F2775F2F7485BB37307984C3C0F2340";
2561 boost::lexical_cast<std::string>(jvParams))[jss::result];
2562 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2563 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
2566 jvParams[jss::ledger_hash] =
2567 "8C3EEDB3124D92E49E75D81A8826A2E6"
2568 "5A75FD71FC3FD6F36FEB803C5F1D812D";
2572 boost::lexical_cast<std::string>(jvParams))[jss::result];
2573 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2574 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2580 jvParams[jss::ledger_index] =
"closed";
2584 boost::lexical_cast<std::string>(jvParams))[jss::result];
2585 BEAST_EXPECT(jrr.isMember(jss::ledger));
2586 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2587 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2588 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
2590 jvParams[jss::ledger_index] =
"validated";
2594 boost::lexical_cast<std::string>(jvParams))[jss::result];
2595 BEAST_EXPECT(jrr.isMember(jss::ledger));
2596 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2597 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2599 jvParams[jss::ledger_index] =
"current";
2603 boost::lexical_cast<std::string>(jvParams))[jss::result];
2604 BEAST_EXPECT(jrr.isMember(jss::ledger));
2605 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
2606 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
2609 jvParams[jss::ledger_index] =
"invalid";
2613 boost::lexical_cast<std::string>(jvParams))[jss::result];
2614 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2615 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
2618 for (
auto i : {1, 2, 3, 4, 5, 6})
2620 jvParams[jss::ledger_index] = i;
2624 boost::lexical_cast<std::string>(jvParams))[jss::result];
2625 BEAST_EXPECT(jrr.isMember(jss::ledger));
2627 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2633 jvParams[jss::ledger_index] = 7;
2637 boost::lexical_cast<std::string>(jvParams))[jss::result];
2638 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2639 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2646 testcase(
"Ledger with queueing disabled");
2647 using namespace test::jtx;
2651 jv[jss::ledger_index] =
"current";
2652 jv[jss::queue] =
true;
2653 jv[jss::expand] =
true;
2655 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2656 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2662 testcase(
"Ledger with Queued Transactions");
2663 using namespace test::jtx;
2665 auto& section = cfg->section(
"transaction_queue");
2666 section.set(
"minimum_txn_in_ledger_standalone",
"3");
2667 section.set(
"normal_consensus_increase_percent",
"0");
2672 jv[jss::ledger_index] =
"current";
2673 jv[jss::queue] =
true;
2674 jv[jss::expand] =
true;
2676 Account
const alice{
"alice"};
2677 Account
const bob{
"bob"};
2678 Account
const charlie{
"charlie"};
2679 Account
const daria{
"daria"};
2680 env.fund(XRP(10000), alice);
2681 env.fund(XRP(10000), bob);
2683 env.fund(XRP(10000), charlie);
2684 env.fund(XRP(10000), daria);
2687 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2688 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2693 auto metrics = env.app().getTxQ().getMetrics(*env.current());
2694 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
2699 BEAST_EXPECT(env.current()->info().seq == 5);
2702 auto aliceSeq = env.seq(alice);
2703 env(pay(alice,
"george", XRP(1000)),
2704 json(R
"({"LastLedgerSequence":7})"),
2706 env(offer(alice, XRP(50000), alice["USD"](5000)),
2709 env(noop(alice), seq(aliceSeq + 2), ter(
terQUEUED));
2711 auto batch = [&env](Account a) {
2712 auto aSeq = env.seq(a);
2714 for (
int i = 0; i < 10; ++i)
2716 env(noop(a), fee(1000 + i), seq(aSeq + i), ter(
terQUEUED));
2725 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2726 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
2732 BEAST_EXPECT(env.current()->info().seq == 8);
2734 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2735 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
2739 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2741 auto const& parentHash = env.current()->info().parentHash;
2742 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2745 auto const& txj = jrr[jss::queue_data][1u];
2746 BEAST_EXPECT(txj[jss::account] == alice.human());
2747 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2748 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2749 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2750 BEAST_EXPECT(txj.isMember(jss::tx));
2751 auto const& tx = txj[jss::tx];
2752 BEAST_EXPECT(tx[jss::Account] == alice.human());
2753 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2754 return tx[jss::hash].asString();
2757 auto const& txj = jrr[jss::queue_data][0u];
2758 BEAST_EXPECT(txj[jss::account] == alice.human());
2759 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2760 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2761 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2762 BEAST_EXPECT(txj.isMember(jss::tx));
2763 auto const& tx = txj[jss::tx];
2764 BEAST_EXPECT(tx[jss::Account] == alice.human());
2765 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
2766 const auto txid0 = tx[jss::hash].asString();
2770 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2778 jv[jss::expand] =
false;
2780 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2781 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2783 auto const& parentHash = env.current()->info().parentHash;
2784 auto const txid1 = [&]() {
2785 auto const& txj = jrr[jss::queue_data][1u];
2786 BEAST_EXPECT(txj[jss::account] == alice.human());
2787 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2788 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2789 BEAST_EXPECT(txj.isMember(jss::tx));
2790 return txj[jss::tx].asString();
2792 auto const& txj = jrr[jss::queue_data][0u];
2793 BEAST_EXPECT(txj[jss::account] == alice.human());
2794 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2795 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2796 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
2797 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2798 BEAST_EXPECT(txj.isMember(jss::tx));
2799 BEAST_EXPECT(txj[jss::tx] == txid0);
2803 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2808 jv[jss::expand] =
true;
2809 jv[jss::binary] =
true;
2811 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2812 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2814 auto const& txj = jrr[jss::queue_data][1u];
2815 BEAST_EXPECT(txj[jss::account] == alice.human());
2816 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2817 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2818 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
2819 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2820 BEAST_EXPECT(txj.isMember(jss::tx));
2821 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
2823 auto const& txj2 = jrr[jss::queue_data][0u];
2824 BEAST_EXPECT(txj2[jss::account] == alice.human());
2825 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
2826 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
2827 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
2828 BEAST_EXPECT(!txj2.isMember(
"last_result"));
2829 BEAST_EXPECT(txj2.isMember(jss::tx));
2830 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
2833 for (
int i = 0; i != 9; ++i)
2838 jv[jss::expand] =
false;
2839 jv[jss::binary] =
false;
2841 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2843 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2845 auto const& txj = jrr[jss::queue_data][0u];
2846 BEAST_EXPECT(txj[jss::account] == alice.human());
2847 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2848 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2849 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2850 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2851 BEAST_EXPECT(txj.isMember(jss::tx));
2852 BEAST_EXPECT(txj[jss::tx] != txid0);
2853 return txj[jss::tx].asString();
2858 jv[jss::full] =
true;
2860 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2861 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2863 auto const& txj = jrr[jss::queue_data][0u];
2864 BEAST_EXPECT(txj[jss::account] == alice.human());
2865 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2866 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2867 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2868 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2869 BEAST_EXPECT(txj.isMember(jss::tx));
2870 auto const& tx = txj[jss::tx];
2871 BEAST_EXPECT(tx[jss::Account] == alice.human());
2872 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2873 BEAST_EXPECT(tx[jss::hash] == txid2);
2880 testcase(
"Ledger Request, Accounts Hashes");
2881 using namespace test::jtx;
2890 jvParams[jss::ledger_index] = 3u;
2891 jvParams[jss::accounts] =
true;
2892 jvParams[jss::expand] =
true;
2893 jvParams[jss::type] =
"hashes";
2895 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2896 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2897 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2898 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2900 jrr[jss::ledger][jss::accountState][0u][
"LedgerEntryType"] ==
2902 index = jrr[jss::ledger][jss::accountState][0u][
"index"].asString();
2906 jvParams[jss::ledger_index] = 3u;
2907 jvParams[jss::accounts] =
true;
2908 jvParams[jss::expand] =
false;
2909 jvParams[jss::type] =
"hashes";
2911 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2912 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2913 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2914 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2915 BEAST_EXPECT(jrr[jss::ledger][jss::accountState][0u] == index);
2922 testcase(
"Invalid Oracle Ledger Entry");
2928 env.
fund(XRP(1'000), owner);
2929 Oracle oracle(env, {.owner = owner});
2932 auto res = Oracle::ledgerEntry(env, owner, NoneTag);
2933 BEAST_EXPECT(res[jss::error].asString() ==
"invalidParams");
2937 auto const res = Oracle::ledgerEntry(env, owner, v);
2938 BEAST_EXPECT(res[jss::error].asString() ==
"malformedDocumentID");
2941 res = Oracle::ledgerEntry(env, owner, std::nullopt);
2942 BEAST_EXPECT(res[jss::error].asString() ==
"malformedRequest");
2945 res = Oracle::ledgerEntry(env, std::nullopt, 1);
2946 BEAST_EXPECT(res[jss::error].asString() ==
"malformedRequest");
2950 malfAccount.
replace(10, 1, 1,
'!');
2951 res = Oracle::ledgerEntry(env, malfAccount, 1);
2952 BEAST_EXPECT(res[jss::error].asString() ==
"malformedAddress");
2965 for (
int i = 0; i < 10; ++i)
2968 env.
fund(XRP(1'000), owner);
2970 Oracle oracle(env, {.owner = owner, .documentID = i});
2974 Oracle oracle1(env, {.owner = owner, .documentID = i + 10});
2976 oracles.
push_back(oracle1.documentID());
2978 for (
int i = 0; i < accounts.
size(); ++i)
2980 auto const jv = [&]() {
2983 return Oracle::ledgerEntry(env, accounts[i], oracles[i]);
2985 return Oracle::ledgerEntry(
2991 jv[jss::node][jss::Owner] ==
to_string(accounts[i]));
3003 testcase(
"ledger_entry Request MPT");
3004 using namespace test::jtx;
3005 using namespace std::literals::chrono_literals;
3010 MPTTester mptAlice(env, alice, {.holders = {bob}});
3017 mptAlice.authorize({.account = bob, .holderCount = 1});
3022 "00000193B9DDCAF401B5B3B26875986043F82CD0D13B4315";
3026 jvParams[jss::mpt_issuance] =
strHex(mptAlice.issuanceID());
3027 jvParams[jss::ledger_hash] = ledgerHash;
3029 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3031 jrr[jss::node][sfMPTokenMetadata.jsonName] ==
3034 jrr[jss::node][jss::mpt_issuance_id] ==
3035 strHex(mptAlice.issuanceID()));
3040 jvParams[jss::mpt_issuance] = badMptID;
3041 jvParams[jss::ledger_hash] = ledgerHash;
3043 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3050 jvParams[jss::mptoken][jss::account] = bob.
human();
3051 jvParams[jss::mptoken][jss::mpt_issuance_id] =
3052 strHex(mptAlice.issuanceID());
3053 jvParams[jss::ledger_hash] = ledgerHash;
3055 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3057 jrr[jss::node][sfMPTokenIssuanceID.jsonName] ==
3058 strHex(mptAlice.issuanceID()));
3064 jvParams[jss::mptoken][jss::account] = bob.
human();
3065 jvParams[jss::mptoken][jss::mpt_issuance_id] = badMptID;
3066 jvParams[jss::ledger_hash] = ledgerHash;
3068 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3076 testcase(
"ledger_entry command-line");
3077 using namespace test::jtx;
3081 env.fund(XRP(10000), alice);
3084 auto const checkId =
keylet::check(env.master, env.seq(env.master));
3086 env(check::create(env.master, alice, XRP(100)));
3093 env.rpc(
"ledger_entry",
to_string(checkId.key))[jss::result];
3095 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
3096 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
3103 testcase(
"ledger_entry PermissionedDomain");
3105 using namespace test::jtx;
3107 Env env(*
this, supported_amendments() | featurePermissionedDomains);
3108 Account const issuer{
"issuer"};
3112 env.
fund(XRP(5000), issuer, alice, bob);
3115 auto const seq = env.
seq(alice);
3116 env(pdomain::setTx(alice, {{alice,
"first credential"}}));
3118 auto const objects = pdomain::getObjects(alice, env);
3119 if (!BEAST_EXPECT(objects.size() == 1))
3125 params[jss::ledger_index] = jss::validated;
3126 params[jss::permissioned_domain][jss::account] = alice.human();
3127 params[jss::permissioned_domain][jss::seq] =
seq;
3128 auto jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3130 jv.isObject() && jv.isMember(jss::result) &&
3131 !jv[jss::result].isMember(jss::error) &&
3132 jv[jss::result].isMember(jss::node) &&
3133 jv[jss::result][jss::node].isMember(
3134 sfLedgerEntryType.jsonName) &&
3135 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
3136 jss::PermissionedDomain);
3138 std::string const pdIdx = jv[jss::result][jss::index].asString();
3143 params[jss::ledger_index] = jss::validated;
3144 params[jss::permissioned_domain] = pdIdx;
3145 jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3147 jv.isObject() && jv.isMember(jss::result) &&
3148 !jv[jss::result].isMember(jss::error) &&
3149 jv[jss::result].isMember(jss::node) &&
3150 jv[jss::result][jss::node].isMember(
3151 sfLedgerEntryType.jsonName) &&
3152 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
3153 jss::PermissionedDomain);
3159 params[jss::ledger_index] = jss::validated;
3160 params[jss::permissioned_domain] =
3161 "12F1F1F1F180D67377B2FAB292A31C922470326268D2B9B74CD1E582645B9A"
3163 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3170 params[jss::ledger_index] = jss::validated;
3171 params[jss::permissioned_domain] =
"NotAHexString";
3172 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3179 params[jss::ledger_index] = jss::validated;
3180 params[jss::permissioned_domain] = 10;
3181 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3188 params[jss::ledger_index] = jss::validated;
3189 params[jss::permissioned_domain][jss::account] = 1;
3190 params[jss::permissioned_domain][jss::seq] =
seq;
3191 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3198 params[jss::ledger_index] = jss::validated;
3199 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] =
"";
3211 params[jss::permissioned_domain][jss::seq] =
seq;
3212 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3219 params[jss::ledger_index] = jss::validated;
3220 params[jss::permissioned_domain][jss::account] = alice.human();
3221 params[jss::permissioned_domain][jss::seq] =
"12g";
3222 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3265BEAST_DEFINE_TESTSUITE(LedgerRPC, app,
ripple);
3266BEAST_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.