2#include <test/jtx/Oracle.h>
3#include <test/jtx/attester.h>
4#include <test/jtx/delegate.h>
5#include <test/jtx/multisign.h>
6#include <test/jtx/xchain_bridge.h>
8#include <xrpld/app/tx/apply.h>
10#include <xrpl/beast/unit_test.h>
11#include <xrpl/json/json_value.h>
12#include <xrpl/protocol/AccountID.h>
13#include <xrpl/protocol/ErrorCodes.h>
14#include <xrpl/protocol/STXChainBridge.h>
15#include <xrpl/protocol/jss.h>
17#include <source_location>
59 return pair.first == fieldName;
67 Throw<std::runtime_error>(
89 return "hex string or object";
93 return "length-2 array of Accounts";
99 Throw<std::runtime_error>(
113 if (BEAST_EXPECT(jv.
isMember(jss::status)))
116 if (BEAST_EXPECT(jv.
isMember(jss::error)))
118 jv[jss::error] == err,
119 "Expected error " + err +
", received " +
120 jv[jss::error].asString() +
", at line " +
127 jv[jss::error_message] ==
"",
128 "Expected no error message, received \"" +
129 jv[jss::error_message].asString() +
"\", at line " +
133 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
135 jv[jss::error_message] == msg,
136 "Expected error message \"" + msg +
"\", received \"" +
137 jv[jss::error_message].asString() +
"\", at line " +
147 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
148 obj[jss::ledger_index] =
"validated";
153 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
154 arr[1u] =
"validated";
168 "0123456789ABCDEFGH",
169 "rJxKV9e9p6wiPw!!!!xrJ4X1n98LosPL1sgcJW",
170 "rPSTrR5yEr11uMkfsz1kHCp9jK4aoa3Avv",
171 "n9K2isxwTxcSHJKxMkJznDoWXAUs7NNy49H9Fknz1pC7oHAH3kH9",
174 "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6B01403D"
185 indices.begin(), indices.end());
190 if (indexSet.
find(i) == indexSet.
end())
198 static auto const& badAccountValues = remove({12});
199 static auto const& badArrayValues = remove({17, 20});
200 static auto const& badBlobValues = remove({3, 7, 8, 16});
201 static auto const& badCurrencyValues = remove({14});
202 static auto const& badHashValues = remove({2, 3, 7, 8, 16});
203 static auto const& badFixedHashValues = remove({1, 2, 3, 4, 7, 8, 16});
204 static auto const& badIndexValues = remove({12, 16, 18, 19});
205 static auto const& badUInt32Values = remove({2, 3});
206 static auto const& badUInt64Values = remove({2, 3});
207 static auto const& badIssueValues = remove({});
212 return badAccountValues;
215 return badArrayValues;
217 return badBlobValues;
219 return badCurrencyValues;
221 return badHashValues;
223 return badIndexValues;
225 return badFixedHashValues;
227 return badIssueValues;
229 return badUInt32Values;
231 return badUInt64Values;
233 Throw<std::runtime_error>(
244 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
245 arr[1u] =
"r4MrUGTdB57duTnRs6KbsRGQXgkseGb1b5";
250 arr[jss::currency] =
"XRP";
258 return "r4MrUGTdB57duTnRs6KbsRGQXgkseGb1b5";
266 return "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6"
271 return "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6"
274 return twoAccountArray;
280 Throw<std::runtime_error>(
311 "No ledger_entry params provided.",
314 auto tryField = [&](
Json::Value fieldValue) ->
void {
315 correctRequest[fieldName] = fieldValue;
321 auto const expectedErrMsg =
327 for (
auto const& value : badValues)
352 correctRequest[parentFieldName].
removeMember(fieldName);
376 auto tryField = [&](
Json::Value fieldValue) ->
void {
377 correctRequest[parentFieldName][fieldName] = fieldValue;
392 for (
auto const& value : badValues)
441 for (
auto const& subfield : subfields)
443 correctOutput[parentField][subfield.fieldName] =
447 for (
auto const& subfield : subfields)
449 auto const fieldType =
getFieldType(subfield.fieldName);
456 subfield.malformedErrorMsg,
466 using namespace test::jtx;
474 jvParams[jss::account_root] = alice.human();
475 jvParams[jss::ledger_hash] =
476 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
478 auto const jrr = env.
rpc(
479 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
485 jvParams[jss::account_root] = alice.human();
489 auto tryField = [&](
Json::Value fieldValue) ->
void {
490 jvParams[jss::ledger_hash] = fieldValue;
499 "Invalid field 'ledger_hash', not hex string.");
503 for (
auto const& value : badValues)
513 jvParams[jss::ledger_index] =
"validated";
514 jvParams[jss::index] =
515 "00000000000000000000000000000000000000000000000000000000000000"
517 auto const jrr = env.
rpc(
518 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
526 jvParams[jss::features] =
527 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
529 jvParams[jss::api_version] = apiVersion;
531 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
539 "No ledger_entry params provided.");
548 using namespace test::jtx;
551 cfg->FEES.reference_fee = 10;
552 Env env{*
this, std::move(cfg)};
562 BEAST_EXPECT(jrr[jss::ledger_hash] ==
ledgerHash);
563 BEAST_EXPECT(jrr[jss::ledger_index] == 3);
570 jvParams[jss::account_root] = alice.human();
573 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
574 BEAST_EXPECT(jrr.
isMember(jss::node));
575 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
576 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
577 accountRootIndex = jrr[jss::index].
asString();
580 constexpr char alicesAcctRootBinary[]{
581 "1100612200800000240000000425000000032D00000000559CE54C3B934E4"
582 "73A995B477E92EC229F99CED5B62BF4D2ACE4DC42719103AE2F6240000002"
583 "540BE4008114AE123A8556F3CF91154711376AFB0F894F832B3D"};
587 jvParams[jss::account_root] = alice.human();
588 jvParams[jss::binary] = 1;
591 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
592 BEAST_EXPECT(jrr.
isMember(jss::node_binary));
593 BEAST_EXPECT(jrr[jss::node_binary] == alicesAcctRootBinary);
598 jvParams[jss::index] = accountRootIndex;
600 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
601 BEAST_EXPECT(!jrr.
isMember(jss::node_binary));
602 BEAST_EXPECT(jrr.
isMember(jss::node));
603 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
604 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
609 jvParams[jss::index] = accountRootIndex;
610 jvParams[jss::binary] = 0;
612 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
613 BEAST_EXPECT(jrr.
isMember(jss::node));
614 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
615 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
620 jvParams[jss::account] = alice.human();
623 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
624 BEAST_EXPECT(jrr.
isMember(jss::node));
625 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
626 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
627 accountRootIndex = jrr[jss::index].
asString();
645 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
654 using namespace test::jtx;
664 auto const amendments = [&](
OpenView& view,
672 "714D104A72F9B4369F97ABF044EE"));
675 "21192D63DE53FFB46E43B9DC8373"));
678 "CC3E51F522F978041E4B57D9158C"));
681 "0F094B02226C1C14AD2858962ED4"));
689 majority1.setFieldH256(
692 "647693B50C5E87A80DFD6FCFAC50"));
693 majority1.setFieldU32(sfCloseTime, 779561310);
694 majorities.
push_back(std::move(majority1));
697 majority2.setFieldH256(
700 "E40AD19554A5EBECDCEC8A1F77FE"));
701 majority2.setFieldU32(sfCloseTime, 779561310);
702 majorities.
push_back(std::move(majority2));
704 sle->setFieldArray(sfMajorities, majorities);
715 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
717 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Amendments);
733 using namespace test::jtx;
740 AMM amm(env, alice,
XRP(10), alice[
"USD"](1000));
745 jvParams[jss::amm] =
to_string(amm.ammID());
749 result.isObject() && result.isMember(jss::result) &&
750 !result[jss::result].isMember(jss::error) &&
751 result[jss::result].isMember(jss::node) &&
752 result[jss::result][jss::node].isMember(
753 sfLedgerEntryType.jsonName) &&
754 result[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
763 obj[jss::currency] =
"XRP";
764 ammParams[jss::asset] = obj;
768 obj[jss::currency] =
"USD";
769 obj[jss::issuer] = alice.human();
770 ammParams[jss::asset2] = obj;
772 jvParams[jss::amm] = ammParams;
776 result.isObject() && result.isMember(jss::result) &&
777 !result[jss::result].isMember(jss::error) &&
778 result[jss::result].isMember(jss::node) &&
779 result[jss::result][jss::node].isMember(
780 sfLedgerEntryType.jsonName) &&
781 result[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
790 {jss::asset,
"malformedRequest"},
791 {jss::asset2,
"malformedRequest"},
799 using namespace test::jtx;
814 jvParams[jss::check] =
to_string(checkId.key);
817 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
819 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
820 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
828 jvParams[jss::account_root] = alice.human();
830 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
831 accountRootIndex = jrr[jss::index].
asString();
834 jvParams[jss::check] = accountRootIndex;
837 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
839 jrr,
"unexpectedLedgerType",
"Unexpected ledger type.");
852 using namespace test::jtx;
855 Account const issuer{
"issuer"};
858 char const credType[] =
"abcde";
860 env.
fund(
XRP(5000), issuer, alice, bob);
872 !jv[jss::result].
isMember(jss::error) &&
873 jv[jss::result].
isMember(jss::node) &&
874 jv[jss::result][jss::node].
isMember(
875 sfLedgerEntryType.jsonName) &&
876 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
884 !jv[jss::result].
isMember(jss::error) &&
885 jv[jss::result].
isMember(jss::node) &&
886 jv[jss::result][jss::node].
isMember(
887 sfLedgerEntryType.jsonName) &&
888 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
896 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
899 jv[jss::result],
"entryNotFound",
"Entry not found.");
908 {jss::subject,
"malformedRequest"},
909 {jss::issuer,
"malformedRequest"},
910 {jss::credential_type,
"malformedRequest"},
920 using namespace test::jtx;
925 env.
fund(
XRP(10000), alice, bob);
934 jvParams[jss::delegate][jss::account] = alice.human();
935 jvParams[jss::delegate][jss::authorize] = bob.human();
938 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
940 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Delegate);
941 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
942 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == bob.human());
943 delegateIndex = jrr[jss::node][jss::index].
asString();
948 jvParams[jss::delegate] = delegateIndex;
951 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
953 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Delegate);
954 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
955 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == bob.human());
964 {jss::account,
"malformedAddress"},
965 {jss::authorize,
"malformedAddress"},
975 using namespace test::jtx;
981 env.
fund(
XRP(10000), alice, becky);
992 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
993 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
996 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
999 jrr[jss::node][sfLedgerEntryType.jsonName] ==
1000 jss::DepositPreauth);
1001 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
1002 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
1003 depositPreauthIndex = jrr[jss::node][jss::index].
asString();
1008 jvParams[jss::deposit_preauth] = depositPreauthIndex;
1011 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1014 jrr[jss::node][sfLedgerEntryType.jsonName] ==
1015 jss::DepositPreauth);
1016 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
1017 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
1023 jss::deposit_preauth,
1025 {jss::owner,
"malformedOwner"},
1026 {jss::authorized,
"malformedAuthorized",
false},
1034 testcase(
"Deposit Preauth with credentials");
1036 using namespace test::jtx;
1039 Account const issuer{
"issuer"};
1042 char const credType[] =
"abcde";
1044 env.
fund(
XRP(5000), issuer, alice, bob);
1058 jvParams[jss::ledger_index] = jss::validated;
1059 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1061 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1064 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1067 jo[jss::issuer] = issuer.human();
1069 arr.append(std::move(jo));
1074 jrr.isObject() && jrr.isMember(jss::result) &&
1075 !jrr[jss::result].isMember(jss::error) &&
1076 jrr[jss::result].isMember(jss::node) &&
1077 jrr[jss::result][jss::node].isMember(
1078 sfLedgerEntryType.jsonName) &&
1079 jrr[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
1080 jss::DepositPreauth);
1086 jvParams[jss::ledger_index] = jss::validated;
1087 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1089 auto tryField = [&](
Json::Value fieldValue) ->
void {
1092 jo[jss::issuer] = fieldValue;
1095 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1099 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1100 auto const expectedErrMsg = fieldValue.
isNull()
1104 jrr,
"malformedAuthorizedCredentials", expectedErrMsg);
1108 for (
auto const& value : badValues)
1118 jvParams[jss::ledger_index] = jss::validated;
1119 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1121 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1124 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1127 jo[jss::issuer] = issuer.human();
1130 arr.append(std::move(jo));
1135 "malformedAuthorizedCredentials",
1137 jss::authorized_credentials,
"array"));
1143 jvParams[jss::ledger_index] = jss::validated;
1144 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1146 auto tryField = [&](
Json::Value fieldValue) ->
void {
1149 jo[jss::issuer] = issuer.human();
1150 jo[jss::credential_type] = fieldValue;
1152 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1156 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1157 auto const expectedErrMsg = fieldValue.
isNull()
1160 jss::credential_type,
"hex string");
1162 jrr,
"malformedAuthorizedCredentials", expectedErrMsg);
1166 for (
auto const& value : badValues)
1176 jvParams[jss::ledger_index] = jss::validated;
1177 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1178 jvParams[jss::deposit_preauth][jss::authorized] = alice.human();
1180 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1183 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1186 jo[jss::issuer] = issuer.human();
1188 arr.append(std::move(jo));
1195 "Must have exactly one of `authorized` and "
1196 "`authorized_credentials`.");
1202 jvParams[jss::ledger_index] = jss::validated;
1203 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1207 jss::deposit_preauth,
1208 jss::authorized_credentials,
1210 "malformedAuthorizedCredentials",
1217 jvParams[jss::ledger_index] = jss::validated;
1218 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1219 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1222 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1223 arr.append(
"foobar");
1229 "malformedAuthorizedCredentials",
1230 "Invalid field 'authorized_credentials', not array.");
1236 jvParams[jss::ledger_index] = jss::validated;
1237 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1238 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1241 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1244 arr.
append(std::move(payload));
1250 "malformedAuthorizedCredentials",
1251 "Invalid field 'authorized_credentials', not array.");
1257 jvParams[jss::ledger_index] = jss::validated;
1258 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1259 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1266 "malformedAuthorizedCredentials",
1267 "Invalid field 'authorized_credentials', array empty.");
1283 sizeof(credTypes) /
sizeof(credTypes[0]) >
1287 jvParams[jss::ledger_index] = jss::validated;
1288 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1289 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1293 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1295 for (
auto cred : credTypes)
1298 jo[jss::issuer] = issuer.human();
1300 arr.append(std::move(jo));
1307 "malformedAuthorizedCredentials",
1308 "Invalid field 'authorized_credentials', array too long.");
1316 using namespace test::jtx;
1320 auto const USD = gw[
"USD"];
1321 env.
fund(
XRP(10000), alice, gw);
1324 env.
trust(USD(1000), alice);
1329 for (
int d = 1'000'032; d >= 1'000'000; --d)
1339 BEAST_EXPECT(jrr[jss::ledger_hash] ==
ledgerHash);
1340 BEAST_EXPECT(jrr[jss::ledger_index] == 5);
1344 "A33EC6BB85FB5674074C4A3A43373BB17645308F3EAE1933E3E35252162B217D";
1348 jvParams[jss::directory] = dirRootIndex;
1351 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1352 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 32);
1358 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1360 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1361 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1367 jvParams[jss::directory][jss::owner] = alice.human();
1370 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1371 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1377 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1378 jvParams[jss::directory][jss::sub_index] = 1;
1380 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1381 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1382 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1388 jvParams[jss::directory][jss::owner] = alice.human();
1389 jvParams[jss::directory][jss::sub_index] = 1;
1392 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1393 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1394 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1405 "malformedRequest");
1411 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1441 jvParams[jss::directory][jss::owner] = alice.human();
1442 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1445 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1449 "Must have exactly one of `owner` and `dir_root` fields.");
1455 jvParams[jss::directory][jss::sub_index] = 1;
1458 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1462 "Must have exactly one of `owner` and `dir_root` fields.");
1470 using namespace test::jtx;
1482 jv[jss::TransactionType] = jss::EscrowCreate;
1483 jv[jss::Account] = account.human();
1484 jv[jss::Destination] = to.human();
1486 jv[sfFinishAfter.jsonName] =
1487 cancelAfter.time_since_epoch().count() + 2;
1491 using namespace std::chrono_literals;
1492 env(escrowCreate(alice, alice,
XRP(333), env.
now() + 2s));
1501 jvParams[jss::escrow][jss::owner] = alice.human();
1502 jvParams[jss::escrow][jss::seq] = env.
seq(alice) - 1;
1504 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1506 jrr[jss::node][jss::Amount] ==
XRP(333).value().getText());
1507 escrowIndex = jrr[jss::index].
asString();
1512 jvParams[jss::escrow] = escrowIndex;
1515 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1517 jrr[jss::node][jss::Amount] ==
XRP(333).value().getText());
1524 {{jss::owner,
"malformedOwner"}, {jss::seq,
"malformedSeq"}});
1532 using namespace test::jtx;
1541 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1543 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::FeeSettings);
1552 "malformedRequest");
1559 using namespace test::jtx;
1568 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1570 jrr[jss::node][sfLedgerEntryType.jsonName] ==
1580 "malformedRequest");
1587 using namespace test::jtx;
1591 Account const issuer{
"issuer"};
1593 env.
fund(
XRP(1000), issuer, buyer);
1606 jvParams[jss::nft_offer] =
to_string(offerID);
1608 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1610 jrr[jss::node][sfLedgerEntryType.jsonName] ==
1612 BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == issuer.human());
1614 jrr[jss::node][sfNFTokenID.jsonName] ==
to_string(nftokenID0));
1615 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"1");
1626 using namespace test::jtx;
1630 Account const issuer{
"issuer"};
1637 BEAST_EXPECT(env.
le(nftpage) !=
nullptr);
1643 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1645 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::NFTokenPage);
1656 using namespace test::jtx;
1671 auto disabledValidator =
1674 "ED58F6770DB5DD77E59D28CB650EC3816E2FC95021BB56E720C9A1"
1676 disabledValidator.setFieldVL(sfPublicKey, *pubKeyBlob);
1677 disabledValidator.setFieldU32(
1678 sfFirstLedgerSequence, 91371264);
1679 disabledValidators.
push_back(std::move(disabledValidator));
1682 sfDisabledValidators, disabledValidators);
1686 "A95160CC6D351341B9"
1688 sle->setFieldU32(sfPreviousTxnLgrSeq, 91442944);
1699 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1701 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::NegativeUNL);
1710 "malformedRequest");
1717 using namespace test::jtx;
1721 auto const USD = gw[
"USD"];
1722 env.
fund(
XRP(10000), alice, gw);
1725 env(
offer(alice, USD(321),
XRP(322)));
1734 jvParams[jss::offer][jss::account] = alice.human();
1735 jvParams[jss::offer][jss::seq] = env.
seq(alice) - 1;
1738 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1739 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1740 offerIndex = jrr[jss::index].
asString();
1745 jvParams[jss::offer] = offerIndex;
1747 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1748 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1756 {{jss::account,
"malformedAddress"},
1757 {jss::seq,
"malformedRequest"}});
1765 using namespace test::jtx;
1780 jv[jss::TransactionType] = jss::PaymentChannelCreate;
1781 jv[jss::Account] = account.human();
1782 jv[jss::Destination] = to.human();
1784 jv[sfSettleDelay.jsonName] = settleDelay.count();
1785 jv[sfPublicKey.jsonName] =
strHex(pk.slice());
1789 env(payChanCreate(alice, env.
master,
XRP(57), 18s, alice.pk()));
1799 jvParams[jss::payment_channel] =
to_string(payChanIndex);
1802 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1803 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"57000000");
1804 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"0");
1805 BEAST_EXPECT(jrr[jss::node][sfSettleDelay.jsonName] == 18);
1813 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1827 using namespace test::jtx;
1831 auto const USD = gw[
"USD"];
1832 env.
fund(
XRP(10000), alice, gw);
1835 env.
trust(USD(999), alice);
1838 env(
pay(gw, alice, USD(97)));
1842 for (
auto const& fieldName : {jss::ripple_state, jss::state})
1851 jvParams[fieldName][jss::accounts][0u] = alice.human();
1852 jvParams[fieldName][jss::accounts][1u] = gw.human();
1853 jvParams[fieldName][jss::currency] =
"USD";
1856 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1858 jrr[jss::node][sfBalance.jsonName][jss::value] ==
"-97");
1860 jrr[jss::node][sfHighLimit.jsonName][jss::value] ==
"999");
1868 {jss::accounts,
"malformedRequest"},
1869 {jss::currency,
"malformedCurrency"},
1877 jvParams[fieldName][jss::accounts][0u] = alice.human();
1878 jvParams[fieldName][jss::currency] =
"USD";
1881 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1885 "Invalid field 'accounts', not length-2 array of "
1893 jvParams[fieldName][jss::accounts][0u] = alice.human();
1894 jvParams[fieldName][jss::accounts][1u] = gw.human();
1895 jvParams[fieldName][jss::accounts][2u] = alice.human();
1896 jvParams[fieldName][jss::currency] =
"USD";
1899 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1903 "Invalid field 'accounts', not length-2 array of "
1910 auto tryField = [&](
Json::Value badAccount) ->
void {
1914 jvParams[fieldName][jss::accounts][0u] = badAccount;
1915 jvParams[fieldName][jss::accounts][1u] = gw.human();
1916 jvParams[fieldName][jss::currency] =
"USD";
1926 jss::accounts,
"array of Accounts"));
1932 jvParams[fieldName][jss::accounts][0u] = alice.human();
1933 jvParams[fieldName][jss::accounts][1u] = badAccount;
1934 jvParams[fieldName][jss::currency] =
"USD";
1944 jss::accounts,
"array of Accounts"));
1949 for (
auto const& value : badValues)
1960 jvParams[fieldName][jss::accounts][0u] = alice.human();
1961 jvParams[fieldName][jss::accounts][1u] = alice.human();
1962 jvParams[fieldName][jss::currency] =
"USD";
1965 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1969 "Cannot have a trustline to self.");
1978 using namespace test::jtx;
1987 using namespace test::jtx;
2003 jvParams[jss::ticket] =
2007 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2016 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2018 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Ticket);
2019 BEAST_EXPECT(jrr[jss::node][sfTicketSequence.jsonName] == tkt1);
2025 jvParams[jss::ticket][jss::account] = env.
master.
human();
2026 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 1;
2029 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2031 jrr[jss::node][jss::index] ==
2038 jvParams[jss::ticket][jss::account] = env.
master.
human();
2039 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 2;
2042 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2051 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2053 jrr,
"unexpectedLedgerType",
"Unexpected ledger type.");
2062 {jss::account,
"malformedAddress"},
2063 {jss::ticket_seq,
"malformedRequest"},
2072 using namespace test::jtx;
2083 jv[jss::TransactionType] = jss::DIDSet;
2084 jv[jss::Account] = account.human();
2090 env(didCreate(alice));
2098 jvParams[jss::did] = alice.human();
2101 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2103 jrr[jss::node][sfDIDDocument.jsonName] ==
2114 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2125 "malformedAddress");
2132 testcase(
"Invalid Oracle Ledger Entry");
2142 .fee =
static_cast<int>(env.
current()->fees().base.drops())});
2150 {jss::account,
"malformedAccount"},
2151 {jss::oracle_document_id,
"malformedDocumentID"},
2164 auto const baseFee =
2165 static_cast<int>(env.
current()->fees().base.drops());
2168 for (
int i = 0; i < 10; ++i)
2174 env, {.owner = owner, .documentID = i, .fee = baseFee});
2179 env, {.owner = owner, .documentID = i + 10, .fee = baseFee});
2181 oracles.
push_back(oracle1.documentID());
2183 for (
int i = 0; i < accounts.
size(); ++i)
2185 auto const jv = [&]() {
2188 return Oracle::ledgerEntry(env, accounts[i], oracles[i]);
2190 return Oracle::ledgerEntry(
2196 jv[jss::node][jss::Owner] ==
to_string(accounts[i]));
2209 using namespace test::jtx;
2215 MPTTester mptAlice(env, alice, {.holders = {bob}});
2222 mptAlice.authorize({.account = bob, .holderCount = 1});
2227 "00000193B9DDCAF401B5B3B26875986043F82CD0D13B4315";
2231 jvParams[jss::mpt_issuance] =
strHex(mptAlice.issuanceID());
2234 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2236 jrr[jss::node][sfMPTokenMetadata.jsonName] ==
2239 jrr[jss::node][jss::mpt_issuance_id] ==
2240 strHex(mptAlice.issuanceID()));
2245 jvParams[jss::mpt_issuance] = badMptID;
2248 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2255 jvParams[jss::mptoken][jss::account] = bob.
human();
2256 jvParams[jss::mptoken][jss::mpt_issuance_id] =
2257 strHex(mptAlice.issuanceID());
2260 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2262 jrr[jss::node][sfMPTokenIssuanceID.jsonName] ==
2263 strHex(mptAlice.issuanceID()));
2269 jvParams[jss::mptoken][jss::account] = bob.
human();
2270 jvParams[jss::mptoken][jss::mpt_issuance_id] = badMptID;
2273 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2284 "malformedRequest");
2293 using namespace test::jtx;
2296 Account const issuer{
"issuer"};
2300 env.
fund(
XRP(5000), issuer, alice, bob);
2303 auto const seq = env.
seq(alice);
2307 if (!BEAST_EXPECT(objects.size() == 1))
2313 params[jss::ledger_index] = jss::validated;
2314 params[jss::permissioned_domain][jss::account] = alice.human();
2315 params[jss::permissioned_domain][jss::seq] =
seq;
2316 auto jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2319 !jv[jss::result].
isMember(jss::error) &&
2320 jv[jss::result].
isMember(jss::node) &&
2321 jv[jss::result][jss::node].
isMember(
2322 sfLedgerEntryType.jsonName) &&
2323 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
2324 jss::PermissionedDomain);
2331 params[jss::ledger_index] = jss::validated;
2332 params[jss::permissioned_domain] = pdIdx;
2333 jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2336 !jv[jss::result].
isMember(jss::error) &&
2337 jv[jss::result].
isMember(jss::node) &&
2338 jv[jss::result][jss::node].
isMember(
2339 sfLedgerEntryType.jsonName) &&
2340 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
2341 jss::PermissionedDomain);
2347 params[jss::ledger_index] = jss::validated;
2348 params[jss::permissioned_domain] =
2349 "12F1F1F1F180D67377B2FAB292A31C922470326268D2B9B74CD1E582645B9A"
2351 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2353 jrr[jss::result],
"entryNotFound",
"Entry not found.");
2359 jss::permissioned_domain,
2361 {jss::account,
"malformedAddress"},
2362 {jss::seq,
"malformedRequest"},
2371 using namespace test::jtx;
2401 jv.isObject() && jv.isMember(jss::result) &&
2402 !jv[jss::result].isMember(jss::error) &&
2403 jv[jss::result].isMember(jss::node) &&
2404 jv[jss::result][jss::node].isMember(
2405 sfLedgerEntryType.jsonName) &&
2406 jv[jss::result][jss::node]
2407 [sfLedgerEntryType.jsonName] == expectedType,
2413 jv.isObject() && jv.isMember(jss::result) &&
2414 jv[jss::result].isMember(jss::error) &&
2415 !jv[jss::result].isMember(jss::node) &&
2416 jv[jss::result][jss::error] ==
2417 expectedError.value_or(
"entryNotFound"),
2434 Keylet const& expectedKey,
2436 testcase << expectedType.c_str() << (good ?
"" :
" not")
2439 auto const hexKey =
strHex(expectedKey.key);
2445 params[jss::ledger_index] = jss::validated;
2449 checkResult(
false, jv, expectedType,
"malformedRequest");
2450 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2456 params[jss::ledger_index] = jss::validated;
2457 params[field] =
"arbitrary string";
2460 checkResult(
false, jv, expectedType,
"malformedRequest");
2461 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2467 params[jss::ledger_index] = jss::validated;
2468 params[field] =
false;
2471 checkResult(
false, jv, expectedType,
"invalidParams");
2472 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2480 params[jss::ledger_index] = jss::validated;
2481 params[field] = badKey;
2484 checkResult(
false, jv, expectedType,
"entryNotFound");
2486 jv[jss::result][jss::index] == badKey,
to_string(jv));
2492 params[jss::ledger_index] = jss::validated;
2493 params[jss::index] = field;
2494 params[jss::api_version] = 2;
2497 checkResult(
false, jv, expectedType,
"malformedRequest");
2498 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2506 params[jss::ledger_index] = jss::validated;
2507 params[field] =
true;
2512 jv[jss::result][jss::index].asString();
2513 BEAST_EXPECTS(hexKey == pdIdx,
to_string(jv));
2514 checkResult(good, jv, expectedType);
2523 params[jss::ledger_index] = jss::validated;
2524 params[field] = hexKey;
2527 checkResult(good, jv, expectedType);
2528 BEAST_EXPECT(jv[jss::result][jss::index].asString() == hexKey);
2535 params[jss::ledger_index] = jss::validated;
2536 params[jss::index] = field;
2537 params[jss::api_version] = 2;
2540 checkResult(
false, jv, expectedType,
"malformedRequest");
2541 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2547 params[jss::ledger_index] = jss::validated;
2548 params[jss::index] = field;
2549 params[jss::api_version] = 3;
2553 BEAST_EXPECT(jv[jss::result][jss::index].asString() == hexKey);
2554 checkResult(good, jv, expectedType);
2560 params[jss::ledger_index] = jss::validated;
2561 params[jss::index] = pdIdx;
2565 BEAST_EXPECT(jv[jss::result][jss::index].asString() == hexKey);
2566 checkResult(good, jv, expectedType);
2571 test(jss::fee, jss::FeeSettings,
keylet::fees(),
true);
2575 test(jss::hashes, jss::LedgerHashes,
keylet::skip(),
true);
2581 using namespace test::jtx;
2611 jv.isObject() && jv.isMember(jss::result) &&
2612 !jv[jss::result].isMember(jss::error) &&
2613 jv[jss::result].isMember(jss::node) &&
2614 jv[jss::result][jss::node].isMember(
2615 sfLedgerEntryType.jsonName) &&
2616 jv[jss::result][jss::node]
2617 [sfLedgerEntryType.jsonName] == jss::LedgerHashes,
2620 jv[jss::result].isMember(jss::node) &&
2621 jv[jss::result][jss::node].isMember(
"Hashes") &&
2622 jv[jss::result][jss::node][
"Hashes"].size() ==
2624 to_string(jv[jss::result][jss::node][
"Hashes"].size()));
2629 jv.isObject() && jv.isMember(jss::result) &&
2630 jv[jss::result].isMember(jss::error) &&
2631 !jv[jss::result].isMember(jss::node) &&
2632 jv[jss::result][jss::error] ==
2633 expectedError.value_or(
"entryNotFound"),
2649 Keylet const& expectedKey,
2651 int expectedCount = 0) {
2654 << (good ?
"" :
" not") <<
" found";
2656 auto const hexKey =
strHex(expectedKey.key);
2662 params[jss::ledger_index] = jss::validated;
2664 auto jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2665 checkResult(
false, jv, 0,
"malformedRequest");
2666 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2672 params[jss::ledger_index] = jss::validated;
2673 params[jss::hashes] =
"arbitrary string";
2676 checkResult(
false, jv, 0,
"malformedRequest");
2677 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2683 params[jss::ledger_index] = jss::validated;
2684 params[jss::hashes] =
"10";
2687 checkResult(
false, jv, 0,
"malformedRequest");
2688 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2694 params[jss::ledger_index] = jss::validated;
2695 params[jss::hashes] =
false;
2698 checkResult(
false, jv, 0,
"invalidParams");
2699 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2705 params[jss::ledger_index] = jss::validated;
2706 params[jss::hashes] = -1;
2709 checkResult(
false, jv, 0,
"internal");
2710 BEAST_EXPECT(!jv[jss::result].isMember(jss::index));
2717 params[jss::ledger_index] = jss::validated;
2718 params[jss::hashes] = badKey;
2721 checkResult(
false, jv, 0,
"entryNotFound");
2722 BEAST_EXPECT(jv[jss::result][jss::index] == badKey);
2729 params[jss::ledger_index] = jss::validated;
2730 params[jss::hashes] = ledger;
2733 checkResult(good, jv, expectedCount);
2736 jv[jss::result][jss::index].asString();
2737 BEAST_EXPECTS(hexKey == pdIdx,
strHex(pdIdx));
2743 params[jss::ledger_index] = jss::validated;
2744 params[jss::hashes] = hexKey;
2747 checkResult(good, jv, expectedCount);
2750 hexKey == jv[jss::result][jss::index].asString(),
2751 strHex(jv[jss::result][jss::index].asString()));
2757 params[jss::ledger_index] = jss::validated;
2758 params[jss::index] = hexKey;
2761 checkResult(good, jv, expectedCount);
2764 hexKey == jv[jss::result][jss::index].asString(),
2765 strHex(jv[jss::result][jss::index].asString()));
2777 for (
auto i = env.
current()->seq(); i <= 250; ++i)
2788 for (
auto i = env.
current()->seq(); i <= 260; ++i)
2803 using namespace test::jtx;
2819 env.
rpc(
"ledger_entry",
to_string(checkId.key))[jss::result];
2821 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
2822 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
2871 if (BEAST_EXPECT(jv.
isMember(jss::status)))
2872 BEAST_EXPECT(jv[jss::status] ==
"error");
2873 if (BEAST_EXPECT(jv.
isMember(jss::error)))
2874 BEAST_EXPECT(jv[jss::error] == err);
2879 jv[jss::error_message] ==
"");
2881 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
2882 BEAST_EXPECT(jv[jss::error_message] == msg);
2889 using namespace test::jtx;
2903 jvParams[jss::bridge] =
jvb;
2905 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2907 BEAST_EXPECT(jrr.
isMember(jss::node));
2908 auto r = jrr[jss::node];
2910 BEAST_EXPECT(r.isMember(jss::Account));
2913 BEAST_EXPECT(r.isMember(jss::Flags));
2915 BEAST_EXPECT(r.isMember(sfLedgerEntryType.jsonName));
2916 BEAST_EXPECT(r[sfLedgerEntryType.jsonName] == jss::Bridge);
2919 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
2920 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 0);
2923 BEAST_EXPECT(r.isMember(sfXChainAccountClaimCount.jsonName));
2924 BEAST_EXPECT(r[sfXChainAccountClaimCount.jsonName].asInt() == 0);
2926 BEAST_EXPECT(r.isMember(jss::index));
2927 bridge_index = r[jss::index].asString();
2933 jvParams[jss::index] = bridge_index;
2935 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2937 BEAST_EXPECT(jrr.
isMember(jss::node));
2938 BEAST_EXPECT(jrr[jss::node] == mcBridge);
2945 jvParams[jss::bridge] =
jvb;
2948 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2963 jvParams[jss::bridge] =
jvb;
2965 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2967 BEAST_EXPECT(jrr.
isMember(jss::node));
2968 auto r = jrr[jss::node];
2971 BEAST_EXPECT(r.isMember(sfXChainClaimID.jsonName));
2972 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
2979 testcase(
"ledger_entry: xchain_claim_id");
2980 using namespace test::jtx;
2997 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
3000 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3002 BEAST_EXPECT(jrr.
isMember(jss::node));
3003 auto r = jrr[jss::node];
3005 BEAST_EXPECT(r.isMember(jss::Account));
3008 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
3009 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 1);
3010 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
3017 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
3020 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3022 BEAST_EXPECT(jrr.
isMember(jss::node));
3023 auto r = jrr[jss::node];
3025 BEAST_EXPECT(r.isMember(jss::Account));
3026 BEAST_EXPECT(r[jss::Account] ==
scBob.
human());
3028 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
3029 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
3030 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
3037 testcase(
"ledger_entry: xchain_create_account_claim_id");
3038 using namespace test::jtx;
3049 auto const amt =
XRP(1000);
3056 size_t constexpr num_attest = 3;
3069 for (
size_t i = 0; i < num_attest; ++i)
3071 scEnv(attestations[i]);
3078 jvParams[jss::xchain_owned_create_account_claim_id] =
3080 jvParams[jss::xchain_owned_create_account_claim_id]
3081 [jss::xchain_owned_create_account_claim_id] = 1;
3083 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3085 BEAST_EXPECT(jrr.
isMember(jss::node));
3086 auto r = jrr[jss::node];
3088 BEAST_EXPECT(r.isMember(jss::Account));
3091 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
3092 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 1);
3095 r.isMember(sfXChainCreateAccountAttestations.jsonName));
3096 auto attest = r[sfXChainCreateAccountAttestations.jsonName];
3097 BEAST_EXPECT(attest.isArray());
3098 BEAST_EXPECT(attest.size() == 3);
3100 sfXChainCreateAccountProofSig.jsonName));
3102 for (
size_t i = 0; i < num_attest; ++i)
3105 [sfXChainCreateAccountProofSig.jsonName];
3107 a[i].isMember(jss::Amount) &&
3110 a[i].isMember(jss::Destination) &&
3113 a[i].isMember(sfAttestationSignerAccount.jsonName) &&
3116 return a[i][sfAttestationSignerAccount.jsonName] ==
3120 a[i].isMember(sfAttestationRewardAccount.jsonName) &&
3125 return a[i][sfAttestationRewardAccount.jsonName] ==
3129 a[i].isMember(sfWasLockingChainSend.jsonName) &&
3130 a[i][sfWasLockingChainSend.jsonName] == 1);
3132 a[i].isMember(sfSignatureReward.jsonName) &&
3133 a[i][sfSignatureReward.jsonName].
asInt() ==
3142 scEnv(attestations[i]);
3148 jvParams[jss::xchain_owned_create_account_claim_id] =
3150 jvParams[jss::xchain_owned_create_account_claim_id]
3151 [jss::xchain_owned_create_account_claim_id] = 1;
3153 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
3169BEAST_DEFINE_TESTSUITE(LedgerEntry_XChain,
rpc,
xrpl);
Lightweight wrapper to tag static string.
constexpr char const * c_str() 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 toStyledString() const
void clear()
Remove all object members and array elements.
Value removeMember(char const *key)
Remove and return the named member.
std::string asString() const
Returns the unquoted string value.
bool isNull() const
isNull() tests to see if this field is null.
bool isMember(char const *key) const
Return true if the object has a member named key.
A generic endpoint for log messages.
testcase_t testcase
Memberspace for declaring test cases.
void fail(String const &reason, char const *file, int line)
Record a failure.
virtual OpenLedger & openLedger()=0
bool modify(modify_type const &f)
Modify the open ledger.
Writable ledger view that accumulates state and tx changes.
void rawInsert(std::shared_ptr< SLE > const &sle) override
Unconditionally insert a state item.
void push_back(STObject const &object)
static STObject makeInnerObject(SField const &name)
static base_uint fromVoid(void const *data)
void testCreateAccountClaimID()
void run() override
Runs the suite.
void checkErrorValue(Json::Value const &jv, std::string const &err, std::string const &msg)
void checkErrorValue(Json::Value const &jv, std::string const &err, std::string const &msg, std::source_location const location=std::source_location::current())
void testOracleLedgerEntry()
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 run() override
Runs the suite.
void testMalformedField(test::jtx::Env &env, Json::Value correctRequest, Json::StaticString const fieldName, FieldType const typeID, std::string const &expectedError, bool required=true, std::source_location const location=std::source_location::current())
void testDepositPreauth()
void runLedgerEntryTest(test::jtx::Env &env, Json::StaticString const &parentField, std::source_location const location=std::source_location::current())
void runLedgerEntryTest(test::jtx::Env &env, Json::StaticString const &parentField, std::vector< Subfield > const &subfields, 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()
Json::Value getCorrectValue(Json::StaticString fieldName)
void testInvalidOracleLedgerEntry()
std::vector< Json::Value > getBadValues(FieldType fieldType)
Convenience class to test AMM functionality.
Immutable cryptographic account descriptor.
std::string const & human() const
Returns the human readable public key.
static Account const master
The master account.
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.
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
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.
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
NetClock::time_point now()
Returns the current network time.
void create(MPTCreate const &arg=MPTCreate{})
Oracle class facilitates unit-testing of the Price Oracle feature.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Sets the optional Destination field on an NFTokenOffer.
@ arrayValue
array value (ordered list)
@ objectValue
object value (collection of name/value pairs).
std::string expected_field_message(std::string const &name, std::string const &type)
std::string missing_field_message(std::string const &name)
Keylet const & skip() noexcept
The index of the "short" skip list.
Keylet const & negativeUNL() noexcept
The (fixed) index of the object containing the ledger negativeUNL.
Keylet nftpage_max(AccountID const &owner)
A keylet for the owner's last possible NFT page.
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Keylet const & amendments() noexcept
The index of the amendment table.
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
Json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
Json::Value ledgerEntry(jtx::Env &env, jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
Json::Value create(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.
Json::Value setTx(AccountID const &account, Credentials const &credentials, std::optional< uint256 > domain)
std::map< uint256, Json::Value > getObjects(Account const &account, Env &env, bool withType)
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 sidechain_xchain_account_create(Account const &acc, Json::Value const &bridge, Account const &dst, AnyAmount const &amt, AnyAmount const &reward)
constexpr std::size_t UT_XCHAIN_DEFAULT_NUM_SIGNERS
XRP_t const XRP
Converts to XRP Issue or STAmount.
require_t required(Args const &... args)
Compose many condition functors into one.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
JValueVec create_account_attestations(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 xchain_create_claim_id(Account const &acc, Json::Value const &bridge, STAmount const &reward, Account const &otherChainSource)
FeatureBitset testable_amendments()
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
std::vector< std::pair< Json::StaticString, FieldType > > mappings
FieldType getFieldType(Json::StaticString fieldName)
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.
constexpr std::uint32_t const tfTransferable
constexpr std::uint32_t const tfMPTCanTransfer
std::string to_string(base_uint< Bits, Tag > const &a)
std::string strHex(FwdIt begin, FwdIt end)
constexpr std::uint32_t const tfMPTRequireAuth
uint256 getTicketIndex(AccountID const &account, std::uint32_t uSequence)
constexpr std::uint32_t asfDepositAuth
constexpr std::uint32_t const tfMPTCanTrade
constexpr std::uint32_t const tfMPTCanLock
constexpr std::uint32_t const tfMPTCanClawback
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
void forAllApiVersions(Fn const &fn, Args &&... args)
constexpr std::uint32_t const tfSellNFToken
constexpr std::uint32_t const tfMPTCanEscrow
A pair of SHAMap key and LedgerEntryType.
Json::StaticString fieldName
std::string malformedErrorMsg
void createBridgeObjects(Env &mcEnv, Env &scEnv)
Json::Value const jvXRPBridgeRPC
std::vector< Account > const payee
std::vector< signer > const signers
FeatureBitset const features
static constexpr int drop_per_xrp
Set the sequence number on a JTx.
A signer in a SignerList.