20#include <xrpld/rpc/Context.h> 
   21#include <xrpld/rpc/GRPCHandlers.h> 
   22#include <xrpld/rpc/detail/RPCHelpers.h> 
   23#include <xrpld/rpc/handlers/LedgerEntryHelpers.h> 
   25#include <xrpl/basics/StringUtilities.h> 
   26#include <xrpl/basics/strHex.h> 
   27#include <xrpl/beast/core/LexicalCast.h> 
   28#include <xrpl/json/json_errors.h> 
   29#include <xrpl/ledger/CredentialHelpers.h> 
   30#include <xrpl/ledger/ReadView.h> 
   31#include <xrpl/protocol/ErrorCodes.h> 
   32#include <xrpl/protocol/Indexes.h> 
   33#include <xrpl/protocol/LedgerFormats.h> 
   34#include <xrpl/protocol/RPCErr.h> 
   35#include <xrpl/protocol/STXChainBridge.h> 
   36#include <xrpl/protocol/jss.h> 
   42static Expected<uint256, Json::Value>
 
   46    std::string const& expectedType = 
"hex string or object")
 
   48    if (
auto const uNodeIndex = LedgerEntryHelpers::parse<uint256>(params))
 
   53        "malformedRequest", fieldName, expectedType);
 
 
   56static Expected<uint256, Json::Value>
 
   62static Expected<uint256, Json::Value>
 
   65    if (
auto const account = LedgerEntryHelpers::parse<AccountID>(params))
 
   71        "malformedAddress", fieldName, 
"AccountID");
 
 
   74static Expected<uint256, Json::Value>
 
   80static Expected<uint256, Json::Value>
 
   88    if (
auto const value =
 
 
  107static Expected<uint256, Json::Value>
 
  115    if (params[jss::bridge].isString())
 
  126        params, jss::bridge_account, 
"malformedBridgeAccount");
 
  132    if (account.value() != bridge->door(chainType))
 
 
  138static Expected<uint256, Json::Value>
 
  144static Expected<uint256, Json::Value>
 
  153        cred, jss::subject, 
"malformedRequest");
 
  158        cred, jss::issuer, 
"malformedRequest");
 
  164        jss::credential_type,
 
  171               *subject, *issuer, 
Slice(credType->data(), credType->size()))
 
 
  175static Expected<uint256, Json::Value>
 
  184        params, jss::account, 
"malformedAddress");
 
  189        params, jss::authorize, 
"malformedAddress");
 
 
  196static Expected<STArray, Json::Value>
 
  201            "malformedAuthorizedCredentials",
 
  202            jss::authorized_credentials,
 
  205    for (
auto const& jo : jv)
 
  209                "malformedAuthorizedCredentials",
 
  210                jss::authorized_credentials,
 
  214                {jss::issuer, jss::credential_type},
 
  215                "malformedAuthorizedCredentials");
 
  222            jo, jss::issuer, 
"malformedAuthorizedCredentials");
 
  228            jss::credential_type,
 
  230            "malformedAuthorizedCredentials");
 
  236        credential.setFieldVL(sfCredentialType, *credentialType);
 
 
  243static Expected<uint256, Json::Value>
 
  251    if ((dp.
isMember(jss::authorized) ==
 
  252         dp.
isMember(jss::authorized_credentials)))
 
  256            "Must have exactly one of `authorized` and " 
  257            "`authorized_credentials`.");
 
  270                LedgerEntryHelpers::parse<AccountID>(dp[jss::authorized]))
 
  275            "malformedAuthorized", jss::authorized, 
"AccountID");
 
  278    auto const& ac(dp[jss::authorized_credentials]);
 
  280    if (!arr.has_value())
 
  285            "malformedAuthorizedCredentials",
 
  286            jss::authorized_credentials,
 
  295            "malformedAuthorizedCredentials",
 
  296            jss::authorized_credentials,
 
 
  303static Expected<uint256, Json::Value>
 
  306    auto const account = LedgerEntryHelpers::parse<AccountID>(params);
 
  310            "malformedAddress", fieldName, 
"AccountID");
 
 
  316static Expected<uint256, Json::Value>
 
  326    if (params.
isMember(jss::sub_index) &&
 
  328         params[jss::sub_index].
isBool()))
 
  331            "malformedRequest", jss::sub_index, 
"number");
 
  338            "Must have exactly one of `owner` and `dir_root` fields.");
 
  345        if (
auto const uDirRoot =
 
  346                LedgerEntryHelpers::parse<uint256>(params[jss::dir_root]))
 
  352            "malformedDirRoot", jss::dir_root, 
"hash");
 
  358            LedgerEntryHelpers::parse<AccountID>(params[jss::owner]);
 
  362                "malformedAddress", jss::owner, 
"AccountID");
 
 
  371static Expected<uint256, Json::Value>
 
  380        params, jss::owner, 
"malformedOwner");
 
 
  391static Expected<uint256, Json::Value>
 
  397static Expected<uint256, Json::Value>
 
  403static Expected<uint256, Json::Value>
 
  412        params, jss::mpt_issuance_id, 
"malformedMPTIssuanceID");
 
  417        params, jss::account, 
"malformedAccount");
 
 
  424static Expected<uint256, Json::Value>
 
  429    auto const mptIssuanceID = LedgerEntryHelpers::parse<uint192>(params);
 
  432            "malformedMPTokenIssuance", fieldName, 
"Hash192");
 
 
  437static Expected<uint256, Json::Value>
 
  443static Expected<uint256, Json::Value>
 
  449static Expected<uint256, Json::Value>
 
  455static Expected<uint256, Json::Value>
 
  464        params, jss::account, 
"malformedAddress");
 
  469        params, jss::seq, 
"malformedRequest");
 
 
  476static Expected<uint256, Json::Value>
 
  485        params, jss::account, 
"malformedAccount");
 
  490        params, jss::oracle_document_id, 
"malformedDocumentID");
 
 
  497static Expected<uint256, Json::Value>
 
  503static Expected<uint256, Json::Value>
 
  516            "malformedRequest", fieldName, 
"hex string or object");
 
  520        pd, jss::account, 
"malformedAddress");
 
 
  532static Expected<uint256, Json::Value>
 
  545            jvRippleState, {jss::currency, jss::accounts});
 
  551    if (!jvRippleState[jss::accounts].isArray() ||
 
  552        jvRippleState[jss::accounts].size() != 2)
 
  555            "malformedRequest", jss::accounts, 
"length-2 array of Accounts");
 
  559        LedgerEntryHelpers::parse<AccountID>(jvRippleState[jss::accounts][0u]);
 
  561        LedgerEntryHelpers::parse<AccountID>(jvRippleState[jss::accounts][1u]);
 
  565            "malformedAddress", jss::accounts, 
"array of Accounts");
 
  570            "malformedRequest", 
"Cannot have a trustline to self.");
 
  573    if (!jvRippleState[jss::currency].isString() ||
 
  574        jvRippleState[jss::currency] == 
"" ||
 
  575        !
to_currency(uCurrency, jvRippleState[jss::currency].asString()))
 
  578            "malformedCurrency", jss::currency, 
"Currency");
 
 
  584static Expected<uint256, Json::Value>
 
  590static Expected<uint256, Json::Value>
 
  599        params, jss::account, 
"malformedAddress");
 
  604        params, jss::ticket_seq, 
"malformedRequest");
 
 
  611static Expected<uint256, Json::Value>
 
  620        params, jss::owner, 
"malformedOwner");
 
  625        params, jss::seq, 
"malformedRequest");
 
 
  632static Expected<uint256, Json::Value>
 
  647        claim_id, jss::xchain_owned_claim_id, 
"malformedXChainOwnedClaimID");
 
 
  657static Expected<uint256, Json::Value>
 
  673        jss::xchain_owned_create_account_claim_id,
 
  674        "malformedXChainOwnedCreateAccountClaimID");
 
 
  704#pragma push_macro("LEDGER_ENTRY") 
  707#define LEDGER_ENTRY(tag, value, name, rpcName, fields) \ 
  708    {jss::rpcName, parse##name, tag}, 
  710#include <xrpl/protocol/detail/ledger_entries.macro> 
  713#pragma pop_macro("LEDGER_ENTRY") 
  720    auto hasMoreThanOneMember = [&]() {
 
  723        for (
auto const& ledgerEntry : ledgerEntryParsers)
 
  735    if (hasMoreThanOneMember)
 
  752        for (
auto const& ledgerEntry : ledgerEntryParsers)
 
  756                expectedType = ledgerEntry.expectedType;
 
  761                Json::Value const& params = ledgerEntry.fieldName == jss::bridge
 
  763                    : context.
params[ledgerEntry.fieldName];
 
  765                    ledgerEntry.parseFunction(params, ledgerEntry.fieldName);
 
  767                    return result.error();
 
  769                uNodeIndex = result.value();
 
  778                jvResult[jss::error] = 
"unknownOption";
 
  803    bool bNodeBinary = 
false;
 
  813    if ((expectedType != 
ltANY) && (expectedType != sleNode->getType()))
 
  825        jvResult[jss::index] = 
to_string(uNodeIndex);
 
  830        jvResult[jss::index] = 
to_string(uNodeIndex);
 
 
  840    org::xrpl::rpc::v1::GetLedgerEntryRequest& request = context.
params;
 
  841    org::xrpl::rpc::v1::GetLedgerEntryResponse response;
 
  842    grpc::Status status = grpc::Status::OK;
 
  847        grpc::Status errorStatus;
 
  850            errorStatus = grpc::Status(
 
  851                grpc::StatusCode::INVALID_ARGUMENT, status.message());
 
  856                grpc::Status(grpc::StatusCode::NOT_FOUND, status.message());
 
  858        return {response, errorStatus};
 
  864        grpc::Status errorStatus{
 
  865            grpc::StatusCode::INVALID_ARGUMENT, 
"index malformed"};
 
  866        return {response, errorStatus};
 
  872        grpc::Status errorStatus{
 
  873            grpc::StatusCode::NOT_FOUND, 
"object not found"};
 
  874        return {response, errorStatus};
 
  880    auto& stateObject = *response.mutable_ledger_object();
 
  882    stateObject.set_key(request.key());
 
  883    *(response.mutable_ledger()) = request.ledger();
 
  884    return {response, status};
 
 
Lightweight wrapper to tag static string.
 
UInt size() const
Number of values in array or object.
 
bool isMember(char const *key) const
Return true if the object has a member named key.
 
Value get(UInt index, Value const &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
 
bool isConvertibleTo(ValueType other) const
 
void push_back(STObject const &object)
 
static STObject makeInnerObject(SField const &name)
 
static ChainType srcChain(bool wasLockingChainSend)
 
Blob const & peekData() const
 
An immutable linear range of bytes.
 
static std::optional< base_uint > fromVoidChecked(T const &from)
 
@ uintValue
unsigned integer value
 
Expected< STXChainBridge, Json::Value > parseBridgeFields(Json::Value const ¶ms)
 
Unexpected< Json::Value > malformedError(std::string const &err, std::string const &message)
 
Unexpected< Json::Value > invalidFieldError(std::string const &err, Json::StaticString const field, std::string const &type)
 
Unexpected< Json::Value > missingFieldError(Json::StaticString const field, std::optional< std::string > err=std::nullopt)
 
Expected< bool, Json::Value > hasRequired(Json::Value const ¶ms, std::initializer_list< Json::StaticString > fields, std::optional< std::string > err=std::nullopt)
 
Expected< AccountID, Json::Value > requiredAccountID(Json::Value const ¶ms, Json::StaticString const fieldName, std::string const &err)
 
Expected< std::uint32_t, Json::Value > requiredUInt32(Json::Value const ¶ms, Json::StaticString const fieldName, std::string const &err)
 
Expected< uint192, Json::Value > requiredUInt192(Json::Value const ¶ms, Json::StaticString const fieldName, std::string const &err)
 
Expected< Blob, Json::Value > requiredHexBlob(Json::Value const ¶ms, Json::StaticString const fieldName, std::size_t maxLength, std::string const &err)
 
Status ledgerFromRequest(T &ledger, GRPCContext< R > &context)
 
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
 
Json::Value make_param_error(std::string const &message)
Returns a new json object that indicates invalid parameters.
 
Status lookupLedger(std::shared_ptr< ReadView const > &ledger, JsonContext &context, Json::Value &result)
Look up a ledger from a request and fill a Json::Result with the data representing a ledger.
 
std::set< std::pair< AccountID, Slice > > makeSorted(STArray const &credentials)
 
Keylet mptoken(MPTID const &issuanceID, AccountID const &holder) noexcept
 
Keylet oracle(AccountID const &account, std::uint32_t const &documentID) noexcept
 
Keylet delegate(AccountID const &account, AccountID const &authorizedAccount) noexcept
A keylet for Delegate object.
 
Keylet permissionedDomain(AccountID const &account, std::uint32_t seq) noexcept
 
Keylet amm(Asset const &issue1, Asset const &issue2) noexcept
AMM entry.
 
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
 
Keylet mptIssuance(std::uint32_t seq, AccountID const &issuer) noexcept
 
Keylet xChainClaimID(STXChainBridge const &bridge, std::uint64_t seq)
 
Keylet did(AccountID const &account) noexcept
 
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
 
Keylet vault(AccountID const &owner, std::uint32_t seq) noexcept
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
 
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
 
Keylet escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow entry.
 
Keylet bridge(STXChainBridge const &bridge, STXChainBridge::ChainType chainType)
 
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
 
Keylet xChainCreateAccountClaimID(STXChainBridge const &bridge, std::uint64_t seq)
 
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
 
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
static Expected< uint256, Json::Value > parseOracle(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseCredential(Json::Value const &cred, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseFeeSettings(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseXChainOwnedClaimID(Json::Value const &claim_id, Json::StaticString const fieldName)
 
Json::Value doLedgerEntry(RPC::JsonContext &)
 
static Expected< uint256, Json::Value > parsePayChannel(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseNFTokenOffer(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseCheck(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseEscrow(Json::Value const ¶ms, Json::StaticString const fieldName)
 
@ rpcUNEXPECTED_LEDGER_TYPE
 
static Expected< uint256, Json::Value > parseXChainOwnedCreateAccountClaimID(Json::Value const &claim_id, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseIndex(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseDelegate(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseDepositPreauth(Json::Value const &dp, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseSignerList(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parsePermissionedDomain(Json::Value const &pd, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseBridge(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseAMM(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseMPToken(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< STArray, Json::Value > parseAuthorizeCredentials(Json::Value const &jv)
 
Issue issueFromJson(Json::Value const &v)
 
std::string strHex(FwdIt begin, FwdIt end)
 
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
 
std::pair< org::xrpl::rpc::v1::GetLedgerEntryResponse, grpc::Status > doLedgerEntryGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerEntryRequest > &context)
 
std::size_t constexpr maxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
 
static Expected< uint256, Json::Value > parseOffer(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseNegativeUNL(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseVault(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseMPTokenIssuance(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseNFTokenPage(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseDirectoryNode(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseAmendments(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseAccountRoot(Json::Value const ¶ms, Json::StaticString const fieldName)
 
uint256 getTicketIndex(AccountID const &account, std::uint32_t uSequence)
 
static Expected< uint256, Json::Value > parseTicket(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseObjectID(Json::Value const ¶ms, Json::StaticString const fieldName, std::string const &expectedType="hex string or object")
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
LedgerEntryType
Identifiers for on-ledger objects.
 
@ ltANY
A special type, matching any ledger entry type.
 
Expected< uint256, Json::Value >(*)(Json::Value const  &, Json::StaticString const) FunctionType
 
static Expected< uint256, Json::Value > parseLedgerHashes(Json::Value const ¶ms, Json::StaticString const fieldName)
 
@ credential
Credentials signature.
 
static Expected< uint256, Json::Value > parseDID(Json::Value const ¶ms, Json::StaticString const fieldName)
 
static Expected< uint256, Json::Value > parseRippleState(Json::Value const &jvRippleState, Json::StaticString const fieldName)
 
static bool authorized(Port const &port, std::map< std::string, std::string > const &h)
 
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
 
A pair of SHAMap key and LedgerEntryType.
 
LedgerEntryType expectedType
 
Json::StaticString fieldName
 
FunctionType parseFunction