20#include <xrpld/app/ledger/LedgerMaster.h>
21#include <xrpld/app/main/Application.h>
22#include <xrpld/app/misc/DeliverMax.h>
23#include <xrpld/app/misc/NetworkOPs.h>
24#include <xrpld/app/misc/Transaction.h>
25#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
26#include <xrpld/ledger/ReadView.h>
27#include <xrpld/rpc/Context.h>
28#include <xrpld/rpc/DeliveredAmount.h>
29#include <xrpld/rpc/MPTokenIssuanceID.h>
30#include <xrpld/rpc/Role.h>
31#include <xrpl/json/json_reader.h>
32#include <xrpl/json/json_value.h>
33#include <xrpl/protocol/ErrorCodes.h>
34#include <xrpl/protocol/NFTSyntheticSerializer.h>
35#include <xrpl/protocol/RPCErr.h>
36#include <xrpl/protocol/UintTypes.h>
37#include <xrpl/protocol/jss.h>
38#include <xrpl/resource/Fees.h>
40#include <grpcpp/grpcpp.h>
62 if ((params.
isMember(jss::ledger_index_min) ||
63 params.
isMember(jss::ledger_index_max)) &&
64 (params.
isMember(jss::ledger_hash) ||
68 status.inject(response);
72 if (params.
isMember(jss::ledger_index_min) ||
73 params.
isMember(jss::ledger_index_max))
75 uint32_t min = params.
isMember(jss::ledger_index_min) &&
76 params[jss::ledger_index_min].
asInt() >= 0
77 ? params[jss::ledger_index_min].
asUInt()
79 uint32_t max = params.
isMember(jss::ledger_index_max) &&
80 params[jss::ledger_index_max].
asInt() >= 0
81 ? params[jss::ledger_index_max].
asUInt()
86 else if (params.
isMember(jss::ledger_hash))
88 auto& hashValue = params[jss::ledger_hash];
89 if (!hashValue.isString())
92 status.inject(response);
97 if (!hash.
parseHex(hashValue.asString()))
100 status.inject(response);
105 else if (params.
isMember(jss::ledger_index))
108 if (params[jss::ledger_index].isNumeric())
109 ledger = params[jss::ledger_index].
asUInt();
114 if (ledgerStr ==
"current" || ledgerStr.
empty())
115 ledger = LedgerShortcut::CURRENT;
116 else if (ledgerStr ==
"closed")
117 ledger = LedgerShortcut::CLOSED;
118 else if (ledgerStr ==
"validated")
119 ledger = LedgerShortcut::VALIDATED;
124 status.inject(response);
159 if constexpr (std::is_same_v<T, LedgerRange>)
166 if ((ls.max > uValidatedMax && ls.max != -1) ||
167 (ls.min < uValidatedMin && ls.min != 0))
172 if (ls.min > uValidatedMin)
176 if (ls.max < uValidatedMax)
180 if (uLedgerMax < uLedgerMin)
190 auto const status = getLedger(ledgerView, ls, context);
199 if (!validated || ledgerView->info().seq > uValidatedMax ||
200 ledgerView->info().seq < uValidatedMin)
204 uLedgerMin = uLedgerMax = ledgerView->info().seq;
224 if (
auto stat = std::get_if<RPC::Status>(&lgrRange))
227 return {result, *stat};
230 result.
ledgerRange = std::get<LedgerRange>(lgrRange);
246 Throw<std::runtime_error>(
"Failed to get relational database");
252 auto [tx, marker] = db->oldestAccountTxPageB(options);
258 auto [tx, marker] = db->newestAccountTxPageB(options);
267 auto [tx, marker] = db->oldestAccountTxPage(options);
273 auto [tx, marker] = db->newestAccountTxPage(options);
280 JLOG(context.
j.
debug()) << __func__ <<
" : finished";
295 error.inject(response);
300 response[jss::validated] =
true;
301 response[jss::limit] = result.
limit;
308 if (
auto txnsData = std::get_if<TxnsData>(&result.
transactions))
312 "ripple::populateJsonResponse : binary is not set");
314 for (
auto const& [txn, txnMeta] : *txnsData)
319 jvObj[jss::validated] =
true;
322 (context.
apiVersion > 1 ? jss::tx_json : jss::tx);
325 jvObj[json_tx] = txn->getJson(
329 jvObj[jss::hash] =
to_string(txn->getID());
330 jvObj[jss::ledger_index] = txn->getLedger();
331 jvObj[jss::ledger_hash] =
338 jvObj[jss::close_time_iso] =
345 auto const& sttx = txn->getSTransaction();
347 jvObj[json_tx], sttx->getTxnType(), context.
apiVersion);
352 insertDeliveredAmount(
353 jvObj[jss::meta], context, txn, *txnMeta);
356 jvObj[jss::meta], sttx, *txnMeta);
360 "ripple::populateJsonResponse : missing "
361 "transaction medatata");
368 args.
binary,
"ripple::populateJsonResponse : binary is set");
370 for (
auto const& binaryData :
375 jvObj[jss::tx_blob] =
strHex(std::get<0>(binaryData));
376 auto const json_meta =
377 (context.
apiVersion > 1 ? jss::meta_blob : jss::meta);
378 jvObj[json_meta] =
strHex(std::get<1>(binaryData));
379 jvObj[jss::ledger_index] = std::get<2>(binaryData);
380 jvObj[jss::validated] =
true;
387 response[jss::marker][jss::ledger] = result.
marker->ledgerSeq;
388 response[jss::marker][jss::seq] = result.
marker->txnSeq;
392 JLOG(context.
j.
debug()) << __func__ <<
" : finished";
412 auto& params = context.
params;
420 if (context.
apiVersion > 1u && params.isMember(jss::binary) &&
421 !params[jss::binary].isBool())
425 if (context.
apiVersion > 1u && params.isMember(jss::forward) &&
426 !params[jss::forward].isBool())
431 args.
limit = params.isMember(jss::limit) ? params[jss::limit].asUInt() : 0;
432 args.
binary = params.isMember(jss::binary) && params[jss::binary].asBool();
434 params.isMember(jss::forward) && params[jss::forward].asBool();
436 if (!params.isMember(jss::account))
439 if (!params[jss::account].isString())
443 parseBase58<AccountID>(params[jss::account].asString());
450 if (
auto jv = std::get_if<Json::Value>(&parseRes))
456 args.
ledger = std::get<std::optional<LedgerSpecifier>>(parseRes);
459 if (params.isMember(jss::marker))
461 auto& token = params[jss::marker];
462 if (!token.isMember(jss::ledger) || !token.isMember(jss::seq) ||
468 "invalid marker. Provide ledger index via ledger field, and "
469 "transaction sequence number via seq field"};
470 status.inject(response);
473 args.
marker = {token[jss::ledger].asUInt(), token[jss::seq].asUInt()};
477 JLOG(context.
j.
debug()) << __func__ <<
" populating response";
Value & append(const Value &value)
Append value to array at the end.
std::string asString() const
Returns the unquoted string value.
bool isMember(const char *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
Json::Value invalid_field_error(std::string const &name)
void insertMPTokenIssuanceID(Json::Value &response, std::shared_ptr< STTx const > const &transaction, TxMeta const &transactionMeta)
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)
void insertNFTSyntheticInJson(Json::Value &, std::shared_ptr< STTx const > const &, TxMeta const &)
Adds common synthetic fields to transaction-related JSON responses.
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