1#include <test/jtx/AMM.h>
2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/Oracle.h>
5#include <test/jtx/TestHelpers.h>
6#include <test/jtx/amount.h>
7#include <test/jtx/attester.h>
8#include <test/jtx/credentials.h>
9#include <test/jtx/delegate.h>
10#include <test/jtx/deposit.h>
11#include <test/jtx/envconfig.h>
12#include <test/jtx/flags.h>
13#include <test/jtx/mpt.h>
14#include <test/jtx/multisign.h>
15#include <test/jtx/offer.h>
16#include <test/jtx/pay.h>
17#include <test/jtx/permissioned_domains.h>
18#include <test/jtx/proposal.h>
19#include <test/jtx/sponsor.h>
20#include <test/jtx/ticket.h>
21#include <test/jtx/token.h>
22#include <test/jtx/txflags.h>
23#include <test/jtx/xchain_bridge.h>
25#include <xrpl/basics/Number.h>
26#include <xrpl/basics/StringUtilities.h>
27#include <xrpl/basics/base_uint.h>
28#include <xrpl/basics/chrono.h>
29#include <xrpl/basics/contract.h>
30#include <xrpl/basics/strHex.h>
31#include <xrpl/beast/unit_test/suite.h>
32#include <xrpl/beast/utility/Journal.h>
33#include <xrpl/core/ServiceRegistry.h>
34#include <xrpl/core/StartUpType.h>
35#include <xrpl/json/json_value.h>
36#include <xrpl/json/to_string.h>
37#include <xrpl/ledger/OpenView.h>
38#include <xrpl/protocol/AccountID.h>
39#include <xrpl/protocol/ApiVersion.h>
40#include <xrpl/protocol/Asset.h>
41#include <xrpl/protocol/ErrorCodes.h>
42#include <xrpl/protocol/Feature.h>
43#include <xrpl/protocol/Indexes.h>
44#include <xrpl/protocol/Keylet.h>
45#include <xrpl/protocol/Protocol.h>
46#include <xrpl/protocol/SField.h>
47#include <xrpl/protocol/STArray.h>
48#include <xrpl/protocol/STVector256.h>
49#include <xrpl/protocol/STXChainBridge.h>
50#include <xrpl/protocol/SeqProxy.h>
51#include <xrpl/protocol/TxFlags.h>
52#include <xrpl/protocol/jss.h>
61#include <source_location>
110 gMappings, [&fieldName](
auto const& pair) {
return pair.first == fieldName; });
136 return "hex string or object";
140 return "length-2 array of Accounts";
159 if (BEAST_EXPECT(jv.
isMember(jss::status)))
160 BEAST_EXPECTS(jv[jss::status] ==
"error",
std::to_string(location.line()));
161 if (BEAST_EXPECT(jv.
isMember(jss::error)))
164 jv[jss::error] == err,
165 "Expected error " + err +
", received " + jv[jss::error].asString() +
", at line " +
172 "Expected no error message, received \"" + jv[jss::error_message].asString() +
175 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
178 jv[jss::error_message] == msg,
179 "Expected error message \"" + msg +
"\", received \"" +
180 jv[jss::error_message].asString() +
"\", at line " +
190 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
191 obj[jss::ledger_index] =
"validated";
196 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
197 arr[1u] =
"validated";
211 "0123456789ABCDEFGH",
212 "rJxKV9e9p6wiPw!!!!xrJ4X1n98LosPL1sgcJW",
213 "rPSTrR5yEr11uMkfsz1kHCp9jK4aoa3Avv",
214 "n9K2isxwTxcSHJKxMkJznDoWXAUs7NNy49H9Fknz1pC7oHAH3kH9",
217 "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6B01403D"
239 static auto const& kBadAccountValues = remove({12});
240 static auto const& kBadArrayValues = remove({17, 20});
241 static auto const& kBadBlobValues = remove({3, 7, 8, 16});
242 static auto const& kBadCurrencyValues = remove({14});
243 static auto const& kBadHashValues = remove({2, 3, 7, 8, 16});
244 static auto const& kBadFixedHashValues = remove({1, 2, 3, 4, 7, 8, 16});
245 static auto const& kBadIndexValues = remove({12, 16, 18, 19});
246 static auto const& kBadUInt32Values = remove({2, 3});
247 static auto const& kBadUInt64Values = remove({2, 3});
248 static auto const& kBadIssueValues = remove({});
253 return kBadAccountValues;
256 return kBadArrayValues;
258 return kBadBlobValues;
260 return kBadCurrencyValues;
262 return kBadHashValues;
264 return kBadIndexValues;
266 return kBadFixedHashValues;
268 return kBadIssueValues;
270 return kBadUInt32Values;
272 return kBadUInt64Values;
275 "unknown type " +
std::to_string(
static_cast<uint8_t
>(fieldType)));
284 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
285 arr[1u] =
"r4MrUGTdB57duTnRs6KbsRGQXgkseGb1b5";
290 arr[jss::currency] =
"XRP";
298 return "r4MrUGTdB57duTnRs6KbsRGQXgkseGb1b5";
306 return "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6"
311 return "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6"
314 return kTwoAccountArray;
340 apiVersion,
"json",
"ledger_entry",
to_string(correctRequest))[jss::result];
348 jrr,
"invalidParams",
"No ledger_entry params provided.", location);
351 auto tryField = [&](
json::Value fieldValue) ->
void {
352 correctRequest[fieldName] = fieldValue;
354 apiVersion,
"json",
"ledger_entry",
to_string(correctRequest))[jss::result];
356 fieldName, typeNameOverride.value_or(
getTypeName(typeID)));
361 for (
auto const& value : badValues)
386 correctRequest[parentFieldName].
removeMember(fieldName);
388 apiVersion,
"json",
"ledger_entry",
to_string(correctRequest))[jss::result];
394 apiVersion,
"json",
"ledger_entry",
to_string(correctRequest))[jss::result];
398 auto tryField = [&](
json::Value fieldValue) ->
void {
399 correctRequest[parentFieldName][fieldName] = fieldValue;
402 apiVersion,
"json",
"ledger_entry",
to_string(correctRequest))[jss::result];
411 for (
auto const& value : badValues)
458 parentTypeNameOverride,
463 for (
auto const& subfield : subfields)
465 correctOutput[parentField][subfield.fieldName] =
getCorrectValue(subfield.fieldName);
468 for (
auto const& subfield : subfields)
470 auto const fieldType =
getFieldType(subfield.fieldName);
477 subfield.malformedErrorMsg,
495 jvParams[jss::account_root] = alice.
human();
496 jvParams[jss::ledger_hash] =
497 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
499 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
505 jvParams[jss::account_root] = alice.
human();
509 auto tryField = [&](
json::Value fieldValue) ->
void {
510 jvParams[jss::ledger_hash] = fieldValue;
512 apiVersion,
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
514 jrr,
"invalidParams",
"Invalid field 'ledger_hash', not hex string.");
518 for (
auto const& value : badValues)
528 jvParams[jss::ledger_index] =
"validated";
529 jvParams[jss::index] =
530 "00000000000000000000000000000000000000000000000000000000000000"
532 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
540 jvParams[jss::features] =
541 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
543 jvParams[jss::api_version] = apiVersion;
545 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
553 checkErrorValue(jrr,
"invalidParams",
"No ledger_entry params provided.");
566 cfg->fees.referenceFee = 10;
567 Env env{*
this, std::move(cfg)};
577 BEAST_EXPECT(jrr[jss::ledger_hash] ==
ledgerHash);
578 BEAST_EXPECT(jrr[jss::ledger_index] == 3);
585 jvParams[jss::account_root] = alice.
human();
588 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
589 BEAST_EXPECT(jrr.
isMember(jss::node));
590 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.
human());
591 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
592 accountRootIndex = jrr[jss::index].
asString();
595 static constexpr char kAliceAcctRootBinary[]{
596 "1100612200800000240000000425000000032D00000000559CE54C3B934E4"
597 "73A995B477E92EC229F99CED5B62BF4D2ACE4DC42719103AE2F6240000002"
598 "540BE4008114AE123A8556F3CF91154711376AFB0F894F832B3D"};
602 jvParams[jss::account_root] = alice.
human();
603 jvParams[jss::binary] = 1;
606 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
607 BEAST_EXPECT(jrr.
isMember(jss::node_binary));
608 BEAST_EXPECT(jrr[jss::node_binary] == kAliceAcctRootBinary);
613 jvParams[jss::index] = accountRootIndex;
615 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
616 BEAST_EXPECT(!jrr.
isMember(jss::node_binary));
617 BEAST_EXPECT(jrr.
isMember(jss::node));
618 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.
human());
619 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
624 jvParams[jss::index] = accountRootIndex;
625 jvParams[jss::binary] = 0;
627 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
628 BEAST_EXPECT(jrr.
isMember(jss::node));
629 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.
human());
630 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
635 jvParams[jss::account] = alice.
human();
638 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
639 BEAST_EXPECT(jrr.
isMember(jss::node));
640 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.
human());
641 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
642 accountRootIndex = jrr[jss::index].
asString();
653 jvParams[jss::account_root] =
Account(
"bob").human();
656 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
682 "42426C4D4F1009EE67080A9B7965B44656D7"
683 "714D104A72F9B4369F97ABF044EE"));
686 "4C97EBA926031A7CF7D7B36FDE3ED66DDA54"
687 "21192D63DE53FFB46E43B9DC8373"));
690 "03BDC0099C4E14163ADA272C1B6F6FABB448"
691 "CC3E51F522F978041E4B57D9158C"));
694 "35291ADD2D79EB6991343BDA0912269C817D"
695 "0F094B02226C1C14AD2858962ED4"));
696 sle->setFieldV256(sfAmendments,
STVector256(enabledAmendments));
702 majority1.setFieldH256(
705 "7BB62DC13EC72B775091E9C71BF8CF97E122"
706 "647693B50C5E87A80DFD6FCFAC50"));
707 majority1.setFieldU32(sfCloseTime, 779561310);
708 majorities.
pushBack(std::move(majority1));
711 majority2.setFieldH256(
714 "755C971C29971C9F20C6F080F2ED96F87884"
715 "E40AD19554A5EBECDCEC8A1F77FE"));
716 majority2.setFieldU32(sfCloseTime, 779561310);
717 majorities.
pushBack(std::move(majority2));
719 sle->setFieldArray(sfMajorities, majorities);
730 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
731 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Amendments);
753 AMM const amm(env, alice,
XRP(10), usd(1000));
759 auto const result = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
761 result.isObject() && result.isMember(jss::result) &&
762 !result[jss::result].isMember(jss::error) &&
763 result[jss::result].isMember(jss::node) &&
764 result[jss::result][jss::node].isMember(sfLedgerEntryType.jsonName) &&
765 result[jss::result][jss::node][sfLedgerEntryType.jsonName] == jss::AMM);
773 obj[jss::currency] =
"XRP";
774 ammParams[jss::asset] = obj;
778 ammParams[jss::asset2] =
toJson(usd.
raw());
780 jvParams[jss::amm] = ammParams;
781 auto const result = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
783 result.isObject() && result.isMember(jss::result) &&
784 !result[jss::result].isMember(jss::error) &&
785 result[jss::result].isMember(jss::node) &&
786 result[jss::result][jss::node].isMember(sfLedgerEntryType.jsonName) &&
787 result[jss::result][jss::node][sfLedgerEntryType.jsonName] == jss::AMM);
795 {.fieldName = jss::asset, .malformedErrorMsg =
"malformedRequest"},
796 {.fieldName = jss::asset2, .malformedErrorMsg =
"malformedRequest"},
799 auto getIOU = [&](
Env& env) ->
PrettyAsset {
return alice[
"USD"]; };
801 return MPTTester({.env = env, .issuer = alice});
817 auto const checkSeq = env.
seq(env.
master);
827 jvParams[jss::check] =
to_string(checkId.key);
830 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
831 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
832 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
838 jvParams[jss::check][jss::account] = env.
master.
human();
839 jvParams[jss::check][jss::seq] = checkSeq;
842 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
843 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
844 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
845 BEAST_EXPECT(jrr[jss::index] ==
to_string(checkId.key));
851 jvParams[jss::check][jss::account] = env.
master.
human();
852 jvParams[jss::check][jss::seq] = checkSeq + 1000;
855 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
864 jvParams[jss::account_root] = alice.
human();
866 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
867 accountRootIndex = jrr[jss::index].
asString();
870 jvParams[jss::check] = accountRootIndex;
873 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
874 checkErrorValue(jrr,
"unexpectedLedgerType",
"Unexpected ledger type.");
882 {.fieldName = jss::account, .malformedErrorMsg =
"malformedAddress"},
883 {.fieldName = jss::seq, .malformedErrorMsg =
"malformedRequest"},
896 Account const issuer{
"issuer"};
899 char const credType[] =
"abcde";
901 env.
fund(
XRP(5000), issuer, alice, bob);
913 !jv[jss::result].
isMember(jss::error) && jv[jss::result].
isMember(jss::node) &&
914 jv[jss::result][jss::node].
isMember(sfLedgerEntryType.jsonName) &&
915 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] == jss::Credential);
922 !jv[jss::result].
isMember(jss::error) && jv[jss::result].
isMember(jss::node) &&
923 jv[jss::result][jss::node].
isMember(sfLedgerEntryType.jsonName) &&
924 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] == jss::Credential);
931 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
942 {.fieldName = jss::subject, .malformedErrorMsg =
"malformedRequest"},
943 {.fieldName = jss::issuer, .malformedErrorMsg =
"malformedRequest"},
944 {.fieldName = jss::credential_type, .malformedErrorMsg =
"malformedRequest"},
959 env.
fund(
XRP(10000), alice, bob);
968 jvParams[jss::delegate][jss::account] = alice.
human();
969 jvParams[jss::delegate][jss::authorize] = bob.
human();
972 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
973 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Delegate);
974 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.
human());
975 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == bob.
human());
976 delegateIndex = jrr[jss::node][jss::index].
asString();
981 jvParams[jss::delegate] = delegateIndex;
984 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
985 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Delegate);
986 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.
human());
987 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == bob.
human());
996 {.fieldName = jss::account, .malformedErrorMsg =
"malformedAddress"},
997 {.fieldName = jss::authorize, .malformedErrorMsg =
"malformedAddress"},
1013 env.
fund(
XRP(10000), alice, becky);
1024 jvParams[jss::deposit_preauth][jss::owner] = alice.
human();
1025 jvParams[jss::deposit_preauth][jss::authorized] = becky.
human();
1028 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1030 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::DepositPreauth);
1031 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.
human());
1032 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.
human());
1033 depositPreauthIndex = jrr[jss::node][jss::index].
asString();
1038 jvParams[jss::deposit_preauth] = depositPreauthIndex;
1041 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1043 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::DepositPreauth);
1044 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.
human());
1045 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.
human());
1051 jss::deposit_preauth,
1053 {.fieldName = jss::owner, .malformedErrorMsg =
"malformedOwner"},
1054 {.fieldName = jss::authorized,
1055 .malformedErrorMsg =
"malformedAuthorized",
1064 testcase(
"Deposit Preauth with credentials");
1069 Account const issuer{
"issuer"};
1072 char const credType[] =
"abcde";
1074 env.
fund(
XRP(5000), issuer, alice, bob);
1079 env(
fset(bob, asfDepositAuth));
1088 jvParams[jss::ledger_index] = jss::validated;
1089 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1092 auto& arr(jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1095 jo[jss::issuer] = issuer.
human();
1097 arr.append(std::move(jo));
1098 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
1101 jrr.isObject() && jrr.isMember(jss::result) &&
1102 !jrr[jss::result].isMember(jss::error) && jrr[jss::result].isMember(jss::node) &&
1103 jrr[jss::result][jss::node].isMember(sfLedgerEntryType.jsonName) &&
1104 jrr[jss::result][jss::node][sfLedgerEntryType.jsonName] == jss::DepositPreauth);
1110 jvParams[jss::ledger_index] = jss::validated;
1111 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1113 auto tryField = [&](
json::Value fieldValue) ->
void {
1116 jo[jss::issuer] = fieldValue;
1119 jvParams[jss::deposit_preauth][jss::authorized_credentials] = arr;
1122 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1123 auto const expectedErrMsg = fieldValue.
isNull()
1126 checkErrorValue(jrr,
"malformedAuthorizedCredentials", expectedErrMsg);
1130 for (
auto const& value : badValues)
1140 jvParams[jss::ledger_index] = jss::validated;
1141 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1144 auto& arr(jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1147 jo[jss::issuer] = issuer.
human();
1150 arr.append(std::move(jo));
1151 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
1154 "malformedAuthorizedCredentials",
1161 jvParams[jss::ledger_index] = jss::validated;
1162 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1164 auto tryField = [&](
json::Value fieldValue) ->
void {
1167 jo[jss::issuer] = issuer.
human();
1168 jo[jss::credential_type] = fieldValue;
1170 jvParams[jss::deposit_preauth][jss::authorized_credentials] = arr;
1173 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1174 auto const expectedErrMsg = fieldValue.
isNull()
1177 checkErrorValue(jrr,
"malformedAuthorizedCredentials", expectedErrMsg);
1181 for (
auto const& value : badValues)
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();
1196 auto& arr(jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1199 jo[jss::issuer] = issuer.
human();
1201 arr.append(std::move(jo));
1203 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
1207 "Must have exactly one of `authorized` and "
1208 "`authorized_credentials`.");
1214 jvParams[jss::ledger_index] = jss::validated;
1215 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1219 jss::deposit_preauth,
1220 jss::authorized_credentials,
1222 "malformedAuthorizedCredentials",
1229 jvParams[jss::ledger_index] = jss::validated;
1230 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1232 auto& arr(jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1233 arr.append(
"foobar");
1235 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
1238 "malformedAuthorizedCredentials",
1239 "Invalid field 'authorized_credentials', not array of objects.");
1245 jvParams[jss::ledger_index] = jss::validated;
1246 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1248 auto& arr(jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1251 arr.
append(std::move(payload));
1253 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
1256 "malformedAuthorizedCredentials",
1257 "Invalid field 'authorized_credentials', not array of objects.");
1263 jvParams[jss::ledger_index] = jss::validated;
1264 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1267 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
1270 "malformedAuthorizedCredentials",
1271 "Invalid field 'authorized_credentials', array empty.");
1277 "cred1",
"cred2",
"cred3",
"cred4",
"cred5",
"cred6",
"cred7",
"cred8",
"cred9"};
1281 jvParams[jss::ledger_index] = jss::validated;
1282 jvParams[jss::deposit_preauth][jss::owner] = bob.
human();
1285 auto& arr(jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1287 for (
auto cred : kCredTypes)
1290 jo[jss::issuer] = issuer.
human();
1292 arr.append(std::move(jo));
1295 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams));
1298 "malformedAuthorizedCredentials",
1299 "Invalid field 'authorized_credentials', array too long.");
1311 auto const usd = gw[
"USD"];
1312 env.
fund(
XRP(10000), alice, gw);
1315 env.
trust(usd(1000), alice);
1320 for (
int d = 1'000'032; d >= 1'000'000; --d)
1330 BEAST_EXPECT(jrr[jss::ledger_hash] ==
ledgerHash);
1331 BEAST_EXPECT(jrr[jss::ledger_index] == 5);
1335 "A33EC6BB85FB5674074C4A3A43373BB17645308F3EAE1933E3E35252162B217D";
1339 jvParams[jss::directory] = dirRootIndex;
1342 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1343 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 32);
1349 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1351 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1352 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1358 jvParams[jss::directory][jss::owner] = alice.
human();
1361 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1362 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1368 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1369 jvParams[jss::directory][jss::sub_index] = 1;
1371 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1372 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1373 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1379 jvParams[jss::directory][jss::owner] = alice.
human();
1380 jvParams[jss::directory][jss::sub_index] = 1;
1383 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1384 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1385 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1398 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1428 jvParams[jss::directory][jss::owner] = alice.
human();
1429 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1432 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1434 jrr,
"malformedRequest",
"Must have exactly one of `owner` and `dir_root` fields.");
1440 jvParams[jss::directory][jss::sub_index] = 1;
1443 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1445 jrr,
"malformedRequest",
"Must have exactly one of `owner` and `dir_root` fields.");
1465 jv[jss::TransactionType] = jss::EscrowCreate;
1466 jv[jss::Account] = account.human();
1467 jv[jss::Destination] = to.human();
1469 jv[sfFinishAfter.jsonName] = cancelAfter.time_since_epoch().count() + 2;
1473 using namespace std::chrono_literals;
1474 env(escrowCreate(alice, alice,
XRP(333), env.
now() + 2s));
1483 jvParams[jss::escrow][jss::owner] = alice.
human();
1484 jvParams[jss::escrow][jss::seq] = env.
seq(alice) - 1;
1486 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1487 BEAST_EXPECT(jrr[jss::node][jss::Amount] ==
XRP(333).value().getText());
1488 escrowIndex = jrr[jss::index].
asString();
1493 jvParams[jss::escrow] = escrowIndex;
1496 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1497 BEAST_EXPECT(jrr[jss::node][jss::Amount] ==
XRP(333).value().getText());
1504 {{.fieldName = jss::owner, .malformedErrorMsg =
"malformedOwner"},
1505 {.fieldName = jss::seq, .malformedErrorMsg =
"malformedSeq"}});
1522 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1523 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::FeeSettings);
1544 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1545 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::LedgerHashes);
1561 Account const issuer{
"issuer"};
1563 env.
fund(
XRP(1000), issuer, buyer);
1576 jvParams[jss::nft_offer] =
to_string(offerID);
1578 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1579 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::NFTokenOffer);
1580 BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == issuer.
human());
1581 BEAST_EXPECT(jrr[jss::node][sfNFTokenID.jsonName] ==
to_string(nftokenID0));
1582 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"1");
1588 jvParams[jss::nft_offer][jss::owner] = issuer.
human();
1589 jvParams[jss::nft_offer][jss::seq] = offerSeq;
1591 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1592 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::NFTokenOffer);
1593 BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == issuer.
human());
1594 BEAST_EXPECT(jrr[jss::node][sfNFTokenID.jsonName] ==
to_string(nftokenID0));
1595 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"1");
1596 BEAST_EXPECT(jrr[jss::index] ==
to_string(offerID));
1602 jvParams[jss::nft_offer][jss::owner] = issuer.
human();
1603 jvParams[jss::nft_offer][jss::seq] = offerSeq + 1000;
1605 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1614 {.fieldName = jss::owner, .malformedErrorMsg =
"malformedOwner"},
1615 {.fieldName = jss::seq, .malformedErrorMsg =
"malformedRequest"},
1627 Account const issuer{
"issuer"};
1634 BEAST_EXPECT(env.
le(nftpage) !=
nullptr);
1638 jvParams[jss::nft_page] =
to_string(nftpage.key);
1640 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1641 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::NFTokenPage);
1669 "ED58F6770DB5DD77E59D28CB650EC3816E2FC95021BB56E720C9A1"
1671 disabledValidator.setFieldVL(sfPublicKey, *pubKeyBlob);
1672 disabledValidator.setFieldU32(sfFirstLedgerSequence, 91371264);
1673 disabledValidators.
pushBack(std::move(disabledValidator));
1675 sle->setFieldArray(sfDisabledValidators, disabledValidators);
1679 "8D47FFE664BE6C335108DF689537625855A6"
1680 "A95160CC6D351341B9"
1682 sle->setFieldU32(sfPreviousTxnLgrSeq, 91442944);
1693 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1694 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::NegativeUNL);
1710 auto const usd = gw[
"USD"];
1711 env.
fund(
XRP(10000), alice, gw);
1714 env(
offer(alice, usd(321),
XRP(322)));
1723 jvParams[jss::offer][jss::account] = alice.
human();
1724 jvParams[jss::offer][jss::seq] = env.
seq(alice) - 1;
1727 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1728 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1729 offerIndex = jrr[jss::index].
asString();
1734 jvParams[jss::offer] = offerIndex;
1736 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1737 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1745 {{.fieldName = jss::account, .malformedErrorMsg =
"malformedAddress"},
1746 {.fieldName = jss::seq, .malformedErrorMsg =
"malformedRequest"}});
1769 jv[jss::TransactionType] = jss::PaymentChannelCreate;
1770 jv[jss::Account] = account.human();
1771 jv[jss::Destination] = to.human();
1773 jv[sfSettleDelay.jsonName] = settleDelay.count();
1774 jv[sfPublicKey.jsonName] =
strHex(pk.slice());
1778 auto const payChanSeq = env.
seq(alice);
1779 env(payChanCreate(alice, env.
master,
XRP(57), 18s, alice.
pk()));
1789 jvParams[jss::payment_channel] =
to_string(payChanIndex);
1792 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1793 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"57000000");
1794 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"0");
1795 BEAST_EXPECT(jrr[jss::node][sfSettleDelay.jsonName] == 18);
1801 jvParams[jss::payment_channel][jss::account] = alice.
human();
1802 jvParams[jss::payment_channel][jss::destination] = env.
master.
human();
1803 jvParams[jss::payment_channel][jss::seq] = payChanSeq;
1806 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1807 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"57000000");
1808 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"0");
1809 BEAST_EXPECT(jrr[jss::node][sfSettleDelay.jsonName] == 18);
1810 BEAST_EXPECT(jrr[jss::index] ==
to_string(payChanIndex));
1816 jvParams[jss::payment_channel][jss::account] = alice.
human();
1817 jvParams[jss::payment_channel][jss::destination] = env.
master.
human();
1818 jvParams[jss::payment_channel][jss::seq] = payChanSeq + 1000;
1821 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1830 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1838 jss::payment_channel,
1840 {.fieldName = jss::account, .malformedErrorMsg =
"malformedAddress"},
1841 {.fieldName = jss::destination, .malformedErrorMsg =
"malformedAddress"},
1842 {.fieldName = jss::seq, .malformedErrorMsg =
"malformedRequest"},
1855 auto const usd = gw[
"USD"];
1856 env.
fund(
XRP(10000), alice, gw);
1859 env.
trust(usd(999), alice);
1862 env(
pay(gw, alice, usd(97)));
1866 for (
auto const& fieldName : {jss::ripple_state, jss::state})
1874 jvParams[fieldName][jss::accounts][0u] = alice.
human();
1875 jvParams[fieldName][jss::accounts][1u] = gw.
human();
1876 jvParams[fieldName][jss::currency] =
"USD";
1879 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1880 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName][jss::value] ==
"-97");
1881 BEAST_EXPECT(jrr[jss::node][sfHighLimit.jsonName][jss::value] ==
"999");
1889 {.fieldName = jss::accounts, .malformedErrorMsg =
"malformedRequest"},
1890 {.fieldName = jss::currency, .malformedErrorMsg =
"malformedCurrency"},
1898 jvParams[fieldName][jss::accounts][0u] = alice.
human();
1899 jvParams[fieldName][jss::currency] =
"USD";
1902 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1906 "Invalid field 'accounts', not length-2 array of "
1914 jvParams[fieldName][jss::accounts][0u] = alice.
human();
1915 jvParams[fieldName][jss::accounts][1u] = gw.
human();
1916 jvParams[fieldName][jss::accounts][2u] = alice.
human();
1917 jvParams[fieldName][jss::currency] =
"USD";
1920 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1924 "Invalid field 'accounts', not length-2 array of "
1931 auto tryField = [&](
json::Value badAccount) ->
void {
1935 jvParams[fieldName][jss::accounts][0u] = badAccount;
1936 jvParams[fieldName][jss::accounts][1u] = gw.
human();
1937 jvParams[fieldName][jss::currency] =
"USD";
1940 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1950 jvParams[fieldName][jss::accounts][0u] = alice.
human();
1951 jvParams[fieldName][jss::accounts][1u] = badAccount;
1952 jvParams[fieldName][jss::currency] =
"USD";
1955 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1964 for (
auto const& value : badValues)
1975 jvParams[fieldName][jss::accounts][0u] = alice.
human();
1976 jvParams[fieldName][jss::accounts][1u] = alice.
human();
1977 jvParams[fieldName][jss::currency] =
"USD";
1980 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
1981 checkErrorValue(jrr,
"malformedRequest",
"Cannot have a trustline to self.");
2000 env(
signers(alice, 1, {{bogie, 1}, {demon, 1}}));
2008 jvParams[jss::signer_list] =
to_string(signerListIndex);
2011 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2012 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::SignerList);
2013 BEAST_EXPECT(jrr[jss::node][sfSignerQuorum.jsonName] == 1);
2019 jvParams[jss::signer_list][jss::account] = alice.
human();
2022 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2023 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::SignerList);
2024 BEAST_EXPECT(jrr[jss::node][sfSignerQuorum.jsonName] == 1);
2025 BEAST_EXPECT(jrr[jss::index] ==
to_string(signerListIndex));
2031 jvParams[jss::signer_list][jss::account] = env.
master.
human();
2034 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2043 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2053 {.fieldName = jss::account, .malformedErrorMsg =
"malformedAddress"},
2068 env.
fund(
XRP(10000), alice, bob);
2078 jvParams[jss::sponsorship][jss::sponsor] = alice.
human();
2079 jvParams[jss::sponsorship][jss::sponsee] = bob.
human();
2081 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2082 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Sponsorship);
2083 BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == alice.
human());
2084 BEAST_EXPECT(jrr[jss::node][sfSponsee.jsonName] == bob.
human());
2085 BEAST_EXPECT(sponsorshipIndex == jrr[jss::node][jss::index].asString());
2090 jvParams[jss::sponsorship] = sponsorshipIndex;
2093 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2094 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Sponsorship);
2095 BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == alice.
human());
2096 BEAST_EXPECT(jrr[jss::node][sfSponsee.jsonName] == bob.
human());
2097 BEAST_EXPECT(sponsorshipIndex == jrr[jss::node][jss::index].asString());
2105 {.fieldName = jss::sponsor, .malformedErrorMsg =
"malformedSponsor"},
2106 {.fieldName = jss::sponsee, .malformedErrorMsg =
"malformedSponsee"},
2134 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2144 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2145 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Ticket);
2146 BEAST_EXPECT(jrr[jss::node][sfTicketSequence.jsonName] == tkt1.
value());
2153 jvParams[jss::ticket][jss::account] = env.
master.
human();
2154 jvParams[jss::ticket][jss::ticket_seq] = tkt1.
value();
2157 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2166 jvParams[jss::ticket][jss::account] = env.
master.
human();
2167 jvParams[jss::ticket][jss::ticket_seq] = tkt1.
value();
2170 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2179 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2180 checkErrorValue(jrr,
"unexpectedLedgerType",
"Unexpected ledger type.");
2189 {.fieldName = jss::account, .malformedErrorMsg =
"malformedAddress"},
2190 {.fieldName = jss::ticket_seq, .malformedErrorMsg =
"malformedRequest"},
2204 Account const target{
"target"};
2206 env.
fund(
XRP(10000), target, bob);
2225 jvParams[jss::transaction_proposal][jss::account] = target.
human();
2226 jvParams[jss::transaction_proposal][jss::ticket_seq] = ticketSeq;
2228 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2229 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::TransactionProposal);
2230 BEAST_EXPECT(proposalIndex == jrr[jss::node][jss::index].asString());
2235 jvParams[jss::transaction_proposal] = proposalIndex;
2237 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2238 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::TransactionProposal);
2239 BEAST_EXPECT(proposalIndex == jrr[jss::node][jss::index].asString());
2244 jvParams[jss::transaction_proposal][jss::account] = target.
human();
2245 jvParams[jss::transaction_proposal][jss::ticket_seq] = ticketSeq + 1;
2247 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2255 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2256 checkErrorValue(jrr,
"unexpectedLedgerType",
"Unexpected ledger type.");
2267 jss::transaction_proposal,
2269 {.fieldName = jss::account, .malformedErrorMsg =
"malformedAddress"},
2270 {.fieldName = jss::ticket_seq, .malformedErrorMsg =
"malformedRequest"},
2291 jv[jss::TransactionType] = jss::DIDSet;
2292 jv[jss::Account] = account.human();
2298 env(didCreate(alice));
2306 jvParams[jss::did] = alice.
human();
2309 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2310 BEAST_EXPECT(jrr[jss::node][sfDIDDocument.jsonName] ==
strHex(
std::string{
"data"}));
2319 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2333 testcase(
"Invalid Oracle Ledger Entry");
2341 env, {.owner = owner, .fee =
static_cast<int>(env.
current()->fees().base.drops())});
2349 {.fieldName = jss::account, .malformedErrorMsg =
"malformedAccount"},
2350 {.fieldName = jss::oracle_document_id,
2351 .malformedErrorMsg =
"malformedDocumentID"},
2364 auto const baseFee =
static_cast<int>(env.
current()->fees().base.drops());
2367 for (
int i = 0; i < 10; ++i)
2372 Oracle const oracle(env, {.owner = owner, .documentID = i, .fee = baseFee});
2376 Oracle const oracle1(env, {.owner = owner, .documentID = i + 10, .fee = baseFee});
2378 oracles.
push_back(oracle1.documentID());
2380 for (
int i = 0; i < accounts.
size(); ++i)
2382 auto const jv = [&]() {
2391 BEAST_EXPECT(jv[jss::node][jss::Owner] ==
to_string(accounts[i]));
2410 MPTTester mptAlice(env, alice, {.holders = {bob}});
2415 .flags = tfMPTCanLock | tfMPTRequireAuth | tfMPTCanEscrow | tfMPTCanTrade |
2416 tfMPTCanTransfer | tfMPTCanClawback});
2417 mptAlice.authorize({.account = bob, .holderCount = 1});
2421 std::string const badMptID =
"00000193B9DDCAF401B5B3B26875986043F82CD0D13B4315";
2425 jvParams[jss::mpt_issuance] =
strHex(mptAlice.issuanceID());
2428 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2429 BEAST_EXPECT(jrr[jss::node][sfMPTokenMetadata.jsonName] ==
strHex(
std::string{
"123"}));
2430 BEAST_EXPECT(jrr[jss::node][jss::mpt_issuance_id] ==
strHex(mptAlice.issuanceID()));
2435 jvParams[jss::mpt_issuance] = badMptID;
2438 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2445 jvParams[jss::mptoken][jss::account] = bob.
human();
2446 jvParams[jss::mptoken][jss::mpt_issuance_id] =
strHex(mptAlice.issuanceID());
2449 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2451 jrr[jss::node][sfMPTokenIssuanceID.jsonName] ==
strHex(mptAlice.issuanceID()));
2457 jvParams[jss::mptoken][jss::account] = bob.
human();
2458 jvParams[jss::mptoken][jss::mpt_issuance_id] = badMptID;
2461 env.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
2480 Account const issuer{
"issuer"};
2484 env.
fund(
XRP(5000), issuer, alice, bob);
2487 auto const seq = env.
seq(alice);
2488 env(
pdomain::setTx(alice, {{.issuer = alice, .credType =
"first credential"}}));
2491 if (!BEAST_EXPECT(objects.size() == 1))
2497 params[jss::ledger_index] = jss::validated;
2498 params[jss::permissioned_domain][jss::account] = alice.
human();
2499 params[jss::permissioned_domain][jss::seq] = seq;
2500 auto jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2503 !jv[jss::result].
isMember(jss::error) && jv[jss::result].
isMember(jss::node) &&
2504 jv[jss::result][jss::node].
isMember(sfLedgerEntryType.jsonName) &&
2505 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] == jss::PermissionedDomain);
2512 params[jss::ledger_index] = jss::validated;
2513 params[jss::permissioned_domain] = pdIdx;
2514 jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2517 !jv[jss::result].
isMember(jss::error) && jv[jss::result].
isMember(jss::node) &&
2518 jv[jss::result][jss::node].
isMember(sfLedgerEntryType.jsonName) &&
2519 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] == jss::PermissionedDomain);
2525 params[jss::ledger_index] = jss::validated;
2526 params[jss::permissioned_domain] =
2527 "12F1F1F1F180D67377B2FAB292A31C922470326268D2B9B74CD1E582645B9A"
2529 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2530 checkErrorValue(jrr[jss::result],
"entryNotFound",
"Entry not found.");
2536 jss::permissioned_domain,
2538 {.fieldName = jss::account, .malformedErrorMsg =
"malformedAddress"},
2539 {.fieldName = jss::seq, .malformedErrorMsg =
"malformedRequest"},
2573 auto checkResult = [&](
bool good,
2580 jv.isObject() && jv.isMember(jss::result) &&
2581 !jv[jss::result].isMember(jss::error) &&
2582 jv[jss::result].isMember(jss::node) &&
2583 jv[jss::result][jss::node].isMember(sfLedgerEntryType.jsonName) &&
2584 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] == expectedType,
2590 jv.isObject() && jv.isMember(jss::result) &&
2591 jv[jss::result].isMember(jss::error) &&
2592 !jv[jss::result].isMember(jss::node) &&
2593 jv[jss::result][jss::error] == expectedError.value_or(
"entryNotFound"),
2611 Keylet const& expectedKey,
2613 testcase << expectedType.cStr() << (good ?
"" :
" not") <<
" found";
2615 auto const hexKey =
strHex(expectedKey.key);
2621 params[jss::ledger_index] = jss::validated;
2623 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2624 checkResult(
false, jv, expectedType,
"malformedRequest");
2625 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2631 params[jss::ledger_index] = jss::validated;
2632 params[field] =
"arbitrary string";
2633 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2634 checkResult(
false, jv, expectedType,
"malformedRequest");
2635 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2641 params[jss::ledger_index] = jss::validated;
2642 params[field] =
false;
2643 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2644 checkResult(
false, jv, expectedType,
"invalidParams");
2645 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2653 params[jss::ledger_index] = jss::validated;
2654 params[field] = badKey;
2655 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2656 checkResult(
false, jv, expectedType,
"entryNotFound");
2657 BEAST_EXPECTS(jv[jss::result][jss::index] == badKey,
to_string(jv));
2663 params[jss::ledger_index] = jss::validated;
2664 params[jss::index] = field;
2665 params[jss::api_version] = 2;
2666 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2667 checkResult(
false, jv, expectedType,
"malformedRequest");
2668 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2676 params[jss::ledger_index] = jss::validated;
2677 params[field] =
true;
2678 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2680 std::string const pdIdx = jv[jss::result][jss::index].asString();
2681 BEAST_EXPECTS(hexKey == pdIdx,
to_string(jv));
2682 checkResult(good, jv, expectedType);
2691 params[jss::ledger_index] = jss::validated;
2692 params[field] = hexKey;
2693 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2694 checkResult(good, jv, expectedType);
2695 BEAST_EXPECT(jv[jss::result][jss::index].asString() == hexKey);
2702 params[jss::ledger_index] = jss::validated;
2703 params[jss::index] = field;
2704 params[jss::api_version] = 2;
2705 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2706 checkResult(
false, jv, expectedType,
"malformedRequest");
2707 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2713 params[jss::ledger_index] = jss::validated;
2714 params[jss::index] = field;
2715 params[jss::api_version] = 3;
2716 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2718 BEAST_EXPECT(jv[jss::result][jss::index].asString() == hexKey);
2719 checkResult(good, jv, expectedType);
2725 params[jss::ledger_index] = jss::validated;
2726 params[jss::index] = pdIdx;
2727 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2729 BEAST_EXPECT(jv[jss::result][jss::index].asString() == hexKey);
2730 checkResult(good, jv, expectedType);
2768 auto checkResult = [&](
bool good,
2775 jv.isObject() && jv.isMember(jss::result) &&
2776 !jv[jss::result].isMember(jss::error) &&
2777 jv[jss::result].isMember(jss::node) &&
2778 jv[jss::result][jss::node].isMember(sfLedgerEntryType.jsonName) &&
2779 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] == jss::LedgerHashes,
2782 jv[jss::result].isMember(jss::node) &&
2783 jv[jss::result][jss::node].isMember(
"Hashes") &&
2784 jv[jss::result][jss::node][
"Hashes"].
size() == expectedCount,
2790 jv.isObject() && jv.isMember(jss::result) &&
2791 jv[jss::result].isMember(jss::error) &&
2792 !jv[jss::result].isMember(jss::node) &&
2793 jv[jss::result][jss::error] == expectedError.value_or(
"entryNotFound"),
2810 [&](
json::Value ledger,
Keylet const& expectedKey,
bool good,
int expectedCount = 0) {
2812 <<
" \"hashes\":" <<
to_string(ledger) << (good ?
"" :
" not") <<
" found";
2814 auto const hexKey =
strHex(expectedKey.key);
2820 params[jss::ledger_index] = jss::validated;
2822 auto jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2823 checkResult(
false, jv, 0,
"malformedRequest");
2824 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2830 params[jss::ledger_index] = jss::validated;
2831 params[jss::hashes] =
"arbitrary string";
2832 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2833 checkResult(
false, jv, 0,
"malformedRequest");
2834 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2840 params[jss::ledger_index] = jss::validated;
2841 params[jss::hashes] =
"10";
2842 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2843 checkResult(
false, jv, 0,
"malformedRequest");
2844 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2850 params[jss::ledger_index] = jss::validated;
2851 params[jss::hashes] =
false;
2852 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2853 checkResult(
false, jv, 0,
"invalidParams");
2854 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2860 params[jss::ledger_index] = jss::validated;
2861 params[jss::hashes] = -1;
2862 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2863 checkResult(
false, jv, 0,
"internal");
2864 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2871 params[jss::ledger_index] = jss::validated;
2872 params[jss::hashes] = badKey;
2873 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2874 checkResult(
false, jv, 0,
"entryNotFound");
2875 BEAST_EXPECT(jv[jss::result][jss::index] == badKey);
2882 params[jss::ledger_index] = jss::validated;
2883 params[jss::hashes] = ledger;
2884 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2885 checkResult(good, jv, expectedCount);
2887 std::string const pdIdx = jv[jss::result][jss::index].asString();
2888 BEAST_EXPECTS(hexKey == pdIdx,
strHex(pdIdx));
2894 params[jss::ledger_index] = jss::validated;
2895 params[jss::hashes] = hexKey;
2896 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2897 checkResult(good, jv, expectedCount);
2900 hexKey == jv[jss::result][jss::index].asString(),
2901 strHex(jv[jss::result][jss::index].asString()));
2907 params[jss::ledger_index] = jss::validated;
2908 params[jss::index] = hexKey;
2909 auto const jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2910 checkResult(good, jv, expectedCount);
2913 hexKey == jv[jss::result][jss::index].asString(),
2914 strHex(jv[jss::result][jss::index].asString()));
2926 for (
auto i = env.
current()->seq(); i <= 250; ++i)
2937 for (
auto i = env.
current()->seq(); i <= 260; ++i)
2966 BEAST_EXPECT(jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
2967 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
3014 if (BEAST_EXPECT(jv.
isMember(jss::status)))
3015 BEAST_EXPECT(jv[jss::status] ==
"error");
3016 if (BEAST_EXPECT(jv.
isMember(jss::error)))
3017 BEAST_EXPECT(jv[jss::error] == err);
3023 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
3025 BEAST_EXPECT(jv[jss::error_message] == msg);
3046 jvParams[jss::bridge_account] =
mcDoor.human();
3047 jvParams[jss::bridge] =
jvb;
3049 mcEnv.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
3051 BEAST_EXPECT(jrr.
isMember(jss::node));
3052 auto r = jrr[jss::node];
3054 BEAST_EXPECT(r.isMember(jss::Account));
3055 BEAST_EXPECT(r[jss::Account] ==
mcDoor.human());
3057 BEAST_EXPECT(r.isMember(jss::Flags));
3059 BEAST_EXPECT(r.isMember(sfLedgerEntryType.jsonName));
3060 BEAST_EXPECT(r[sfLedgerEntryType.jsonName] == jss::Bridge);
3063 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
3064 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 0);
3067 BEAST_EXPECT(r.isMember(sfXChainAccountClaimCount.jsonName));
3068 BEAST_EXPECT(r[sfXChainAccountClaimCount.jsonName].asInt() == 0);
3070 BEAST_EXPECT(r.isMember(jss::index));
3071 bridgeIndex = r[jss::index].asString();
3077 jvParams[jss::index] = bridgeIndex;
3079 mcEnv.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
3081 BEAST_EXPECT(jrr.
isMember(jss::node));
3082 BEAST_EXPECT(jrr[jss::node] == mcBridge);
3089 jvParams[jss::bridge] =
jvb;
3092 mcEnv.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
3106 jvParams[jss::bridge_account] =
mcDoor.human();
3107 jvParams[jss::bridge] =
jvb;
3109 mcEnv.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
3111 BEAST_EXPECT(jrr.
isMember(jss::node));
3112 auto r = jrr[jss::node];
3115 BEAST_EXPECT(r.isMember(sfXChainClaimID.jsonName));
3116 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
3123 testcase(
"ledger_entry: xchain_claim_id");
3140 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] = 1;
3142 scEnv.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
3144 BEAST_EXPECT(jrr.
isMember(jss::node));
3145 auto r = jrr[jss::node];
3147 BEAST_EXPECT(r.isMember(jss::Account));
3148 BEAST_EXPECT(r[jss::Account] ==
scAlice.human());
3149 BEAST_EXPECT(r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
3150 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 1);
3151 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
3158 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] = 2;
3160 scEnv.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
3162 BEAST_EXPECT(jrr.
isMember(jss::node));
3163 auto r = jrr[jss::node];
3165 BEAST_EXPECT(r.isMember(jss::Account));
3166 BEAST_EXPECT(r[jss::Account] ==
scBob.human());
3167 BEAST_EXPECT(r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
3168 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
3169 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
3176 testcase(
"ledger_entry: xchain_create_account_claim_id");
3187 auto const amt =
XRP(1000);
3193 static constexpr size_t kNumAttest = 3;
3206 for (
size_t i = 0; i < kNumAttest; ++i)
3215 jvParams[jss::xchain_owned_create_account_claim_id] =
jvXRPBridgeRPC;
3216 jvParams[jss::xchain_owned_create_account_claim_id]
3217 [jss::xchain_owned_create_account_claim_id] = 1;
3219 scEnv.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
3221 BEAST_EXPECT(jrr.
isMember(jss::node));
3222 auto r = jrr[jss::node];
3224 BEAST_EXPECT(r.isMember(jss::Account));
3227 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
3228 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 1);
3230 BEAST_EXPECT(r.isMember(sfXChainCreateAccountAttestations.jsonName));
3231 auto attest = r[sfXChainCreateAccountAttestations.jsonName];
3232 BEAST_EXPECT(attest.isArray());
3233 BEAST_EXPECT(attest.size() == 3);
3237 for (
auto& attestation : a)
3239 attestation = attest[
json::Value::UInt(0)][sfXChainCreateAccountProofSig.jsonName];
3241 attestation.isMember(jss::Amount) &&
3242 attestation[jss::Amount].asInt() == 1000 *
kDropPerXrp);
3244 attestation.isMember(jss::Destination) &&
3245 attestation[jss::Destination] ==
scCarol.human());
3247 attestation.isMember(sfAttestationSignerAccount.jsonName) &&
3249 return attestation[sfAttestationSignerAccount.jsonName] ==
3253 attestation.isMember(sfAttestationRewardAccount.jsonName) &&
3255 return attestation[sfAttestationRewardAccount.jsonName] == account.human();
3258 attestation.isMember(sfWasLockingChainSend.jsonName) &&
3259 attestation[sfWasLockingChainSend.jsonName] == 1);
3261 attestation.isMember(sfSignatureReward.jsonName) &&
3262 attestation[sfSignatureReward.jsonName].asInt() == 1 *
kDropPerXrp);
3276 jvParams[jss::xchain_owned_create_account_claim_id] =
jvXRPBridgeRPC;
3277 jvParams[jss::xchain_owned_create_account_claim_id]
3278 [jss::xchain_owned_create_account_claim_id] = 1;
3280 scEnv.
rpc(
"json",
"ledger_entry",
to_string(jvParams))[jss::result];
A generic endpoint for log messages.
void fail(String const &reason, char const *file, int line)
Record a failure.
TestcaseT testcase
Memberspace for declaring test cases.
Lightweight wrapper to tag static string.
constexpr char const * cStr() const
Value removeMember(char const *key)
Remove and return the named member.
bool isNull() const
isNull() tests to see if this field is null.
std::string toStyledString() const
Value & append(Value const &value)
Append value to array at the end.
UInt size() const
Number of values in array or object.
std::string asString() const
Returns the unquoted string value.
bool isMember(char const *key) const
Return true if the object has a member named key.
void clear()
Remove all object members and array elements.
static BaseUInt fromVoid(void const *data)
std::chrono::time_point< NetClock > time_point
std::chrono::duration< rep, period > duration
bool modify(ModifyType const &f)
Modify the open ledger.
Writable ledger view that accumulates state and tx changes.
void rawInsert(SLE::Ref sle) override
Unconditionally insert a state item.
void pushBack(STObject const &object)
static STObject makeInnerObject(SField const &name)
A type that represents either a sequence value or a ticket value.
static constexpr SeqProxy rawSequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
SeqProxy & advanceBy(std::uint32_t amount)
static constexpr SeqProxy rawTicket(std::uint32_t v)
Factory function to return a ticket-based SeqProxy.
constexpr std::uint32_t value() const
virtual OpenLedger & getOpenLedger()=0
static Account const kMaster
The master account that holds all XRP in genesis.
void testCreateAccountClaimID()
void run() override
Runs the suite.
void checkErrorValue(json::Value const &jv, std::string const &err, std::string const &msg)
void runLedgerEntryTest(test::jtx::Env &env, json::StaticString const &parentField, std::source_location const location=std::source_location::current())
void testOracleLedgerEntry()
void checkErrorValue(json::Value const &jv, std::string const &err, std::string const &msg, std::source_location const location=std::source_location::current())
void run() override
Runs the suite.
void testTransactionProposal()
void testMalformedField(test::jtx::Env &env, json::Value correctRequest, json::StaticString const fieldName, FieldType const typeID, std::string const &expectedError, bool required=true, std::optional< std::string > typeNameOverride=std::nullopt, std::source_location const location=std::source_location::current())
static std::vector< json::Value > getBadValues(FieldType fieldType)
void testDepositPreauth()
void testMalformedSubfield(test::jtx::Env &env, json::Value correctRequest, json::StaticString parentFieldName, json::StaticString fieldName, FieldType typeID, std::string const &expectedError, bool required=true, std::source_location const location=std::source_location::current())
void testFixed()
Test the ledger entry types that don't take parameters.
void testPermissionedDomain()
void testDepositPreauthCred()
void runLedgerEntryTest(test::jtx::Env &env, json::StaticString const &parentField, std::vector< Subfield > const &subfields, std::optional< std::string > parentTypeNameOverride=std::nullopt, std::source_location const location=std::source_location::current())
void testInvalidOracleLedgerEntry()
static json::Value getCorrectValue(json::StaticString fieldName)
Convenience class to test AMM functionality.
Immutable cryptographic account descriptor.
std::string const & human() const
Returns the human readable public key.
PublicKey const & pk() const
Return the public key.
AccountID id() const
Returns the Account ID.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
SLE::const_pointer le(Account const &account) const
Return an account root.
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
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 trust(STAmount const &amount, Account const &account)
Establish trust lines.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
NetClock::time_point now()
Returns the current network time.
Test helper for creating, mutating, and asserting MPT and confidential MPT ledger state.
void create(MPTCreate const &arg=MPTCreate{}, std::source_location const &loc=std::source_location::current())
Oracle class facilitates unit-testing of the Price Oracle feature.
static json::Value ledgerEntry(Env &env, std::optional< std::variant< AccountID, std::string > > const &account, std::optional< AnyValue > const &documentID, std::optional< std::string > const &index=std::nullopt)
Sets the optional Destination field on an NFTokenOffer.
@ Array
array value (ordered list)
@ Object
object value (collection of name/value pairs).
Keylet computation functions.
Keylet const & skip() noexcept
The index of the "short" skip list.
Keylet nftokenOffer(AccountID const &owner, SeqProxy const &seq)
An offer from an account to buy or sell an NFT.
Keylet payChannel(AccountID const &src, AccountID const &dst, SeqProxy const &seq) noexcept
A PaymentChannel.
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
Keylet const & feeSettings() noexcept
The (fixed) index of the object containing the ledger fees.
Keylet const & amendments() noexcept
The index of the amendment table.
Keylet signerList(AccountID const &account) noexcept
A SignerList.
Keylet txProposal(AccountID const &target, std::uint32_t ticketSequence) noexcept
A TransactionProposal.
Keylet check(AccountID const &id, SeqProxy const &seq) noexcept
A Check.
Keylet ticket(AccountID const &id, SeqProxy const &ticketSeq)
A ticket belonging to an account.
Keylet permissionedDomain(AccountID const &account, SeqProxy const &seq) noexcept
Keylet nftokenPageMax(AccountID const &owner)
A keylet for the owner's last possible NFT page.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet sponsorship(AccountID const &sponsor, AccountID const &sponsee) noexcept
A Sponsorship.
API version numbers used in later API versions.
std::string expectedFieldMessage(std::string const &name, std::string const &type)
std::string missingFieldMessage(std::string const &name)
json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
json::Value create(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
json::Value ledgerEntry(jtx::Env &env, jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
json::Value set(jtx::Account const &account, jtx::Account const &authorize, std::vector< std::string > const &permissions)
json::Value authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
std::map< UInt256, json::Value > getObjects(Account const &account, Env &env, bool withType)
json::Value setTx(AccountID const &account, Credentials const &credentials, std::optional< UInt256 > domain)
Create create()
Check the ledger effects a TransactionProposalCreate must have, whatever its outcome: on tesSUCCESS a...
std::uint32_t createTicket(Env &env, Account const &account, std::uint32_t count)
Create tickets for a proposal to be built against, and close the ledger.
json::Value unsignedPayload(Env const &env, json::Value tx, std::uint32_t ticketSeq)
Put a transaction of any type into the form a proposal stores it in: unsigned and ticket-based,...
json::Value create(Account const &proposer, json::Value const &proposedTx, std::uint32_t expiration)
Build a TransactionProposalCreate carrying an unsigned proposed transaction.
std::uint32_t expiration(Env &env, NetClock::duration delta)
An absolute expiration delta past the environment's current time.
json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
json::Value mint(jtx::Account const &account, std::uint32_t nfTokenTaxon)
Mint an NFToken.
json::Value createOffer(jtx::Account const &account, UInt256 const &nftokenID, STAmount const &amount)
Create an NFTokenOffer.
UInt256 getNextID(jtx::Env const &env, jtx::Account const &issuer, std::uint32_t nfTokenTaxon, std::uint16_t flags, std::uint16_t xferFee)
Get the next NFTokenID that will be issued.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
RequireT required(Args const &... args)
Compose many condition functors into one.
json::Value sidechainXchainAccountCreate(Account const &acc, json::Value const &bridge, Account const &dst, AnyAmount const &amt, AnyAmount const &reward)
XrpT const XRP
Converts to XRP Issue or STAmount.
FeatureBitset testableAmendments()
constexpr std::size_t kUtXchainDefaultNumSigners
json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
json::Value xchainCreateClaimId(Account const &acc, json::Value const &bridge, STAmount const &reward, Account const &otherChainSource)
json::Value signers(Account const &account, std::uint32_t quorum, std::vector< Signer > const &v)
JValueVec createAccountAttestations(jtx::Account const &submittingAccount, json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, jtx::AnyAmount const &rewardAmount, std::vector< jtx::Account > const &rewardAccounts, bool wasLockingChainSend, std::uint64_t createCount, jtx::Account const &dst, std::vector< jtx::Signer > const &signers, std::size_t const numAtts, std::size_t const fromIdx)
json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
FieldType getFieldType(json::StaticString fieldName)
std::vector< std::pair< json::StaticString, FieldType > > gMappings
static UInt256 ledgerHash(LedgerHeader const &info)
std::string getTypeName(FieldType typeID)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
void forAllApiVersions(Fn const &fn, Args &&... args)
std::string strHex(FwdIt begin, FwdIt end)
std::string to_string(BaseUInt< Bits, Tag > const &a)
json::Value toJson(Asset const &asset)
Asset getAsset(T const &amt)
constexpr std::size_t kMaxCredentialsArraySize
The maximum number of credentials can be passed in array.
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
A pair of SHAMap key and LedgerEntryType.
json::StaticString fieldName
std::string malformedErrorMsg
Asset const & raw() const
A signer in a SignerList.
void createBridgeObjects(Env &mcEnv, Env &scEnv)
std::vector< Account > const payee
FeatureBitset const features
std::vector< Signer > const signers
static constexpr int kDropPerXrp
json::Value const jvXRPBridgeRPC