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 <xrpl/beast/unit_test.h>
9#include <xrpl/json/json_value.h>
10#include <xrpl/protocol/AccountID.h>
11#include <xrpl/protocol/ErrorCodes.h>
12#include <xrpl/protocol/STXChainBridge.h>
13#include <xrpl/protocol/jss.h>
15#if (defined(__clang_major__) && __clang_major__ < 15)
16#include <experimental/source_location>
19#include <source_location>
62 return pair.first == fieldName;
70 Throw<std::runtime_error>(
91 return "hex string or object";
95 return "length-2 array of Accounts";
101 Throw<std::runtime_error>(
115 if (BEAST_EXPECT(jv.
isMember(jss::status)))
118 if (BEAST_EXPECT(jv.
isMember(jss::error)))
120 jv[jss::error] == err,
121 "Expected error " + err +
", received " +
122 jv[jss::error].asString() +
", at line " +
129 jv[jss::error_message] ==
"",
130 "Expected no error message, received \"" +
131 jv[jss::error_message].asString() +
"\", at line " +
135 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
137 jv[jss::error_message] == msg,
138 "Expected error message \"" + msg +
"\", received \"" +
139 jv[jss::error_message].asString() +
"\", at line " +
149 obj[jss::account] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
150 obj[jss::ledger_index] =
"validated";
155 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
156 arr[1u] =
"validated";
170 "0123456789ABCDEFGH",
171 "rJxKV9e9p6wiPw!!!!xrJ4X1n98LosPL1sgcJW",
172 "rPSTrR5yEr11uMkfsz1kHCp9jK4aoa3Avv",
173 "n9K2isxwTxcSHJKxMkJznDoWXAUs7NNy49H9Fknz1pC7oHAH3kH9",
176 "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6B01403D"
187 indices.begin(), indices.end());
192 if (indexSet.
find(i) == indexSet.
end())
200 static auto const& badAccountValues = remove({12});
201 static auto const& badArrayValues = remove({17, 20});
202 static auto const& badBlobValues = remove({3, 7, 8, 16});
203 static auto const& badCurrencyValues = remove({14});
204 static auto const& badHashValues = remove({2, 3, 7, 8, 16});
205 static auto const& badIndexValues = remove({12, 16, 18, 19});
206 static auto const& badUInt32Values = remove({2, 3});
207 static auto const& badUInt64Values = remove({2, 3});
208 static auto const& badIssueValues = remove({});
213 return badAccountValues;
216 return badArrayValues;
218 return badBlobValues;
220 return badCurrencyValues;
222 return badHashValues;
224 return badIndexValues;
226 return badIssueValues;
228 return badUInt32Values;
230 return badUInt64Values;
232 Throw<std::runtime_error>(
243 arr[0u] =
"rhigTLJJyXXSRUyRCQtqi1NoAZZzZnS4KU";
244 arr[1u] =
"r4MrUGTdB57duTnRs6KbsRGQXgkseGb1b5";
249 arr[jss::currency] =
"XRP";
257 return "r4MrUGTdB57duTnRs6KbsRGQXgkseGb1b5";
265 return "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6"
270 return "5233D68B4D44388F98559DE42903767803EFA7C1F8D01413FC16EE6"
273 return twoAccountArray;
279 Throw<std::runtime_error>(
310 "No ledger_entry params provided.",
313 auto tryField = [&](
Json::Value fieldValue) ->
void {
314 correctRequest[fieldName] = fieldValue;
320 auto const expectedErrMsg =
326 for (
auto const& value : badValues)
351 correctRequest[parentFieldName].
removeMember(fieldName);
375 auto tryField = [&](
Json::Value fieldValue) ->
void {
376 correctRequest[parentFieldName][fieldName] = fieldValue;
391 for (
auto const& value : badValues)
440 for (
auto const& subfield : subfields)
442 correctOutput[parentField][subfield.fieldName] =
446 for (
auto const& subfield : subfields)
448 auto const fieldType =
getFieldType(subfield.fieldName);
455 subfield.malformedErrorMsg,
465 using namespace test::jtx;
473 jvParams[jss::account_root] = alice.human();
474 jvParams[jss::ledger_hash] =
475 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
477 auto const jrr = env.
rpc(
478 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
484 jvParams[jss::account_root] = alice.human();
488 auto tryField = [&](
Json::Value fieldValue) ->
void {
489 jvParams[jss::ledger_hash] = fieldValue;
498 "Invalid field 'ledger_hash', not hex string.");
502 for (
auto const& value : badValues)
512 jvParams[jss::ledger_index] =
"validated";
513 jvParams[jss::index] =
514 "00000000000000000000000000000000000000000000000000000000000000"
516 auto const jrr = env.
rpc(
517 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
525 jvParams[jss::features] =
526 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
528 jvParams[jss::api_version] = apiVersion;
530 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
538 "No ledger_entry params provided.");
547 using namespace test::jtx;
550 cfg->FEES.reference_fee = 10;
551 Env env{*
this, std::move(cfg)};
561 BEAST_EXPECT(jrr[jss::ledger_hash] ==
ledgerHash);
562 BEAST_EXPECT(jrr[jss::ledger_index] == 3);
569 jvParams[jss::account_root] = alice.human();
572 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
573 BEAST_EXPECT(jrr.
isMember(jss::node));
574 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
575 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
576 accountRootIndex = jrr[jss::index].
asString();
579 constexpr char alicesAcctRootBinary[]{
580 "1100612200800000240000000425000000032D00000000559CE54C3B934E4"
581 "73A995B477E92EC229F99CED5B62BF4D2ACE4DC42719103AE2F6240000002"
582 "540BE4008114AE123A8556F3CF91154711376AFB0F894F832B3D"};
586 jvParams[jss::account_root] = alice.human();
587 jvParams[jss::binary] = 1;
590 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
591 BEAST_EXPECT(jrr.
isMember(jss::node_binary));
592 BEAST_EXPECT(jrr[jss::node_binary] == alicesAcctRootBinary);
597 jvParams[jss::index] = accountRootIndex;
599 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
600 BEAST_EXPECT(!jrr.
isMember(jss::node_binary));
601 BEAST_EXPECT(jrr.
isMember(jss::node));
602 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
603 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
608 jvParams[jss::index] = accountRootIndex;
609 jvParams[jss::binary] = 0;
611 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
612 BEAST_EXPECT(jrr.
isMember(jss::node));
613 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
614 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
619 jvParams[jss::account] = alice.human();
622 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
623 BEAST_EXPECT(jrr.
isMember(jss::node));
624 BEAST_EXPECT(jrr[jss::node][jss::Account] == alice.human());
625 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"10000000000");
626 accountRootIndex = jrr[jss::index].
asString();
644 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
653 using namespace test::jtx;
663 auto const amendments = [&](
OpenView& view,
671 "714D104A72F9B4369F97ABF044EE"));
674 "21192D63DE53FFB46E43B9DC8373"));
677 "CC3E51F522F978041E4B57D9158C"));
680 "0F094B02226C1C14AD2858962ED4"));
688 majority1.setFieldH256(
691 "647693B50C5E87A80DFD6FCFAC50"));
692 majority1.setFieldU32(sfCloseTime, 779561310);
693 majorities.
push_back(std::move(majority1));
696 majority2.setFieldH256(
699 "E40AD19554A5EBECDCEC8A1F77FE"));
700 majority2.setFieldU32(sfCloseTime, 779561310);
701 majorities.
push_back(std::move(majority2));
703 sle->setFieldArray(sfMajorities, majorities);
714 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
716 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Amendments);
727 using namespace test::jtx;
734 AMM amm(env, alice,
XRP(10), alice[
"USD"](1000));
739 jvParams[jss::amm] =
to_string(amm.ammID());
743 result.isObject() && result.isMember(jss::result) &&
744 !result[jss::result].isMember(jss::error) &&
745 result[jss::result].isMember(jss::node) &&
746 result[jss::result][jss::node].isMember(
747 sfLedgerEntryType.jsonName) &&
748 result[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
757 obj[jss::currency] =
"XRP";
758 ammParams[jss::asset] = obj;
762 obj[jss::currency] =
"USD";
763 obj[jss::issuer] = alice.human();
764 ammParams[jss::asset2] = obj;
766 jvParams[jss::amm] = ammParams;
770 result.isObject() && result.isMember(jss::result) &&
771 !result[jss::result].isMember(jss::error) &&
772 result[jss::result].isMember(jss::node) &&
773 result[jss::result][jss::node].isMember(
774 sfLedgerEntryType.jsonName) &&
775 result[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
784 {jss::asset,
"malformedRequest"},
785 {jss::asset2,
"malformedRequest"},
793 using namespace test::jtx;
808 jvParams[jss::check] =
to_string(checkId.key);
811 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
813 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
814 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
822 jvParams[jss::account_root] = alice.human();
824 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
825 accountRootIndex = jrr[jss::index].
asString();
828 jvParams[jss::check] = accountRootIndex;
831 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
833 jrr,
"unexpectedLedgerType",
"Unexpected ledger type.");
846 using namespace test::jtx;
849 Account const issuer{
"issuer"};
852 char const credType[] =
"abcde";
854 env.
fund(
XRP(5000), issuer, alice, bob);
866 !jv[jss::result].
isMember(jss::error) &&
867 jv[jss::result].
isMember(jss::node) &&
868 jv[jss::result][jss::node].
isMember(
869 sfLedgerEntryType.jsonName) &&
870 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
878 !jv[jss::result].
isMember(jss::error) &&
879 jv[jss::result].
isMember(jss::node) &&
880 jv[jss::result][jss::node].
isMember(
881 sfLedgerEntryType.jsonName) &&
882 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
890 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
893 jv[jss::result],
"entryNotFound",
"Entry not found.");
902 {jss::subject,
"malformedRequest"},
903 {jss::issuer,
"malformedRequest"},
904 {jss::credential_type,
"malformedRequest"},
914 using namespace test::jtx;
919 env.
fund(
XRP(10000), alice, bob);
928 jvParams[jss::delegate][jss::account] = alice.human();
929 jvParams[jss::delegate][jss::authorize] = bob.human();
932 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
934 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Delegate);
935 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
936 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == bob.human());
937 delegateIndex = jrr[jss::node][jss::index].
asString();
942 jvParams[jss::delegate] = delegateIndex;
945 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
947 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Delegate);
948 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
949 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == bob.human());
958 {jss::account,
"malformedAddress"},
959 {jss::authorize,
"malformedAddress"},
969 using namespace test::jtx;
975 env.
fund(
XRP(10000), alice, becky);
986 jvParams[jss::deposit_preauth][jss::owner] = alice.human();
987 jvParams[jss::deposit_preauth][jss::authorized] = becky.human();
990 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
993 jrr[jss::node][sfLedgerEntryType.jsonName] ==
994 jss::DepositPreauth);
995 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
996 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
997 depositPreauthIndex = jrr[jss::node][jss::index].
asString();
1002 jvParams[jss::deposit_preauth] = depositPreauthIndex;
1005 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1008 jrr[jss::node][sfLedgerEntryType.jsonName] ==
1009 jss::DepositPreauth);
1010 BEAST_EXPECT(jrr[jss::node][sfAccount.jsonName] == alice.human());
1011 BEAST_EXPECT(jrr[jss::node][sfAuthorize.jsonName] == becky.human());
1017 jss::deposit_preauth,
1019 {jss::owner,
"malformedOwner"},
1020 {jss::authorized,
"malformedAuthorized",
false},
1028 testcase(
"Deposit Preauth with credentials");
1030 using namespace test::jtx;
1033 Account const issuer{
"issuer"};
1036 char const credType[] =
"abcde";
1038 env.
fund(
XRP(5000), issuer, alice, bob);
1052 jvParams[jss::ledger_index] = jss::validated;
1053 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1055 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1058 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1061 jo[jss::issuer] = issuer.human();
1063 arr.append(std::move(jo));
1068 jrr.isObject() && jrr.isMember(jss::result) &&
1069 !jrr[jss::result].isMember(jss::error) &&
1070 jrr[jss::result].isMember(jss::node) &&
1071 jrr[jss::result][jss::node].isMember(
1072 sfLedgerEntryType.jsonName) &&
1073 jrr[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
1074 jss::DepositPreauth);
1080 jvParams[jss::ledger_index] = jss::validated;
1081 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1083 auto tryField = [&](
Json::Value fieldValue) ->
void {
1086 jo[jss::issuer] = fieldValue;
1089 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1093 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1094 auto const expectedErrMsg = fieldValue.
isNull()
1098 jrr,
"malformedAuthorizedCredentials", expectedErrMsg);
1102 for (
auto const& value : badValues)
1112 jvParams[jss::ledger_index] = jss::validated;
1113 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1115 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1118 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1121 jo[jss::issuer] = issuer.human();
1124 arr.append(std::move(jo));
1129 "malformedAuthorizedCredentials",
1131 jss::authorized_credentials,
"array"));
1137 jvParams[jss::ledger_index] = jss::validated;
1138 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1140 auto tryField = [&](
Json::Value fieldValue) ->
void {
1143 jo[jss::issuer] = issuer.human();
1144 jo[jss::credential_type] = fieldValue;
1146 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1150 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1151 auto const expectedErrMsg = fieldValue.
isNull()
1154 jss::credential_type,
"hex string");
1156 jrr,
"malformedAuthorizedCredentials", expectedErrMsg);
1160 for (
auto const& value : badValues)
1170 jvParams[jss::ledger_index] = jss::validated;
1171 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1172 jvParams[jss::deposit_preauth][jss::authorized] = alice.human();
1174 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1177 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1180 jo[jss::issuer] = issuer.human();
1182 arr.append(std::move(jo));
1189 "Must have exactly one of `authorized` and "
1190 "`authorized_credentials`.");
1196 jvParams[jss::ledger_index] = jss::validated;
1197 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1201 jss::deposit_preauth,
1202 jss::authorized_credentials,
1204 "malformedAuthorizedCredentials",
1211 jvParams[jss::ledger_index] = jss::validated;
1212 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1213 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1216 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1217 arr.append(
"foobar");
1223 "malformedAuthorizedCredentials",
1224 "Invalid field 'authorized_credentials', not array.");
1230 jvParams[jss::ledger_index] = jss::validated;
1231 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1232 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1235 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1238 arr.
append(std::move(payload));
1244 "malformedAuthorizedCredentials",
1245 "Invalid field 'authorized_credentials', not array.");
1251 jvParams[jss::ledger_index] = jss::validated;
1252 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1253 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1260 "malformedAuthorizedCredentials",
1261 "Invalid field 'authorized_credentials', array empty.");
1277 sizeof(credTypes) /
sizeof(credTypes[0]) >
1281 jvParams[jss::ledger_index] = jss::validated;
1282 jvParams[jss::deposit_preauth][jss::owner] = bob.human();
1283 jvParams[jss::deposit_preauth][jss::authorized_credentials] =
1287 jvParams[jss::deposit_preauth][jss::authorized_credentials]);
1289 for (
auto cred : credTypes)
1292 jo[jss::issuer] = issuer.human();
1294 arr.append(std::move(jo));
1301 "malformedAuthorizedCredentials",
1302 "Invalid field 'authorized_credentials', array too long.");
1310 using namespace test::jtx;
1314 auto const USD = gw[
"USD"];
1315 env.
fund(
XRP(10000), alice, gw);
1318 env.
trust(USD(1000), alice);
1323 for (
int d = 1'000'032; d >= 1'000'000; --d)
1333 BEAST_EXPECT(jrr[jss::ledger_hash] ==
ledgerHash);
1334 BEAST_EXPECT(jrr[jss::ledger_index] == 5);
1338 "A33EC6BB85FB5674074C4A3A43373BB17645308F3EAE1933E3E35252162B217D";
1342 jvParams[jss::directory] = dirRootIndex;
1345 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1346 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 32);
1352 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1354 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1355 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1361 jvParams[jss::directory][jss::owner] = alice.human();
1364 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1365 BEAST_EXPECT(jrr[jss::index] == dirRootIndex);
1371 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1372 jvParams[jss::directory][jss::sub_index] = 1;
1374 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1375 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1376 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1382 jvParams[jss::directory][jss::owner] = alice.human();
1383 jvParams[jss::directory][jss::sub_index] = 1;
1386 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1387 BEAST_EXPECT(jrr[jss::index] != dirRootIndex);
1388 BEAST_EXPECT(jrr[jss::node][sfIndexes.jsonName].
size() == 2);
1399 "malformedRequest");
1405 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1435 jvParams[jss::directory][jss::owner] = alice.human();
1436 jvParams[jss::directory][jss::dir_root] = dirRootIndex;
1439 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1443 "Must have exactly one of `owner` and `dir_root` fields.");
1449 jvParams[jss::directory][jss::sub_index] = 1;
1452 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1456 "Must have exactly one of `owner` and `dir_root` fields.");
1464 using namespace test::jtx;
1476 jv[jss::TransactionType] = jss::EscrowCreate;
1477 jv[jss::Account] = account.human();
1478 jv[jss::Destination] = to.human();
1480 jv[sfFinishAfter.jsonName] =
1481 cancelAfter.time_since_epoch().count() + 2;
1485 using namespace std::chrono_literals;
1486 env(escrowCreate(alice, alice,
XRP(333), env.
now() + 2s));
1495 jvParams[jss::escrow][jss::owner] = alice.human();
1496 jvParams[jss::escrow][jss::seq] = env.
seq(alice) - 1;
1498 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1500 jrr[jss::node][jss::Amount] ==
XRP(333).value().getText());
1501 escrowIndex = jrr[jss::index].
asString();
1506 jvParams[jss::escrow] = escrowIndex;
1509 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1511 jrr[jss::node][jss::Amount] ==
XRP(333).value().getText());
1518 {{jss::owner,
"malformedOwner"}, {jss::seq,
"malformedSeq"}});
1526 using namespace test::jtx;
1535 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1537 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::FeeSettings);
1548 using namespace test::jtx;
1557 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1559 jrr[jss::node][sfLedgerEntryType.jsonName] ==
1571 using namespace test::jtx;
1575 Account const issuer{
"issuer"};
1577 env.
fund(
XRP(1000), issuer, buyer);
1590 jvParams[jss::nft_offer] =
to_string(offerID);
1592 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1594 jrr[jss::node][sfLedgerEntryType.jsonName] ==
1596 BEAST_EXPECT(jrr[jss::node][sfOwner.jsonName] == issuer.human());
1598 jrr[jss::node][sfNFTokenID.jsonName] ==
to_string(nftokenID0));
1599 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"1");
1610 using namespace test::jtx;
1614 Account const issuer{
"issuer"};
1621 BEAST_EXPECT(env.
le(nftpage) !=
nullptr);
1627 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1629 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::NFTokenPage);
1640 using namespace test::jtx;
1655 auto disabledValidator =
1658 "ED58F6770DB5DD77E59D28CB650EC3816E2FC95021BB56E720C9A1"
1660 disabledValidator.setFieldVL(sfPublicKey, *pubKeyBlob);
1661 disabledValidator.setFieldU32(
1662 sfFirstLedgerSequence, 91371264);
1663 disabledValidators.
push_back(std::move(disabledValidator));
1666 sfDisabledValidators, disabledValidators);
1670 "A95160CC6D351341B9"
1672 sle->setFieldU32(sfPreviousTxnLgrSeq, 91442944);
1683 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1685 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::NegativeUNL);
1696 using namespace test::jtx;
1700 auto const USD = gw[
"USD"];
1701 env.
fund(
XRP(10000), alice, gw);
1704 env(
offer(alice, USD(321),
XRP(322)));
1713 jvParams[jss::offer][jss::account] = alice.human();
1714 jvParams[jss::offer][jss::seq] = env.
seq(alice) - 1;
1717 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1718 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1719 offerIndex = jrr[jss::index].
asString();
1724 jvParams[jss::offer] = offerIndex;
1726 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1727 BEAST_EXPECT(jrr[jss::node][jss::TakerGets] ==
"322000000");
1735 {{jss::account,
"malformedAddress"},
1736 {jss::seq,
"malformedRequest"}});
1744 using namespace test::jtx;
1759 jv[jss::TransactionType] = jss::PaymentChannelCreate;
1760 jv[jss::Account] = account.human();
1761 jv[jss::Destination] = to.human();
1763 jv[sfSettleDelay.jsonName] = settleDelay.count();
1764 jv[sfPublicKey.jsonName] =
strHex(pk.slice());
1768 env(payChanCreate(alice, env.
master,
XRP(57), 18s, alice.pk()));
1778 jvParams[jss::payment_channel] =
to_string(payChanIndex);
1781 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1782 BEAST_EXPECT(jrr[jss::node][sfAmount.jsonName] ==
"57000000");
1783 BEAST_EXPECT(jrr[jss::node][sfBalance.jsonName] ==
"0");
1784 BEAST_EXPECT(jrr[jss::node][sfSettleDelay.jsonName] == 18);
1792 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1806 using namespace test::jtx;
1810 auto const USD = gw[
"USD"];
1811 env.
fund(
XRP(10000), alice, gw);
1814 env.
trust(USD(999), alice);
1817 env(
pay(gw, alice, USD(97)));
1821 for (
auto const& fieldName : {jss::ripple_state, jss::state})
1830 jvParams[fieldName][jss::accounts][0u] = alice.human();
1831 jvParams[fieldName][jss::accounts][1u] = gw.human();
1832 jvParams[fieldName][jss::currency] =
"USD";
1835 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1837 jrr[jss::node][sfBalance.jsonName][jss::value] ==
"-97");
1839 jrr[jss::node][sfHighLimit.jsonName][jss::value] ==
"999");
1847 {jss::accounts,
"malformedRequest"},
1848 {jss::currency,
"malformedCurrency"},
1856 jvParams[fieldName][jss::accounts][0u] = alice.human();
1857 jvParams[fieldName][jss::currency] =
"USD";
1860 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1864 "Invalid field 'accounts', not length-2 array of "
1872 jvParams[fieldName][jss::accounts][0u] = alice.human();
1873 jvParams[fieldName][jss::accounts][1u] = gw.human();
1874 jvParams[fieldName][jss::accounts][2u] = alice.human();
1875 jvParams[fieldName][jss::currency] =
"USD";
1878 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1882 "Invalid field 'accounts', not length-2 array of "
1889 auto tryField = [&](
Json::Value badAccount) ->
void {
1893 jvParams[fieldName][jss::accounts][0u] = badAccount;
1894 jvParams[fieldName][jss::accounts][1u] = gw.human();
1895 jvParams[fieldName][jss::currency] =
"USD";
1905 jss::accounts,
"array of Accounts"));
1911 jvParams[fieldName][jss::accounts][0u] = alice.human();
1912 jvParams[fieldName][jss::accounts][1u] = badAccount;
1913 jvParams[fieldName][jss::currency] =
"USD";
1923 jss::accounts,
"array of Accounts"));
1928 for (
auto const& value : badValues)
1939 jvParams[fieldName][jss::accounts][0u] = alice.human();
1940 jvParams[fieldName][jss::accounts][1u] = alice.human();
1941 jvParams[fieldName][jss::currency] =
"USD";
1944 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1948 "Cannot have a trustline to self.");
1957 using namespace test::jtx;
1966 using namespace test::jtx;
1982 jvParams[jss::ticket] =
1986 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1995 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
1997 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Ticket);
1998 BEAST_EXPECT(jrr[jss::node][sfTicketSequence.jsonName] == tkt1);
2004 jvParams[jss::ticket][jss::account] = env.
master.
human();
2005 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 1;
2008 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2010 jrr[jss::node][jss::index] ==
2017 jvParams[jss::ticket][jss::account] = env.
master.
human();
2018 jvParams[jss::ticket][jss::ticket_seq] = tkt1 + 2;
2021 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2030 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2032 jrr,
"unexpectedLedgerType",
"Unexpected ledger type.");
2041 {jss::account,
"malformedAddress"},
2042 {jss::ticket_seq,
"malformedRequest"},
2051 using namespace test::jtx;
2062 jv[jss::TransactionType] = jss::DIDSet;
2063 jv[jss::Account] = account.human();
2069 env(didCreate(alice));
2077 jvParams[jss::did] = alice.human();
2080 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2082 jrr[jss::node][sfDIDDocument.jsonName] ==
2093 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2104 "malformedAddress");
2111 testcase(
"Invalid Oracle Ledger Entry");
2121 .fee =
static_cast<int>(env.
current()->fees().base.drops())});
2129 {jss::account,
"malformedAccount"},
2130 {jss::oracle_document_id,
"malformedDocumentID"},
2143 auto const baseFee =
2144 static_cast<int>(env.
current()->fees().base.drops());
2147 for (
int i = 0; i < 10; ++i)
2153 env, {.owner = owner, .documentID = i, .fee = baseFee});
2158 env, {.owner = owner, .documentID = i + 10, .fee = baseFee});
2160 oracles.
push_back(oracle1.documentID());
2162 for (
int i = 0; i < accounts.
size(); ++i)
2164 auto const jv = [&]() {
2167 return Oracle::ledgerEntry(env, accounts[i], oracles[i]);
2169 return Oracle::ledgerEntry(
2175 jv[jss::node][jss::Owner] ==
to_string(accounts[i]));
2188 using namespace test::jtx;
2194 MPTTester mptAlice(env, alice, {.holders = {bob}});
2201 mptAlice.authorize({.account = bob, .holderCount = 1});
2206 "00000193B9DDCAF401B5B3B26875986043F82CD0D13B4315";
2210 jvParams[jss::mpt_issuance] =
strHex(mptAlice.issuanceID());
2213 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2215 jrr[jss::node][sfMPTokenMetadata.jsonName] ==
2218 jrr[jss::node][jss::mpt_issuance_id] ==
2219 strHex(mptAlice.issuanceID()));
2224 jvParams[jss::mpt_issuance] = badMptID;
2227 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2234 jvParams[jss::mptoken][jss::account] = bob.
human();
2235 jvParams[jss::mptoken][jss::mpt_issuance_id] =
2236 strHex(mptAlice.issuanceID());
2239 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2241 jrr[jss::node][sfMPTokenIssuanceID.jsonName] ==
2242 strHex(mptAlice.issuanceID()));
2248 jvParams[jss::mptoken][jss::account] = bob.
human();
2249 jvParams[jss::mptoken][jss::mpt_issuance_id] = badMptID;
2252 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2263 "malformedRequest");
2272 using namespace test::jtx;
2275 Account const issuer{
"issuer"};
2279 env.
fund(
XRP(5000), issuer, alice, bob);
2282 auto const seq = env.
seq(alice);
2286 if (!BEAST_EXPECT(objects.size() == 1))
2292 params[jss::ledger_index] = jss::validated;
2293 params[jss::permissioned_domain][jss::account] = alice.human();
2294 params[jss::permissioned_domain][jss::seq] =
seq;
2295 auto jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2298 !jv[jss::result].
isMember(jss::error) &&
2299 jv[jss::result].
isMember(jss::node) &&
2300 jv[jss::result][jss::node].
isMember(
2301 sfLedgerEntryType.jsonName) &&
2302 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
2303 jss::PermissionedDomain);
2310 params[jss::ledger_index] = jss::validated;
2311 params[jss::permissioned_domain] = pdIdx;
2312 jv = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2315 !jv[jss::result].
isMember(jss::error) &&
2316 jv[jss::result].
isMember(jss::node) &&
2317 jv[jss::result][jss::node].
isMember(
2318 sfLedgerEntryType.jsonName) &&
2319 jv[jss::result][jss::node][sfLedgerEntryType.jsonName] ==
2320 jss::PermissionedDomain);
2326 params[jss::ledger_index] = jss::validated;
2327 params[jss::permissioned_domain] =
2328 "12F1F1F1F180D67377B2FAB292A31C922470326268D2B9B74CD1E582645B9A"
2330 auto const jrr = env.
rpc(
"json",
"ledger_entry",
to_string(params));
2332 jrr[jss::result],
"entryNotFound",
"Entry not found.");
2338 jss::permissioned_domain,
2340 {jss::account,
"malformedAddress"},
2341 {jss::seq,
"malformedRequest"},
2350 using namespace test::jtx;
2366 env.
rpc(
"ledger_entry",
to_string(checkId.key))[jss::result];
2368 jrr[jss::node][sfLedgerEntryType.jsonName] == jss::Check);
2369 BEAST_EXPECT(jrr[jss::node][sfSendMax.jsonName] ==
"100000000");
2416 if (BEAST_EXPECT(jv.
isMember(jss::status)))
2417 BEAST_EXPECT(jv[jss::status] ==
"error");
2418 if (BEAST_EXPECT(jv.
isMember(jss::error)))
2419 BEAST_EXPECT(jv[jss::error] == err);
2424 jv[jss::error_message] ==
"");
2426 else if (BEAST_EXPECT(jv.
isMember(jss::error_message)))
2427 BEAST_EXPECT(jv[jss::error_message] == msg);
2434 using namespace test::jtx;
2448 jvParams[jss::bridge] =
jvb;
2450 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2452 BEAST_EXPECT(jrr.
isMember(jss::node));
2453 auto r = jrr[jss::node];
2455 BEAST_EXPECT(r.isMember(jss::Account));
2458 BEAST_EXPECT(r.isMember(jss::Flags));
2460 BEAST_EXPECT(r.isMember(sfLedgerEntryType.jsonName));
2461 BEAST_EXPECT(r[sfLedgerEntryType.jsonName] == jss::Bridge);
2464 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
2465 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 0);
2468 BEAST_EXPECT(r.isMember(sfXChainAccountClaimCount.jsonName));
2469 BEAST_EXPECT(r[sfXChainAccountClaimCount.jsonName].asInt() == 0);
2471 BEAST_EXPECT(r.isMember(jss::index));
2472 bridge_index = r[jss::index].asString();
2478 jvParams[jss::index] = bridge_index;
2480 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2482 BEAST_EXPECT(jrr.
isMember(jss::node));
2483 BEAST_EXPECT(jrr[jss::node] == mcBridge);
2490 jvParams[jss::bridge] =
jvb;
2493 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2508 jvParams[jss::bridge] =
jvb;
2510 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2512 BEAST_EXPECT(jrr.
isMember(jss::node));
2513 auto r = jrr[jss::node];
2516 BEAST_EXPECT(r.isMember(sfXChainClaimID.jsonName));
2517 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
2524 testcase(
"ledger_entry: xchain_claim_id");
2525 using namespace test::jtx;
2542 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
2545 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2547 BEAST_EXPECT(jrr.
isMember(jss::node));
2548 auto r = jrr[jss::node];
2550 BEAST_EXPECT(r.isMember(jss::Account));
2553 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
2554 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 1);
2555 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
2562 jvParams[jss::xchain_owned_claim_id][jss::xchain_owned_claim_id] =
2565 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2567 BEAST_EXPECT(jrr.
isMember(jss::node));
2568 auto r = jrr[jss::node];
2570 BEAST_EXPECT(r.isMember(jss::Account));
2571 BEAST_EXPECT(r[jss::Account] ==
scBob.
human());
2573 r[sfLedgerEntryType.jsonName] == jss::XChainOwnedClaimID);
2574 BEAST_EXPECT(r[sfXChainClaimID.jsonName].asInt() == 2);
2575 BEAST_EXPECT(r[sfOwnerNode.jsonName].asInt() == 0);
2582 testcase(
"ledger_entry: xchain_create_account_claim_id");
2583 using namespace test::jtx;
2594 auto const amt =
XRP(1000);
2601 size_t constexpr num_attest = 3;
2614 for (
size_t i = 0; i < num_attest; ++i)
2616 scEnv(attestations[i]);
2623 jvParams[jss::xchain_owned_create_account_claim_id] =
2625 jvParams[jss::xchain_owned_create_account_claim_id]
2626 [jss::xchain_owned_create_account_claim_id] = 1;
2628 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2630 BEAST_EXPECT(jrr.
isMember(jss::node));
2631 auto r = jrr[jss::node];
2633 BEAST_EXPECT(r.isMember(jss::Account));
2636 BEAST_EXPECT(r.isMember(sfXChainAccountCreateCount.jsonName));
2637 BEAST_EXPECT(r[sfXChainAccountCreateCount.jsonName].asInt() == 1);
2640 r.isMember(sfXChainCreateAccountAttestations.jsonName));
2641 auto attest = r[sfXChainCreateAccountAttestations.jsonName];
2642 BEAST_EXPECT(attest.isArray());
2643 BEAST_EXPECT(attest.size() == 3);
2645 sfXChainCreateAccountProofSig.jsonName));
2647 for (
size_t i = 0; i < num_attest; ++i)
2650 [sfXChainCreateAccountProofSig.jsonName];
2652 a[i].isMember(jss::Amount) &&
2655 a[i].isMember(jss::Destination) &&
2658 a[i].isMember(sfAttestationSignerAccount.jsonName) &&
2661 return a[i][sfAttestationSignerAccount.jsonName] ==
2665 a[i].isMember(sfAttestationRewardAccount.jsonName) &&
2670 return a[i][sfAttestationRewardAccount.jsonName] ==
2674 a[i].isMember(sfWasLockingChainSend.jsonName) &&
2675 a[i][sfWasLockingChainSend.jsonName] == 1);
2677 a[i].isMember(sfSignatureReward.jsonName) &&
2678 a[i][sfSignatureReward.jsonName].
asInt() ==
2687 scEnv(attestations[i]);
2693 jvParams[jss::xchain_owned_create_account_claim_id] =
2695 jvParams[jss::xchain_owned_create_account_claim_id]
2696 [jss::xchain_owned_create_account_claim_id] = 1;
2698 "json",
"ledger_entry",
to_string(jvParams))[jss::result];
2714BEAST_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 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, source_location const location=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, source_location const location=source_location::current())
void testDepositPreauth()
void testPermissionedDomain()
void testDepositPreauthCred()
Json::Value getCorrectValue(Json::StaticString fieldName)
void runLedgerEntryTest(test::jtx::Env &env, Json::StaticString const &parentField, std::vector< Subfield > const &subfields, source_location const location=source_location::current())
void testInvalidOracleLedgerEntry()
void runLedgerEntryTest(test::jtx::Env &env, Json::StaticString const &parentField, source_location const location=source_location::current())
std::vector< Json::Value > getBadValues(FieldType fieldType)
void checkErrorValue(Json::Value const &jv, std::string const &err, std::string const &msg, source_location const location=source_location::current())
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.