8#include "data/AmendmentCenterInterface.hpp"
9#include "data/BackendInterface.hpp"
10#include "data/Types.hpp"
13#include "rpc/common/Types.hpp"
14#include "util/JsonUtils.hpp"
15#include "util/Taggable.hpp"
16#include "util/log/Logger.hpp"
17#include "web/Context.hpp"
19#include <boost/asio/spawn.hpp>
20#include <boost/json/array.hpp>
21#include <boost/json/object.hpp>
22#include <boost/json/value.hpp>
23#include <boost/regex.hpp>
24#include <boost/regex/v5/regex_match.hpp>
25#include <fmt/format.h>
26#include <xrpl/basics/Number.h>
27#include <xrpl/basics/base_uint.h>
28#include <xrpl/json/json_value.h>
29#include <xrpl/protocol/AccountID.h>
30#include <xrpl/protocol/Book.h>
31#include <xrpl/protocol/Fees.h>
32#include <xrpl/protocol/Indexes.h>
33#include <xrpl/protocol/Issue.h>
34#include <xrpl/protocol/Keylet.h>
35#include <xrpl/protocol/LedgerFormats.h>
36#include <xrpl/protocol/LedgerHeader.h>
37#include <xrpl/protocol/MPTIssue.h>
38#include <xrpl/protocol/PublicKey.h>
39#include <xrpl/protocol/Rate.h>
40#include <xrpl/protocol/SField.h>
41#include <xrpl/protocol/STAmount.h>
42#include <xrpl/protocol/STBase.h>
43#include <xrpl/protocol/STLedgerEntry.h>
44#include <xrpl/protocol/STObject.h>
45#include <xrpl/protocol/STTx.h>
46#include <xrpl/protocol/SecretKey.h>
47#include <xrpl/protocol/Seed.h>
48#include <xrpl/protocol/Serializer.h>
49#include <xrpl/protocol/TxMeta.h>
50#include <xrpl/protocol/UintTypes.h>
51#include <xrpl/protocol/XRPAmount.h>
52#include <xrpl/protocol/jss.h>
78std::optional<xrpl::AccountID>
99getStartHint(xrpl::SLE
const& sle, xrpl::AccountID
const& accountID);
107std::optional<AccountCursor>
117std::pair<std::shared_ptr<xrpl::STTx const>, std::shared_ptr<xrpl::STObject const>>
128std::pair<std::shared_ptr<xrpl::STTx const>, std::shared_ptr<xrpl::TxMeta const>>
140std::pair<boost::json::object, boost::json::object>
143 std::uint32_t apiVersion,
145 std::optional<uint16_t> networkId = std::nullopt
178 boost::json::object& metaJson,
179 std::shared_ptr<xrpl::STTx const>
const& txn,
180 std::shared_ptr<xrpl::TxMeta const>
const& meta,
198 boost::json::object& txnJson,
199 std::shared_ptr<xrpl::STTx const>
const& txn,
200 boost::json::object& metaJson,
201 std::shared_ptr<xrpl::TxMeta const>
const& meta
211toJson(xrpl::STBase
const& obj);
220toJson(xrpl::SLE
const& sle);
231toJson(xrpl::LedgerHeader
const& info,
bool binary, std::uint32_t apiVersion);
240toJson(xrpl::TxMeta
const& meta);
242using RippledJson = json::Value;
264 xrpl::LedgerHeader
const& lgrInfo,
265 xrpl::Fees
const& fees,
266 std::string
const& ledgerRange,
267 std::uint32_t txnCount
277std::expected<xrpl::LedgerHeader, Status>
279 std::shared_ptr<data::BackendInterface const>
const& backend,
293std::expected<xrpl::LedgerHeader, Status>
295 BackendInterface
const& backend,
296 boost::asio::yield_context yield,
297 std::optional<std::string> ledgerHash,
298 std::optional<uint32_t> ledgerIndex,
315std::expected<AccountCursor, Status>
317 BackendInterface
const& backend,
318 xrpl::Keylet
const& owner,
319 xrpl::uint256
const& hexMarker,
320 std::uint32_t startHint,
321 std::uint32_t sequence,
323 boost::asio::yield_context yield,
324 std::function<
void(xrpl::SLE)> atOwnedNode
342std::expected<AccountCursor, Status>
344 BackendInterface
const& backend,
345 xrpl::AccountID
const& accountID,
346 std::uint32_t sequence,
348 std::optional<std::string> jsonCursor,
349 boost::asio::yield_context yield,
350 std::function<
void(xrpl::SLE)> atOwnedNode,
351 bool nftIncluded =
false
363std::shared_ptr<xrpl::SLE const>
365 std::shared_ptr<data::BackendInterface const>
const& backend,
366 xrpl::Keylet
const& keylet,
367 xrpl::LedgerHeader
const& lgrInfo,
377std::vector<xrpl::AccountID>
387std::vector<unsigned char>
401 BackendInterface
const& backend,
403 xrpl::AccountID
const& issuer,
404 boost::asio::yield_context yield
420 BackendInterface
const& backend,
421 std::uint32_t sequence,
422 xrpl::AccountID
const& account,
423 xrpl::Currency
const& currency,
424 xrpl::AccountID
const& issuer,
425 boost::asio::yield_context yield
440 BackendInterface
const& backend,
441 std::uint32_t sequence,
442 xrpl::Keylet
const& keylet,
443 std::vector<std::uint32_t>
const& flags,
444 boost::asio::yield_context yield
463 BackendInterface
const& backend,
464 std::uint32_t sequence,
465 xrpl::AccountID
const& account,
466 xrpl::Currency
const& currency,
467 xrpl::AccountID
const& issuer,
468 boost::asio::yield_context yield
484 BackendInterface
const& backend,
485 std::uint32_t sequence,
486 xrpl::AccountID
const& account,
487 xrpl::Issue
const& asset,
488 xrpl::Issue
const& asset2,
489 boost::asio::yield_context yield
505 BackendInterface
const& backend,
507 std::uint32_t sequence,
508 xrpl::STAmount
const& amount,
509 xrpl::AccountID
const&
id,
510 boost::asio::yield_context yield
528 BackendInterface
const& backend,
530 std::uint32_t sequence,
531 xrpl::AccountID
const& account,
532 xrpl::Currency
const& currency,
533 xrpl::AccountID
const& issuer,
535 boost::asio::yield_context yield
552 BackendInterface
const& backend,
553 std::uint32_t sequence,
554 xrpl::AccountID
const& account,
555 xrpl::Currency
const& currency,
556 xrpl::AccountID
const& issuer,
557 bool const zeroIfFrozen,
558 boost::asio::yield_context yield
572 BackendInterface
const& backend,
573 std::uint32_t sequence,
574 xrpl::AccountID
const& issuer,
575 boost::asio::yield_context yield
589 BackendInterface
const& backend,
590 std::uint32_t sequence,
591 xrpl::AccountID
const&
id,
592 boost::asio::yield_context yield
609 std::vector<data::LedgerObject>
const& offers,
610 xrpl::Book
const& book,
611 xrpl::AccountID
const& takerID,
614 std::uint32_t ledgerSequence,
615 boost::asio::yield_context yield
628std::expected<xrpl::Book, Status>
631 xrpl::AccountID payIssuer,
633 xrpl::AccountID getIssuer,
634 std::optional<std::string>
const& domain
643std::expected<xrpl::Book, Status>
644parseBook(boost::json::object
const& request);
652std::expected<xrpl::AccountID, Status>
681isAdminCmd(std::string
const& method, boost::json::object
const& request);
689std::expected<xrpl::uint256, Status>
690getNFTID(boost::json::object
const& request);
700std::optional<std::string>
701encodeCTID(uint32_t ledgerSeq, uint16_t txnIndex, uint16_t networkId)
noexcept;
711inline std::optional<std::tuple<uint32_t, uint16_t, uint16_t>>
714 auto const getCTID64 = [](T
const ctid)
noexcept -> std::optional<uint64_t> {
715 if constexpr (std::is_convertible_v<T, std::string>) {
716 std::string
const ctidString(ctid);
717 static constexpr std::size_t kCtidStringLength = 16;
718 if (ctidString.length() != kCtidStringLength)
721 if (!boost::regex_match(ctidString, boost::regex(
"^[0-9A-F]+$")))
724 return std::stoull(ctidString,
nullptr, 16);
727 if constexpr (std::is_same_v<T, uint64_t>)
733 auto const ctidValue = getCTID64(ctid).value_or(0);
735 static constexpr uint64_t kCtidPrefix = 0xC000'0000'0000'0000ULL;
736 static constexpr uint64_t kCtidPrefixMask = 0xF000'0000'0000'0000ULL;
738 if ((ctidValue & kCtidPrefixMask) != kCtidPrefix)
741 uint32_t
const ledgerSeq = (ctidValue >> 32) & 0xFFFF'FFFUL;
742 uint16_t
const txnIndex = (ctidValue >> 16) & 0xFFFFU;
743 uint16_t
const networkId = ctidValue & 0xFFFFU;
744 return {{ledgerSeq, txnIndex, networkId}};
755template <
typename DurationType>
758 boost::json::object
const& request,
760 DurationType
const& dur
763 using boost::json::serialize;
766 static constexpr std::int64_t kDurationErrorThresholdSeconds = 10;
768 auto const millis = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
769 auto const seconds = std::chrono::duration_cast<std::chrono::seconds>(dur).count();
770 auto const msg = fmt::format(
771 "Request processing duration = {} milliseconds. request = {}",
776 if (seconds > kDurationErrorThresholdSeconds) {
777 LOG(log.
error()) << tag << msg;
778 }
else if (seconds > 1) {
779 LOG(log.
warn()) << tag << msg;
781 LOG(log.
info()) << tag << msg;
791std::optional<xrpl::Seed>
806std::expected<AccountCursor, Status>
808 BackendInterface
const& backend,
809 std::uint32_t sequence,
810 xrpl::AccountID
const& accountID,
811 xrpl::uint256 nextPage,
813 boost::asio::yield_context yield,
814 std::function<
void(xrpl::SLE)> atOwnedNode
823std::optional<std::uint32_t>
835 std::shared_ptr<xrpl::STTx const>
const& txn,
836 std::shared_ptr<xrpl::TxMeta const>
const& meta
848std::optional<xrpl::STAmount>
850 std::shared_ptr<xrpl::STTx const>
const& txn,
851 std::shared_ptr<xrpl::TxMeta const>
const& meta,
852 std::uint32_t ledgerSequence,
The interface of an amendment center.
Definition AmendmentCenterInterface.hpp:17
The interface to the database used by Clio.
Definition BackendInterface.hpp:125
Represents any tag decorator.
Definition Taggable.hpp:55
A simple thread-safe logger for the channel specified in the constructor.
Definition Logger.hpp:78
Pump info(std::source_location const &loc=std::source_location::current()) const
Interface for logging at Severity::NFO severity.
Definition Logger.cpp:502
Pump error(std::source_location const &loc=std::source_location::current()) const
Interface for logging at Severity::ERR severity.
Definition Logger.cpp:512
Pump warn(std::source_location const &loc=std::source_location::current()) const
Interface for logging at Severity::WRN severity.
Definition Logger.cpp:507
This namespace contains all the RPC logic and handlers.
Definition AMMHelpers.cpp:17
boost::json::object generatePubLedgerMessage(xrpl::LedgerHeader const &lgrInfo, xrpl::Fees const &fees, std::string const &ledgerRange, std::uint32_t txnCount)
Generate a JSON object to publish ledger message.
std::expected< AccountCursor, Status > traverseOwnedNodes(BackendInterface const &backend, xrpl::AccountID const &accountID, std::uint32_t sequence, std::uint32_t limit, std::optional< std::string > jsonCursor, boost::asio::yield_context yield, std::function< void(xrpl::SLE)> atOwnedNode, bool nftIncluded)
Traverse nodes owned by an account.
Definition RPCHelpers.cpp:641
bool isGlobalFrozen(BackendInterface const &backend, std::uint32_t sequence, xrpl::AccountID const &issuer, boost::asio::yield_context yield)
Whether global frozen is set.
Definition RPCHelpers.cpp:909
bool isFrozen(BackendInterface const &backend, std::uint32_t sequence, xrpl::AccountID const &account, xrpl::Currency const ¤cy, xrpl::AccountID const &issuer, boost::asio::yield_context yield)
Whether the account is frozen.
Definition RPCHelpers.cpp:952
bool canHaveDeliveredAmount(std::shared_ptr< xrpl::STTx const > const &txn, std::shared_ptr< xrpl::TxMeta const > const &meta)
Whether the transaction can have a delivered amount.
Definition RPCHelpers.cpp:147
boost::json::object toJsonWithBinaryTx(data::TransactionAndMetadata const &txnPlusMeta, std::uint32_t const apiVersion)
Convert a TransactionAndMetadata to JSON object containing tx and metadata data in hex format....
Definition RPCHelpers.cpp:1640
xrpl::STAmount accountFunds(BackendInterface const &backend, data::AmendmentCenterInterface const &amendmentCenter, std::uint32_t const sequence, xrpl::STAmount const &amount, xrpl::AccountID const &id, boost::asio::yield_context yield)
Get the account funds.
Definition RPCHelpers.cpp:1053
std::optional< AccountCursor > parseAccountCursor(std::optional< std::string > jsonCursor)
Parse the account cursor from the JSON.
Definition RPCHelpers.cpp:88
void logDuration(boost::json::object const &request, util::BaseTagDecorator const &tag, DurationType const &dur)
Log the duration of the request processing.
Definition RPCHelpers.hpp:757
std::expected< xrpl::uint256, Status > getNFTID(boost::json::object const &request)
Get the NFTID from the request.
Definition RPCHelpers.cpp:1624
std::optional< xrpl::STAmount > getDeliveredAmount(std::shared_ptr< xrpl::STTx const > const &txn, std::shared_ptr< xrpl::TxMeta const > const &meta, std::uint32_t const ledgerSequence, uint32_t date)
Get the delivered amount.
Definition RPCHelpers.cpp:119
bool insertMPTIssuanceID(boost::json::object &txnJson, std::shared_ptr< xrpl::STTx const > const &txn, boost::json::object &metaJson, std::shared_ptr< xrpl::TxMeta const > const &meta)
Add "mpt_issuance_id" into various MPTToken transaction json.
Definition RPCHelpers.cpp:347
std::shared_ptr< xrpl::SLE const > read(std::shared_ptr< data::BackendInterface const > const &backend, xrpl::Keylet const &keylet, xrpl::LedgerHeader const &lgrInfo, web::Context const &context)
Read SLE from the backend.
Definition RPCHelpers.cpp:849
std::optional< std::string > encodeCTID(uint32_t ledgerSeq, uint16_t txnIndex, uint16_t networkId) noexcept
Encode CTID as string.
Definition RPCHelpers.cpp:268
bool isDeepFrozen(BackendInterface const &backend, std::uint32_t sequence, xrpl::AccountID const &account, xrpl::Currency const ¤cy, xrpl::AccountID const &issuer, boost::asio::yield_context yield)
Whether the trustline is deep frozen.
Definition RPCHelpers.cpp:981
std::vector< xrpl::AccountID > getAccountsFromTransaction(boost::json::object const &transaction)
Get the account associated with a transaction.
Definition RPCHelpers.cpp:888
std::vector< unsigned char > ledgerHeaderToBlob(xrpl::LedgerHeader const &info, bool includeHash)
Convert a ledger header to a blob.
Definition RPCHelpers.cpp:549
boost::json::object toJson(xrpl::STBase const &obj)
Convert STBase object to JSON.
Definition RPCHelpers.cpp:223
std::optional< std::tuple< uint32_t, uint16_t, uint16_t > > decodeCTID(T const ctid) noexcept
Decode the CTID from a string or a uint64_t.
Definition RPCHelpers.hpp:712
xrpl::Issue parseIssue(boost::json::object const &issue)
Parse the json object into a xrpl::Issue object.
Definition RPCHelpers.cpp:1572
std::pair< boost::json::object, boost::json::object > toExpandedJson(data::TransactionAndMetadata const &blobs, std::uint32_t const apiVersion, NFTokenjson nftEnabled, std::optional< uint16_t > networkId)
Convert a TransactionAndMetadata to two JSON objects.
Definition RPCHelpers.cpp:232
std::expected< AccountCursor, Status > traverseNFTObjects(BackendInterface const &backend, std::uint32_t sequence, xrpl::AccountID const &accountID, xrpl::uint256 nextPage, std::uint32_t limit, boost::asio::yield_context yield, std::function< void(xrpl::SLE)> atOwnedNode)
Traverse NFT objects and call the callback for each owned node.
Definition RPCHelpers.cpp:587
xrpl::XRPAmount xrpLiquid(BackendInterface const &backend, std::uint32_t sequence, xrpl::AccountID const &id, boost::asio::yield_context yield)
Get the XRP liquidity.
Definition RPCHelpers.cpp:1018
bool fetchAndCheckAnyFlagsExists(BackendInterface const &backend, std::uint32_t sequence, xrpl::Keylet const &keylet, std::vector< std::uint32_t > const &flags, boost::asio::yield_context yield)
Fetches a ledger object and checks if any of the specified flag is set on the account.
Definition RPCHelpers.cpp:932
std::optional< xrpl::Seed > parseRippleLibSeed(boost::json::value const &value)
Parse a ripple-lib seed.
Definition RPCHelpers.cpp:867
bool isOwnedByAccount(xrpl::SLE const &sle, xrpl::AccountID const &accountID)
Check whether the SLE is owned by the account.
NFTokenjson
Enum for NFT json manipulation.
Definition RPCHelpers.hpp:70
std::expected< xrpl::AccountID, Status > parseTaker(boost::json::value const &taker)
Parse the taker from the request.
Definition RPCHelpers.cpp:1558
std::expected< xrpl::LedgerHeader, Status > ledgerHeaderFromRequest(std::shared_ptr< data::BackendInterface const > const &backend, web::Context const &ctx)
Get ledger info from the request.
Definition RPCHelpers.cpp:462
std::optional< xrpl::AccountID > accountFromStringStrict(std::string const &account)
Get a xrpl::AccountID from its string representation.
Definition RPCHelpers.cpp:160
std::expected< xrpl::Book, Status > parseBook(xrpl::Currency pays, xrpl::AccountID payIssuer, xrpl::Currency gets, xrpl::AccountID getIssuer, std::optional< std::string > const &domain)
Parse the book from the request.
Definition RPCHelpers.cpp:1358
std::expected< xrpl::LedgerHeader, Status > getLedgerHeaderFromHashOrSeq(BackendInterface const &backend, boost::asio::yield_context yield, std::optional< std::string > ledgerHash, std::optional< uint32_t > ledgerIndex, uint32_t maxSeq)
Get ledger info from hash or sequence.
Definition RPCHelpers.cpp:516
void insertDeliverMaxAlias(boost::json::object &txJson, std::uint32_t const apiVersion)
Add "DeliverMax" which is the alias of "Amount" for "Payment" transaction to transaction json....
Definition RPCHelpers.cpp:375
bool specifiesCurrentOrClosedLedger(boost::json::object const &request)
Check whether the request specifies the current or closed ledger.
Definition RPCHelpers.cpp:1584
xrpl::STAmount accountHolds(BackendInterface const &backend, data::AmendmentCenterInterface const &amendmentCenter, std::uint32_t sequence, xrpl::AccountID const &account, xrpl::Currency const ¤cy, xrpl::AccountID const &issuer, bool const zeroIfFrozen, boost::asio::yield_context yield)
Get the amount that an account holds.
Definition RPCHelpers.cpp:1124
std::pair< std::shared_ptr< xrpl::STTx const >, std::shared_ptr< xrpl::STObject const > > deserializeTxPlusMeta(data::TransactionAndMetadata const &blobs)
Deserialize a TransactionAndMetadata into a pair of STTx and STObject.
Definition RPCHelpers.cpp:183
bool isLPTokenFrozen(BackendInterface const &backend, std::uint32_t sequence, xrpl::AccountID const &account, xrpl::Issue const &asset, xrpl::Issue const &asset2, boost::asio::yield_context yield)
Whether the account that owns a LPToken is frozen for the assets in the pool.
Definition RPCHelpers.cpp:1004
std::uint64_t getStartHint(xrpl::SLE const &sle, xrpl::AccountID const &accountID)
Get the start hint for the account.
Definition RPCHelpers.cpp:567
boost::json::value toBoostJson(json::Value const &value)
Convert a RippledJson to boost::json::value.
Definition RPCHelpers.cpp:395
boost::json::array postProcessOrderBook(std::vector< data::LedgerObject > const &offers, xrpl::Book const &book, xrpl::AccountID const &takerID, data::BackendInterface const &backend, data::AmendmentCenterInterface const &amendmentCenter, std::uint32_t const ledgerSequence, boost::asio::yield_context yield)
Post process an order book.
Definition RPCHelpers.cpp:1237
xrpl::Rate transferRate(BackendInterface const &backend, std::uint32_t sequence, xrpl::AccountID const &issuer, boost::asio::yield_context yield)
Get the transfer rate.
Definition RPCHelpers.cpp:1215
xrpl::STAmount ammAccountHolds(BackendInterface const &backend, std::uint32_t sequence, xrpl::AccountID const &account, xrpl::Currency const ¤cy, xrpl::AccountID const &issuer, bool const zeroIfFrozen, boost::asio::yield_context yield)
Get the amount that an LPToken owner holds.
Definition RPCHelpers.cpp:1079
bool insertDeliveredAmount(boost::json::object &metaJson, std::shared_ptr< xrpl::STTx const > const &txn, std::shared_ptr< xrpl::TxMeta const > const &meta, uint32_t date)
Add "DeliveredAmount" to the transaction json object.
Definition RPCHelpers.cpp:285
std::optional< std::uint32_t > parseStringAsUInt(std::string const &value)
Parse the string as a uint32_t.
Definition RPCHelpers.cpp:449
bool isAdminCmd(std::string const &method, boost::json::object const &request)
Check whether a request requires administrative privileges on rippled side.
Definition RPCHelpers.cpp:1597
boost::json::object removeSecret(boost::json::object const &object)
Removes any detected secret information from a response JSON object.
Definition JsonUtils.hpp:55
Context that is used by the Webserver to pass around information about an incoming request.
Definition Context.hpp:22