1#include <xrpld/app/ledger/LedgerMaster.h>
2#include <xrpld/app/main/Application.h>
3#include <xrpld/app/misc/DeliverMax.h>
4#include <xrpld/app/misc/Transaction.h>
5#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
6#include <xrpld/rpc/Context.h>
7#include <xrpld/rpc/DeliveredAmount.h>
8#include <xrpld/rpc/MPTokenIssuanceID.h>
9#include <xrpld/rpc/Role.h>
10#include <xrpld/rpc/detail/RPCHelpers.h>
11#include <xrpld/rpc/detail/Tuning.h>
13#include <xrpl/json/json_value.h>
14#include <xrpl/ledger/ReadView.h>
15#include <xrpl/protocol/ErrorCodes.h>
16#include <xrpl/protocol/NFTSyntheticSerializer.h>
17#include <xrpl/protocol/RPCErr.h>
18#include <xrpl/protocol/UintTypes.h>
19#include <xrpl/protocol/jss.h>
20#include <xrpl/resource/Fees.h>
42 if ((params.
isMember(jss::ledger_index_min) ||
43 params.
isMember(jss::ledger_index_max)) &&
44 (params.
isMember(jss::ledger_hash) ||
48 status.inject(response);
52 if (params.
isMember(jss::ledger_index_min) ||
53 params.
isMember(jss::ledger_index_max))
55 uint32_t min = params.
isMember(jss::ledger_index_min) &&
56 params[jss::ledger_index_min].
asInt() >= 0
57 ? params[jss::ledger_index_min].
asUInt()
59 uint32_t max = params.
isMember(jss::ledger_index_max) &&
60 params[jss::ledger_index_max].
asInt() >= 0
61 ? params[jss::ledger_index_max].
asUInt()
66 else if (params.
isMember(jss::ledger_hash))
68 auto& hashValue = params[jss::ledger_hash];
69 if (!hashValue.isString())
72 status.inject(response);
77 if (!hash.
parseHex(hashValue.asString()))
80 status.inject(response);
85 else if (params.
isMember(jss::ledger_index))
88 if (params[jss::ledger_index].isNumeric())
89 ledger = params[jss::ledger_index].
asUInt();
94 if (ledgerStr ==
"current" || ledgerStr.
empty())
95 ledger = LedgerShortcut::CURRENT;
96 else if (ledgerStr ==
"closed")
97 ledger = LedgerShortcut::CLOSED;
98 else if (ledgerStr ==
"validated")
99 ledger = LedgerShortcut::VALIDATED;
104 status.inject(response);
146 if ((ls.max > uValidatedMax && ls.max != -1) ||
147 (ls.min < uValidatedMin && ls.min != 0))
152 if (ls.min > uValidatedMin)
156 if (ls.max < uValidatedMax)
160 if (uLedgerMax < uLedgerMin)
170 auto const status = getLedger(ledgerView, ls, context);
179 if (!validated || ledgerView->info().seq > uValidatedMax ||
180 ledgerView->info().seq < uValidatedMin)
184 uLedgerMin = uLedgerMax = ledgerView->info().seq;
207 return {result, *stat};
226 Throw<std::runtime_error>(
"Failed to get relational database");
232 auto [tx, marker] = db->oldestAccountTxPageB(options);
238 auto [tx, marker] = db->newestAccountTxPageB(options);
247 auto [tx, marker] = db->oldestAccountTxPage(options);
253 auto [tx, marker] = db->newestAccountTxPage(options);
260 JLOG(context.
j.
debug()) << __func__ <<
" : finished";
275 error.inject(response);
280 response[jss::validated] =
true;
281 response[jss::limit] = result.
limit;
292 "ripple::populateJsonResponse : binary is not set");
294 for (
auto const& [txn, txnMeta] : *txnsData)
299 jvObj[jss::validated] =
true;
302 (context.
apiVersion > 1 ? jss::tx_json : jss::tx);
305 jvObj[json_tx] = txn->getJson(
309 jvObj[jss::hash] =
to_string(txn->getID());
310 jvObj[jss::ledger_index] = txn->getLedger();
311 jvObj[jss::ledger_hash] =
318 jvObj[jss::close_time_iso] =
325 auto const& sttx = txn->getSTransaction();
327 jvObj[json_tx], sttx->getTxnType(), context.
apiVersion);
332 insertDeliveredAmount(
333 jvObj[jss::meta], context, txn, *txnMeta);
336 jvObj[jss::meta], sttx, *txnMeta);
342 "ripple::populateJsonResponse : missing "
343 "transaction medatata");
352 args.
binary,
"ripple::populateJsonResponse : binary is set");
354 for (
auto const& binaryData :
360 auto const json_meta =
361 (context.
apiVersion > 1 ? jss::meta_blob : jss::meta);
363 jvObj[jss::ledger_index] =
std::get<2>(binaryData);
364 jvObj[jss::validated] =
true;
371 response[jss::marker][jss::ledger] = result.
marker->ledgerSeq;
372 response[jss::marker][jss::seq] = result.
marker->txnSeq;
376 JLOG(context.
j.
debug()) << __func__ <<
" : finished";
396 auto& params = context.
params;
404 if (context.
apiVersion > 1u && params.isMember(jss::binary) &&
405 !params[jss::binary].isBool())
409 if (context.
apiVersion > 1u && params.isMember(jss::forward) &&
410 !params[jss::forward].isBool())
419 args.
binary = params.isMember(jss::binary) && params[jss::binary].asBool();
421 params.isMember(jss::forward) && params[jss::forward].asBool();
423 if (!params.isMember(jss::account))
426 if (!params[jss::account].isString())
430 parseBase58<AccountID>(params[jss::account].asString());
446 if (params.isMember(jss::marker))
448 auto& token = params[jss::marker];
449 if (!token.isMember(jss::ledger) || !token.isMember(jss::seq) ||
455 "invalid marker. Provide ledger index via ledger field, and "
456 "transaction sequence number via seq field"};
457 status.inject(response);
460 args.
marker = {token[jss::ledger].asUInt(), token[jss::seq].asUInt()};
464 JLOG(context.
j.
debug()) << __func__ <<
" populating response";
Value & append(Value const &value)
Append value to array at the end.
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.
virtual Config & config()=0
virtual RelationalDatabase & getRelationalDatabase()=0
std::optional< NetClock::time_point > getCloseTimeBySeq(LedgerIndex ledgerIndex)
bool isValidated(ReadView const &ledger)
uint256 getHashBySeq(std::uint32_t index)
Get a ledger's hash by sequence number using the cache.
bool getValidatedRange(std::uint32_t &minVal, std::uint32_t &maxVal)
std::vector< txnMetaLedgerType > MetaTxsList
std::vector< AccountTx > AccountTxs
RPC::LedgerShortcut LedgerShortcut
std::tuple< Blob, Blob, std::uint32_t > txnMetaLedgerType
std::variant< LedgerRange, LedgerShortcut, LedgerSequence, LedgerHash > LedgerSpecifier
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
@ arrayValue
array value (ordered list)
@ objectValue
object value (collection of name/value pairs).
@ uintValue
unsigned integer value
static LimitRange constexpr accountTx
Limits for the account_tx command.
Json::Value invalid_field_error(std::string const &name)
void insertNFTSyntheticInJson(Json::Value &, std::shared_ptr< STTx const > const &, TxMeta const &)
Adds common synthetic fields to transaction-related JSON responses.
void insertMPTokenIssuanceID(Json::Value &response, std::shared_ptr< STTx const > const &transaction, TxMeta const &transactionMeta)
std::optional< Json::Value > readLimitField(unsigned int &limit, Tuning::LimitRange const &range, JsonContext const &context)
Retrieve the limit value from a JsonContext, or set a default - then restrict the limit by max and mi...
void insertDeliverMax(Json::Value &tx_json, TxType txnType, unsigned int apiVersion)
Copy Amount field to DeliverMax field in transaction output JSON.
Json::Value missing_field_error(std::string const &name)
Charge const feeMediumBurdenRPC
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::variant< LedgerRange, RPC::Status > getLedgerRange(RPC::Context &context, std::optional< LedgerSpecifier > const &ledgerSpecifier)
Json::Value doAccountTxJson(RPC::JsonContext &context)
Json::Value rpcError(int iError)
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
std::string strHex(FwdIt begin, FwdIt end)
std::string to_string_iso(date::sys_time< Duration > tp)
Json::Value populateJsonResponse(std::pair< AccountTxResult, RPC::Status > const &res, AccountTxArgs const &args, RPC::JsonContext const &context)
std::string to_string(base_uint< Bits, Tag > const &a)
std::variant< std::optional< LedgerSpecifier >, Json::Value > parseLedgerArgs(RPC::Context &context, Json::Value const ¶ms)
std::pair< AccountTxResult, RPC::Status > doAccountTxHelp(RPC::Context &context, AccountTxArgs const &args)
The context of information needed to call an RPC.
Resource::Charge & loadType
LedgerMaster & ledgerMaster
Status represents the results of an operation that might fail.
std::optional< AccountTxMarker > marker
std::optional< LedgerSpecifier > ledger
std::optional< AccountTxMarker > marker
std::variant< AccountTxs, MetaTxsList > transactions