27#include "data/AmendmentCenterInterface.hpp"
28#include "data/BackendInterface.hpp"
29#include "data/Types.hpp"
32#include "rpc/common/Types.hpp"
33#include "util/JsonUtils.hpp"
34#include "util/Taggable.hpp"
35#include "util/log/Logger.hpp"
36#include "web/Context.hpp"
38#include <boost/asio/spawn.hpp>
39#include <boost/json/array.hpp>
40#include <boost/json/object.hpp>
41#include <boost/json/value.hpp>
42#include <boost/regex.hpp>
43#include <boost/regex/v5/regex_fwd.hpp>
44#include <boost/regex/v5/regex_match.hpp>
45#include <fmt/format.h>
46#include <xrpl/basics/Number.h>
47#include <xrpl/basics/base_uint.h>
48#include <xrpl/json/json_value.h>
49#include <xrpl/protocol/AccountID.h>
50#include <xrpl/protocol/Book.h>
51#include <xrpl/protocol/Fees.h>
52#include <xrpl/protocol/Indexes.h>
53#include <xrpl/protocol/Issue.h>
54#include <xrpl/protocol/Keylet.h>
55#include <xrpl/protocol/LedgerFormats.h>
56#include <xrpl/protocol/LedgerHeader.h>
57#include <xrpl/protocol/MPTIssue.h>
58#include <xrpl/protocol/PublicKey.h>
59#include <xrpl/protocol/Rate.h>
60#include <xrpl/protocol/SField.h>
61#include <xrpl/protocol/STAmount.h>
62#include <xrpl/protocol/STBase.h>
63#include <xrpl/protocol/STLedgerEntry.h>
64#include <xrpl/protocol/STObject.h>
65#include <xrpl/protocol/STTx.h>
66#include <xrpl/protocol/SecretKey.h>
67#include <xrpl/protocol/Seed.h>
68#include <xrpl/protocol/Serializer.h>
69#include <xrpl/protocol/TxMeta.h>
70#include <xrpl/protocol/UintTypes.h>
71#include <xrpl/protocol/XRPAmount.h>
72#include <xrpl/protocol/jss.h>
96std::optional<ripple::AccountID>
117getStartHint(ripple::SLE
const& sle, ripple::AccountID
const& accountID);
125std::optional<AccountCursor>
135std::pair<std::shared_ptr<ripple::STTx const>, std::shared_ptr<ripple::STObject const>>
146std::pair<std::shared_ptr<ripple::STTx const>, std::shared_ptr<ripple::TxMeta const>>
158std::pair<boost::json::object, boost::json::object>
161 std::uint32_t apiVersion,
163 std::optional<uint16_t> networkId = std::nullopt
196 boost::json::object& metaJson,
197 std::shared_ptr<ripple::STTx const>
const& txn,
198 std::shared_ptr<ripple::TxMeta const>
const& meta,
216 boost::json::object& txnJson,
217 std::shared_ptr<ripple::STTx const>
const& txn,
218 boost::json::object& metaJson,
219 std::shared_ptr<ripple::TxMeta const>
const& meta
229toJson(ripple::STBase
const& obj);
238toJson(ripple::SLE
const& sle);
249toJson(ripple::LedgerHeader
const& info,
bool binary, std::uint32_t apiVersion);
258toJson(ripple::TxMeta
const& meta);
260using RippledJson = Json::Value;
282 ripple::LedgerHeader
const& lgrInfo,
283 ripple::Fees
const& fees,
284 std::string
const& ledgerRange,
285 std::uint32_t txnCount
295std::expected<ripple::LedgerHeader, Status>
308std::expected<ripple::LedgerHeader, Status>
310 BackendInterface
const& backend,
311 boost::asio::yield_context yield,
312 std::optional<std::string> ledgerHash,
313 std::optional<uint32_t> ledgerIndex,
330std::expected<AccountCursor, Status>
332 BackendInterface
const& backend,
333 ripple::Keylet
const& owner,
334 ripple::uint256
const& hexMarker,
335 std::uint32_t startHint,
336 std::uint32_t sequence,
338 boost::asio::yield_context yield,
339 std::function<
void(ripple::SLE)> atOwnedNode
357std::expected<AccountCursor, Status>
359 BackendInterface
const& backend,
360 ripple::AccountID
const& accountID,
361 std::uint32_t sequence,
363 std::optional<std::string> jsonCursor,
364 boost::asio::yield_context yield,
365 std::function<
void(ripple::SLE)> atOwnedNode,
366 bool nftIncluded =
false
378std::shared_ptr<ripple::SLE const>
380 std::shared_ptr<data::BackendInterface const>
const& backend,
381 ripple::Keylet
const& keylet,
382 ripple::LedgerHeader
const& lgrInfo,
392std::vector<ripple::AccountID>
402std::vector<unsigned char>
416 BackendInterface
const& backend,
418 ripple::AccountID
const& issuer,
419 boost::asio::yield_context yield
435 BackendInterface
const& backend,
436 std::uint32_t sequence,
437 ripple::AccountID
const& account,
438 ripple::Currency
const& currency,
439 ripple::AccountID
const& issuer,
440 boost::asio::yield_context yield
455 BackendInterface
const& backend,
456 std::uint32_t sequence,
457 ripple::Keylet
const& keylet,
458 std::vector<std::uint32_t>
const& flags,
459 boost::asio::yield_context yield
478 BackendInterface
const& backend,
479 std::uint32_t sequence,
480 ripple::AccountID
const& account,
481 ripple::Currency
const& currency,
482 ripple::AccountID
const& issuer,
483 boost::asio::yield_context yield
499 BackendInterface
const& backend,
500 std::uint32_t sequence,
501 ripple::AccountID
const& account,
502 ripple::Issue
const& asset,
503 ripple::Issue
const& asset2,
504 boost::asio::yield_context yield
520 BackendInterface
const& backend,
522 std::uint32_t sequence,
523 ripple::STAmount
const& amount,
524 ripple::AccountID
const&
id,
525 boost::asio::yield_context yield
543 BackendInterface
const& backend,
545 std::uint32_t sequence,
546 ripple::AccountID
const& account,
547 ripple::Currency
const& currency,
548 ripple::AccountID
const& issuer,
550 boost::asio::yield_context yield
567 BackendInterface
const& backend,
568 std::uint32_t sequence,
569 ripple::AccountID
const& account,
570 ripple::Currency
const& currency,
571 ripple::AccountID
const& issuer,
572 bool const zeroIfFrozen,
573 boost::asio::yield_context yield
587 BackendInterface
const& backend,
588 std::uint32_t sequence,
589 ripple::AccountID
const& issuer,
590 boost::asio::yield_context yield
604 BackendInterface
const& backend,
605 std::uint32_t sequence,
606 ripple::AccountID
const&
id,
607 boost::asio::yield_context yield
624 std::vector<data::LedgerObject>
const& offers,
625 ripple::Book
const& book,
626 ripple::AccountID
const& takerID,
629 std::uint32_t ledgerSequence,
630 boost::asio::yield_context yield
643std::expected<ripple::Book, Status>
645 ripple::Currency pays,
646 ripple::AccountID payIssuer,
647 ripple::Currency gets,
648 ripple::AccountID getIssuer,
649 std::optional<std::string>
const& domain
658std::expected<ripple::Book, Status>
659parseBook(boost::json::object
const& request);
667std::expected<ripple::AccountID, Status>
696isAdminCmd(std::string
const& method, boost::json::object
const& request);
704std::expected<ripple::uint256, Status>
705getNFTID(boost::json::object
const& request);
715std::optional<std::string>
716encodeCTID(uint32_t ledgerSeq, uint16_t txnIndex, uint16_t networkId)
noexcept;
726inline std::optional<std::tuple<uint32_t, uint16_t, uint16_t>>
729 auto const getCTID64 = [](T
const ctid)
noexcept -> std::optional<uint64_t> {
730 if constexpr (std::is_convertible_v<T, std::string>) {
731 std::string
const ctidString(ctid);
732 static constexpr std::size_t kCTID_STRING_LENGTH = 16;
733 if (ctidString.length() != kCTID_STRING_LENGTH)
736 if (!boost::regex_match(ctidString, boost::regex(
"^[0-9A-F]+$")))
739 return std::stoull(ctidString,
nullptr, 16);
742 if constexpr (std::is_same_v<T, uint64_t>)
748 auto const ctidValue = getCTID64(ctid).value_or(0);
750 static constexpr uint64_t kCTID_PREFIX = 0xC000'0000'0000'0000ULL;
751 static constexpr uint64_t kCTID_PREFIX_MASK = 0xF000'0000'0000'0000ULL;
753 if ((ctidValue & kCTID_PREFIX_MASK) != kCTID_PREFIX)
756 uint32_t
const ledgerSeq = (ctidValue >> 32) & 0xFFFF'FFFUL;
757 uint16_t
const txnIndex = (ctidValue >> 16) & 0xFFFFU;
758 uint16_t
const networkId = ctidValue & 0xFFFFU;
759 return {{ledgerSeq, txnIndex, networkId}};
770template <
typename DurationType>
774 using boost::json::serialize;
777 static constexpr std::int64_t kDURATION_ERROR_THRESHOLD_SECONDS = 10;
779 auto const millis = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
780 auto const seconds = std::chrono::duration_cast<std::chrono::seconds>(dur).count();
781 auto const msg = fmt::format(
782 "Request processing duration = {} milliseconds. request = {}", millis, serialize(
util::removeSecret(request))
785 if (seconds > kDURATION_ERROR_THRESHOLD_SECONDS) {
786 LOG(log.
error()) << tag << msg;
787 }
else if (seconds > 1) {
788 LOG(log.
warn()) << tag << msg;
790 LOG(log.
info()) << tag << msg;
799std::optional<ripple::Seed>
814std::expected<AccountCursor, Status>
816 BackendInterface
const& backend,
817 std::uint32_t sequence,
818 ripple::AccountID
const& accountID,
819 ripple::uint256 nextPage,
821 boost::asio::yield_context yield,
822 std::function<
void(ripple::SLE)> atOwnedNode
831std::optional<std::uint32_t>
843 std::shared_ptr<ripple::STTx const>
const& txn,
844 std::shared_ptr<ripple::TxMeta const>
const& meta
856std::optional<ripple::STAmount>
858 std::shared_ptr<ripple::STTx const>
const& txn,
859 std::shared_ptr<ripple::TxMeta const>
const& meta,
860 std::uint32_t ledgerSequence,
The interface of an amendment center.
Definition AmendmentCenterInterface.hpp:36
The interface to the database used by Clio.
Definition BackendInterface.hpp:139
Represents any tag decorator.
Definition Taggable.hpp:74
A simple thread-safe logger for the channel specified in the constructor.
Definition Logger.hpp:95
Pump warn(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::WRN severity.
Definition Logger.cpp:485
Pump error(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::ERR severity.
Definition Logger.cpp:490
Pump info(SourceLocationType const &loc=CURRENT_SRC_LOCATION) const
Interface for logging at Severity::NFO severity.
Definition Logger.cpp:480
This namespace contains all the RPC logic and handlers.
Definition AMMHelpers.cpp:37
std::pair< std::shared_ptr< ripple::STTx const >, std::shared_ptr< ripple::STObject const > > deserializeTxPlusMeta(data::TransactionAndMetadata const &blobs)
Deserialize a TransactionAndMetadata into a pair of STTx and STObject.
Definition RPCHelpers.cpp:202
std::expected< ripple::uint256, Status > getNFTID(boost::json::object const &request)
Get the NFTID from the request.
Definition RPCHelpers.cpp:1545
std::uint64_t getStartHint(ripple::SLE const &sle, ripple::AccountID const &accountID)
Get the start hint for the account.
Definition RPCHelpers.cpp:571
ripple::Issue parseIssue(boost::json::object const &issue)
Parse the json object into a ripple::Issue object.
Definition RPCHelpers.cpp:1495
bool isFrozen(BackendInterface const &backend, std::uint32_t sequence, ripple::AccountID const &account, ripple::Currency const ¤cy, ripple::AccountID const &issuer, boost::asio::yield_context yield)
Whether the account is frozen.
Definition RPCHelpers.cpp:929
bool insertDeliveredAmount(boost::json::object &metaJson, std::shared_ptr< ripple::STTx const > const &txn, std::shared_ptr< ripple::TxMeta const > const &meta, uint32_t date)
Add "DeliveredAmount" to the transaction json object.
Definition RPCHelpers.cpp:301
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:1561
bool isDeepFrozen(BackendInterface const &backend, std::uint32_t sequence, ripple::AccountID const &account, ripple::Currency const ¤cy, ripple::AccountID const &issuer, boost::asio::yield_context yield)
Whether the trustline is deep frozen.
Definition RPCHelpers.cpp:958
std::optional< AccountCursor > parseAccountCursor(std::optional< std::string > jsonCursor)
Parse the account cursor from the JSON.
Definition RPCHelpers.cpp:108
std::expected< ripple::LedgerHeader, Status > ledgerHeaderFromRequest(std::shared_ptr< data::BackendInterface const > const &backend, web::Context const &ctx)
Get ledger info from the request.
Definition RPCHelpers.cpp:469
std::vector< ripple::AccountID > getAccountsFromTransaction(boost::json::object const &transaction)
Get the account associated with a transaction.
Definition RPCHelpers.cpp:867
void logDuration(boost::json::object const &request, util::BaseTagDecorator const &tag, DurationType const &dur)
Log the duration of the request processing.
Definition RPCHelpers.hpp:772
ripple::STAmount ammAccountHolds(BackendInterface const &backend, std::uint32_t sequence, ripple::AccountID const &account, ripple::Currency const ¤cy, ripple::AccountID const &issuer, bool const zeroIfFrozen, boost::asio::yield_context yield)
Get the amount that an LPToken owner holds.
Definition RPCHelpers.cpp:1047
std::optional< std::string > encodeCTID(uint32_t ledgerSeq, uint16_t txnIndex, uint16_t networkId) noexcept
Encode CTID as string.
Definition RPCHelpers.cpp:284
boost::json::object generatePubLedgerMessage(ripple::LedgerHeader const &lgrInfo, ripple::Fees const &fees, std::string const &ledgerRange, std::uint32_t txnCount)
Generate a JSON object to publish ledger message.
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:727
std::expected< ripple::Book, Status > parseBook(ripple::Currency pays, ripple::AccountID payIssuer, ripple::Currency gets, ripple::AccountID getIssuer, std::optional< std::string > const &domain)
Parse the book from the request.
Definition RPCHelpers.cpp:1315
boost::json::array postProcessOrderBook(std::vector< data::LedgerObject > const &offers, ripple::Book const &book, ripple::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:1199
bool isOwnedByAccount(ripple::SLE const &sle, ripple::AccountID const &accountID)
Check whether the SLE is owned by the account.
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:248
std::optional< ripple::AccountID > accountFromStringStrict(std::string const &account)
Get a ripple::AccountID from its string representation.
Definition RPCHelpers.cpp:180
ripple::STAmount accountHolds(BackendInterface const &backend, data::AmendmentCenterInterface const &amendmentCenter, std::uint32_t sequence, ripple::AccountID const &account, ripple::Currency const ¤cy, ripple::AccountID const &issuer, bool const zeroIfFrozen, boost::asio::yield_context yield)
Get the amount that an account holds.
Definition RPCHelpers.cpp:1092
std::expected< ripple::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:520
ripple::STAmount accountFunds(BackendInterface const &backend, data::AmendmentCenterInterface const &amendmentCenter, std::uint32_t const sequence, ripple::STAmount const &amount, ripple::AccountID const &id, boost::asio::yield_context yield)
Get the account funds.
Definition RPCHelpers.cpp:1030
boost::json::object toJson(ripple::STBase const &obj)
Convert STBase object to JSON.
Definition RPCHelpers.cpp:240
ripple::XRPAmount xrpLiquid(BackendInterface const &backend, std::uint32_t sequence, ripple::AccountID const &id, boost::asio::yield_context yield)
Get the XRP liquidity.
Definition RPCHelpers.cpp:995
std::expected< ripple::AccountID, Status > parseTaker(boost::json::value const &taker)
Parse the taker from the request.
Definition RPCHelpers.cpp:1481
bool canHaveDeliveredAmount(std::shared_ptr< ripple::STTx const > const &txn, std::shared_ptr< ripple::TxMeta const > const &meta)
Whether the transaction can have a delivered amount.
Definition RPCHelpers.cpp:167
std::shared_ptr< ripple::SLE const > read(std::shared_ptr< data::BackendInterface const > const &backend, ripple::Keylet const &keylet, ripple::LedgerHeader const &lgrInfo, web::Context const &context)
Read SLE from the backend.
Definition RPCHelpers.cpp:832
NFTokenjson
Enum for NFT json manipulation.
Definition RPCHelpers.hpp:88
std::optional< ripple::Seed > parseRippleLibSeed(boost::json::value const &value)
Parse a ripple-lib seed.
Definition RPCHelpers.cpp:847
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:385
bool specifiesCurrentOrClosedLedger(boost::json::object const &request)
Check whether the request specifies the current or closed ledger.
Definition RPCHelpers.cpp:1507
std::optional< ripple::STAmount > getDeliveredAmount(std::shared_ptr< ripple::STTx const > const &txn, std::shared_ptr< ripple::TxMeta const > const &meta, std::uint32_t const ledgerSequence, uint32_t date)
Get the delivered amount.
Definition RPCHelpers.cpp:139
ripple::Rate transferRate(BackendInterface const &backend, std::uint32_t sequence, ripple::AccountID const &issuer, boost::asio::yield_context yield)
Get the transfer rate.
Definition RPCHelpers.cpp:1177
bool isGlobalFrozen(BackendInterface const &backend, std::uint32_t sequence, ripple::AccountID const &issuer, boost::asio::yield_context yield)
Whether global frozen is set.
Definition RPCHelpers.cpp:886
boost::json::value toBoostJson(Json::Value const &value)
Convert a RippledJson to boost::json::value.
Definition RPCHelpers.cpp:404
std::expected< AccountCursor, Status > traverseOwnedNodes(BackendInterface const &backend, ripple::AccountID const &accountID, std::uint32_t sequence, std::uint32_t limit, std::optional< std::string > jsonCursor, boost::asio::yield_context yield, std::function< void(ripple::SLE)> atOwnedNode, bool nftIncluded)
Traverse nodes owned by an account.
Definition RPCHelpers.cpp:643
bool isLPTokenFrozen(BackendInterface const &backend, std::uint32_t sequence, ripple::AccountID const &account, ripple::Issue const &asset, ripple::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:981
bool insertMPTIssuanceID(boost::json::object &txnJson, std::shared_ptr< ripple::STTx const > const &txn, boost::json::object &metaJson, std::shared_ptr< ripple::TxMeta const > const &meta)
Add "mpt_issuance_id" into various MPTToken transaction json.
Definition RPCHelpers.cpp:359
std::optional< std::uint32_t > parseStringAsUInt(std::string const &value)
Parse the string as a uint32_t.
Definition RPCHelpers.cpp:456
bool isAdminCmd(std::string const &method, boost::json::object const &request)
Check whether a request requires administrative privileges on rippled side.
Definition RPCHelpers.cpp:1520
std::expected< AccountCursor, Status > traverseNFTObjects(BackendInterface const &backend, std::uint32_t sequence, ripple::AccountID const &accountID, ripple::uint256 nextPage, std::uint32_t limit, boost::asio::yield_context yield, std::function< void(ripple::SLE)> atOwnedNode)
Traverse NFT objects and call the callback for each owned node.
Definition RPCHelpers.cpp:591
bool fetchAndCheckAnyFlagsExists(BackendInterface const &backend, std::uint32_t sequence, ripple::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:909
std::vector< unsigned char > ledgerHeaderToBlob(ripple::LedgerHeader const &info, bool includeHash)
Convert a ledger header to a blob.
Definition RPCHelpers.cpp:553
boost::json::object removeSecret(boost::json::object const &object)
Removes any detected secret information from a response JSON object.
Definition JsonUtils.hpp:69
Context that is used by the Webserver to pass around information about an incoming request.
Definition Context.hpp:40