1#include <xrpld/rpc/detail/RPCHelpers.h>
3#include <xrpld/rpc/Context.h>
4#include <xrpld/rpc/DeliveredAmount.h>
5#include <xrpld/rpc/Role.h>
6#include <xrpld/rpc/Status.h>
7#include <xrpld/rpc/detail/Tuning.h>
9#include <xrpl/basics/Log.h>
10#include <xrpl/basics/Slice.h>
11#include <xrpl/basics/UnorderedContainers.h>
12#include <xrpl/basics/base_uint.h>
13#include <xrpl/basics/contract.h>
14#include <xrpl/beast/utility/Journal.h>
15#include <xrpl/beast/utility/instrumentation.h>
16#include <xrpl/core/ServiceRegistry.h>
17#include <xrpl/protocol/AccountID.h>
18#include <xrpl/protocol/Asset.h>
19#include <xrpl/protocol/ErrorCodes.h>
20#include <xrpl/protocol/Indexes.h>
21#include <xrpl/protocol/Issue.h>
22#include <xrpl/protocol/KeyType.h>
23#include <xrpl/protocol/Keylet.h>
24#include <xrpl/protocol/LedgerFormats.h>
25#include <xrpl/protocol/PublicKey.h>
26#include <xrpl/protocol/RPCErr.h>
27#include <xrpl/protocol/SField.h>
28#include <xrpl/protocol/SecretKey.h>
29#include <xrpl/protocol/Seed.h>
30#include <xrpl/protocol/UintTypes.h>
31#include <xrpl/protocol/jss.h>
32#include <xrpl/protocol/tokens.h>
34#include <boost/algorithm/string/predicate.hpp>
50 if (sle->getType() == ltRIPPLE_STATE)
52 if (sle->getFieldAmount(sfLowLimit).getIssuer() == accountID)
54 return sle->getFieldU64(sfLowNode);
56 if (sle->getFieldAmount(sfHighLimit).getIssuer() == accountID)
58 return sle->getFieldU64(sfHighNode);
62 if (!sle->isFieldPresent(sfOwnerNode))
65 return sle->getFieldU64(sfOwnerNode);
71 if (sle->getType() == ltRIPPLE_STATE)
73 return (sle->getFieldAmount(sfLowLimit).getIssuer() == accountID) ||
74 (sle->getFieldAmount(sfHighLimit).getIssuer() == accountID);
76 if (sle->isFieldPresent(sfAccount))
84 return sle->getAccountID(sfAccount) == accountID ||
85 (sle->isFieldPresent(sfDestination) && sle->getAccountID(sfDestination) == accountID);
87 if (sle->getType() == ltSIGNER_LIST)
90 return sle->key() == accountSignerList.
key;
92 if (sle->getType() == ltNFTOKEN_OFFER)
96 return sle->getAccountID(sfOwner) == accountID;
106 for (
auto const& jv : jvArray)
121 limit =
range.rDefault;
125 auto const& jvLimit = context.
params[jss::limit];
126 if (!jvLimit.isUInt() && (!jvLimit.isInt() || jvLimit.asInt() < 0))
129 limit = jvLimit.asUInt();
145 if (!value.isString())
163 static seed_match_t
const kSeedTypes[]{
174 seed_match_t
const* seedType =
nullptr;
176 for (
auto const& t : kSeedTypes)
188 "Exactly one of the following must be specified: " +
std::string(jss::passphrase) +
194 auto const& param = params[seedType->first];
195 if (!param.isString())
201 auto const fieldContents = param.
asString();
215 bool const hasKeyType = params.
isMember(jss::key_type);
218 static char const*
const kSecretTypes[]{
219 jss::passphrase.cStr(), jss::secret.cStr(), jss::seed.cStr(), jss::seed_hex.cStr()};
222 char const* secretType =
nullptr;
224 for (
auto t : kSecretTypes)
233 if (count == 0 || secretType ==
nullptr)
242 "Exactly one of the following must be specified: " +
std::string(jss::passphrase) +
253 if (!params[jss::key_type].isString())
276 if (strcmp(secretType, jss::secret.cStr()) == 0)
279 "The secret field is not allowed if " +
std::string(jss::key_type) +
" is used.");
289 if (strcmp(secretType, jss::seed_hex.cStr()) != 0)
318 if (!params[jss::secret].isString())
339 logicError(
"keypairForSignature: invalid key type");
350 static constexpr auto kTypes =
351 std::to_array<std::tuple<char const*, char const*, LedgerEntryType>>({
352#pragma push_macro("LEDGER_ENTRY")
355#define LEDGER_ENTRY(tag, value, name, rpcName, ...) {jss::name, jss::rpcName, tag},
357#include <xrpl/protocol/detail/ledger_entries.macro>
360#pragma pop_macro("LEDGER_ENTRY")
363 auto const& p = params[jss::type];
369 "xrpl::RPC::chooseLedgerEntryType : first valid result type");
378 return boost::iequals(std::get<0>(t), filter) || std::get<1>(t) == filter;
380 if (iter == kTypes.end())
385 "xrpl::RPC::chooseLedgerEntryType : second valid result "
389 result.
second = std::get<2>(*iter);
399 case LedgerEntryType::ltAMENDMENTS:
400 case LedgerEntryType::ltDIR_NODE:
401 case LedgerEntryType::ltFEE_SETTINGS:
402 case LedgerEntryType::ltLEDGER_HASHES:
403 case LedgerEntryType::ltNEGATIVE_UNL:
417 auto const& jv = params[name];
418 auto const [issuerError, assetError] = [&]() {
419 if (name == jss::taker_pays)
424 if (jv.isMember(jss::mpt_issuance_id) &&
425 (jv.isMember(jss::currency) || jv.isMember(jss::issuer)))
427 JLOG(j.
info()) << boost::format(
"Bad %s currency or MPT.") % name.
cStr();
431 if (jv.isMember(jss::currency))
435 if (!jv.isMember(jss::currency) ||
438 JLOG(j.
info()) << boost::format(
"Bad %s currency.") % name.
cStr();
443 if (((jv.isMember(jss::issuer)) &&
444 (!jv[jss::issuer].isString() || !
toIssuer(issue.
account, jv[jss::issuer].asString())))
448 JLOG(j.
info()) << boost::format(
"Bad %s issuer.") % name.
cStr();
453 else if (jv.isMember(jss::mpt_issuance_id))
456 if (!mptid.
parseHex(jv[jss::mpt_issuance_id].asString()))
462 JLOG(j.
info()) << boost::format(
"Neither %s currency or MPT is present.") % name.
cStr();
A generic endpoint for log messages.
Lightweight wrapper to tag static string.
constexpr char const * cStr() const
bool isNull() const
isNull() tests to see if this field is null.
std::string asString() const
Returns the unquoted string value.
bool isMember(char const *key) const
Return true if the object has a member named key.
static constexpr std::size_t size()
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
A currency issued by an account.
std::shared_ptr< STLedgerEntry const > const & const_ref
Seeds are used to generate deterministic secret keys.
An immutable linear range of bytes.
API version numbers used in later API versions.
hash_set< AccountID > parseAccountIds(json::Value const &jvArray)
Parses an array of account IDs from a JSON value.
bool isRelatedToAccount(ReadView const &ledger, SLE::const_ref sle, AccountID const &accountID)
Tests if a ledger entry (SLE) is owned by the specified account.
std::optional< std::pair< PublicKey, SecretKey > > keypairForSignature(json::Value const ¶ms, json::Value &error, unsigned int apiVersion)
Generates a keypair for signature from RPC parameters.
bool isAccountObjectsValidType(LedgerEntryType const &type)
Checks if the type is a valid filtering type for the account_objects method.
std::optional< Seed > parseXrplLibSeed(json::Value const &value)
Parses a XrplLib seed from RPC parameters.
std::string invalidFieldMessage(std::string const &name)
json::Value makeError(ErrorCodeI code)
Returns a new json object that reflects the error code.
ErrorCodeI parseSubUnsubJson(Asset &asset, json::Value const ¶ms, json::StaticString const &name, beast::Journal j)
Parse subscribe/unsubscribe parameters.
std::uint64_t getStartHint(SLE::const_ref sle, AccountID const &accountID)
Gets the start hint for traversing account objects.
std::optional< Seed > getSeedFromRPC(json::Value const ¶ms, json::Value &error)
Extracts a Seed from RPC parameters.
bool containsError(json::Value const &json)
Returns true if the json contains an rpc error specification.
json::Value invalidFieldError(std::string const &name)
json::Value makeParamError(std::string const &message)
Returns a new json object that indicates invalid parameters.
std::optional< json::Value > readLimitField(unsigned int &limit, Tuning::LimitRange const &range, JsonContext const &context)
Retrieves the limit value from a JsonContext or sets a default.
json::Value missingFieldError(std::string const &name)
std::pair< RPC::Status, LedgerEntryType > chooseLedgerEntryType(json::Value const ¶ms)
Chooses the ledger entry type based on RPC parameters.
json::Value expectedFieldError(std::string const &name, std::string const &type)
Keylet signerList(AccountID const &account) noexcept
A SignerList.
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
std::optional< KeyType > keyTypeFromString(std::string const &s)
std::optional< AccountID > parseBase58(std::string const &s)
Parse AccountID from checked, base58 string.
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
std::unordered_set< Value, Hash, Pred, Allocator > hash_set
bool toCurrency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
json::Value rpcError(ErrorCodeI iError)
BaseUInt< 192 > MPTID
MPTID is a 192-bit value representing MPT Issuance ID, which is a concatenation of a 32-bit sequence ...
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
AccountID const & noAccount()
A placeholder for empty accounts.
LedgerEntryType
Identifiers for on-ledger objects.
@ ltANY
A special type, matching any ledger entry type.
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
std::string decodeBase58Token(std::string const &s, TokenType type)
bool toIssuer(AccountID &, std::string const &)
Convert hex or base58 string to AccountID.
std::optional< Seed > parseGenericSeed(std::string const &str, bool rfc1751=true)
Attempt to parse a string as a seed.
std::enable_if_t< std::is_same_v< T, char >||std::is_same_v< T, unsigned char >, Slice > makeSlice(std::array< T, N > const &a)
A pair of SHAMap key and LedgerEntryType.
Status represents the results of an operation that might fail.
static constexpr Code kOK
Represents RPC limit parameter values that have a min, default and max.