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/Transaction.h> 
   24#include <xrpld/app/rdb/backend/SQLiteDatabase.h> 
   25#include <xrpld/rpc/Context.h> 
   26#include <xrpld/rpc/DeliveredAmount.h> 
   27#include <xrpld/rpc/MPTokenIssuanceID.h> 
   28#include <xrpld/rpc/Role.h> 
   29#include <xrpld/rpc/detail/RPCHelpers.h> 
   30#include <xrpld/rpc/detail/Tuning.h> 
   32#include <xrpl/json/json_value.h> 
   33#include <xrpl/ledger/ReadView.h> 
   34#include <xrpl/protocol/ErrorCodes.h> 
   35#include <xrpl/protocol/NFTSyntheticSerializer.h> 
   36#include <xrpl/protocol/RPCErr.h> 
   37#include <xrpl/protocol/UintTypes.h> 
   38#include <xrpl/protocol/jss.h> 
   39#include <xrpl/resource/Fees.h> 
   61        if ((params.
isMember(jss::ledger_index_min) ||
 
   62             params.
isMember(jss::ledger_index_max)) &&
 
   63            (params.
isMember(jss::ledger_hash) ||
 
   67            status.inject(response);
 
   71    if (params.
isMember(jss::ledger_index_min) ||
 
   72        params.
isMember(jss::ledger_index_max))
 
   74        uint32_t min = params.
isMember(jss::ledger_index_min) &&
 
   75                params[jss::ledger_index_min].
asInt() >= 0
 
   76            ? params[jss::ledger_index_min].
asUInt()
 
   78        uint32_t max = params.
isMember(jss::ledger_index_max) &&
 
   79                params[jss::ledger_index_max].
asInt() >= 0
 
   80            ? params[jss::ledger_index_max].
asUInt()
 
   85    else if (params.
isMember(jss::ledger_hash))
 
   87        auto& hashValue = params[jss::ledger_hash];
 
   88        if (!hashValue.isString())
 
   91            status.inject(response);
 
   96        if (!hash.
parseHex(hashValue.asString()))
 
   99            status.inject(response);
 
  104    else if (params.
isMember(jss::ledger_index))
 
  107        if (params[jss::ledger_index].isNumeric())
 
  108            ledger = params[jss::ledger_index].
asUInt();
 
  113            if (ledgerStr == 
"current" || ledgerStr.
empty())
 
  114                ledger = LedgerShortcut::CURRENT;
 
  115            else if (ledgerStr == 
"closed")
 
  116                ledger = LedgerShortcut::CLOSED;
 
  117            else if (ledgerStr == 
"validated")
 
  118                ledger = LedgerShortcut::VALIDATED;
 
  123                status.inject(response);
 
 
  165                        if ((ls.max > uValidatedMax && ls.max != -1) ||
 
  166                            (ls.min < uValidatedMin && ls.min != 0))
 
  171                    if (ls.min > uValidatedMin)
 
  175                    if (ls.max < uValidatedMax)
 
  179                    if (uLedgerMax < uLedgerMin)
 
  189                    auto const status = getLedger(ledgerView, ls, context);
 
  198                    if (!validated || ledgerView->info().seq > uValidatedMax ||
 
  199                        ledgerView->info().seq < uValidatedMin)
 
  203                    uLedgerMin = uLedgerMax = ledgerView->info().seq;
 
 
  226        return {result, *stat};
 
  245        Throw<std::runtime_error>(
"Failed to get relational database");
 
  251            auto [tx, marker] = db->oldestAccountTxPageB(options);
 
  257            auto [tx, marker] = db->newestAccountTxPageB(options);
 
  266            auto [tx, marker] = db->oldestAccountTxPage(options);
 
  272            auto [tx, marker] = db->newestAccountTxPage(options);
 
  279    JLOG(context.
j.
debug()) << __func__ << 
" : finished";
 
 
  294        error.inject(response);
 
  299        response[jss::validated] = 
true;
 
  300        response[jss::limit] = result.
limit;
 
  311                "ripple::populateJsonResponse : binary is not set");
 
  313            for (
auto const& [txn, txnMeta] : *txnsData)
 
  318                    jvObj[jss::validated] = 
true;
 
  321                        (context.
apiVersion > 1 ? jss::tx_json : jss::tx);
 
  324                        jvObj[json_tx] = txn->getJson(
 
  328                        jvObj[jss::hash] = 
to_string(txn->getID());
 
  329                        jvObj[jss::ledger_index] = txn->getLedger();
 
  330                        jvObj[jss::ledger_hash] =
 
  337                            jvObj[jss::close_time_iso] =
 
  344                    auto const& sttx = txn->getSTransaction();
 
  346                        jvObj[json_tx], sttx->getTxnType(), context.
apiVersion);
 
  351                        insertDeliveredAmount(
 
  352                            jvObj[jss::meta], context, txn, *txnMeta);
 
  355                            jvObj[jss::meta], sttx, *txnMeta);
 
  361                            "ripple::populateJsonResponse : missing " 
  362                            "transaction medatata");
 
  371                args.
binary, 
"ripple::populateJsonResponse : binary is set");
 
  373            for (
auto const& binaryData :
 
  379                auto const json_meta =
 
  380                    (context.
apiVersion > 1 ? jss::meta_blob : jss::meta);
 
  382                jvObj[jss::ledger_index] = 
std::get<2>(binaryData);
 
  383                jvObj[jss::validated] = 
true;
 
  390            response[jss::marker][jss::ledger] = result.
marker->ledgerSeq;
 
  391            response[jss::marker][jss::seq] = result.
marker->txnSeq;
 
  395    JLOG(context.
j.
debug()) << __func__ << 
" : finished";
 
 
  415    auto& params = context.
params;
 
  423    if (context.
apiVersion > 1u && params.isMember(jss::binary) &&
 
  424        !params[jss::binary].isBool())
 
  428    if (context.
apiVersion > 1u && params.isMember(jss::forward) &&
 
  429        !params[jss::forward].isBool())
 
  438    args.
binary = params.isMember(jss::binary) && params[jss::binary].asBool();
 
  440        params.isMember(jss::forward) && params[jss::forward].asBool();
 
  442    if (!params.isMember(jss::account))
 
  445    if (!params[jss::account].isString())
 
  449        parseBase58<AccountID>(params[jss::account].asString());
 
  465    if (params.isMember(jss::marker))
 
  467        auto& token = params[jss::marker];
 
  468        if (!token.isMember(jss::ledger) || !token.isMember(jss::seq) ||
 
  474                "invalid marker. Provide ledger index via ledger field, and " 
  475                "transaction sequence number via seq field"};
 
  476            status.inject(response);
 
  479        args.
marker = {token[jss::ledger].asUInt(), token[jss::seq].asUInt()};
 
  483    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