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 auto cfg = envconfig();
613 cfg->FEES.reference_fee = 10;
614 Env env{*
this, std::move(cfg)};
615 Account
const alice{
"alice"};
616 env.fund(XRP(10000), alice);
622 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
623 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
624 BEAST_EXPECT(jrr[jss::ledger_index] == 3);
631 jvParams[jss::account_root] = alice.human();
632 jvParams[jss::ledger_hash] = ledgerHash;
634 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
635 BEAST_EXPECT(jrr.
isMember(jss::node));
636 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
637 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
638 accountRootIndex = jrr[jss::index].
asString();
641 constexpr char alicesAcctRootBinary[]{
642 "1100612200800000240000000425000000032D00000000559CE54C3B934E4"
643 "73A995B477E92EC229F99CED5B62BF4D2ACE4DC42719103AE2F6240000002"
644 "540BE4008114AE123A8556F3CF91154711376AFB0F894F832B3D"};
648 jvParams[jss::account_root] = alice.human();
649 jvParams[jss::binary] = 1;
650 jvParams[jss::ledger_hash] = ledgerHash;
652 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
653 BEAST_EXPECT(jrr.
isMember(jss::node_binary));
654 BEAST_EXPECT(jrr[jss::node_binary] == alicesAcctRootBinary);
659 jvParams[jss::index] = accountRootIndex;
661 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
662 BEAST_EXPECT(!jrr.
isMember(jss::node_binary));
663 BEAST_EXPECT(jrr.
isMember(jss::node));
664 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
665 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
670 jvParams[jss::index] = accountRootIndex;
671 jvParams[jss::binary] = 0;
673 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
674 BEAST_EXPECT(jrr.
isMember(jss::node));
675 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
676 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
682 jvParams[jss::ledger_hash] = ledgerHash;
684 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
690 jvParams[jss::account_root] = Account(
"bob").human();
691 jvParams[jss::ledger_hash] = ledgerHash;
693 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
701 testcase(
"ledger_entry Request Check");
702 using namespace test::jtx;
704 Account
const alice{
"alice"};
705 env.fund(XRP(10000), alice);
708 auto const checkId =
keylet::check(env.master, env.seq(env.master));
710 env(check::create(env.master, alice, XRP(100)));
717 jvParams[jss::check] =
to_string(checkId.key);
718 jvParams[jss::ledger_hash] = ledgerHash;
720 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
722 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
723 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
731 jvParams[jss::account_root] = alice.human();
733 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
734 accountRootIndex = jrr[jss::index].
asString();
737 jvParams[jss::check] = accountRootIndex;
738 jvParams[jss::ledger_hash] = ledgerHash;
740 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
748 testcase(
"ledger_entry credentials");
750 using namespace test::jtx;
753 Account
const issuer{
"issuer"};
754 Account
const alice{
"alice"};
755 Account
const bob{
"bob"};
756 const char credType[] =
"abcde";
758 env.fund(XRP(5000), issuer, alice, bob);
762 env(credentials::create(alice, issuer, credType));
767 auto jv = credentials::ledgerEntry(env, alice, issuer, credType);
769 jv.isObject() && jv.isMember(jss::result) &&
770 !jv[jss::result].isMember(jss::error) &&
771 jv[jss::result].isMember(jss::node) &&
772 jv[jss::result][jss::node].isMember(
773 sfLedgerEntryType.jsonName) &&
774 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
777 std::string const credIdx = jv[jss::result][jss::index].asString();
779 jv = credentials::ledgerEntry(env, credIdx);
781 jv.isObject() && jv.isMember(jss::result) &&
782 !jv[jss::result].isMember(jss::error) &&
783 jv[jss::result].isMember(jss::node) &&
784 jv[jss::result][jss::node].isMember(
785 sfLedgerEntryType.jsonName) &&
786 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
792 auto const jv = credentials::ledgerEntry(env,
"");
798 auto const jv = credentials::ledgerEntry(
800 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
808 jv[jss::ledger_index] = jss::validated;
809 jv[jss::credential][jss::subject] = 42;
810 jv[jss::credential][jss::issuer] = issuer.human();
811 jv[jss::credential][jss::credential_type] =
813 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
820 jv[jss::ledger_index] = jss::validated;
821 jv[jss::credential][jss::subject] = alice.human();
822 jv[jss::credential][jss::issuer] = 42;
823 jv[jss::credential][jss::credential_type] =
825 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
832 jv[jss::ledger_index] = jss::validated;
833 jv[jss::credential][jss::subject] = alice.human();
834 jv[jss::credential][jss::issuer] = issuer.human();
835 jv[jss::credential][jss::credential_type] = 42;
836 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
843 jv[jss::ledger_index] = jss::validated;
844 jv[jss::credential][jss::subject] =
"";
845 jv[jss::credential][jss::issuer] = issuer.human();
846 jv[jss::credential][jss::credential_type] =
848 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
855 jv[jss::ledger_index] = jss::validated;
856 jv[jss::credential][jss::subject] = alice.human();
857 jv[jss::credential][jss::issuer] =
"";
858 jv[jss::credential][jss::credential_type] =
860 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
867 jv[jss::ledger_index] = jss::validated;
868 jv[jss::credential][jss::subject] = alice.human();
869 jv[jss::credential][jss::issuer] = issuer.human();
870 jv[jss::credential][jss::credential_type] =
"";
871 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
878 jv[jss::ledger_index] = jss::validated;
879 jv[jss::credential][jss::issuer] = issuer.human();
880 jv[jss::credential][jss::credential_type] =
882 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
889 jv[jss::ledger_index] = jss::validated;
890 jv[jss::credential][jss::subject] = alice.human();
891 jv[jss::credential][jss::credential_type] =
893 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
900 jv[jss::ledger_index] = jss::validated;
901 jv[jss::credential][jss::subject] = alice.human();
902 jv[jss::credential][jss::issuer] = issuer.human();
903 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
910 jv[jss::ledger_index] = jss::validated;
911 jv[jss::credential][jss::subject] =
"wehsdbvasbdfvj";
912 jv[jss::credential][jss::issuer] = issuer.human();
913 jv[jss::credential][jss::credential_type] =
915 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
922 jv[jss::ledger_index] = jss::validated;
923 jv[jss::credential][jss::subject] = alice.human();
924 jv[jss::credential][jss::issuer] =
"c4p93ugndfbsiu";
925 jv[jss::credential][jss::credential_type] =
927 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
934 jv[jss::ledger_index] = jss::validated;
935 jv[jss::credential][jss::subject] = alice.human();
936 jv[jss::credential][jss::issuer] = issuer.human();
937 jv[jss::credential][jss::credential_type] =
"12KK";
938 auto const jrr = env.rpc(
"json",
"ledger_entry",
to_string(jv));
946 testcase(
"ledger_entry Deposit Preauth");
948 using namespace test::jtx;
951 Account
const alice{
"alice"};
952 Account
const becky{
"becky"};
954 env.fund(XRP(10000), alice, becky);
957 env(deposit::auth(alice, becky));
965 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
966 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
967 jvParams[jss::ledger_hash] = ledgerHash;
969 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
972 jrr[jss::node][sfLedgerEntryType.jsonName] ==
973 jss::DepositPreauth);
974 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
975 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
976 depositPreauthIndex = jrr[jss::node][jss::index].
asString();
981 jvParams[jss::deposit_preauth] = depositPreauthIndex;
982 jvParams[jss::ledger_hash] = ledgerHash;
984 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
987 jrr[jss::node][sfLedgerEntryType.jsonName] ==
988 jss::DepositPreauth);
989 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
990 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
995 jvParams[jss::deposit_preauth] = -5;
996 jvParams[jss::ledger_hash] = ledgerHash;
998 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1004 jvParams[jss::deposit_preauth] =
"0123456789ABCDEFG";
1005 jvParams[jss::ledger_hash] = ledgerHash;
1007 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1013 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1014 jvParams[jss::ledger_hash] = ledgerHash;
1016 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1022 jvParams[jss::deposit_preauth][jss::owner] = 7;
1023 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1024 jvParams[jss::ledger_hash] = ledgerHash;
1026 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1032 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1033 jvParams[jss::ledger_hash] = ledgerHash;
1035 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1041 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1042 jvParams[jss::deposit_preauth][jss::authorized] = 47;
1043 jvParams[jss::ledger_hash] = ledgerHash;
1045 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1051 jvParams[jss::deposit_preauth][jss::owner] =
1052 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
1054 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
1055 jvParams[jss::ledger_hash] = ledgerHash;
1057 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1063 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
1064 jvParams[jss::deposit_preauth][jss::authorized] =
1065 "rP6P9ypfAmc!pw8SZHNwM4nvZHFXDraQas";
1067 jvParams[jss::ledger_hash] = ledgerHash;
1069 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1077 testcase(
"ledger_entry Deposit Preauth with credentials");
1079 using namespace test::jtx;
1082 Account
const issuer{
"issuer"};
1083 Account
const alice{
"alice"};
1084 Account
const bob{
"bob"};
1085 const char credType[] =
"abcde";
1087 env.fund(XRP(5000), issuer, alice, bob);
1094 env(deposit::authCredentials(bob, {{issuer, credType}}));
1101 jvParams[jss::ledger_index] = jss::validated;
1102 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1104 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1107 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1110 jo[jss::issuer] = issuer.human();
1112 arr.append(std::move(jo));
1114 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1117 jrr.isObject() && jrr.isMember(jss::result) &&
1118 !jrr[jss::result].isMember(jss::error) &&
1119 jrr[jss::result].isMember(jss::node) &&
1120 jrr[jss::result][jss::node].isMember(
1121 sfLedgerEntryType.jsonName) &&
1122 jrr[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
1123 jss::DepositPreauth);
1129 jvParams[jss::ledger_index] = jss::validated;
1130 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1132 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1135 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1140 arr.append(std::move(jo));
1142 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1144 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1150 jvParams[jss::ledger_index] = jss::validated;
1151 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1153 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1156 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1159 jo[jss::issuer] = issuer.human();
1162 arr.append(std::move(jo));
1164 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1166 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1172 jvParams[jss::ledger_index] = jss::validated;
1173 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1175 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1178 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1181 jo[jss::issuer] = issuer.human();
1182 jo[jss::credential_type] =
"";
1183 arr.
append(std::move(jo));
1186 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1188 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1194 jvParams[jss::ledger_index] = jss::validated;
1195 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1196 jvParams[jss::deposit_preauth][jss::authorized] = alice.human();
1198 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1201 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1204 jo[jss::issuer] = issuer.human();
1206 arr.append(std::move(jo));
1209 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1216 jvParams[jss::ledger_index] = jss::validated;
1217 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1218 jvParams[jss::deposit_preauth][jss::authorized_credentials] = 42;
1221 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1228 jvParams[jss::ledger_index] = jss::validated;
1229 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1230 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1233 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1234 arr.append(
"foobar");
1237 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1239 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1245 jvParams[jss::ledger_index] = jss::validated;
1246 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1247 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1250 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1253 arr.
append(std::move(payload));
1256 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1258 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1264 jvParams[jss::ledger_index] = jss::validated;
1265 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1266 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1270 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1272 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1289 sizeof(credTypes) /
sizeof(credTypes[0]) >
1293 jvParams[jss::ledger_index] = jss::validated;
1294 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1295 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1299 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1301 for (
unsigned i = 0; i <
sizeof(credTypes) /
sizeof(credTypes[0]);
1305 jo[jss::issuer] = issuer.human();
1306 jo[jss::credential_type] =
1308 arr.append(std::move(jo));
1312 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1314 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1320 jvParams[jss::ledger_index] = jss::validated;
1321 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1323 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1326 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1330 arr.append(std::move(jo));
1333 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1335 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1341 jvParams[jss::ledger_index] = jss::validated;
1342 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1344 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1347 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1350 jo[jss::issuer] = 42;
1352 arr.append(std::move(jo));
1355 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1357 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1363 jvParams[jss::ledger_index] = jss::validated;
1364 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1366 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1369 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1374 jo[jss::issuer] = std::move(payload);
1376 arr.append(std::move(jo));
1379 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1381 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1387 jvParams[jss::ledger_index] = jss::validated;
1388 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1390 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1393 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1396 jo[jss::issuer] =
"invalid_account";
1398 arr.append(std::move(jo));
1401 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1403 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1409 jvParams[jss::ledger_index] = jss::validated;
1410 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1412 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1415 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1418 jo[jss::issuer] = issuer.human();
1419 arr.
append(std::move(jo));
1422 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1424 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1430 jvParams[jss::ledger_index] = jss::validated;
1431 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1433 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1436 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1439 jo[jss::issuer] = issuer.human();
1440 jo[jss::credential_type] = 42;
1441 arr.
append(std::move(jo));
1444 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1446 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1452 jvParams[jss::ledger_index] = jss::validated;
1453 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1455 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1458 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1461 jo[jss::issuer] = issuer.human();
1464 jo[jss::credential_type] = std::move(payload);
1465 arr.append(std::move(jo));
1468 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1470 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1476 jvParams[jss::ledger_index] = jss::validated;
1477 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1479 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1482 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1485 jo[jss::issuer] = issuer.human();
1486 jo[jss::credential_type] =
"12KK";
1487 arr.
append(std::move(jo));
1490 env.rpc(
"json",
"ledger_entry",
to_string(jvParams));
1492 jrr[jss::result],
"malformedAuthorizedCredentials",
"");
1499 testcase(
"ledger_entry Request Directory");
1500 using namespace test::jtx;
1502 Account
const alice{
"alice"};
1503 Account
const gw{
"gateway"};
1504 auto const USD = gw[
"USD"];
1505 env.fund(XRP(10000), alice, gw);
1508 env.trust(USD(1000), alice);
1513 for (
int d = 1'000'032; d >= 1'000'000; --d)
1515 env(offer(alice, USD(1), drops(d)));
1522 Json::Value const jrr = env.rpc(
"ledger_closed")[jss::result];
1523 BEAST_EXPECT(jrr[jss::ledger_hash] == ledgerHash);
1524 BEAST_EXPECT(jrr[jss::ledger_index] == 5);
1528 "A33EC6BB85FB5674074C4A3A43373BB17645308F3EAE1933E3E35252162B217D";
1532 jvParams[jss::directory] = dirRootIndex;
1533 jvParams[jss::ledger_hash] = ledgerHash;
1535 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1536 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 32);
1542 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1544 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1545 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1551 jvParams[jss::directory][jss::owner] = alice.human();
1552 jvParams[jss::ledger_hash] = ledgerHash;
1554 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1555 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1561 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1562 jvParams[jss::directory][jss::sub_index] = 1;
1564 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1565 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1566 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1572 jvParams[jss::directory][jss::owner] = alice.human();
1573 jvParams[jss::directory][jss::sub_index] = 1;
1574 jvParams[jss::ledger_hash] = ledgerHash;
1576 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1577 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1578 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1584 jvParams[jss::ledger_hash] = ledgerHash;
1586 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1593 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1594 jvParams[jss::directory][jss::sub_index] = 1.5;
1595 jvParams[jss::ledger_hash] = ledgerHash;
1597 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1606 jvParams[jss::directory][jss::owner] = badAddress;
1607 jvParams[jss::ledger_hash] = ledgerHash;
1609 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1616 jvParams[jss::directory][jss::owner] = alice.human();
1617 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1618 jvParams[jss::ledger_hash] = ledgerHash;
1620 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1627 jvParams[jss::directory][jss::sub_index] = 1;
1628 jvParams[jss::ledger_hash] = ledgerHash;
1630 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1638 testcase(
"ledger_entry Request Escrow");
1639 using namespace test::jtx;
1641 Account
const alice{
"alice"};
1642 env.fund(XRP(10000), alice);
1651 jv[jss::TransactionType] = jss::EscrowCreate;
1653 jv[jss::Account] = account.human();
1654 jv[jss::Destination] = to.human();
1656 jv[sfFinishAfter.jsonName] =
1657 cancelAfter.time_since_epoch().count() + 2;
1661 using namespace std::chrono_literals;
1662 env(escrowCreate(alice, alice, XRP(333), env.now() + 2s));
1671 jvParams[jss::escrow][jss::owner] = alice.human();
1672 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1674 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1676 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1677 escrowIndex = jrr[jss::index].
asString();
1682 jvParams[jss::escrow] = escrowIndex;
1683 jvParams[jss::ledger_hash] = ledgerHash;
1685 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1687 jrr[jss::node][jss::Amount] == XRP(333).value().getText());
1695 jvParams[jss::escrow][jss::owner] = badAddress;
1696 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1697 jvParams[jss::ledger_hash] = ledgerHash;
1699 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1706 jvParams[jss::escrow][jss::seq] = env.seq(alice) - 1;
1707 jvParams[jss::ledger_hash] = ledgerHash;
1709 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1716 jvParams[jss::escrow][jss::owner] = alice.human();
1717 jvParams[jss::ledger_hash] = ledgerHash;
1719 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1726 jvParams[jss::escrow][jss::owner] = alice.human();
1727 jvParams[jss::escrow][jss::seq] =
1729 jvParams[jss::ledger_hash] = ledgerHash;
1731 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1739 testcase(
"ledger_entry Request Offer");
1740 using namespace test::jtx;
1742 Account
const alice{
"alice"};
1743 Account
const gw{
"gateway"};
1744 auto const USD = gw[
"USD"];
1745 env.fund(XRP(10000), alice, gw);
1748 env(offer(alice, USD(321), XRP(322)));
1757 jvParams[jss::offer][jss::account] = alice.human();
1758 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1759 jvParams[jss::ledger_hash] = ledgerHash;
1761 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1762 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1763 offerIndex = jrr[jss::index].
asString();
1768 jvParams[jss::offer] = offerIndex;
1770 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1771 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1779 jvParams[jss::offer][jss::account] = badAddress;
1780 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1781 jvParams[jss::ledger_hash] = ledgerHash;
1783 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1790 jvParams[jss::offer][jss::seq] = env.seq(alice) - 1;
1791 jvParams[jss::ledger_hash] = ledgerHash;
1793 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1800 jvParams[jss::offer][jss::account] = alice.human();
1801 jvParams[jss::ledger_hash] = ledgerHash;
1803 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1810 jvParams[jss::offer][jss::account] = alice.human();
1811 jvParams[jss::offer][jss::seq] =
std::to_string(env.seq(alice) - 1);
1812 jvParams[jss::ledger_hash] = ledgerHash;
1814 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1822 testcase(
"ledger_entry Request Pay Chan");
1823 using namespace test::jtx;
1824 using namespace std::literals::chrono_literals;
1826 Account
const alice{
"alice"};
1828 env.fund(XRP(10000), alice);
1838 jv[jss::TransactionType] = jss::PaymentChannelCreate;
1839 jv[jss::Account] = account.human();
1840 jv[jss::Destination] = to.human();
1842 jv[sfSettleDelay.jsonName] = settleDelay.count();
1843 jv[sfPublicKey.jsonName] =
strHex(pk.slice());
1847 env(payChanCreate(alice, env.master, XRP(57), 18s, alice.pk()));
1857 jvParams[jss::payment_channel] =
to_string(payChanIndex);
1858 jvParams[jss::ledger_hash] = ledgerHash;
1860 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1861 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"57000000");
1862 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"0");
1863 BEAST_EXPECT(jrr[jss::node][sfSettleDelay.jsonName] == 18);
1868 jvParams[jss::payment_channel] = ledgerHash;
1869 jvParams[jss::ledger_hash] = ledgerHash;
1871 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1879 testcase(
"ledger_entry Request RippleState");
1880 using namespace test::jtx;
1882 Account
const alice{
"alice"};
1883 Account
const gw{
"gateway"};
1884 auto const USD = gw[
"USD"];
1885 env.fund(XRP(10000), alice, gw);
1888 env.trust(USD(999), alice);
1891 env(pay(gw, alice, USD(97)));
1895 for (
auto const& fieldName : {jss::ripple_state, jss::state})
1903 jvParams[fieldName][jss::accounts][0u] = alice.human();
1904 jvParams[fieldName][jss::accounts][1u] = gw.human();
1905 jvParams[fieldName][jss::currency] =
"USD";
1906 jvParams[jss::ledger_hash] = ledgerHash;
1908 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1910 jrr[jss::node][sfBalance.jsonName][jss::value] ==
"-97");
1912 jrr[jss::node][sfHighLimit.jsonName][jss::value] ==
"999");
1917 jvParams[fieldName] =
"ripple_state";
1918 jvParams[jss::ledger_hash] = ledgerHash;
1920 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1928 jvParams[fieldName][jss::accounts][0u] = alice.human();
1929 jvParams[fieldName][jss::accounts][1u] = gw.human();
1930 jvParams[jss::ledger_hash] = ledgerHash;
1932 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1939 jvParams[fieldName][jss::accounts] = 2;
1940 jvParams[fieldName][jss::currency] =
"USD";
1941 jvParams[jss::ledger_hash] = ledgerHash;
1943 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1951 jvParams[fieldName][jss::accounts][0u] = alice.human();
1952 jvParams[fieldName][jss::currency] =
"USD";
1953 jvParams[jss::ledger_hash] = ledgerHash;
1955 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1963 jvParams[fieldName][jss::accounts][0u] = alice.human();
1964 jvParams[fieldName][jss::accounts][1u] = gw.human();
1965 jvParams[fieldName][jss::accounts][2u] = alice.human();
1966 jvParams[fieldName][jss::currency] =
"USD";
1967 jvParams[jss::ledger_hash] = ledgerHash;
1969 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1977 jvParams[fieldName][jss::accounts][0u] = 44;
1978 jvParams[fieldName][jss::accounts][1u] = gw.human();
1979 jvParams[fieldName][jss::currency] =
"USD";
1980 jvParams[jss::ledger_hash] = ledgerHash;
1982 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1990 jvParams[fieldName][jss::accounts][0u] = alice.human();
1991 jvParams[fieldName][jss::accounts][1u] = 21;
1992 jvParams[fieldName][jss::currency] =
"USD";
1993 jvParams[jss::ledger_hash] = ledgerHash;
1995 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2003 jvParams[fieldName][jss::accounts][0u] = alice.human();
2004 jvParams[fieldName][jss::accounts][1u] = alice.human();
2005 jvParams[fieldName][jss::currency] =
"USD";
2006 jvParams[jss::ledger_hash] = ledgerHash;
2008 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2016 jvParams[fieldName][jss::accounts][0u] =
2018 jvParams[fieldName][jss::accounts][1u] = gw.human();
2019 jvParams[fieldName][jss::currency] =
"USD";
2020 jvParams[jss::ledger_hash] = ledgerHash;
2022 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2030 jvParams[fieldName][jss::accounts][0u] = alice.human();
2031 jvParams[fieldName][jss::accounts][1u] =
2033 jvParams[fieldName][jss::currency] =
"USD";
2034 jvParams[jss::ledger_hash] = ledgerHash;
2036 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2044 jvParams[fieldName][jss::accounts][0u] = alice.human();
2045 jvParams[fieldName][jss::accounts][1u] = gw.human();
2046 jvParams[fieldName][jss::currency] =
"USDollars";
2047 jvParams[jss::ledger_hash] = ledgerHash;
2049 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2058 testcase(
"ledger_entry Request Ticket");
2059 using namespace test::jtx;
2065 env(ticket::create(env.master, 2));
2075 jvParams[jss::ticket] =
2077 jvParams[jss::ledger_hash] = ledgerHash;
2079 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2086 jvParams[jss::ledger_hash] = ledgerHash;
2088 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2090 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Ticket);
2091 BEAST_EXPECT(jrr[jss::node][sfTicketSequence.jsonName] == tkt1);
2097 jvParams[jss::ticket][jss::account] = env.master.human();
2098 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 1;
2099 jvParams[jss::ledger_hash] = ledgerHash;
2101 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2103 jrr[jss::node][jss::index] ==
2110 jvParams[jss::ticket][jss::account] = env.master.human();
2111 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 2;
2112 jvParams[jss::ledger_hash] = ledgerHash;
2114 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2121 jvParams[jss::ledger_hash] = ledgerHash;
2123 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2132 jvParams[jss::ticket][jss::account] = badAddress;
2133 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
2134 jvParams[jss::ledger_hash] = ledgerHash;
2136 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2143 jvParams[jss::ticket][jss::ticket_seq] = env.seq(env.master) - 1;
2144 jvParams[jss::ledger_hash] = ledgerHash;
2146 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2153 jvParams[jss::ticket][jss::account] = env.master.human();
2154 jvParams[jss::ledger_hash] = ledgerHash;
2156 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2163 jvParams[jss::ticket][jss::account] = env.master.human();
2164 jvParams[jss::ticket][jss::ticket_seq] =
2166 jvParams[jss::ledger_hash] = ledgerHash;
2168 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2176 testcase(
"ledger_entry Request DID");
2177 using namespace test::jtx;
2178 using namespace std::literals::chrono_literals;
2180 Account
const alice{
"alice"};
2182 env.fund(XRP(10000), alice);
2188 jv[jss::TransactionType] = jss::DIDSet;
2189 jv[jss::Account] = account.human();
2195 env(didCreate(alice));
2203 jvParams[jss::did] = alice.human();
2204 jvParams[jss::ledger_hash] = ledgerHash;
2206 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2208 jrr[jss::node][sfDIDDocument.jsonName] ==
2216 jvParams[jss::did] = env.master.human();
2217 jvParams[jss::ledger_hash] = ledgerHash;
2219 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2228 "ledger_entry Request With Invalid Parameters v" +
2230 using namespace test::jtx;
2237 params[jss::api_version] = apiVersion;
2243 auto const jvParams =
2245 jvParams[jss::features] = ledgerHash;
2246 jvParams[jss::ledger_hash] = ledgerHash;
2249 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2251 if (apiVersion < 2u)
2258 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2259 obj[jss::ledger_index] =
"validated";
2264 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2265 arr[1u] =
"validated";
2271 for (
auto const& field :
2272 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
2274 auto const jvParams =
2275 makeParams([&field, &injectArray](
Json::Value& jvParams) {
2276 jvParams[field] = injectArray;
2280 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2282 if (apiVersion < 2u)
2288 for (
auto const& field :
2289 {jss::directory, jss::escrow, jss::offer, jss::ticket, jss::amm})
2291 auto const jvParams =
2292 makeParams([&field, &injectObject](
Json::Value& jvParams) {
2293 jvParams[field] = injectObject;
2297 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2302 for (
auto const& inject : {injectObject, injectArray})
2305 for (
auto const& field :
2309 jss::payment_channel})
2311 auto const jvParams =
2312 makeParams([&field, &inject](
Json::Value& jvParams) {
2313 jvParams[field] = inject;
2317 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2319 if (apiVersion < 2u)
2325 for (
auto const& field : {jss::dir_root, jss::owner})
2327 auto const jvParams =
2328 makeParams([&field, &inject](
Json::Value& jvParams) {
2329 jvParams[jss::directory][field] = inject;
2333 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2335 if (apiVersion < 2u)
2342 auto const jvParams =
2344 jvParams[jss::escrow][jss::owner] = inject;
2345 jvParams[jss::escrow][jss::seq] = 99;
2349 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2351 if (apiVersion < 2u)
2358 auto const jvParams =
2360 jvParams[jss::offer][jss::account] = inject;
2361 jvParams[jss::offer][jss::seq] = 99;
2365 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2367 if (apiVersion < 2u)
2374 auto const jvParams =
2377 rs[jss::currency] =
"FOO";
2379 rs[jss::accounts][0u] =
2380 "rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2381 rs[jss::accounts][1u] =
2382 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
2383 rs[jss::currency] = inject;
2384 jvParams[jss::ripple_state] = std::move(rs);
2388 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2390 if (apiVersion < 2u)
2397 auto const jvParams =
2399 jvParams[jss::ticket][jss::account] = inject;
2400 jvParams[jss::ticket][jss::ticket_seq] = 99;
2404 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2406 if (apiVersion < 2u)
2413 for (
auto const& field : {jss::nft_page, jss::deposit_preauth})
2415 auto const jvParams =
2416 makeParams([&field, &inject](
Json::Value& jvParams) {
2417 jvParams[field] = inject;
2421 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2427 for (
auto const& field : {jss::owner, jss::authorized})
2429 auto const jvParams =
2430 makeParams([&field, &inject](
Json::Value& jvParams) {
2432 pa[jss::owner] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
2433 pa[jss::authorized] =
2434 "rKssEq6pg1KbqEqAFnua5mFAL6Ggpsh2wv";
2436 jvParams[jss::deposit_preauth] = std::move(pa);
2440 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2455 using namespace test::jtx;
2457 auto cfg = envconfig();
2458 cfg->FEES.reference_fee = 10;
2462 env.fund(XRP(10000),
"alice");
2464 env.fund(XRP(10000),
"bob");
2466 env.fund(XRP(10000),
"jim");
2468 env.fund(XRP(10000),
"jill");
2473 jvParams[jss::ledger] =
"closed";
2477 boost::lexical_cast<std::string>(jvParams))[jss::result];
2478 BEAST_EXPECT(jrr.isMember(jss::ledger));
2479 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2480 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2482 jvParams[jss::ledger] =
"validated";
2486 boost::lexical_cast<std::string>(jvParams))[jss::result];
2487 BEAST_EXPECT(jrr.isMember(jss::ledger));
2488 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2489 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2491 jvParams[jss::ledger] =
"current";
2495 boost::lexical_cast<std::string>(jvParams))[jss::result];
2496 BEAST_EXPECT(jrr.isMember(jss::ledger));
2497 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
2500 jvParams[jss::ledger] =
"invalid";
2504 boost::lexical_cast<std::string>(jvParams))[jss::result];
2505 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2506 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
2509 jvParams[jss::ledger] = 4;
2513 boost::lexical_cast<std::string>(jvParams))[jss::result];
2514 BEAST_EXPECT(jrr.isMember(jss::ledger));
2515 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2516 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"4");
2519 jvParams[jss::ledger] = 20;
2523 boost::lexical_cast<std::string>(jvParams))[jss::result];
2524 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2525 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2530 "E86DE7F3D7A4D9CE17EF7C8BA08A8F4D"
2531 "8F643B9552F0D895A31CDA78F541DE4E"};
2534 jvParams[jss::ledger_hash] = hash3;
2538 boost::lexical_cast<std::string>(jvParams))[jss::result];
2539 BEAST_EXPECT(jrr.isMember(jss::ledger));
2540 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2541 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"3");
2544 jvParams[jss::ledger_hash] =
"DEADBEEF" + hash3;
2548 boost::lexical_cast<std::string>(jvParams))[jss::result];
2549 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2550 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
2553 jvParams[jss::ledger_hash] = 2;
2557 boost::lexical_cast<std::string>(jvParams))[jss::result];
2558 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2559 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashNotString");
2562 jvParams[jss::ledger_hash] =
2563 "2E81FC6EC0DD943197EGC7E3FBE9AE30"
2564 "7F2775F2F7485BB37307984C3C0F2340";
2568 boost::lexical_cast<std::string>(jvParams))[jss::result];
2569 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2570 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerHashMalformed");
2573 jvParams[jss::ledger_hash] =
2574 "8C3EEDB3124D92E49E75D81A8826A2E6"
2575 "5A75FD71FC3FD6F36FEB803C5F1D812D";
2579 boost::lexical_cast<std::string>(jvParams))[jss::result];
2580 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2581 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2587 jvParams[jss::ledger_index] =
"closed";
2591 boost::lexical_cast<std::string>(jvParams))[jss::result];
2592 BEAST_EXPECT(jrr.isMember(jss::ledger));
2593 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2594 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2595 BEAST_EXPECT(jrr.isMember(jss::ledger_index));
2597 jvParams[jss::ledger_index] =
"validated";
2601 boost::lexical_cast<std::string>(jvParams))[jss::result];
2602 BEAST_EXPECT(jrr.isMember(jss::ledger));
2603 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2604 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"5");
2606 jvParams[jss::ledger_index] =
"current";
2610 boost::lexical_cast<std::string>(jvParams))[jss::result];
2611 BEAST_EXPECT(jrr.isMember(jss::ledger));
2612 BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] ==
"6");
2613 BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
2616 jvParams[jss::ledger_index] =
"invalid";
2620 boost::lexical_cast<std::string>(jvParams))[jss::result];
2621 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
2622 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerIndexMalformed");
2625 for (
auto i : {1, 2, 3, 4, 5, 6})
2627 jvParams[jss::ledger_index] = i;
2631 boost::lexical_cast<std::string>(jvParams))[jss::result];
2632 BEAST_EXPECT(jrr.isMember(jss::ledger));
2634 BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
2640 jvParams[jss::ledger_index] = 7;
2644 boost::lexical_cast<std::string>(jvParams))[jss::result];
2645 BEAST_EXPECT(jrr[jss::error] ==
"lgrNotFound");
2646 BEAST_EXPECT(jrr[jss::error_message] ==
"ledgerNotFound");
2653 testcase(
"Ledger with queueing disabled");
2654 using namespace test::jtx;
2658 jv[jss::ledger_index] =
"current";
2659 jv[jss::queue] =
true;
2660 jv[jss::expand] =
true;
2662 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2663 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2669 testcase(
"Ledger with Queued Transactions");
2670 using namespace test::jtx;
2672 auto& section = cfg->section(
"transaction_queue");
2673 section.set(
"minimum_txn_in_ledger_standalone",
"3");
2674 section.set(
"normal_consensus_increase_percent",
"0");
2678 cfg->FEES.reference_fee = 10;
2679 Env env(*
this, std::move(cfg));
2682 jv[jss::ledger_index] =
"current";
2683 jv[jss::queue] =
true;
2684 jv[jss::expand] =
true;
2686 Account
const alice{
"alice"};
2687 Account
const bob{
"bob"};
2688 Account
const charlie{
"charlie"};
2689 Account
const daria{
"daria"};
2690 env.fund(XRP(10000), alice);
2691 env.fund(XRP(10000), bob);
2693 env.fund(XRP(10000), charlie);
2694 env.fund(XRP(10000), daria);
2697 auto jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2698 BEAST_EXPECT(!jrr.isMember(jss::queue_data));
2703 auto metrics = env.app().getTxQ().getMetrics(*env.current());
2704 if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
2709 BEAST_EXPECT(env.current()->info().seq == 5);
2712 auto aliceSeq = env.seq(alice);
2713 env(pay(alice,
"george", XRP(1000)),
2714 json(R
"({"LastLedgerSequence":7})"),
2716 env(offer(alice, XRP(50000), alice["USD"](5000)),
2721 auto batch = [&env](Account a) {
2722 auto aSeq = env.seq(a);
2724 for (
int i = 0; i < 10; ++i)
2735 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2736 BEAST_EXPECT(jrr[jss::queue_data].size() == 33);
2742 BEAST_EXPECT(env.current()->info().seq == 8);
2744 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2745 BEAST_EXPECT(jrr[jss::queue_data].size() == 11);
2749 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2751 auto const& parentHash = env.current()->info().parentHash;
2752 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2755 auto const& txj = jrr[jss::queue_data][1u];
2756 BEAST_EXPECT(txj[jss::account] == alice.human());
2757 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2758 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2759 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2760 BEAST_EXPECT(txj.isMember(jss::tx));
2761 auto const& tx = txj[jss::tx];
2762 BEAST_EXPECT(tx[jss::Account] == alice.human());
2763 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2764 return tx[jss::hash].asString();
2767 auto const& txj = jrr[jss::queue_data][0u];
2768 BEAST_EXPECT(txj[jss::account] == alice.human());
2769 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2770 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2771 BEAST_EXPECT(txj[
"retries_remaining"] == 10);
2772 BEAST_EXPECT(txj.isMember(jss::tx));
2773 auto const& tx = txj[jss::tx];
2774 BEAST_EXPECT(tx[jss::Account] == alice.human());
2775 BEAST_EXPECT(tx[jss::TransactionType] == jss::OfferCreate);
2776 const auto txid0 = tx[jss::hash].asString();
2780 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2788 jv[jss::expand] =
false;
2790 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2791 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2793 auto const& parentHash = env.current()->info().parentHash;
2794 auto const txid1 = [&]() {
2795 auto const& txj = jrr[jss::queue_data][1u];
2796 BEAST_EXPECT(txj[jss::account] == alice.human());
2797 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2798 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2799 BEAST_EXPECT(txj.isMember(jss::tx));
2800 return txj[jss::tx].asString();
2802 auto const& txj = jrr[jss::queue_data][0u];
2803 BEAST_EXPECT(txj[jss::account] == alice.human());
2804 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2805 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2806 BEAST_EXPECT(txj[
"retries_remaining"] == 9);
2807 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2808 BEAST_EXPECT(txj.isMember(jss::tx));
2809 BEAST_EXPECT(txj[jss::tx] == txid0);
2813 BEAST_EXPECT((tx0 ^ parentHash) < (tx1 ^ parentHash));
2818 jv[jss::expand] =
true;
2819 jv[jss::binary] =
true;
2821 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2822 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 2))
2824 auto const& txj = jrr[jss::queue_data][1u];
2825 BEAST_EXPECT(txj[jss::account] == alice.human());
2826 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2827 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2828 BEAST_EXPECT(txj[
"retries_remaining"] == 8);
2829 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2830 BEAST_EXPECT(txj.isMember(jss::tx));
2831 BEAST_EXPECT(txj[jss::tx].isMember(jss::tx_blob));
2833 auto const& txj2 = jrr[jss::queue_data][0u];
2834 BEAST_EXPECT(txj2[jss::account] == alice.human());
2835 BEAST_EXPECT(txj2[jss::fee_level] ==
"256");
2836 BEAST_EXPECT(txj2[
"preflight_result"] ==
"tesSUCCESS");
2837 BEAST_EXPECT(txj2[
"retries_remaining"] == 10);
2838 BEAST_EXPECT(!txj2.isMember(
"last_result"));
2839 BEAST_EXPECT(txj2.isMember(jss::tx));
2840 BEAST_EXPECT(txj2[jss::tx].isMember(jss::tx_blob));
2843 for (
int i = 0; i != 9; ++i)
2848 jv[jss::expand] =
false;
2849 jv[jss::binary] =
false;
2851 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2853 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2855 auto const& txj = jrr[jss::queue_data][0u];
2856 BEAST_EXPECT(txj[jss::account] == alice.human());
2857 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2858 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2859 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2860 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2861 BEAST_EXPECT(txj.isMember(jss::tx));
2862 BEAST_EXPECT(txj[jss::tx] != txid0);
2863 return txj[jss::tx].asString();
2868 jv[jss::full] =
true;
2870 jrr = env.rpc(
"json",
"ledger",
to_string(jv))[jss::result];
2871 if (BEAST_EXPECT(jrr[jss::queue_data].size() == 1))
2873 auto const& txj = jrr[jss::queue_data][0u];
2874 BEAST_EXPECT(txj[jss::account] == alice.human());
2875 BEAST_EXPECT(txj[jss::fee_level] ==
"256");
2876 BEAST_EXPECT(txj[
"preflight_result"] ==
"tesSUCCESS");
2877 BEAST_EXPECT(txj[
"retries_remaining"] == 1);
2878 BEAST_EXPECT(txj[
"last_result"] ==
"terPRE_SEQ");
2879 BEAST_EXPECT(txj.isMember(jss::tx));
2880 auto const& tx = txj[jss::tx];
2881 BEAST_EXPECT(tx[jss::Account] == alice.human());
2882 BEAST_EXPECT(tx[jss::TransactionType] == jss::AccountSet);
2883 BEAST_EXPECT(tx[jss::hash] == txid2);
2890 testcase(
"Ledger Request, Accounts Hashes");
2891 using namespace test::jtx;
2900 jvParams[jss::ledger_index] = 3u;
2901 jvParams[jss::accounts] =
true;
2902 jvParams[jss::expand] =
true;
2903 jvParams[jss::type] =
"hashes";
2905 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2906 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2907 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2908 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2910 jrr[jss::ledger][jss::accountState][0u][
"LedgerEntryType"] ==
2912 index = jrr[jss::ledger][jss::accountState][0u][
"index"].asString();
2916 jvParams[jss::ledger_index] = 3u;
2917 jvParams[jss::accounts] =
true;
2918 jvParams[jss::expand] =
false;
2919 jvParams[jss::type] =
"hashes";
2921 env.rpc(
"json",
"ledger",
to_string(jvParams))[jss::result];
2922 BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
2923 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
2924 BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
2925 BEAST_EXPECT(jrr[jss::ledger][jss::accountState][0u] == index);
2932 testcase(
"Invalid Oracle Ledger Entry");
2938 env.
fund(XRP(1'000), owner);
2942 .fee =
static_cast<int>(env.
current()->fees().base.drops())});
2945 auto res = Oracle::ledgerEntry(env, owner, NoneTag);
2946 BEAST_EXPECT(res[jss::error].asString() ==
"invalidParams");
2950 auto const res = Oracle::ledgerEntry(env, owner, v);
2951 BEAST_EXPECT(res[jss::error].asString() ==
"malformedDocumentID");
2954 res = Oracle::ledgerEntry(env, owner, std::nullopt);
2955 BEAST_EXPECT(res[jss::error].asString() ==
"malformedRequest");
2958 res = Oracle::ledgerEntry(env, std::nullopt, 1);
2959 BEAST_EXPECT(res[jss::error].asString() ==
"malformedRequest");
2963 malfAccount.
replace(10, 1, 1,
'!');
2964 res = Oracle::ledgerEntry(env, malfAccount, 1);
2965 BEAST_EXPECT(res[jss::error].asString() ==
"malformedAddress");
2976 auto const baseFee =
2977 static_cast<int>(env.
current()->fees().base.drops());
2980 for (
int i = 0; i < 10; ++i)
2983 env.
fund(XRP(1'000), owner);
2986 env, {.owner = owner, .documentID = i, .fee = baseFee});
2991 env, {.owner = owner, .documentID = i + 10, .fee = baseFee});
2993 oracles.
push_back(oracle1.documentID());
2995 for (
int i = 0; i < accounts.
size(); ++i)
2997 auto const jv = [&]() {
3000 return Oracle::ledgerEntry(env, accounts[i], oracles[i]);
3002 return Oracle::ledgerEntry(
3008 jv[jss::node][jss::Owner] ==
to_string(accounts[i]));
3020 testcase(
"ledger_entry Request MPT");
3021 using namespace test::jtx;
3022 using namespace std::literals::chrono_literals;
3027 MPTTester mptAlice(env, alice, {.holders = {bob}});
3034 mptAlice.authorize({.account = bob, .holderCount = 1});
3039 "00000193B9DDCAF401B5B3B26875986043F82CD0D13B4315";
3043 jvParams[jss::mpt_issuance] =
strHex(mptAlice.issuanceID());
3044 jvParams[jss::ledger_hash] = ledgerHash;
3046 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3048 jrr[jss::node][sfMPTokenMetadata.jsonName] ==
3051 jrr[jss::node][jss::mpt_issuance_id] ==
3052 strHex(mptAlice.issuanceID()));
3057 jvParams[jss::mpt_issuance] = badMptID;
3058 jvParams[jss::ledger_hash] = ledgerHash;
3060 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3067 jvParams[jss::mptoken][jss::account] = bob.
human();
3068 jvParams[jss::mptoken][jss::mpt_issuance_id] =
3069 strHex(mptAlice.issuanceID());
3070 jvParams[jss::ledger_hash] = ledgerHash;
3072 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3074 jrr[jss::node][sfMPTokenIssuanceID.jsonName] ==
3075 strHex(mptAlice.issuanceID()));
3081 jvParams[jss::mptoken][jss::account] = bob.
human();
3082 jvParams[jss::mptoken][jss::mpt_issuance_id] = badMptID;
3083 jvParams[jss::ledger_hash] = ledgerHash;
3085 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3093 testcase(
"ledger_entry command-line");
3094 using namespace test::jtx;
3098 env.fund(XRP(10000), alice);
3101 auto const checkId =
keylet::check(env.master, env.seq(env.master));
3103 env(check::create(env.master, alice, XRP(100)));
3110 env.rpc(
"ledger_entry",
to_string(checkId.key))[jss::result];
3112 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
3113 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
3120 testcase(
"ledger_entry PermissionedDomain");
3122 using namespace test::jtx;
3124 Env env(*
this, supported_amendments() | featurePermissionedDomains);
3125 Account const issuer{
"issuer"};
3129 env.
fund(XRP(5000), issuer, alice, bob);
3132 auto const seq = env.
seq(alice);
3133 env(pdomain::setTx(alice, {{alice,
"first credential"}}));
3135 auto const objects = pdomain::getObjects(alice, env);
3136 if (!BEAST_EXPECT(objects.size() == 1))
3142 params[jss::ledger_index] = jss::validated;
3143 params[jss::permissioned_domain][jss::account] = alice.human();
3144 params[jss::permissioned_domain][jss::seq] =
seq;
3145 auto 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);
3155 std::string const pdIdx = jv[jss::result][jss::index].asString();
3160 params[jss::ledger_index] = jss::validated;
3161 params[jss::permissioned_domain] = pdIdx;
3162 jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3164 jv.isObject() && jv.isMember(jss::result) &&
3165 !jv[jss::result].isMember(jss::error) &&
3166 jv[jss::result].isMember(jss::node) &&
3167 jv[jss::result][jss::node].isMember(
3168 sfLedgerEntryType.jsonName) &&
3169 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
3170 jss::PermissionedDomain);
3176 params[jss::ledger_index] = jss::validated;
3177 params[jss::permissioned_domain] =
3178 "12F1F1F1F180D67377B2FAB292A31C922470326268D2B9B74CD1E582645B9A"
3180 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3187 params[jss::ledger_index] = jss::validated;
3188 params[jss::permissioned_domain] =
"NotAHexString";
3189 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3196 params[jss::ledger_index] = jss::validated;
3197 params[jss::permissioned_domain] = 10;
3198 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3205 params[jss::ledger_index] = jss::validated;
3206 params[jss::permissioned_domain][jss::account] = 1;
3207 params[jss::permissioned_domain][jss::seq] =
seq;
3208 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3215 params[jss::ledger_index] = jss::validated;
3216 params[jss::permissioned_domain][jss::account] =
3218 params[jss::permissioned_domain][jss::seq] =
seq;
3219 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3226 params[jss::ledger_index] = jss::validated;
3227 params[jss::permissioned_domain][jss::account] =
"";
3228 params[jss::permissioned_domain][jss::seq] =
seq;
3229 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3236 params[jss::ledger_index] = jss::validated;
3237 params[jss::permissioned_domain][jss::account] = alice.human();
3238 params[jss::permissioned_domain][jss::seq] =
"12g";
3239 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
3282BEAST_DEFINE_TESTSUITE(LedgerRPC, app,
ripple);
3283BEAST_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.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
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.