mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-27 15:15:52 +00:00
15
Doxyfile
15
Doxyfile
@@ -2,8 +2,18 @@ PROJECT_NAME = "Clio"
|
||||
PROJECT_LOGO = ../docs/img/xrpl-logo.svg
|
||||
PROJECT_NUMBER = @DOC_CLIO_VERSION@
|
||||
PROJECT_BRIEF = The XRP Ledger API server.
|
||||
INPUT = ../src ../unittests
|
||||
EXCLUDE_PATTERNS = *Test*.cpp *Test*.hpp */impl/*
|
||||
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_PACKAGE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
|
||||
SORT_MEMBERS_CTORS_1ST = YES
|
||||
|
||||
INPUT = ../src
|
||||
EXCLUDE_SYMBOLS = impl
|
||||
RECURSIVE = YES
|
||||
HAVE_DOT = YES
|
||||
|
||||
@@ -12,7 +22,6 @@ WARNINGS = YES
|
||||
WARN_NO_PARAMDOC = YES
|
||||
WARN_IF_INCOMPLETE_DOC = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_AS_ERROR = FAIL_ON_WARNINGS
|
||||
|
||||
GENERATE_LATEX = NO
|
||||
GENERATE_HTML = YES
|
||||
|
||||
@@ -83,39 +83,92 @@ class BackendCounters {
|
||||
public:
|
||||
using PtrType = std::shared_ptr<BackendCounters>;
|
||||
|
||||
/**
|
||||
* @brief Create a new BackendCounters object
|
||||
*
|
||||
* @return A shared pointer to the new BackendCounters object
|
||||
*/
|
||||
static PtrType
|
||||
make();
|
||||
|
||||
/**
|
||||
* @brief Register that the backend was too busy to process a request
|
||||
*/
|
||||
void
|
||||
registerTooBusy();
|
||||
|
||||
/**
|
||||
* @brief Register that a write operation was started
|
||||
*
|
||||
* @param startTime The time the operation was started
|
||||
*/
|
||||
void
|
||||
registerWriteSync(std::chrono::steady_clock::time_point startTime);
|
||||
|
||||
/**
|
||||
* @brief Register that a write operation was retried
|
||||
*/
|
||||
void
|
||||
registerWriteSyncRetry();
|
||||
|
||||
/**
|
||||
* @brief Register that a write operation was started
|
||||
*/
|
||||
void
|
||||
registerWriteStarted();
|
||||
|
||||
/**
|
||||
* @brief Register that a write operation was finished
|
||||
*
|
||||
* @param startTime The time the operation was started
|
||||
*/
|
||||
void
|
||||
registerWriteFinished(std::chrono::steady_clock::time_point startTime);
|
||||
|
||||
/**
|
||||
* @brief Register that a write operation was retried
|
||||
*/
|
||||
void
|
||||
registerWriteRetry();
|
||||
|
||||
/**
|
||||
* @brief Register that one or more read operations were started
|
||||
*
|
||||
* @param count The number of operations started
|
||||
*/
|
||||
void
|
||||
registerReadStarted(std::uint64_t count = 1u);
|
||||
|
||||
/**
|
||||
* @brief Register that one or more read operations were finished
|
||||
*
|
||||
* @param startTime The time the operations were started
|
||||
* @param count The number of operations finished
|
||||
*/
|
||||
void
|
||||
registerReadFinished(std::chrono::steady_clock::time_point startTime, std::uint64_t count = 1u);
|
||||
|
||||
/**
|
||||
* @brief Register that one or more read operations were retried
|
||||
*
|
||||
* @param count The number of operations retried
|
||||
*/
|
||||
void
|
||||
registerReadRetry(std::uint64_t count = 1u);
|
||||
|
||||
/**
|
||||
* @brief Register that one or more read operations had an error
|
||||
*
|
||||
* @param count The number of operations with an error
|
||||
*/
|
||||
void
|
||||
registerReadError(std::uint64_t count = 1u);
|
||||
|
||||
/**
|
||||
* @brief Get a report of the backend counters
|
||||
*
|
||||
* @return The report
|
||||
*/
|
||||
boost::json::object
|
||||
report() const;
|
||||
|
||||
|
||||
@@ -53,6 +53,9 @@ namespace data {
|
||||
*/
|
||||
class DatabaseTimeout : public std::exception {
|
||||
public:
|
||||
/**
|
||||
* @return The error message as a C string
|
||||
*/
|
||||
char const*
|
||||
what() const throw() override
|
||||
{
|
||||
@@ -67,9 +70,9 @@ static constexpr std::size_t DEFAULT_WAIT_BETWEEN_RETRY = 500;
|
||||
* @tparam FnType The type of function object to execute
|
||||
* @param func The function object to execute
|
||||
* @param waitMs Delay between retry attempts
|
||||
* @return auto The same as the return type of func
|
||||
* @return The same as the return type of func
|
||||
*/
|
||||
template <class FnType>
|
||||
template <typename FnType>
|
||||
auto
|
||||
retryOnTimeout(FnType func, size_t waitMs = DEFAULT_WAIT_BETWEEN_RETRY)
|
||||
{
|
||||
@@ -90,9 +93,9 @@ retryOnTimeout(FnType func, size_t waitMs = DEFAULT_WAIT_BETWEEN_RETRY)
|
||||
*
|
||||
* @tparam FnType The type of function object to execute
|
||||
* @param func The function object to execute
|
||||
* @return auto The same as the return type of func
|
||||
* @return The same as the return type of func
|
||||
*/
|
||||
template <class FnType>
|
||||
template <typename FnType>
|
||||
auto
|
||||
synchronous(FnType&& func)
|
||||
{
|
||||
@@ -118,9 +121,9 @@ synchronous(FnType&& func)
|
||||
*
|
||||
* @tparam FnType The type of function object to execute
|
||||
* @param func The function object to execute
|
||||
* @return auto The same as the return type of func
|
||||
* @return The same as the return type of func
|
||||
*/
|
||||
template <class FnType>
|
||||
template <typename FnType>
|
||||
auto
|
||||
synchronousAndRetryOnTimeout(FnType&& func)
|
||||
{
|
||||
@@ -219,7 +222,7 @@ public:
|
||||
*
|
||||
* @param seq The sequence to fetch for
|
||||
* @param yield The coroutine context
|
||||
* @return ripple::Fees if fees are found; nullopt otherwise
|
||||
* @return Fees if fees are found; nullopt otherwise
|
||||
*/
|
||||
std::optional<ripple::Fees>
|
||||
fetchFees(std::uint32_t seq, boost::asio::yield_context yield) const;
|
||||
@@ -318,12 +321,11 @@ public:
|
||||
*
|
||||
* @param issuer AccountID of issuer you wish you query.
|
||||
* @param taxon Optional taxon of NFTs by which you wish to filter.
|
||||
* @param ledgerSequence The ledger sequence to fetch for
|
||||
* @param limit Paging limit.
|
||||
* @param cursorIn Optional cursor to allow us to pick up from where we
|
||||
* last left off.
|
||||
* @param cursorIn Optional cursor to allow us to pick up from where we last left off.
|
||||
* @param yield Currently executing coroutine.
|
||||
* @return std::vector<NFT> of NFTs issued by this account, or
|
||||
* this issuer/taxon combination if taxon is passed and an optional marker
|
||||
* @return NFTs issued by this account, or this issuer/taxon combination if taxon is passed and an optional marker
|
||||
*/
|
||||
virtual NFTsAndCursor
|
||||
fetchNFTsByIssuer(
|
||||
@@ -488,6 +490,7 @@ public:
|
||||
/**
|
||||
* @brief Fetches the ledger range from DB.
|
||||
*
|
||||
* @param yield The coroutine context
|
||||
* @return The ledger range if available; nullopt otherwise
|
||||
*/
|
||||
virtual std::optional<LedgerRange>
|
||||
@@ -598,15 +601,27 @@ public:
|
||||
isTooBusy() const = 0;
|
||||
|
||||
/**
|
||||
* @return json object containing backend usage statistics
|
||||
* @return A JSON object containing backend usage statistics
|
||||
*/
|
||||
virtual boost::json::object
|
||||
stats() const = 0;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Writes a ledger object to the database
|
||||
*
|
||||
* @param key The key of the object
|
||||
* @param seq The sequence of the ledger
|
||||
* @param blob The data
|
||||
*/
|
||||
virtual void
|
||||
doWriteLedgerObject(std::string&& key, std::uint32_t seq, std::string&& blob) = 0;
|
||||
|
||||
/**
|
||||
* @brief The implementation should wait for all pending writes to finish
|
||||
*
|
||||
* @return true on success; false otherwise
|
||||
*/
|
||||
virtual bool
|
||||
doFinishWrites() = 0;
|
||||
};
|
||||
|
||||
@@ -48,6 +48,12 @@ struct AccountTransactionsData {
|
||||
std::uint32_t transactionIndex{};
|
||||
ripple::uint256 txHash;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountTransactionsData object
|
||||
*
|
||||
* @param meta The transaction metadata
|
||||
* @param txHash The transaction hash
|
||||
*/
|
||||
AccountTransactionsData(ripple::TxMeta& meta, ripple::uint256 const& txHash)
|
||||
: accounts(meta.getAffectedAccounts())
|
||||
, ledgerSequence(meta.getLgrSeq())
|
||||
@@ -70,6 +76,13 @@ struct NFTTransactionsData {
|
||||
std::uint32_t transactionIndex;
|
||||
ripple::uint256 txHash;
|
||||
|
||||
/**
|
||||
* @brief Construct a new NFTTransactionsData object
|
||||
*
|
||||
* @param tokenID The token ID
|
||||
* @param meta The transaction metadata
|
||||
* @param txHash The transaction hash
|
||||
*/
|
||||
NFTTransactionsData(ripple::uint256 const& tokenID, ripple::TxMeta const& meta, ripple::uint256 const& txHash)
|
||||
: tokenID(tokenID), ledgerSequence(meta.getLgrSeq()), transactionIndex(meta.getIndex()), txHash(txHash)
|
||||
{
|
||||
@@ -80,35 +93,33 @@ struct NFTTransactionsData {
|
||||
* @brief Represents an NFT state at a particular ledger.
|
||||
*
|
||||
* Gets written to nf_tokens table and the like.
|
||||
*
|
||||
* The transaction index is only stored because we want to store only the final state of an NFT per ledger.
|
||||
* Since we pull this from transactions we keep track of which tx index created this so we can de-duplicate, as it is
|
||||
* possible for one ledger to have multiple txs that change the state of the same NFT.
|
||||
*
|
||||
* We only set the uri if this is a mint tx, or if we are loading initial state from NFTokenPage objects.
|
||||
*/
|
||||
struct NFTsData {
|
||||
ripple::uint256 tokenID;
|
||||
std::uint32_t ledgerSequence;
|
||||
|
||||
// The transaction index is only stored because we want to store only the
|
||||
// final state of an NFT per ledger. Since we pull this from transactions
|
||||
// we keep track of which tx index created this so we can de-duplicate, as
|
||||
// it is possible for one ledger to have multiple txs that change the
|
||||
// state of the same NFT. This field is not applicable when we are loading
|
||||
// initial NFT state via ledger objects, since we do not have to tiebreak
|
||||
// NFT state for a given ledger in that case.
|
||||
std::optional<std::uint32_t> transactionIndex;
|
||||
ripple::AccountID owner;
|
||||
// We only set the uri if this is a mint tx, or if we are
|
||||
// loading initial state from NFTokenPage objects. In other words,
|
||||
// uri should only be set if the etl process believes this NFT hasn't
|
||||
// been seen before in our local database. We do this so that we don't
|
||||
// write to the the nf_token_uris table every
|
||||
// time the same NFT changes hands. We also can infer if there is a URI
|
||||
// that we need to write to the issuer_nf_tokens table.
|
||||
std::optional<ripple::Blob> uri;
|
||||
bool isBurned = false;
|
||||
|
||||
// This constructor is used when parsing an NFTokenMint tx.
|
||||
// Unfortunately because of the extreme edge case of being able to
|
||||
// re-mint an NFT with the same ID, we must explicitly record a null
|
||||
// URI. For this reason, we _always_ write this field as a result of
|
||||
// this tx.
|
||||
/**
|
||||
* @brief Construct a new NFTsData object
|
||||
*
|
||||
* @note This constructor is used when parsing an NFTokenMint tx
|
||||
* Unfortunately because of the extreme edge case of being able to re-mint an NFT with the same ID, we must
|
||||
* explicitly record a null URI. For this reason, we _always_ write this field as a result of this tx.
|
||||
*
|
||||
* @param tokenID The token ID
|
||||
* @param owner The owner
|
||||
* @param uri The URI
|
||||
* @param meta The transaction metadata
|
||||
*/
|
||||
NFTsData(
|
||||
ripple::uint256 const& tokenID,
|
||||
ripple::AccountID const& owner,
|
||||
@@ -119,8 +130,16 @@ struct NFTsData {
|
||||
{
|
||||
}
|
||||
|
||||
// This constructor is used when parsing an NFTokenBurn or
|
||||
// NFTokenAcceptOffer tx
|
||||
/**
|
||||
* @brief Construct a new NFTsData object
|
||||
*
|
||||
* @note This constructor is used when parsing an NFTokenBurn or NFTokenAcceptOffer tx
|
||||
*
|
||||
* @param tokenID The token ID
|
||||
* @param owner The owner
|
||||
* @param meta The transaction metadata
|
||||
* @param isBurned Whether the NFT is burned
|
||||
*/
|
||||
NFTsData(ripple::uint256 const& tokenID, ripple::AccountID const& owner, ripple::TxMeta const& meta, bool isBurned)
|
||||
: tokenID(tokenID)
|
||||
, ledgerSequence(meta.getLgrSeq())
|
||||
@@ -130,12 +149,18 @@ struct NFTsData {
|
||||
{
|
||||
}
|
||||
|
||||
// This constructor is used when parsing an NFTokenPage directly from
|
||||
// ledger state.
|
||||
// Unfortunately because of the extreme edge case of being able to
|
||||
// re-mint an NFT with the same ID, we must explicitly record a null
|
||||
// URI. For this reason, we _always_ write this field as a result of
|
||||
// this tx.
|
||||
/**
|
||||
* @brief Construct a new NFTsData object
|
||||
*
|
||||
* @note This constructor is used when parsing an NFTokenPage directly from ledger state.
|
||||
* Unfortunately because of the extreme edge case of being able to re-mint an NFT with the same ID, we must
|
||||
* explicitly record a null URI. For this reason, we _always_ write this field as a result of this tx.
|
||||
*
|
||||
* @param tokenID The token ID
|
||||
* @param ledgerSequence The ledger sequence
|
||||
* @param owner The owner
|
||||
* @param uri The URI
|
||||
*/
|
||||
NFTsData(
|
||||
ripple::uint256 const& tokenID,
|
||||
std::uint32_t const ledgerSequence,
|
||||
@@ -153,7 +178,7 @@ struct NFTsData {
|
||||
* @param object The object to check
|
||||
* @return true if the object is an offer; false otherwise
|
||||
*/
|
||||
template <class T>
|
||||
template <typename T>
|
||||
inline bool
|
||||
isOffer(T const& object)
|
||||
{
|
||||
@@ -170,7 +195,7 @@ isOffer(T const& object)
|
||||
* @param object The object to check
|
||||
* @return true if the object is an offer; false otherwise
|
||||
*/
|
||||
template <class T>
|
||||
template <typename T>
|
||||
inline bool
|
||||
isOfferHex(T const& object)
|
||||
{
|
||||
@@ -186,7 +211,7 @@ isOfferHex(T const& object)
|
||||
* @param object The object to check
|
||||
* @return true if the object is a dir node; false otherwise
|
||||
*/
|
||||
template <class T>
|
||||
template <typename T>
|
||||
inline bool
|
||||
isDirNode(T const& object)
|
||||
{
|
||||
@@ -202,7 +227,7 @@ isDirNode(T const& object)
|
||||
* @param object The object to check
|
||||
* @return true if the object is a book dir; false otherwise
|
||||
*/
|
||||
template <class T, class R>
|
||||
template <typename T, typename R>
|
||||
inline bool
|
||||
isBookDir(T const& key, R const& object)
|
||||
{
|
||||
@@ -219,7 +244,7 @@ isBookDir(T const& key, R const& object)
|
||||
* @param offer The offer to get the book for
|
||||
* @return Book as ripple::uint256
|
||||
*/
|
||||
template <class T>
|
||||
template <typename T>
|
||||
inline ripple::uint256
|
||||
getBook(T const& offer)
|
||||
{
|
||||
@@ -236,7 +261,7 @@ getBook(T const& offer)
|
||||
* @param key The key to get the book base out of
|
||||
* @return Book base as ripple::uint256
|
||||
*/
|
||||
template <class T>
|
||||
template <typename T>
|
||||
inline ripple::uint256
|
||||
getBookBase(T const& key)
|
||||
{
|
||||
|
||||
@@ -173,6 +173,11 @@ public:
|
||||
float
|
||||
getSuccessorHitRate() const;
|
||||
|
||||
/**
|
||||
* @brief Waits until the cache contains a specific sequence.
|
||||
*
|
||||
* @param seq The sequence to wait for
|
||||
*/
|
||||
void
|
||||
waitUntilCacheContainsSeq(uint32_t seq);
|
||||
};
|
||||
|
||||
@@ -41,10 +41,7 @@ struct LedgerObject {
|
||||
Blob blob;
|
||||
|
||||
bool
|
||||
operator==(LedgerObject const& other) const
|
||||
{
|
||||
return key == other.key && blob == other.blob;
|
||||
}
|
||||
operator==(LedgerObject const& other) const = default;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -73,11 +70,25 @@ struct TransactionAndMetadata {
|
||||
std::uint32_t date = 0;
|
||||
|
||||
TransactionAndMetadata() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Transaction And Metadata object
|
||||
*
|
||||
* @param transaction The transaction
|
||||
* @param metadata The metadata
|
||||
* @param ledgerSequence The ledger sequence
|
||||
* @param date The date
|
||||
*/
|
||||
TransactionAndMetadata(Blob transaction, Blob metadata, std::uint32_t ledgerSequence, std::uint32_t date)
|
||||
: transaction{std::move(transaction)}, metadata{std::move(metadata)}, ledgerSequence{ledgerSequence}, date{date}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Transaction And Metadata object
|
||||
*
|
||||
* @param data The data to construct from
|
||||
*/
|
||||
TransactionAndMetadata(std::tuple<Blob, Blob, std::uint32_t, std::uint32_t> data)
|
||||
: transaction{std::get<0>(data)}
|
||||
, metadata{std::get<1>(data)}
|
||||
@@ -86,6 +97,12 @@ struct TransactionAndMetadata {
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the transaction and metadata are the same as another
|
||||
*
|
||||
* @param other The other transaction and metadata
|
||||
* @return true if they are the same; false otherwise
|
||||
*/
|
||||
bool
|
||||
operator==(TransactionAndMetadata const& other) const
|
||||
{
|
||||
@@ -102,11 +119,23 @@ struct TransactionsCursor {
|
||||
std::uint32_t transactionIndex = 0;
|
||||
|
||||
TransactionsCursor() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Transactions Cursor object
|
||||
*
|
||||
* @param ledgerSequence The ledger sequence
|
||||
* @param transactionIndex The transaction index
|
||||
*/
|
||||
TransactionsCursor(std::uint32_t ledgerSequence, std::uint32_t transactionIndex)
|
||||
: ledgerSequence{ledgerSequence}, transactionIndex{transactionIndex}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Transactions Cursor object
|
||||
*
|
||||
* @param data The data to construct from
|
||||
*/
|
||||
TransactionsCursor(std::tuple<std::uint32_t, std::uint32_t> data)
|
||||
: ledgerSequence{std::get<0>(data)}, transactionIndex{std::get<1>(data)}
|
||||
{
|
||||
@@ -115,6 +144,11 @@ struct TransactionsCursor {
|
||||
bool
|
||||
operator==(TransactionsCursor const& other) const = default;
|
||||
|
||||
/**
|
||||
* @brief Convert the cursor to a tuple of seq and index
|
||||
*
|
||||
* @return The cursor as a tuple
|
||||
*/
|
||||
[[nodiscard]] std::tuple<std::uint32_t, std::uint32_t>
|
||||
asTuple() const
|
||||
{
|
||||
@@ -141,6 +175,16 @@ struct NFT {
|
||||
bool isBurned{};
|
||||
|
||||
NFT() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new NFT object
|
||||
*
|
||||
* @param tokenID The token ID
|
||||
* @param ledgerSequence The ledger sequence
|
||||
* @param owner The owner
|
||||
* @param uri The URI
|
||||
* @param isBurned Whether the token is burned
|
||||
*/
|
||||
NFT(ripple::uint256 const& tokenID,
|
||||
std::uint32_t ledgerSequence,
|
||||
ripple::AccountID const& owner,
|
||||
@@ -150,13 +194,28 @@ struct NFT {
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new NFT object
|
||||
*
|
||||
* @param tokenID The token ID
|
||||
* @param ledgerSequence The ledger sequence
|
||||
* @param owner The owner
|
||||
* @param isBurned Whether the token is burned
|
||||
*/
|
||||
NFT(ripple::uint256 const& tokenID, std::uint32_t ledgerSequence, ripple::AccountID const& owner, bool isBurned)
|
||||
: NFT(tokenID, ledgerSequence, owner, {}, isBurned)
|
||||
{
|
||||
}
|
||||
|
||||
// clearly two tokens are the same if they have the same ID, but this struct stores the state of a given token at a
|
||||
// given ledger sequence, so we also need to compare with ledgerSequence.
|
||||
/**
|
||||
* @brief Check if the NFT is the same as another
|
||||
*
|
||||
* Clearly two tokens are the same if they have the same ID, but this struct stores the state of a given
|
||||
* token at a given ledger sequence, so we also need to compare with ledgerSequence.
|
||||
*
|
||||
* @param other The other NFT
|
||||
* @return true if they are the same; false otherwise
|
||||
*/
|
||||
bool
|
||||
operator==(NFT const& other) const
|
||||
{
|
||||
@@ -164,6 +223,9 @@ struct NFT {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Represents a bundle of NFTs with a cursor to the next page
|
||||
*/
|
||||
struct NFTsAndCursor {
|
||||
std::vector<NFT> nfts;
|
||||
std::optional<ripple::uint256> cursor;
|
||||
|
||||
@@ -36,11 +36,20 @@ class CassandraError {
|
||||
uint32_t code_{};
|
||||
|
||||
public:
|
||||
CassandraError() = default; // default constructible required by Expected
|
||||
// default constructible required by Expected
|
||||
CassandraError() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new CassandraError object
|
||||
*
|
||||
* @param message The error message
|
||||
* @param code The error code
|
||||
*/
|
||||
CassandraError(std::string message, uint32_t code) : message_{std::move(message)}, code_{code}
|
||||
{
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
template <typename T>
|
||||
friend std::string
|
||||
operator+(T const& lhs, CassandraError const& rhs)
|
||||
@@ -70,6 +79,7 @@ public:
|
||||
os << err.message();
|
||||
return os;
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @return The final error message as a std::string
|
||||
|
||||
@@ -96,7 +96,7 @@ Handle::reconnect(std::string_view keyspace) const
|
||||
}
|
||||
|
||||
std::vector<Handle::FutureType>
|
||||
Handle::asyncExecuteEach(std::vector<Statement> const& statements) const
|
||||
Handle::asyncExecuteEach(std::vector<StatementType> const& statements) const
|
||||
{
|
||||
std::vector<Handle::FutureType> futures;
|
||||
futures.reserve(statements.size());
|
||||
@@ -106,7 +106,7 @@ Handle::asyncExecuteEach(std::vector<Statement> const& statements) const
|
||||
}
|
||||
|
||||
Handle::MaybeErrorType
|
||||
Handle::executeEach(std::vector<Statement> const& statements) const
|
||||
Handle::executeEach(std::vector<StatementType> const& statements) const
|
||||
{
|
||||
for (auto futures = asyncExecuteEach(statements); auto const& future : futures) {
|
||||
if (auto rc = future.await(); not rc)
|
||||
@@ -117,38 +117,37 @@ Handle::executeEach(std::vector<Statement> const& statements) const
|
||||
}
|
||||
|
||||
Handle::FutureType
|
||||
Handle::asyncExecute(Statement const& statement) const
|
||||
Handle::asyncExecute(StatementType const& statement) const
|
||||
{
|
||||
return cass_session_execute(session_, statement);
|
||||
}
|
||||
|
||||
Handle::FutureWithCallbackType
|
||||
Handle::asyncExecute(Statement const& statement, std::function<void(Handle::ResultOrErrorType)>&& cb) const
|
||||
Handle::asyncExecute(StatementType const& statement, std::function<void(ResultOrErrorType)>&& cb) const
|
||||
{
|
||||
return Handle::FutureWithCallbackType{cass_session_execute(session_, statement), std::move(cb)};
|
||||
}
|
||||
|
||||
Handle::ResultOrErrorType
|
||||
Handle::execute(Statement const& statement) const
|
||||
Handle::execute(StatementType const& statement) const
|
||||
{
|
||||
return asyncExecute(statement).get();
|
||||
}
|
||||
|
||||
Handle::FutureType
|
||||
Handle::asyncExecute(std::vector<Statement> const& statements) const
|
||||
Handle::asyncExecute(std::vector<StatementType> const& statements) const
|
||||
{
|
||||
return cass_session_execute_batch(session_, Batch{statements});
|
||||
}
|
||||
|
||||
Handle::MaybeErrorType
|
||||
Handle::execute(std::vector<Statement> const& statements) const
|
||||
Handle::execute(std::vector<StatementType> const& statements) const
|
||||
{
|
||||
return asyncExecute(statements).await();
|
||||
}
|
||||
|
||||
Handle::FutureWithCallbackType
|
||||
Handle::asyncExecute(std::vector<Statement> const& statements, std::function<void(Handle::ResultOrErrorType)>&& cb)
|
||||
const
|
||||
Handle::asyncExecute(std::vector<StatementType> const& statements, std::function<void(ResultOrErrorType)>&& cb) const
|
||||
{
|
||||
return Handle::FutureWithCallbackType{cass_session_execute_batch(session_, Batch{statements}), std::move(cb)};
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief This namespace implements a wrapper for the Cassandra C++ driver
|
||||
*/
|
||||
namespace data::cassandra {
|
||||
|
||||
/**
|
||||
@@ -54,7 +57,7 @@ public:
|
||||
using ResultType = Result;
|
||||
|
||||
/**
|
||||
* @brief Construct a new handle from a @ref impl::Settings object.
|
||||
* @brief Construct a new handle from a Settings object.
|
||||
*
|
||||
* @param clusterSettings The settings to use
|
||||
*/
|
||||
@@ -317,7 +320,9 @@ public:
|
||||
* You can call .begin() and .end() in order to iterate as usual.
|
||||
* This also means that you can use it in a range-based for or with some algorithms.
|
||||
*
|
||||
* @tparam Types The types to extract
|
||||
* @param result The result to iterate
|
||||
* @return An extractor object (iterator inside)
|
||||
*/
|
||||
template <typename... Types>
|
||||
[[nodiscard]] impl::ResultExtractor<Types...>
|
||||
|
||||
@@ -34,6 +34,14 @@
|
||||
|
||||
namespace data::cassandra {
|
||||
|
||||
/**
|
||||
* @brief Returns the table name qualified with the keyspace and table prefix
|
||||
*
|
||||
* @tparam SettingsProviderType The settings provider type
|
||||
* @param provider The settings provider
|
||||
* @param name The name of the table
|
||||
* @return The qualified table name
|
||||
*/
|
||||
template <SomeSettingsProvider SettingsProviderType>
|
||||
[[nodiscard]] std::string inline qualifiedTableName(SettingsProviderType const& provider, std::string_view name)
|
||||
{
|
||||
@@ -49,6 +57,11 @@ class Schema {
|
||||
std::reference_wrapper<SettingsProviderType const> settingsProvider_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Schema object
|
||||
*
|
||||
* @param settingsProvider The settings provider
|
||||
*/
|
||||
explicit Schema(SettingsProviderType const& settingsProvider) : settingsProvider_{std::cref(settingsProvider)}
|
||||
{
|
||||
}
|
||||
@@ -279,6 +292,12 @@ public:
|
||||
std::reference_wrapper<Handle const> handle_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Statements object
|
||||
*
|
||||
* @param settingsProvider The settings provider
|
||||
* @param handle The handle to the DB
|
||||
*/
|
||||
Statements(SettingsProviderType const& settingsProvider, Handle const& handle)
|
||||
: settingsProvider_{settingsProvider}, handle_{std::cref(handle)}
|
||||
{
|
||||
@@ -713,6 +732,8 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Recreates the prepared statements.
|
||||
*
|
||||
* @param handle The handle to the DB
|
||||
*/
|
||||
void
|
||||
prepareStatements(Handle const& handle)
|
||||
@@ -724,6 +745,8 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Provides access to statements.
|
||||
*
|
||||
* @return The statements
|
||||
*/
|
||||
std::unique_ptr<Statements> const&
|
||||
operator->() const
|
||||
|
||||
@@ -33,13 +33,13 @@
|
||||
namespace {
|
||||
constexpr auto clusterDeleter = [](CassCluster* ptr) { cass_cluster_free(ptr); };
|
||||
|
||||
template <class... Ts>
|
||||
template <typename... Ts>
|
||||
struct overloadSet : Ts... {
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
// explicit deduction guide (not needed as of C++20, but clang be clang)
|
||||
template <class... Ts>
|
||||
template <typename... Ts>
|
||||
overloadSet(Ts...) -> overloadSet<Ts...>;
|
||||
}; // namespace
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace etl {
|
||||
* @brief Settings for the cache loader
|
||||
*/
|
||||
struct CacheLoaderSettings {
|
||||
/** @brief Ways to load the cache */
|
||||
enum class LoadStyle { ASYNC, SYNC, NONE };
|
||||
|
||||
size_t numCacheDiffs = 32; /**< number of diffs to use to generate cursors */
|
||||
@@ -54,6 +55,12 @@ struct CacheLoaderSettings {
|
||||
isDisabled() const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a CacheLoaderSettings object from a Config object
|
||||
*
|
||||
* @param config The configuration object
|
||||
* @returns The CacheLoaderSettings object
|
||||
*/
|
||||
[[nodiscard]] CacheLoaderSettings
|
||||
make_CacheLoaderSettings(util::Config const& config);
|
||||
|
||||
|
||||
@@ -52,7 +52,9 @@ class NetworkValidatedLedgers {
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A factory function for NetworkValidatedLedgers.
|
||||
* @brief A factory function for NetworkValidatedLedgers
|
||||
*
|
||||
* @return A shared pointer to a new instance of NetworkValidatedLedgers
|
||||
*/
|
||||
static std::shared_ptr<NetworkValidatedLedgers>
|
||||
make_ValidatedLedgers()
|
||||
@@ -93,6 +95,7 @@ public:
|
||||
* @brief Waits for the sequence to be validated by the network.
|
||||
*
|
||||
* @param sequence The sequence to wait for
|
||||
* @param maxWaitMs Maximum time to wait for the sequence to be validated. If empty, wait indefinitely
|
||||
* @return true if sequence was validated, false otherwise a return value of false means the datastructure has been
|
||||
* stopped
|
||||
*/
|
||||
@@ -117,7 +120,7 @@ public:
|
||||
* @note (original note) We can't use a lockfree queue here, since we need the ability to wait for an element to be
|
||||
* added or removed from the queue. These waits are blocking calls.
|
||||
*/
|
||||
template <class T>
|
||||
template <typename T>
|
||||
class ThreadSafeQueue {
|
||||
std::queue<T> queue_;
|
||||
|
||||
@@ -207,6 +210,11 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the size of the queue
|
||||
*
|
||||
* @return The size of the queue
|
||||
*/
|
||||
std::size_t
|
||||
size() const
|
||||
{
|
||||
@@ -218,6 +226,7 @@ public:
|
||||
* @brief Parititions the uint256 keyspace into numMarkers partitions, each of equal size.
|
||||
*
|
||||
* @param numMarkers Total markers to partition for
|
||||
* @return The markers
|
||||
*/
|
||||
inline std::vector<ripple::uint256>
|
||||
getMarkers(size_t numMarkers)
|
||||
|
||||
@@ -144,6 +144,7 @@ public:
|
||||
* @param subscriptions Subscription manager
|
||||
* @param balancer Load balancer to use
|
||||
* @param ledgers The network validated ledgers datastructure
|
||||
* @return A shared pointer to a new instance of ETLService
|
||||
*/
|
||||
static std::shared_ptr<ETLService>
|
||||
make_ETLService(
|
||||
@@ -180,6 +181,8 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Get time passed since last ledger close, in seconds.
|
||||
*
|
||||
* @return Time passed since last ledger close
|
||||
*/
|
||||
std::uint32_t
|
||||
lastCloseAgeSeconds() const
|
||||
@@ -200,6 +203,8 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Get state of ETL as a JSON object
|
||||
*
|
||||
* @return The state of ETL as a JSON object
|
||||
*/
|
||||
boost::json::object
|
||||
getInfo() const
|
||||
@@ -217,7 +222,7 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Get the etl nodes' state
|
||||
* @return the etl nodes' state, nullopt if etl nodes are not connected
|
||||
* @return The etl nodes' state, nullopt if etl nodes are not connected
|
||||
*/
|
||||
std::optional<etl::ETLState>
|
||||
getETLState() const noexcept
|
||||
@@ -234,7 +239,7 @@ private:
|
||||
*
|
||||
* @param startSequence the first ledger to extract
|
||||
* @param numExtractors number of extractors to use
|
||||
* @return the last ledger written to the database, if any
|
||||
* @return The last ledger written to the database, if any
|
||||
*/
|
||||
std::optional<uint32_t>
|
||||
runETLPipeline(uint32_t startSequence, uint32_t numExtractors);
|
||||
@@ -255,7 +260,7 @@ private:
|
||||
* @brief Monitor the network for newly validated ledgers and publish them to the ledgers stream
|
||||
*
|
||||
* @param nextSequence the ledger sequence to publish
|
||||
* @return the next ledger sequence to publish
|
||||
* @return The next ledger sequence to publish
|
||||
*/
|
||||
uint32_t
|
||||
publishNextSequence(uint32_t nextSequence);
|
||||
@@ -283,7 +288,7 @@ private:
|
||||
*
|
||||
* This is equivelent to the degree of parallelism during the initial ledger download.
|
||||
*
|
||||
* @return the number of markers
|
||||
* @return The number of markers
|
||||
*/
|
||||
std::uint32_t
|
||||
getNumMarkers() const
|
||||
|
||||
@@ -57,6 +57,12 @@ struct ETLState {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parse a boost::json::value into a ETLState
|
||||
*
|
||||
* @param jv The json value to convert
|
||||
* @return The ETLState
|
||||
*/
|
||||
ETLState
|
||||
tag_invoke(boost::json::value_to_tag<ETLState>, boost::json::value const& jv);
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ LoadBalancer::toJson() const
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class Func>
|
||||
template <typename Func>
|
||||
bool
|
||||
LoadBalancer::execute(Func f, uint32_t ledgerSequence)
|
||||
{
|
||||
|
||||
@@ -104,6 +104,7 @@ public:
|
||||
* @param backend BackendInterface implementation
|
||||
* @param subscriptions Subscription manager
|
||||
* @param validatedLedgers The network validated ledgers datastructure
|
||||
* @return A shared pointer to a new instance of LoadBalancer
|
||||
*/
|
||||
static std::shared_ptr<LoadBalancer>
|
||||
make_LoadBalancer(
|
||||
@@ -121,6 +122,8 @@ public:
|
||||
*
|
||||
* @param sequence Sequence of ledger to download
|
||||
* @param cacheOnly Whether to only write to cache and not to the DB; defaults to false
|
||||
* @return A std::pair<std::vector<std::string>, bool> The ledger data and a bool indicating whether the download
|
||||
* was successful
|
||||
*/
|
||||
std::pair<std::vector<std::string>, bool>
|
||||
loadInitialLedger(uint32_t sequence, bool cacheOnly = false);
|
||||
@@ -134,13 +137,15 @@ public:
|
||||
* @param ledgerSequence Sequence of the ledger to fetch
|
||||
* @param getObjects Whether to get the account state diff between this ledger and the prior one
|
||||
* @param getObjectNeighbors Whether to request object neighbors
|
||||
* @return The extracted data, if extraction was successful. If the ledger was found in the database or the server
|
||||
* is shutting down, the optional will be empty
|
||||
* @return The extracted data, if extraction was successful. If the ledger was found
|
||||
* in the database or the server is shutting down, the optional will be empty
|
||||
*/
|
||||
OptionalGetLedgerResponseType
|
||||
fetchLedger(uint32_t ledgerSequence, bool getObjects, bool getObjectNeighbors);
|
||||
|
||||
/**
|
||||
* @brief Represent the state of this load balancer as a JSON object
|
||||
*
|
||||
* @return JSON representation of the state of this load balancer.
|
||||
*/
|
||||
boost::json::value
|
||||
@@ -181,7 +186,7 @@ private:
|
||||
* @return true if f was eventually executed successfully. false if the ledger was found in the database or the
|
||||
* server is shutting down
|
||||
*/
|
||||
template <class Func>
|
||||
template <typename Func>
|
||||
bool
|
||||
execute(Func f, uint32_t ledgerSequence);
|
||||
|
||||
|
||||
@@ -33,6 +33,56 @@
|
||||
|
||||
namespace etl {
|
||||
|
||||
/**
|
||||
* @brief Get the NFT Token mint data from a transaction
|
||||
*
|
||||
* @param txMeta Transaction metadata
|
||||
* @param sttx The transaction
|
||||
* @return NFT Token mint data as a pair of transactions and optional NFTsData
|
||||
*/
|
||||
std::pair<std::vector<NFTTransactionsData>, std::optional<NFTsData>>
|
||||
getNFTokenMintData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx);
|
||||
|
||||
/**
|
||||
* @brief Get the NFT Token burn data from a transaction
|
||||
*
|
||||
* @param txMeta Transaction metadata
|
||||
* @param sttx The transaction
|
||||
* @return NFT Token burn data as a pair of transactions and optional NFTsData
|
||||
*/
|
||||
std::pair<std::vector<NFTTransactionsData>, std::optional<NFTsData>>
|
||||
getNFTokenBurnData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx);
|
||||
|
||||
/**
|
||||
* @brief Get the NFT Token accept offer data from a transaction
|
||||
*
|
||||
* @param txMeta Transaction metadata
|
||||
* @param sttx The transaction
|
||||
* @return NFT Token accept offer data as a pair of transactions and optional NFTsData
|
||||
*/
|
||||
std::pair<std::vector<NFTTransactionsData>, std::optional<NFTsData>>
|
||||
getNFTokenAcceptOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx);
|
||||
|
||||
/**
|
||||
* @brief Get the NFT Token cancel offer data from a transaction
|
||||
*
|
||||
* @param txMeta Transaction metadata
|
||||
* @param sttx The transaction
|
||||
* @return NFT Token cancel offer data as a pair of transactions and optional NFTsData
|
||||
*/
|
||||
std::pair<std::vector<NFTTransactionsData>, std::optional<NFTsData>>
|
||||
getNFTokenCancelOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx);
|
||||
|
||||
/**
|
||||
* @brief Get the NFT Token create offer data from a transaction
|
||||
*
|
||||
* @param txMeta Transaction metadata
|
||||
* @param sttx The transaction
|
||||
* @return NFT Token create offer data as a pair of transactions and optional NFTsData
|
||||
*/
|
||||
std::pair<std::vector<NFTTransactionsData>, std::optional<NFTsData>>
|
||||
getNFTokenCreateOfferData(ripple::TxMeta const& txMeta, ripple::STTx const& sttx);
|
||||
|
||||
/**
|
||||
* @brief Pull NFT data from TX via ETLService.
|
||||
*
|
||||
|
||||
@@ -45,6 +45,13 @@
|
||||
|
||||
namespace etl {
|
||||
|
||||
/**
|
||||
* @brief Provides an implementation of a ETL source
|
||||
*
|
||||
* @tparam GrpcSourceType The type of the gRPC source
|
||||
* @tparam SubscriptionSourceTypePtr The type of the subscription source
|
||||
* @tparam ForwardingSourceType The type of the forwarding source
|
||||
*/
|
||||
template <
|
||||
typename GrpcSourceType = impl::GrpcSource,
|
||||
typename SubscriptionSourceTypePtr = std::unique_ptr<impl::SubscriptionSource>,
|
||||
@@ -62,6 +69,16 @@ public:
|
||||
using OnConnectHook = impl::SubscriptionSource::OnConnectHook;
|
||||
using OnDisconnectHook = impl::SubscriptionSource::OnDisconnectHook;
|
||||
|
||||
/**
|
||||
* @brief Construct a new SourceImpl object
|
||||
*
|
||||
* @param ip The IP of the source
|
||||
* @param wsPort The web socket port of the source
|
||||
* @param grpcPort The gRPC port of the source
|
||||
* @param grpcSource The gRPC source
|
||||
* @param subscriptionSource The subscription source
|
||||
* @param forwardingSource The forwarding source
|
||||
*/
|
||||
template <typename SomeGrpcSourceType, typename SomeForwardingSourceType>
|
||||
requires std::is_same_v<GrpcSourceType, SomeGrpcSourceType> &&
|
||||
std::is_same_v<ForwardingSourceType, SomeForwardingSourceType>
|
||||
@@ -91,7 +108,11 @@ public:
|
||||
subscriptionSource_->run();
|
||||
}
|
||||
|
||||
/** @return true if source is connected; false otherwise */
|
||||
/**
|
||||
* @brief Check if source is connected
|
||||
*
|
||||
* @return true if source is connected; false otherwise
|
||||
*/
|
||||
bool
|
||||
isConnected() const
|
||||
{
|
||||
@@ -109,7 +130,11 @@ public:
|
||||
subscriptionSource_->setForwarding(isForwarding);
|
||||
}
|
||||
|
||||
/** @return JSON representation of the source */
|
||||
/**
|
||||
* @brief Represent the source as a JSON object
|
||||
*
|
||||
* @return JSON representation of the source
|
||||
*/
|
||||
boost::json::object
|
||||
toJson() const
|
||||
{
|
||||
@@ -213,6 +238,9 @@ using Source = SourceImpl<>;
|
||||
* @param backend BackendInterface implementation
|
||||
* @param subscriptions Subscription manager
|
||||
* @param validatedLedgers The network validated ledgers data structure
|
||||
* @param onDisconnect The hook to call on disconnect
|
||||
* @param onConnect The hook to call on connect
|
||||
* @return The created source
|
||||
*/
|
||||
Source
|
||||
make_Source(
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
* extraction succeeds, or the server shuts down.
|
||||
*
|
||||
* @param sequence sequence of the ledger to extract
|
||||
* @return ledger header and transaction+metadata blobs; empty optional if the server is shutting down
|
||||
* @return Ledger header and transaction+metadata blobs; Empty optional if the server is shutting down
|
||||
*/
|
||||
OptionalGetLedgerResponseType
|
||||
fetchData(uint32_t sequence)
|
||||
@@ -81,8 +81,7 @@ public:
|
||||
* extraction succeeds, or the server shuts down.
|
||||
*
|
||||
* @param sequence sequence of the ledger to extract
|
||||
* @return ledger header, transaction+metadata blobs, and all ledger objects created, modified or deleted between
|
||||
* this ledger and the parent; Empty optional if the server is shutting down
|
||||
* @return Ledger data diff between sequance and parent; Empty optional if the server is shutting down
|
||||
*/
|
||||
OptionalGetLedgerResponseType
|
||||
fetchDataAndDiff(uint32_t sequence)
|
||||
|
||||
@@ -102,8 +102,7 @@ public:
|
||||
*
|
||||
* @param ledger ledger to insert transactions into
|
||||
* @param data data extracted from an ETL source
|
||||
* @return struct that contains the neccessary info to write to the account_transactions/account_tx and
|
||||
* nft_token_transactions tables (mostly transaction hashes, corresponding nodestore hashes and affected accounts)
|
||||
* @return The neccessary info to write the account_transactions/account_tx and nft_token_transactions tables
|
||||
*/
|
||||
FormattedTransactionsData
|
||||
insertTransactions(ripple::LedgerHeader const& ledger, GetLedgerResponseType& data)
|
||||
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
*
|
||||
* @param ledgerSequence the sequence of the ledger to publish
|
||||
* @param maxAttempts the number of times to attempt to read the ledger from the database. 1 attempt per second
|
||||
* @return whether the ledger was found in the database and published
|
||||
* @return Whether the ledger was found in the database and published
|
||||
*/
|
||||
bool
|
||||
publish(uint32_t ledgerSequence, std::optional<uint32_t> maxAttempts)
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
*/
|
||||
namespace feed {
|
||||
|
||||
/**
|
||||
* @brief A subscription manager is responsible for managing the subscriptions and publishing the feeds
|
||||
*/
|
||||
class SubscriptionManager {
|
||||
std::reference_wrapper<boost::asio::io_context> ioContext_;
|
||||
std::shared_ptr<data::BackendInterface const> backend_;
|
||||
@@ -64,6 +67,12 @@ class SubscriptionManager {
|
||||
impl::ProposedTransactionFeed proposedTransactionFeed_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Subscription Manager object
|
||||
*
|
||||
* @param ioContext The io context to use
|
||||
* @param backend The backend to use
|
||||
*/
|
||||
SubscriptionManager(
|
||||
boost::asio::io_context& ioContext,
|
||||
std::shared_ptr<data::BackendInterface const> const& backend
|
||||
@@ -141,7 +150,9 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Subscribe to the ledger feed.
|
||||
* @param subscriber
|
||||
* @param yield The coroutine context
|
||||
* @param subscriber The subscriber to the ledger feed
|
||||
* @return The ledger feed
|
||||
*/
|
||||
boost::json::object
|
||||
subLedger(boost::asio::yield_context yield, SubscriberSharedPtr const& subscriber);
|
||||
@@ -236,7 +247,8 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Unsubscribe to the transactions feed for particular account.
|
||||
* @param subscriber
|
||||
* @param account The account to stop watching
|
||||
* @param subscriber The subscriber to unsubscribe
|
||||
*/
|
||||
void
|
||||
unsubAccount(ripple::AccountID const& account, SubscriberSharedPtr const& subscriber);
|
||||
@@ -268,6 +280,8 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Get the number of subscribers.
|
||||
*
|
||||
* @return The report of the number of subscribers
|
||||
*/
|
||||
boost::json::object
|
||||
report() const
|
||||
@@ -299,6 +313,12 @@ class SubscriptionManagerRunner {
|
||||
std::vector<std::thread> workers_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Subscription Manager Runner object
|
||||
*
|
||||
* @param config The configuration
|
||||
* @param backend The backend to use
|
||||
*/
|
||||
SubscriptionManagerRunner(util::Config const& config, std::shared_ptr<data::BackendInterface> const& backend)
|
||||
: subscriptionManager_(std::make_shared<SubscriptionManager>(ioContext_, backend))
|
||||
{
|
||||
@@ -309,6 +329,11 @@ public:
|
||||
workers_.emplace_back([&] { ioContext_.run(); });
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the subscription manager
|
||||
*
|
||||
* @return The subscription manager
|
||||
*/
|
||||
std::shared_ptr<SubscriptionManager>
|
||||
getManager()
|
||||
{
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace po = boost::program_options;
|
||||
*
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @return std::string Path to configuration file
|
||||
* @return Path to configuration file
|
||||
*/
|
||||
std::string
|
||||
parseCli(int argc, char* argv[])
|
||||
@@ -109,7 +109,7 @@ parseCli(int argc, char* argv[])
|
||||
* @brief Parse certificates from configuration file
|
||||
*
|
||||
* @param config The configuration
|
||||
* @return std::optional<ssl::context> SSL context if certificates were parsed
|
||||
* @return SSL context if certificates were parsed
|
||||
*/
|
||||
std::optional<ssl::context>
|
||||
parseCerts(Config const& config)
|
||||
|
||||
@@ -34,7 +34,16 @@
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief getAmmPoolHolds returns the balances of the amm asset pair.
|
||||
* @brief getAmmPoolHolds returns the balances of the amm asset pair
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence number to use
|
||||
* @param ammAccountID The amm account
|
||||
* @param issue1 The first issue
|
||||
* @param issue2 The second issue
|
||||
* @param freezeHandling Whether to return zeroes for frozen accounts
|
||||
* @param yield The coroutine context
|
||||
* @return The balances of the amm asset pair
|
||||
*/
|
||||
std::pair<ripple::STAmount, ripple::STAmount>
|
||||
getAmmPoolHolds(
|
||||
@@ -48,7 +57,16 @@ getAmmPoolHolds(
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief getAmmLpHolds returns the lp token balance.
|
||||
* @brief getAmmLpHolds returns the liquidity provider token balance
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence number to use
|
||||
* @param cur1 The first currency
|
||||
* @param cur2 The second currency
|
||||
* @param ammAccount The amm account
|
||||
* @param lpAccount The lp account
|
||||
* @param yield The coroutine context
|
||||
* @return The lp token balance
|
||||
*/
|
||||
ripple::STAmount
|
||||
getAmmLpHolds(
|
||||
@@ -62,7 +80,14 @@ getAmmLpHolds(
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief getAmmLpHolds returns the lp token balance.
|
||||
* @brief getAmmLpHolds returns the liquidity provider token balance
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence number to use
|
||||
* @param ammSle The amm ledger entry
|
||||
* @param lpAccount The lp account
|
||||
* @param yield The coroutine context
|
||||
* @return The lp token balance
|
||||
*/
|
||||
ripple::STAmount
|
||||
getAmmLpHolds(
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
* @brief Computes all book_changes for the given transactions.
|
||||
*
|
||||
* @param transactions The transactions to compute book changes for
|
||||
* @return std::vector<BookChange> Book changes
|
||||
* @return Book changes
|
||||
*/
|
||||
[[nodiscard]] static std::vector<BookChange>
|
||||
compute(std::vector<data::TransactionAndMetadata> const& transactions)
|
||||
@@ -261,6 +261,7 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, BookChange const
|
||||
*
|
||||
* @param lgrInfo The ledger header
|
||||
* @param transactions The vector of transactions with heir metadata
|
||||
* @return The book changes
|
||||
*/
|
||||
[[nodiscard]] boost::json::object
|
||||
computeBookChanges(ripple::LedgerHeader const& lgrInfo, std::vector<data::TransactionAndMetadata> const& transactions);
|
||||
|
||||
@@ -109,6 +109,7 @@ public:
|
||||
* @brief Increments the completed count for a particular RPC method.
|
||||
*
|
||||
* @param method The method to increment the count for
|
||||
* @param rpcDuration The duration of the RPC call
|
||||
*/
|
||||
void
|
||||
rpcComplete(std::string const& method, std::chrono::microseconds const& rpcDuration);
|
||||
|
||||
@@ -37,13 +37,13 @@
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
template <class... Ts>
|
||||
template <typename... Ts>
|
||||
struct overloadSet : Ts... {
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
// explicit deduction guide (not needed as of C++20, but clang be clang)
|
||||
template <class... Ts>
|
||||
template <typename... Ts>
|
||||
overloadSet(Ts...) -> overloadSet<Ts...>;
|
||||
} // namespace
|
||||
|
||||
@@ -107,7 +107,7 @@ getErrorInfo(ClioError code)
|
||||
}
|
||||
|
||||
boost::json::object
|
||||
makeError(RippledError err, optional<string_view> customError, optional<string_view> customMessage)
|
||||
makeError(RippledError err, std::optional<std::string_view> customError, std::optional<std::string_view> customMessage)
|
||||
{
|
||||
boost::json::object json;
|
||||
auto const& info = ripple::RPC::get_error_info(err);
|
||||
@@ -122,7 +122,7 @@ makeError(RippledError err, optional<string_view> customError, optional<string_v
|
||||
}
|
||||
|
||||
boost::json::object
|
||||
makeError(ClioError err, optional<string_view> customError, optional<string_view> customMessage)
|
||||
makeError(ClioError err, std::optional<std::string_view> customError, std::optional<std::string_view> customMessage)
|
||||
{
|
||||
boost::json::object json;
|
||||
auto const& info = getErrorInfo(err);
|
||||
|
||||
@@ -77,25 +77,61 @@ struct Status {
|
||||
std::optional<boost::json::object> extraInfo;
|
||||
|
||||
Status() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Status object
|
||||
*
|
||||
* @param code The error code
|
||||
*/
|
||||
/* implicit */ Status(CombinedError code) : code(code){};
|
||||
|
||||
/**
|
||||
* @brief Construct a new Status object
|
||||
*
|
||||
* @param code The error code
|
||||
* @param extraInfo The extra info
|
||||
*/
|
||||
Status(CombinedError code, boost::json::object&& extraInfo) : code(code), extraInfo(std::move(extraInfo)){};
|
||||
|
||||
// HACK. Some rippled handlers explicitly specify errors.
|
||||
// This means that we have to be able to duplicate this functionality.
|
||||
/**
|
||||
* @brief Construct a new Status object with a custom message
|
||||
*
|
||||
* @note HACK. Some rippled handlers explicitly specify errors. This means that we have to be able to duplicate this
|
||||
* functionality.
|
||||
*
|
||||
* @param message The message
|
||||
*/
|
||||
explicit Status(std::string message) : code(ripple::rpcUNKNOWN), message(std::move(message))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Status object
|
||||
*
|
||||
* @param code The error code
|
||||
* @param message The message
|
||||
*/
|
||||
Status(CombinedError code, std::string message) : code(code), message(std::move(message))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Status object
|
||||
*
|
||||
* @param code The error code
|
||||
* @param error The error
|
||||
* @param message The message
|
||||
*/
|
||||
Status(CombinedError code, std::string error, std::string message)
|
||||
: code(code), error(std::move(error)), message(std::move(message))
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief Returns true if the Status is *not* OK. */
|
||||
/**
|
||||
* @brief Check if the status is not OK
|
||||
*
|
||||
* @return true if the status is not OK; false otherwise
|
||||
*/
|
||||
operator bool() const
|
||||
{
|
||||
if (auto err = std::get_if<RippledError>(&code))
|
||||
@@ -141,6 +177,13 @@ enum WarningCode { warnUNKNOWN = -1, warnRPC_CLIO = 2001, warnRPC_OUTDATED = 200
|
||||
/** @brief Holds information about a clio warning. */
|
||||
struct WarningInfo {
|
||||
constexpr WarningInfo() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Warning Info object
|
||||
*
|
||||
* @param code The warning code
|
||||
* @param message The warning message
|
||||
*/
|
||||
constexpr WarningInfo(WarningCode code, char const* message) : code(code), message(message)
|
||||
{
|
||||
}
|
||||
@@ -154,10 +197,20 @@ class InvalidParamsError : public std::exception {
|
||||
std::string msg;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Invalid Params Error object
|
||||
*
|
||||
* @param msg The error message
|
||||
*/
|
||||
explicit InvalidParamsError(std::string msg) : msg(std::move(msg))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the error message as a C string
|
||||
*
|
||||
* @return The error message
|
||||
*/
|
||||
char const*
|
||||
what() const throw() override
|
||||
{
|
||||
@@ -170,10 +223,20 @@ class AccountNotFoundError : public std::exception {
|
||||
std::string account;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Account Not Found Error object
|
||||
*
|
||||
* @param acct The account
|
||||
*/
|
||||
explicit AccountNotFoundError(std::string acct) : account(std::move(acct))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the error message as a C string
|
||||
*
|
||||
* @return The error message
|
||||
*/
|
||||
char const*
|
||||
what() const throw() override
|
||||
{
|
||||
@@ -224,6 +287,8 @@ makeError(Status const& status);
|
||||
* @brief Generate JSON from a @ref rpc::RippledError.
|
||||
*
|
||||
* @param err The rippled error
|
||||
* @param customError A custom error
|
||||
* @param customMessage A custom message
|
||||
* @return The JSON output
|
||||
*/
|
||||
boost::json::object
|
||||
@@ -237,6 +302,8 @@ makeError(
|
||||
* @brief Generate JSON from a @ref rpc::ClioError.
|
||||
*
|
||||
* @param err The clio's custom error
|
||||
* @param customError A custom error
|
||||
* @param customMessage A custom message
|
||||
* @return The JSON output
|
||||
*/
|
||||
boost::json::object
|
||||
|
||||
@@ -47,10 +47,10 @@ util::Expected<web::Context, Status>
|
||||
make_WsContext(
|
||||
boost::asio::yield_context yc,
|
||||
boost::json::object const& request,
|
||||
shared_ptr<web::ConnectionBase> const& session,
|
||||
TagDecoratorFactory const& tagFactory,
|
||||
std::shared_ptr<web::ConnectionBase> const& session,
|
||||
util::TagDecoratorFactory const& tagFactory,
|
||||
data::LedgerRange const& range,
|
||||
string const& clientIp,
|
||||
std::string const& clientIp,
|
||||
std::reference_wrapper<APIVersionParser const> apiVersionParser
|
||||
)
|
||||
{
|
||||
@@ -76,9 +76,9 @@ Expected<web::Context, Status>
|
||||
make_HttpContext(
|
||||
boost::asio::yield_context yc,
|
||||
boost::json::object const& request,
|
||||
TagDecoratorFactory const& tagFactory,
|
||||
util::TagDecoratorFactory const& tagFactory,
|
||||
data::LedgerRange const& range,
|
||||
string const& clientIp,
|
||||
std::string const& clientIp,
|
||||
std::reference_wrapper<APIVersionParser const> apiVersionParser,
|
||||
bool const isAdmin
|
||||
)
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace rpc {
|
||||
* @param range The ledger range that is available at request time
|
||||
* @param clientIp The IP address of the connected client
|
||||
* @param apiVersionParser A parser that is used to parse out the "api_version" field
|
||||
* @return A Websocket context or error Status
|
||||
*/
|
||||
util::Expected<web::Context, Status>
|
||||
make_WsContext(
|
||||
@@ -76,6 +77,7 @@ make_WsContext(
|
||||
* @param clientIp The IP address of the connected client
|
||||
* @param apiVersionParser A parser that is used to parse out the "api_version" field
|
||||
* @param isAdmin Whether the connection has admin privileges
|
||||
* @return A HTTP context or error Status
|
||||
*/
|
||||
util::Expected<web::Context, Status>
|
||||
make_HttpContext(
|
||||
|
||||
@@ -73,6 +73,16 @@ class RPCEngine {
|
||||
impl::ForwardingProxy<etl::LoadBalancer, Counters, HandlerProvider> forwardingProxy_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new RPCEngine object
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param balancer The load balancer to use
|
||||
* @param dosGuard The DOS guard to use
|
||||
* @param workQueue The work queue to use
|
||||
* @param counters The counters to use
|
||||
* @param handlerProvider The handler provider to use
|
||||
*/
|
||||
RPCEngine(
|
||||
std::shared_ptr<BackendInterface> const& backend,
|
||||
std::shared_ptr<etl::LoadBalancer> const& balancer,
|
||||
@@ -90,6 +100,17 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Factory function to create a new instance of the RPC engine.
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param balancer The load balancer to use
|
||||
* @param dosGuard The DOS guard to use
|
||||
* @param workQueue The work queue to use
|
||||
* @param counters The counters to use
|
||||
* @param handlerProvider The handler provider to use
|
||||
* @return A new instance of the RPC engine
|
||||
*/
|
||||
static std::shared_ptr<RPCEngine>
|
||||
make_RPCEngine(
|
||||
std::shared_ptr<BackendInterface> const& backend,
|
||||
@@ -159,6 +180,7 @@ public:
|
||||
* @tparam FnType The type of function
|
||||
* @param func The lambda to execute when this request is handled
|
||||
* @param ip The ip address for which this request is being executed
|
||||
* @return true if the request was successfully scheduled; false otherwise
|
||||
*/
|
||||
template <typename FnType>
|
||||
bool
|
||||
|
||||
@@ -795,105 +795,6 @@ parseRippleLibSeed(boost::json::value const& value)
|
||||
return {};
|
||||
}
|
||||
|
||||
std::variant<Status, std::pair<ripple::PublicKey, ripple::SecretKey>>
|
||||
keypairFromRequst(boost::json::object const& request)
|
||||
{
|
||||
bool const has_key_type = request.contains("key_type");
|
||||
|
||||
// All of the secret types we allow, but only one at a time.
|
||||
// The array should be constexpr, but that makes Visual Studio unhappy.
|
||||
static std::string const secretTypes[]{"passphrase", "secret", "seed", "seed_hex"};
|
||||
|
||||
// Identify which secret type is in use.
|
||||
std::string secretType;
|
||||
int count = 0;
|
||||
for (auto const& t : secretTypes) {
|
||||
if (request.contains(t)) {
|
||||
++count;
|
||||
secretType = t;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return Status{RippledError::rpcINVALID_PARAMS, "missing field secret"};
|
||||
|
||||
if (count > 1) {
|
||||
return Status{
|
||||
RippledError::rpcINVALID_PARAMS,
|
||||
"Exactly one of the following must be specified: passphrase, secret, seed, or seed_hex"
|
||||
};
|
||||
}
|
||||
|
||||
std::optional<ripple::KeyType> keyType;
|
||||
std::optional<ripple::Seed> seed;
|
||||
|
||||
if (has_key_type) {
|
||||
if (!request.at("key_type").is_string())
|
||||
return Status{RippledError::rpcINVALID_PARAMS, "keyTypeNotString"};
|
||||
|
||||
auto const key_type = boost::json::value_to<std::string>(request.at("key_type"));
|
||||
keyType = ripple::keyTypeFromString(key_type);
|
||||
|
||||
if (!keyType)
|
||||
return Status{RippledError::rpcINVALID_PARAMS, "invalidFieldKeyType"};
|
||||
|
||||
if (secretType == "secret")
|
||||
return Status{RippledError::rpcINVALID_PARAMS, "The secret field is not allowed if key_type is used."};
|
||||
}
|
||||
|
||||
// ripple-lib encodes seed used to generate an Ed25519 wallet in a
|
||||
// non-standard way. While we never encode seeds that way, we try
|
||||
// to detect such keys to avoid user confusion.
|
||||
if (secretType != "seed_hex") {
|
||||
seed = parseRippleLibSeed(request.at(secretType));
|
||||
|
||||
if (seed) {
|
||||
// If the user passed in an Ed25519 seed but *explicitly*
|
||||
// requested another key type, return an error.
|
||||
if (keyType.value_or(ripple::KeyType::ed25519) != ripple::KeyType::ed25519)
|
||||
return Status{RippledError::rpcINVALID_PARAMS, "Specified seed is for an Ed25519 wallet."};
|
||||
|
||||
keyType = ripple::KeyType::ed25519;
|
||||
}
|
||||
}
|
||||
|
||||
if (!keyType)
|
||||
keyType = ripple::KeyType::secp256k1;
|
||||
|
||||
if (!seed) {
|
||||
if (has_key_type) {
|
||||
if (!request.at(secretType).is_string())
|
||||
return Status{RippledError::rpcINVALID_PARAMS, "secret value must be string"};
|
||||
|
||||
auto const key = boost::json::value_to<std::string>(request.at(secretType));
|
||||
|
||||
if (secretType == "seed") {
|
||||
seed = ripple::parseBase58<ripple::Seed>(key);
|
||||
} else if (secretType == "passphrase") {
|
||||
seed = ripple::parseGenericSeed(key);
|
||||
} else if (secretType == "seed_hex") {
|
||||
ripple::uint128 s;
|
||||
if (s.parseHex(key))
|
||||
seed.emplace(ripple::Slice(s.data(), ripple::uint128::size()));
|
||||
}
|
||||
} else {
|
||||
if (!request.at("secret").is_string())
|
||||
return Status{RippledError::rpcINVALID_PARAMS, "field secret should be a string"};
|
||||
|
||||
auto const secret = boost::json::value_to<std::string>(request.at("secret"));
|
||||
seed = ripple::parseGenericSeed(secret);
|
||||
}
|
||||
}
|
||||
|
||||
if (!seed)
|
||||
return Status{RippledError::rpcBAD_SEED, "Bad Seed: invalid field message secretType"};
|
||||
|
||||
if (keyType != ripple::KeyType::secp256k1 && keyType != ripple::KeyType::ed25519)
|
||||
return Status{RippledError::rpcINVALID_PARAMS, "keypairForSignature: invalid key type"};
|
||||
|
||||
return generateKeyPair(*keyType, *seed);
|
||||
}
|
||||
|
||||
std::vector<ripple::AccountID>
|
||||
getAccountsFromTransaction(boost::json::object const& transaction)
|
||||
{
|
||||
|
||||
@@ -75,34 +75,76 @@
|
||||
|
||||
namespace rpc {
|
||||
|
||||
/** @brief Enum for NFT json manipulation */
|
||||
enum class NFTokenjson { ENABLE, DISABLE };
|
||||
|
||||
/**
|
||||
* @brief Get a ripple::AccountID from its string representation
|
||||
*
|
||||
* @param account The string representation of the account
|
||||
* @return The account ID or std::nullopt if the string is not a valid account
|
||||
*/
|
||||
std::optional<ripple::AccountID>
|
||||
accountFromStringStrict(std::string const& account);
|
||||
|
||||
/**
|
||||
* @brief Check whether the SLE is owned by the account
|
||||
*
|
||||
* @param sle The ledger entry
|
||||
* @param accountID The account ID
|
||||
* @return true if the SLE is owned by the account
|
||||
*/
|
||||
bool
|
||||
isOwnedByAccount(ripple::SLE const& sle, ripple::AccountID const& accountID);
|
||||
|
||||
/**
|
||||
* @brief Get the start hint for the account
|
||||
*
|
||||
* @param sle The ledger entry
|
||||
* @param accountID The account ID
|
||||
* @return The start hint
|
||||
*/
|
||||
std::uint64_t
|
||||
getStartHint(ripple::SLE const& sle, ripple::AccountID const& accountID);
|
||||
|
||||
/**
|
||||
* @brief Parse the account cursor from the JSON
|
||||
*
|
||||
* @param jsonCursor The JSON cursor
|
||||
* @return The parsed account cursor
|
||||
*/
|
||||
std::optional<AccountCursor>
|
||||
parseAccountCursor(std::optional<std::string> jsonCursor);
|
||||
|
||||
// TODO this function should probably be in a different file and namespace
|
||||
/**
|
||||
* @brief Deserialize a TransactionAndMetadata into a pair of STTx and STObject
|
||||
*
|
||||
* @param blobs The TransactionAndMetadata to deserialize
|
||||
* @return The deserialized objects
|
||||
*/
|
||||
std::pair<std::shared_ptr<ripple::STTx const>, std::shared_ptr<ripple::STObject const>>
|
||||
deserializeTxPlusMeta(data::TransactionAndMetadata const& blobs);
|
||||
|
||||
// TODO this function should probably be in a different file and namespace
|
||||
/**
|
||||
* @brief Deserialize a TransactionAndMetadata into a pair of STTx and TxMeta
|
||||
*
|
||||
* @param blobs The TransactionAndMetadata to deserialize
|
||||
* @param seq The sequence number to set
|
||||
* @return The deserialized objects
|
||||
*/
|
||||
std::pair<std::shared_ptr<ripple::STTx const>, std::shared_ptr<ripple::TxMeta const>>
|
||||
deserializeTxPlusMeta(data::TransactionAndMetadata const& blobs, std::uint32_t seq);
|
||||
|
||||
/**
|
||||
* @brief Convert a TransactionAndMetadata to two JSON objects.
|
||||
* @brief Convert a TransactionAndMetadata to two JSON objects
|
||||
*
|
||||
* @param blobs The TransactionAndMetadata to convert.
|
||||
* @param nftEnabled Whether to include NFT information in the JSON.
|
||||
* @param networkId The network ID to use for ctid, not include ctid if nullopt.
|
||||
* @param blobs The TransactionAndMetadata to convert
|
||||
* @param apiVersion The api version to generate the JSON for
|
||||
* @param nftEnabled Whether to include NFT information in the JSON
|
||||
* @param networkId The network ID to use for ctid, not include ctid if nullopt
|
||||
* @return The JSON objects
|
||||
*/
|
||||
std::pair<boost::json::object, boost::json::object>
|
||||
toExpandedJson(
|
||||
@@ -131,6 +173,15 @@ toJsonWithBinaryTx(data::TransactionAndMetadata const& txnPlusMeta, std::uint32_
|
||||
void
|
||||
insertDeliverMaxAlias(boost::json::object& txJson, std::uint32_t apiVersion);
|
||||
|
||||
/**
|
||||
* @brief Add "DeliveredAmount" to the transaction json object
|
||||
*
|
||||
* @param metaJson The metadata json object to add "DeliveredAmount"
|
||||
* @param txn The transaction object
|
||||
* @param meta The metadata object
|
||||
* @param date The date of the ledger
|
||||
* @return true if the "DeliveredAmount" is added to the metadata json object
|
||||
*/
|
||||
bool
|
||||
insertDeliveredAmount(
|
||||
boost::json::object& metaJson,
|
||||
@@ -139,9 +190,21 @@ insertDeliveredAmount(
|
||||
uint32_t date
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Convert STBase object to JSON
|
||||
*
|
||||
* @param obj The object to convert
|
||||
* @return The JSON object
|
||||
*/
|
||||
boost::json::object
|
||||
toJson(ripple::STBase const& obj);
|
||||
|
||||
/**
|
||||
* @brief Convert SLE to JSON
|
||||
*
|
||||
* @param sle The ledger entry to convert
|
||||
* @return The JSON object
|
||||
*/
|
||||
boost::json::object
|
||||
toJson(ripple::SLE const& sle);
|
||||
|
||||
@@ -156,13 +219,35 @@ toJson(ripple::SLE const& sle);
|
||||
boost::json::object
|
||||
toJson(ripple::LedgerHeader const& info, bool binary, std::uint32_t apiVersion);
|
||||
|
||||
/**
|
||||
* @brief Convert a TxMeta to JSON object.
|
||||
*
|
||||
* @param meta The TxMeta to convert.
|
||||
* @return The JSON object.
|
||||
*/
|
||||
boost::json::object
|
||||
toJson(ripple::TxMeta const& meta);
|
||||
|
||||
using RippledJson = Json::Value;
|
||||
|
||||
/**
|
||||
* @brief Convert a RippledJson to boost::json::value
|
||||
*
|
||||
* @param value The RippledJson to convert
|
||||
* @return The JSON value
|
||||
*/
|
||||
boost::json::value
|
||||
toBoostJson(RippledJson const& value);
|
||||
|
||||
/**
|
||||
* @brief Generate a JSON object to publish ledger message
|
||||
*
|
||||
* @param lgrInfo The ledger header
|
||||
* @param fees The fees
|
||||
* @param ledgerRange The ledger range
|
||||
* @param txnCount The transaction count
|
||||
* @return The JSON object
|
||||
*/
|
||||
boost::json::object
|
||||
generatePubLedgerMessage(
|
||||
ripple::LedgerHeader const& lgrInfo,
|
||||
@@ -171,9 +256,26 @@ generatePubLedgerMessage(
|
||||
std::uint32_t txnCount
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get ledger info from the request
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param ctx The context of the request
|
||||
* @return The ledger info or an error status
|
||||
*/
|
||||
std::variant<Status, ripple::LedgerHeader>
|
||||
ledgerInfoFromRequest(std::shared_ptr<data::BackendInterface const> const& backend, web::Context const& ctx);
|
||||
|
||||
/**
|
||||
* @brief Get ledger info from hash or sequence
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param yield The coroutine context
|
||||
* @param ledgerHash The optional ledger hash
|
||||
* @param ledgerIndex The optional ledger index
|
||||
* @param maxSeq The maximum sequence to search
|
||||
* @return The ledger info or an error status
|
||||
*/
|
||||
std::variant<Status, ripple::LedgerHeader>
|
||||
getLedgerInfoFromHashOrSeq(
|
||||
BackendInterface const& backend,
|
||||
@@ -183,6 +285,19 @@ getLedgerInfoFromHashOrSeq(
|
||||
uint32_t maxSeq
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Traverse nodes owned by an account
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param owner The keylet of the owner
|
||||
* @param hexMarker The marker
|
||||
* @param startHint The start hint
|
||||
* @param sequence The sequence
|
||||
* @param limit The limit of nodes to traverse
|
||||
* @param yield The coroutine context
|
||||
* @param atOwnedNode The function to call for each owned node
|
||||
* @return The status or the account cursor
|
||||
*/
|
||||
std::variant<Status, AccountCursor>
|
||||
traverseOwnedNodes(
|
||||
BackendInterface const& backend,
|
||||
@@ -195,8 +310,21 @@ traverseOwnedNodes(
|
||||
std::function<void(ripple::SLE)> atOwnedNode
|
||||
);
|
||||
|
||||
// Remove the account check from traverseOwnedNodes
|
||||
// Account check has been done by framework,remove it from internal function
|
||||
/**
|
||||
* @brief Traverse nodes owned by an account
|
||||
*
|
||||
* @note Like the other one but removes the account check
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param accountID The account ID
|
||||
* @param sequence The sequence
|
||||
* @param limit The limit of nodes to traverse
|
||||
* @param jsonCursor The optional JSON cursor
|
||||
* @param yield The coroutine context
|
||||
* @param atOwnedNode The function to call for each owned node
|
||||
* @param nftIncluded Whether to include NFTs
|
||||
* @return The status or the account cursor
|
||||
*/
|
||||
std::variant<Status, AccountCursor>
|
||||
traverseOwnedNodes(
|
||||
BackendInterface const& backend,
|
||||
@@ -209,6 +337,15 @@ traverseOwnedNodes(
|
||||
bool nftIncluded = false
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Read SLE from the backend
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param keylet The keylet to read
|
||||
* @param lgrInfo The ledger header
|
||||
* @param context The context of the request
|
||||
* @return The SLE or nullptr if not found
|
||||
*/
|
||||
std::shared_ptr<ripple::SLE const>
|
||||
read(
|
||||
std::shared_ptr<data::BackendInterface const> const& backend,
|
||||
@@ -217,15 +354,34 @@ read(
|
||||
web::Context const& context
|
||||
);
|
||||
|
||||
std::variant<Status, std::pair<ripple::PublicKey, ripple::SecretKey>>
|
||||
keypairFromRequst(boost::json::object const& request);
|
||||
|
||||
/**
|
||||
* @brief Get the account associated with a transaction
|
||||
*
|
||||
* @param transaction The transaction
|
||||
* @return A vector of accounts associated with the transaction
|
||||
*/
|
||||
std::vector<ripple::AccountID>
|
||||
getAccountsFromTransaction(boost::json::object const& transaction);
|
||||
|
||||
/**
|
||||
* @brief Convert a ledger header to a blob
|
||||
*
|
||||
* @param info The ledger header
|
||||
* @param includeHash Whether to include the hash
|
||||
* @return The blob
|
||||
*/
|
||||
std::vector<unsigned char>
|
||||
ledgerInfoToBlob(ripple::LedgerHeader const& info, bool includeHash = false);
|
||||
|
||||
/**
|
||||
* @brief Whether global frozen is set
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param seq The ledger sequence
|
||||
* @param issuer The issuer
|
||||
* @param yield The coroutine context
|
||||
* @return true if the global frozen is set; false otherwise
|
||||
*/
|
||||
bool
|
||||
isGlobalFrozen(
|
||||
BackendInterface const& backend,
|
||||
@@ -234,6 +390,17 @@ isGlobalFrozen(
|
||||
boost::asio::yield_context yield
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Whether the account is frozen
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence
|
||||
* @param account The account
|
||||
* @param currency The currency
|
||||
* @param issuer The issuer
|
||||
* @param yield The coroutine context
|
||||
* @return true if the account is frozen; false otherwise
|
||||
*/
|
||||
bool
|
||||
isFrozen(
|
||||
BackendInterface const& backend,
|
||||
@@ -244,6 +411,16 @@ isFrozen(
|
||||
boost::asio::yield_context yield
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the account funds
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence
|
||||
* @param amount The amount
|
||||
* @param id The account ID
|
||||
* @param yield The coroutine context
|
||||
* @return The account funds
|
||||
*/
|
||||
ripple::STAmount
|
||||
accountFunds(
|
||||
BackendInterface const& backend,
|
||||
@@ -253,6 +430,18 @@ accountFunds(
|
||||
boost::asio::yield_context yield
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the amount that an account holds
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence
|
||||
* @param account The account
|
||||
* @param currency The currency
|
||||
* @param issuer The issuer
|
||||
* @param zeroIfFrozen Whether to return zero if frozen
|
||||
* @param yield The coroutine context
|
||||
* @return The amount account holds
|
||||
*/
|
||||
ripple::STAmount
|
||||
accountHolds(
|
||||
BackendInterface const& backend,
|
||||
@@ -264,6 +453,15 @@ accountHolds(
|
||||
boost::asio::yield_context yield
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the transfer rate
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence
|
||||
* @param issuer The issuer
|
||||
* @param yield The coroutine context
|
||||
* @return The transfer rate
|
||||
*/
|
||||
ripple::Rate
|
||||
transferRate(
|
||||
BackendInterface const& backend,
|
||||
@@ -272,6 +470,15 @@ transferRate(
|
||||
boost::asio::yield_context yield
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the XRP liquidity
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence
|
||||
* @param id The account ID
|
||||
* @param yield The coroutine context
|
||||
* @return The XRP liquidity
|
||||
*/
|
||||
ripple::XRPAmount
|
||||
xrpLiquid(
|
||||
BackendInterface const& backend,
|
||||
@@ -280,6 +487,17 @@ xrpLiquid(
|
||||
boost::asio::yield_context yield
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Post process an order book
|
||||
*
|
||||
* @param offers The offers
|
||||
* @param book The book
|
||||
* @param takerID The taker ID
|
||||
* @param backend The backend to use
|
||||
* @param ledgerSequence The ledger sequence
|
||||
* @param yield The coroutine context
|
||||
* @return The post processed order book
|
||||
*/
|
||||
boost::json::array
|
||||
postProcessOrderBook(
|
||||
std::vector<data::LedgerObject> const& offers,
|
||||
@@ -290,12 +508,33 @@ postProcessOrderBook(
|
||||
boost::asio::yield_context yield
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Parse the book from the request
|
||||
*
|
||||
* @param pays The currency to pay
|
||||
* @param payIssuer The issuer of the currency to pay
|
||||
* @param gets The currency to get
|
||||
* @param getIssuer The issuer of the currency to get
|
||||
* @return The book or an error status
|
||||
*/
|
||||
std::variant<Status, ripple::Book>
|
||||
parseBook(ripple::Currency pays, ripple::AccountID payIssuer, ripple::Currency gets, ripple::AccountID getIssuer);
|
||||
|
||||
/**
|
||||
* @brief Parse the book from the request
|
||||
*
|
||||
* @param request The request
|
||||
* @return The book or an error status
|
||||
*/
|
||||
std::variant<Status, ripple::Book>
|
||||
parseBook(boost::json::object const& request);
|
||||
|
||||
/**
|
||||
* @brief Parse the taker from the request
|
||||
*
|
||||
* @param taker The taker as json
|
||||
* @return The taker account or an error status
|
||||
*/
|
||||
std::variant<Status, ripple::AccountID>
|
||||
parseTaker(boost::json::value const& taker);
|
||||
|
||||
@@ -309,12 +548,32 @@ parseTaker(boost::json::value const& taker);
|
||||
ripple::Issue
|
||||
parseIssue(boost::json::object const& issue);
|
||||
|
||||
/**
|
||||
* @brief Check whethe the request specifies the `current` or `closed` ledger
|
||||
* @param request The request to check
|
||||
* @return true if the request specifies the `current` or `closed` ledger
|
||||
*/
|
||||
bool
|
||||
specifiesCurrentOrClosedLedger(boost::json::object const& request);
|
||||
|
||||
/**
|
||||
* @brief Get the NFTID from the request
|
||||
*
|
||||
* @param request The request
|
||||
* @return The NFTID or an error status
|
||||
*/
|
||||
std::variant<ripple::uint256, Status>
|
||||
getNFTID(boost::json::object const& request);
|
||||
|
||||
/**
|
||||
* @brief Check if the amendment is enabled
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param yield The yield context
|
||||
* @param seq The ledger sequence
|
||||
* @param amendmentId The amendment ID
|
||||
* @return true if the amendment is enabled
|
||||
*/
|
||||
bool
|
||||
isAmendmentEnabled(
|
||||
std::shared_ptr<data::BackendInterface const> const& backend,
|
||||
@@ -323,9 +582,24 @@ isAmendmentEnabled(
|
||||
ripple::uint256 amendmentId
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Encode CTID as string
|
||||
*
|
||||
* @param ledgerSeq The ledger sequence
|
||||
* @param txnIndex The transaction index
|
||||
* @param networkId The network ID
|
||||
* @return The encoded CTID or std::nullopt if the input is invalid
|
||||
*/
|
||||
std::optional<std::string>
|
||||
encodeCTID(uint32_t ledgerSeq, uint16_t txnIndex, uint16_t networkId) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Decode the CTID from a string or a uint64_t
|
||||
*
|
||||
* @tparam T The type of the CTID
|
||||
* @param ctid The CTID to decode
|
||||
* @return The decoded CTID
|
||||
*/
|
||||
template <typename T>
|
||||
inline std::optional<std::tuple<uint32_t, uint16_t, uint16_t>>
|
||||
decodeCTID(T const ctid) noexcept
|
||||
@@ -363,7 +637,14 @@ decodeCTID(T const ctid) noexcept
|
||||
return {{ledgerSeq, txnIndex, networkId}};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
/**
|
||||
* @brief Log the duration of the request processing
|
||||
*
|
||||
* @tparam T The type of the duration
|
||||
* @param ctx The context of the request
|
||||
* @param dur The duration to log
|
||||
*/
|
||||
template <typename T>
|
||||
void
|
||||
logDuration(web::Context const& ctx, T const& dur)
|
||||
{
|
||||
@@ -386,4 +667,75 @@ logDuration(web::Context const& ctx, T const& dur)
|
||||
LOG(log.info()) << ctx.tag() << msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse a ripple-lib seed
|
||||
*
|
||||
* @param value JSON value to parse from
|
||||
* @return The parsed seed if successful; std::nullopt otherwise
|
||||
*/
|
||||
std::optional<ripple::Seed>
|
||||
parseRippleLibSeed(boost::json::value const& value);
|
||||
|
||||
/**
|
||||
* @brief Traverse NFT objects and call the callback for each owned node
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param sequence The sequence
|
||||
* @param accountID The account ID
|
||||
* @param nextPage The next page
|
||||
* @param limit The limit
|
||||
* @param yield The coroutine context
|
||||
* @param atOwnedNode The function to call for each owned node
|
||||
* @return The account cursor or an error status
|
||||
*/
|
||||
std::variant<Status, AccountCursor>
|
||||
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
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Parse the string as a uint32_t
|
||||
*
|
||||
* @param value The string to parse
|
||||
* @return The parsed value or std::nullopt if the string is not a valid uint32_t
|
||||
*/
|
||||
std::optional<std::uint32_t>
|
||||
parseStringAsUInt(std::string const& value); // TODO: move to string utils or something?
|
||||
|
||||
/**
|
||||
* @brief Whether the transaction can have a delivered amount
|
||||
*
|
||||
* @param txn The transaction
|
||||
* @param meta The metadata
|
||||
* @return true if the transaction can have a delivered amount
|
||||
*/
|
||||
bool
|
||||
canHaveDeliveredAmount(
|
||||
std::shared_ptr<ripple::STTx const> const& txn,
|
||||
std::shared_ptr<ripple::TxMeta const> const& meta
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Get the delivered amount
|
||||
*
|
||||
* @param txn The transaction
|
||||
* @param meta The metadata
|
||||
* @param ledgerSequence The sequence
|
||||
* @param date The date of the ledger
|
||||
* @return The delivered amount or std::nullopt if not available
|
||||
*/
|
||||
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
|
||||
);
|
||||
|
||||
} // namespace rpc
|
||||
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
* @brief A factory function that creates the work queue based on a config.
|
||||
*
|
||||
* @param config The Clio config to use
|
||||
* @return The work queue
|
||||
*/
|
||||
static WorkQueue
|
||||
make_WorkQueue(util::Config const& config)
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
~AnyHandler() = default;
|
||||
AnyHandler(AnyHandler const& other) : pimpl_{other.pimpl_->clone()}
|
||||
{
|
||||
@@ -67,6 +68,7 @@ public:
|
||||
AnyHandler(AnyHandler&&) = default;
|
||||
AnyHandler&
|
||||
operator=(AnyHandler&&) = default;
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Process incoming JSON by the stored handler
|
||||
|
||||
@@ -33,12 +33,30 @@ class HandlerProvider {
|
||||
public:
|
||||
virtual ~HandlerProvider() = default;
|
||||
|
||||
/**
|
||||
* @brief Check if the provider contains a handler for a given method
|
||||
*
|
||||
* @param command The method to check for
|
||||
* @return true if the provider contains a handler for the method, false otherwise
|
||||
*/
|
||||
virtual bool
|
||||
contains(std::string const& method) const = 0;
|
||||
contains(std::string const& command) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the handler for a given method
|
||||
*
|
||||
* @param command The method to get the handler for
|
||||
* @return The handler for the method, or std::nullopt if the method is not found
|
||||
*/
|
||||
virtual std::optional<AnyHandler>
|
||||
getHandler(std::string const& command) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Check if a given method is Clio-only
|
||||
*
|
||||
* @param command The method to check
|
||||
* @return true if the method is Clio-only, false otherwise
|
||||
*/
|
||||
virtual bool
|
||||
isClioOnly(std::string const& command) const = 0;
|
||||
};
|
||||
|
||||
@@ -34,12 +34,20 @@ namespace rpc {
|
||||
struct JsonBool {
|
||||
bool value = false;
|
||||
|
||||
/** @cond */
|
||||
operator bool() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
/** @endcond */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON value to a JsonBool
|
||||
*
|
||||
* @param jsonValue The JSON value to convert
|
||||
* @return The converted JsonBool
|
||||
*/
|
||||
inline JsonBool
|
||||
tag_invoke(boost::json::value_to_tag<JsonBool> const&, boost::json::value const& jsonValue)
|
||||
{
|
||||
|
||||
@@ -168,6 +168,9 @@ public:
|
||||
/**
|
||||
* @brief Constructs a validator that calls the given validator `req` and returns a custom error `err` in case `req`
|
||||
* fails.
|
||||
*
|
||||
* @param req The requirement to validate against
|
||||
* @param err The custom error to return in case `req` fails
|
||||
*/
|
||||
WithCustomError(SomeRequirement req, Status err) : requirement{std::move(req)}, error{std::move(err)}
|
||||
{
|
||||
|
||||
@@ -106,12 +106,22 @@ struct AccountCursor {
|
||||
ripple::uint256 index;
|
||||
std::uint32_t hint{};
|
||||
|
||||
/**
|
||||
* @brief Convert the cursor to a string
|
||||
*
|
||||
* @return The string representation of the cursor
|
||||
*/
|
||||
std::string
|
||||
toString() const
|
||||
{
|
||||
return ripple::strHex(index) + "," + std::to_string(hint);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if the cursor is non-zero
|
||||
*
|
||||
* @return true if the cursor is non-zero, false otherwise
|
||||
*/
|
||||
bool
|
||||
isNonZero() const
|
||||
{
|
||||
@@ -119,6 +129,13 @@ struct AccountCursor {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Convert an empty output to a JSON object
|
||||
*
|
||||
* @note Always generates empty JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
*/
|
||||
inline void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, VoidOutput const&)
|
||||
{
|
||||
|
||||
@@ -81,6 +81,13 @@ template <typename Expected>
|
||||
* @brief A validator that simply requires a field to be present.
|
||||
*/
|
||||
struct Required final {
|
||||
/**
|
||||
* @brief Verify that the JSON value is present and not null.
|
||||
*
|
||||
* @param value The JSON value representing the outer object
|
||||
* @param key The key used to retrieve the tested value from the outer object
|
||||
* @return An error if validation failed; otherwise no error is returned
|
||||
*/
|
||||
[[nodiscard]] static MaybeError
|
||||
verify(boost::json::value const& value, std::string_view key);
|
||||
};
|
||||
@@ -386,7 +393,7 @@ public:
|
||||
*
|
||||
* @param begin,end the range to copy the elements from
|
||||
*/
|
||||
template <class InputIt>
|
||||
template <typename InputIt>
|
||||
explicit OneOf(InputIt begin, InputIt end) : options_{begin, end}
|
||||
{
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
);
|
||||
|
||||
bool
|
||||
contains(std::string const& method) const override;
|
||||
contains(std::string const& command) const override;
|
||||
|
||||
std::optional<AnyHandler>
|
||||
getHandler(std::string const& command) const override;
|
||||
|
||||
@@ -44,6 +44,9 @@ class AMMInfoHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
// todo: use better type than json types
|
||||
boost::json::value amount1;
|
||||
@@ -61,6 +64,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<ripple::AccountID> accountID;
|
||||
std::optional<ripple::AccountID> ammAccount;
|
||||
@@ -72,20 +78,50 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AMMInfoHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AMMInfoHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion);
|
||||
|
||||
/**
|
||||
* @brief Process the AMMInfo command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -55,7 +55,11 @@ public:
|
||||
static constexpr auto LIMIT_MAX = 400;
|
||||
static constexpr auto LIMIT_DEFAULT = 200;
|
||||
|
||||
// type align with SField.h
|
||||
/**
|
||||
* @brief A struct to hold data for one channel response
|
||||
*
|
||||
* @note type aligned with SField.h
|
||||
*/
|
||||
struct ChannelResponse {
|
||||
std::string channelID;
|
||||
std::string account;
|
||||
@@ -71,6 +75,9 @@ public:
|
||||
std::optional<uint32_t> destinationTag;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::vector<ChannelResponse> channels;
|
||||
std::string account;
|
||||
@@ -82,6 +89,9 @@ public:
|
||||
std::optional<std::string> marker;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
std::optional<std::string> destinationAccount;
|
||||
@@ -93,11 +103,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountChannelsHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AccountChannelsHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -116,6 +137,13 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the AccountChannels command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
@@ -123,12 +151,30 @@ private:
|
||||
static void
|
||||
addChannel(std::vector<ChannelResponse>& jsonChannels, ripple::SLE const& channelSle);
|
||||
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
|
||||
/**
|
||||
* @brief Convert the ChannelResponse to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param channel The channel response to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, ChannelResponse const& channel);
|
||||
};
|
||||
|
||||
@@ -48,6 +48,9 @@ class AccountCurrenciesHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string ledgerHash;
|
||||
uint32_t ledgerIndex{};
|
||||
@@ -57,6 +60,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
std::optional<std::string> ledgerHash;
|
||||
@@ -65,11 +71,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountCurrenciesHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AccountCurrenciesHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -82,13 +99,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the AccountCurrencies command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -49,6 +49,9 @@ class AccountInfoHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
uint32_t ledgerIndex;
|
||||
std::string ledgerHash;
|
||||
@@ -60,6 +63,17 @@ public:
|
||||
// validated should be sent via framework
|
||||
bool validated = true;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Output object
|
||||
*
|
||||
* @param ledgerId The ledger index
|
||||
* @param ledgerHash The ledger hash
|
||||
* @param sle The account data
|
||||
* @param isDisallowIncomingEnabled Whether disallow incoming is enabled
|
||||
* @param isClawbackEnabled Whether clawback is enabled
|
||||
* @param version The API version
|
||||
* @param signerLists The signer lists
|
||||
*/
|
||||
Output(
|
||||
uint32_t ledgerId,
|
||||
std::string ledgerHash,
|
||||
@@ -80,8 +94,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// "queue" is not available in Reporting mode
|
||||
// "ident" is deprecated, keep it for now, in line with rippled
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*
|
||||
* `queue` is not available in Reporting mode
|
||||
* `ident` is deprecated, keep it for now, in line with rippled
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::string> account;
|
||||
std::optional<std::string> ident;
|
||||
@@ -92,10 +110,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountInfoHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AccountInfoHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -111,13 +140,32 @@ public:
|
||||
return apiVersion == 1 ? rpcSpecV1 : rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the AccountInfo command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -57,6 +57,9 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 400;
|
||||
static auto constexpr LIMIT_DEFAULT = 200;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold data for one line response
|
||||
*/
|
||||
struct LineResponse {
|
||||
std::string account;
|
||||
std::string balance;
|
||||
@@ -73,6 +76,9 @@ public:
|
||||
std::optional<bool> freezePeer;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string account;
|
||||
std::vector<LineResponse> lines;
|
||||
@@ -83,6 +89,9 @@ public:
|
||||
uint32_t limit{};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
std::optional<std::string> ledgerHash;
|
||||
@@ -96,10 +105,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountLinesHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AccountLinesHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -121,6 +141,13 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the AccountLines command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
@@ -134,12 +161,30 @@ private:
|
||||
);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
|
||||
/**
|
||||
* @brief Convert the LineResponse to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param line The line response to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, LineResponse const& line);
|
||||
};
|
||||
|
||||
@@ -51,6 +51,9 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 400;
|
||||
static auto constexpr LIMIT_DEFAULT = 100;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string account;
|
||||
std::string ledgerHash;
|
||||
@@ -62,6 +65,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
std::optional<std::string> ledgerHash;
|
||||
@@ -72,10 +78,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountNFTsHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AccountNFTsHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -93,13 +110,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the AccountNFTs command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -64,6 +64,9 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 400;
|
||||
static auto constexpr LIMIT_DEFAULT = 200;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string account;
|
||||
std::string ledgerHash;
|
||||
@@ -74,6 +77,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
std::optional<std::string> ledgerHash;
|
||||
@@ -86,11 +92,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountObjectsHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AccountObjectsHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -113,13 +130,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the AccountObjects command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -53,6 +53,9 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 400;
|
||||
static auto constexpr LIMIT_DEFAULT = 200;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold data for one offer response
|
||||
*/
|
||||
struct Offer {
|
||||
uint32_t flags{};
|
||||
uint32_t seq{};
|
||||
@@ -62,6 +65,9 @@ public:
|
||||
std::optional<uint32_t> expiration;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string account;
|
||||
std::string ledgerHash;
|
||||
@@ -72,6 +78,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
std::optional<std::string> ledgerHash;
|
||||
@@ -82,11 +91,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountOffersHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AccountOffersHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -104,6 +124,13 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the AccountOffers command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
@@ -111,12 +138,30 @@ private:
|
||||
static void
|
||||
addOffer(std::vector<Offer>& offers, ripple::SLE const& offerSle);
|
||||
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
|
||||
/**
|
||||
* @brief Convert the Offer to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param offer The offer to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Offer const& offer);
|
||||
};
|
||||
|
||||
@@ -61,11 +61,17 @@ public:
|
||||
static auto constexpr LIMIT_MIN = 1;
|
||||
static auto constexpr LIMIT_DEFAULT = 200;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the marker data
|
||||
*/
|
||||
struct Marker {
|
||||
uint32_t ledger;
|
||||
uint32_t seq;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string account;
|
||||
uint32_t ledgerIndexMin{0};
|
||||
@@ -78,6 +84,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
// You must use at least one of the following fields in your request:
|
||||
@@ -96,10 +105,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new AccountTxHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
AccountTxHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -142,16 +162,41 @@ public:
|
||||
return apiVersion == 1 ? rpcSpecForV1 : rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the AccountTx command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
|
||||
/**
|
||||
* @brief Convert the Marker to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param marker The marker to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Marker const& marker);
|
||||
};
|
||||
|
||||
@@ -47,6 +47,9 @@ class BookChangesHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string ledgerHash;
|
||||
uint32_t ledgerIndex{};
|
||||
@@ -55,7 +58,11 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
// Clio does not implement deletion_blockers_only
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*
|
||||
* @note Clio does not implement `deletion_blockers_only`
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::string> ledgerHash;
|
||||
std::optional<uint32_t> ledgerIndex;
|
||||
@@ -63,10 +70,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new BookChangesHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
BookChangesHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -78,13 +96,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the BookChanges command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -57,6 +57,9 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 100;
|
||||
static auto constexpr LIMIT_DEFAULT = 60;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string ledgerHash;
|
||||
uint32_t ledgerIndex;
|
||||
@@ -64,8 +67,12 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
// the taker is not really used in both clio and rippled, both of them return all the offers regardless the funding
|
||||
// status
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*
|
||||
* @note The taker is not really used in both Clio and `rippled`, both of them return all the offers regardless of
|
||||
* the funding status
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::string> ledgerHash;
|
||||
std::optional<uint32_t> ledgerIndex;
|
||||
@@ -80,10 +87,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new BookOffersHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
BookOffersHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -124,13 +142,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the BookOffers command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -37,7 +37,9 @@
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief The deposit_authorized command indicates whether one account is authorized to send payments directly to
|
||||
* @brief Handles the `deposit_authorized` command
|
||||
*
|
||||
* The deposit_authorized command indicates whether one account is authorized to send payments directly to
|
||||
* another. See Deposit Authorization for information on how to require authorization to deliver money to your account.
|
||||
*
|
||||
* For more details see: https://xrpl.org/deposit_authorized.html
|
||||
@@ -48,6 +50,9 @@ class DepositAuthorizedHandler {
|
||||
|
||||
public:
|
||||
// Note: `ledger_current_index` is omitted because it only makes sense for rippled
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
bool depositAuthorized = true;
|
||||
std::string sourceAccount;
|
||||
@@ -58,6 +63,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string sourceAccount;
|
||||
std::string destinationAccount;
|
||||
@@ -67,11 +75,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new DepositAuthorizedHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
DepositAuthorizedHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -85,13 +104,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the DepositAuthorized command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief Handles the `gateway_balances` command
|
||||
*
|
||||
* The gateway_balances command calculates the total balances issued by a given account, optionally excluding amounts
|
||||
* held by operational addresses.
|
||||
*
|
||||
@@ -58,6 +60,9 @@ class GatewayBalancesHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string ledgerHash;
|
||||
uint32_t ledgerIndex;
|
||||
@@ -71,6 +76,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
std::set<ripple::AccountID> hotWallets;
|
||||
@@ -80,11 +88,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new GatewayBalancesHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
GatewayBalancesHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -128,13 +147,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the GatewayBalances command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -46,6 +46,9 @@ class LedgerHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
uint32_t ledgerIndex{};
|
||||
std::string ledgerHash;
|
||||
@@ -54,9 +57,19 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
// clio not support : accounts/full/owner_finds/queue/type
|
||||
// clio will throw error when accounts/full/owner_funds/queue is set to true
|
||||
// https://github.com/XRPLF/clio/issues/603
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*
|
||||
* Clio does not support:
|
||||
* - accounts
|
||||
* - full
|
||||
* - owner_finds
|
||||
* - queue
|
||||
* - type
|
||||
*
|
||||
* Clio will throw an error when any of `accounts`/`full`/`owner_funds`/`queue` are set to `true`
|
||||
* @see https://github.com/XRPLF/clio/issues/603
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::string> ledgerHash;
|
||||
std::optional<uint32_t> ledgerIndex;
|
||||
@@ -69,10 +82,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new LedgerHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
LedgerHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -92,13 +116,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the Ledger command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -62,6 +62,9 @@ public:
|
||||
static uint32_t constexpr LIMITBINARY = 2048;
|
||||
static uint32_t constexpr LIMITJSON = 256;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
uint32_t ledgerIndex{};
|
||||
std::string ledgerHash;
|
||||
@@ -73,9 +76,12 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
// TODO: Clio does not implement "type" filter
|
||||
// outOfOrder only for clio, there is no document, traverse via seq diff
|
||||
// outOfOrder implementation is copied from old rpc handler
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*
|
||||
* @note `outOfOrder` is only for Clio, there is no document, traverse via seq diff (outOfOrder implementation is
|
||||
* copied from old rpc handler)
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::string> ledgerHash;
|
||||
std::optional<uint32_t> ledgerIndex;
|
||||
@@ -89,10 +95,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new LedgerDataHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
LedgerDataHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -116,13 +133,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the LedgerData command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -58,6 +58,9 @@ class LedgerEntryHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string index;
|
||||
uint32_t ledgerIndex;
|
||||
@@ -67,6 +70,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::string> ledgerHash;
|
||||
std::optional<uint32_t> ledgerIndex;
|
||||
@@ -96,10 +102,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new LedgerEntryHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
LedgerEntryHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -266,6 +283,13 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the LedgerEntry command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
@@ -275,9 +299,21 @@ private:
|
||||
static std::variant<ripple::uint256, Status>
|
||||
composeKeyFromDirectory(boost::json::object const& directory) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -40,20 +40,40 @@ class LedgerRangeHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
data::LedgerRange range;
|
||||
};
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new LedgerRangeHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
LedgerRangeHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the LedgerRange command
|
||||
*
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
};
|
||||
|
||||
@@ -34,11 +34,23 @@ namespace rpc {
|
||||
*/
|
||||
class NFTBuyOffersHandler : public NFTOffersHandlerBase {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new NFTBuyOffersHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
NFTBuyOffersHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: NFTOffersHandlerBase(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the NFTBuyOffers command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
};
|
||||
|
||||
@@ -57,12 +57,18 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 100;
|
||||
static auto constexpr LIMIT_DEFAULT = 50;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the marker data
|
||||
*/
|
||||
// TODO: this marker is same as account_tx, reuse in future
|
||||
struct Marker {
|
||||
uint32_t ledger;
|
||||
uint32_t seq;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string nftID;
|
||||
uint32_t ledgerIndexMin{0};
|
||||
@@ -75,6 +81,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string nftID;
|
||||
// You must use at least one of the following fields in your request:
|
||||
@@ -91,10 +100,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new NFTHistoryHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
NFTHistoryHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -123,16 +143,41 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the NFTHistory command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
|
||||
/**
|
||||
* @brief Convert the Marker to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param marker The marker to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Marker const& marker);
|
||||
};
|
||||
|
||||
@@ -45,6 +45,9 @@ class NFTInfoHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string nftID;
|
||||
uint32_t ledgerIndex;
|
||||
@@ -62,6 +65,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string nftID;
|
||||
std::optional<std::string> ledgerHash;
|
||||
@@ -70,10 +76,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new NFTInfoHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
NFTInfoHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -86,13 +103,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the NFTInfo command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief Contains common functionality for handling the `nft_offers` command
|
||||
*/
|
||||
class NFTOffersHandlerBase {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
@@ -50,6 +53,9 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 500;
|
||||
static auto constexpr LIMIT_DEFAULT = 250;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string nftID = {};
|
||||
std::vector<ripple::SLE> offers = {};
|
||||
@@ -60,6 +66,9 @@ public:
|
||||
std::optional<std::string> marker = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string nftID;
|
||||
std::optional<std::string> ledgerHash;
|
||||
@@ -70,11 +79,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new NFTOffersHandlerBase object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
NFTOffersHandlerBase(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -93,6 +113,15 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Iterate the NFT offer directory
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param tokenID The tokenID of the NFT
|
||||
* @param directory The directory to iterate
|
||||
* @param yield The coroutine context
|
||||
* @return The result of the iteration
|
||||
*/
|
||||
Result
|
||||
iterateOfferDirectory(
|
||||
Input input,
|
||||
@@ -102,9 +131,21 @@ protected:
|
||||
) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -34,11 +34,23 @@ namespace rpc {
|
||||
*/
|
||||
class NFTSellOffersHandler : public NFTOffersHandlerBase {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new NFTSellOffersHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
NFTSellOffersHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: NFTOffersHandlerBase(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the NFTSellOffers command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
};
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
#include <string>
|
||||
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief Handler for the `nfts_by_issuer` command
|
||||
*/
|
||||
class NFTsByIssuerHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
@@ -45,6 +49,9 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 100;
|
||||
static auto constexpr LIMIT_DEFAULT = 50;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
boost::json::array nfts;
|
||||
uint32_t ledgerIndex;
|
||||
@@ -55,6 +62,9 @@ public:
|
||||
std::optional<std::string> marker;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string issuer;
|
||||
std::optional<uint32_t> nftTaxon;
|
||||
@@ -66,10 +76,21 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new NFTsByIssuerHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
NFTsByIssuerHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend) : sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -88,13 +109,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the NFTsByIssuer command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief The noripple_check command provides a quick way to check the status of the Default Ripple field for an account
|
||||
* @brief Handles the `noripple_check` command
|
||||
*
|
||||
* The noripple_check command provides a quick way to check the status of the Default Ripple field for an account
|
||||
* and the No Ripple flag of its trust lines, compared with the recommended settings.
|
||||
*
|
||||
* For more details see: https://xrpl.org/noripple_check.html
|
||||
@@ -57,6 +59,9 @@ public:
|
||||
static auto constexpr LIMIT_MAX = 500;
|
||||
static auto constexpr LIMIT_DEFAULT = 300;
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string ledgerHash;
|
||||
uint32_t ledgerIndex{};
|
||||
@@ -66,6 +71,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string account;
|
||||
bool roleGateway = false;
|
||||
@@ -77,11 +85,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new NoRippleCheckHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
NoRippleCheckHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -110,13 +129,32 @@ public:
|
||||
return apiVersion == 1 ? rpcSpecV1 : rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the NoRippleCheck command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -33,6 +33,12 @@ public:
|
||||
using Output = VoidOutput;
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Process the Ping command
|
||||
*
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
static Result
|
||||
process([[maybe_unused]] Context const& ctx)
|
||||
{
|
||||
|
||||
@@ -36,16 +36,31 @@ namespace rpc {
|
||||
*/
|
||||
class RandomHandler {
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::string random;
|
||||
};
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Process the Random command
|
||||
*
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
static Result
|
||||
process(Context const& ctx);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
};
|
||||
|
||||
@@ -60,6 +60,14 @@ class Counters;
|
||||
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief Contains common functionality for handling the `server_info` command
|
||||
*
|
||||
* @tparam SubscriptionManagerType The type of the subscription manager
|
||||
* @tparam LoadBalancerType The type of the load balancer
|
||||
* @tparam ETLServiceType The type of the ETL service
|
||||
* @tparam CountersType The type of the counters
|
||||
*/
|
||||
template <typename SubscriptionManagerType, typename LoadBalancerType, typename ETLServiceType, typename CountersType>
|
||||
class BaseServerInfoHandler {
|
||||
static constexpr auto BACKEND_COUNTERS_KEY = "backend_counters";
|
||||
@@ -71,10 +79,16 @@ class BaseServerInfoHandler {
|
||||
std::reference_wrapper<CountersType const> counters_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
bool backendCounters = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the admin section of the output
|
||||
*/
|
||||
struct AdminSection {
|
||||
boost::json::object counters = {};
|
||||
std::optional<boost::json::object> backendCounters = {};
|
||||
@@ -82,6 +96,9 @@ public:
|
||||
boost::json::object etl = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the validated ledger section of the output
|
||||
*/
|
||||
struct ValidatedLedgerSection {
|
||||
uint32_t age = 0;
|
||||
std::string hash = {};
|
||||
@@ -89,6 +106,9 @@ public:
|
||||
std::optional<ripple::Fees> fees = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the cache section of the output
|
||||
*/
|
||||
struct CacheSection {
|
||||
std::size_t size = 0;
|
||||
bool isFull = false;
|
||||
@@ -97,6 +117,9 @@ public:
|
||||
float successorHitRate = 1.0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the info section of the output
|
||||
*/
|
||||
struct InfoSection {
|
||||
std::optional<AdminSection> adminSection = std::nullopt;
|
||||
std::string completeLedgers = {};
|
||||
@@ -111,6 +134,9 @@ public:
|
||||
bool isAmendmentBlocked = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
InfoSection info = {};
|
||||
|
||||
@@ -120,6 +146,15 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new BaseServerInfoHandler object
|
||||
*
|
||||
* @param backend The backend to use
|
||||
* @param subscriptions The subscription manager to use
|
||||
* @param balancer The load balancer to use
|
||||
* @param etl The ETL service to use
|
||||
* @param counters The counters to use
|
||||
*/
|
||||
BaseServerInfoHandler(
|
||||
std::shared_ptr<BackendInterface> const& backend,
|
||||
std::shared_ptr<SubscriptionManagerType> const& subscriptions,
|
||||
@@ -135,6 +170,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -142,6 +183,13 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the ServerInfo command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const
|
||||
{
|
||||
|
||||
@@ -52,12 +52,21 @@ class SubscriptionManager;
|
||||
} // namespace feed
|
||||
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief Contains functionality for handling the `subscribe` command
|
||||
*
|
||||
* @tparam SubscriptionManagerType The type of the subscription manager to use
|
||||
*/
|
||||
template <typename SubscriptionManagerType>
|
||||
class BaseSubscribeHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
std::shared_ptr<SubscriptionManagerType> subscriptions_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
// response of stream "ledger"
|
||||
// TODO: use better type than json, this type will be used in the stream as well
|
||||
@@ -71,6 +80,9 @@ public:
|
||||
std::optional<boost::json::array> bids;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the data for one order book
|
||||
*/
|
||||
struct OrderBook {
|
||||
ripple::Book book;
|
||||
std::optional<std::string> taker;
|
||||
@@ -78,6 +90,9 @@ public:
|
||||
bool both = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::vector<std::string>> accounts;
|
||||
std::optional<std::vector<std::string>> streams;
|
||||
@@ -87,6 +102,12 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new BaseSubscribeHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
* @param subscriptions The subscription manager to use
|
||||
*/
|
||||
BaseSubscribeHandler(
|
||||
std::shared_ptr<BackendInterface> const& sharedPtrBackend,
|
||||
std::shared_ptr<SubscriptionManagerType> const& subscriptions
|
||||
@@ -95,6 +116,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion) const
|
||||
{
|
||||
@@ -141,6 +168,13 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the Subscribe command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const
|
||||
{
|
||||
|
||||
@@ -49,6 +49,9 @@ class TransactionEntryHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
std::optional<ripple::LedgerHeader> ledgerHeader;
|
||||
// TODO: use a better type for this
|
||||
@@ -59,6 +62,9 @@ public:
|
||||
uint32_t apiVersion;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::string txHash;
|
||||
std::optional<std::string> ledgerHash;
|
||||
@@ -67,11 +73,22 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Transaction Entry Handler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
*/
|
||||
TransactionEntryHandler(std::shared_ptr<BackendInterface> const& sharedPtrBackend)
|
||||
: sharedPtrBackend_(sharedPtrBackend)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion)
|
||||
{
|
||||
@@ -86,13 +103,32 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the transaction_entry command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the command
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Convert the Output to a JSON object
|
||||
*
|
||||
* @param [out] jv The JSON object to convert to
|
||||
* @param output The output to convert
|
||||
*/
|
||||
friend void
|
||||
tag_invoke(boost::json::value_from_tag, boost::json::value& jv, Output const& output);
|
||||
|
||||
/**
|
||||
* @brief Convert a JSON object to Input type
|
||||
*
|
||||
* @param jv The JSON object to convert
|
||||
* @return Input parsed from the JSON object
|
||||
*/
|
||||
friend Input
|
||||
tag_invoke(boost::json::value_to_tag<Input>, boost::json::value const& jv);
|
||||
};
|
||||
|
||||
@@ -50,12 +50,20 @@
|
||||
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief Contains common functionality for handling the `tx` command
|
||||
*
|
||||
* @tparam ETLServiceType The type of the ETL service to use
|
||||
*/
|
||||
template <typename ETLServiceType>
|
||||
class BaseTxHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
std::shared_ptr<ETLServiceType const> etl_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
uint32_t date = 0u;
|
||||
std::string hash{};
|
||||
@@ -70,6 +78,9 @@ public:
|
||||
bool validated = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::string> transaction;
|
||||
std::optional<std::string> ctid;
|
||||
@@ -80,6 +91,12 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new BaseTxHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
* @param etl The ETL service to use
|
||||
*/
|
||||
BaseTxHandler(
|
||||
std::shared_ptr<BackendInterface> const& sharedPtrBackend,
|
||||
std::shared_ptr<ETLServiceType const> const& etl
|
||||
@@ -88,6 +105,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
static RpcSpecConstRef
|
||||
spec(uint32_t apiVersion)
|
||||
{
|
||||
@@ -103,6 +126,13 @@ public:
|
||||
return apiVersion == 1 ? rpcSpecForV1 : rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the Tx command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const
|
||||
{
|
||||
|
||||
@@ -48,17 +48,26 @@ class SubscriptionManager;
|
||||
|
||||
namespace rpc {
|
||||
|
||||
/**
|
||||
* @brief Handles the `unsubscribe` command which is used to disconnect a subscriber from a feed
|
||||
*/
|
||||
template <typename SubscriptionManagerType>
|
||||
class BaseUnsubscribeHandler {
|
||||
std::shared_ptr<BackendInterface> sharedPtrBackend_;
|
||||
std::shared_ptr<SubscriptionManagerType> subscriptions_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold one order book
|
||||
*/
|
||||
struct OrderBook {
|
||||
ripple::Book book;
|
||||
bool both = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A struct to hold the input data for the command
|
||||
*/
|
||||
struct Input {
|
||||
std::optional<std::vector<std::string>> accounts;
|
||||
std::optional<std::vector<std::string>> streams;
|
||||
@@ -69,6 +78,12 @@ public:
|
||||
using Output = VoidOutput;
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Construct a new BaseUnsubscribeHandler object
|
||||
*
|
||||
* @param sharedPtrBackend The backend to use
|
||||
* @param subscriptions The subscription manager to use
|
||||
*/
|
||||
BaseUnsubscribeHandler(
|
||||
std::shared_ptr<BackendInterface> const& sharedPtrBackend,
|
||||
std::shared_ptr<SubscriptionManagerType> const& subscriptions
|
||||
@@ -77,6 +92,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the API specification for the command
|
||||
*
|
||||
* @param apiVersion The api version to return the spec for
|
||||
* @return The spec for the given apiVersion
|
||||
*/
|
||||
RpcSpecConstRef
|
||||
spec([[maybe_unused]] uint32_t apiVersion) const
|
||||
{
|
||||
@@ -110,6 +131,13 @@ public:
|
||||
return rpcSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process the Unsubscribe command
|
||||
*
|
||||
* @param input The input data for the command
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the operation
|
||||
*/
|
||||
Result
|
||||
process(Input input, Context const& ctx) const
|
||||
{
|
||||
|
||||
@@ -39,12 +39,20 @@ class VersionHandler {
|
||||
rpc::impl::ProductionAPIVersionParser apiVersionParser_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief A struct to hold the output data of the command
|
||||
*/
|
||||
struct Output {
|
||||
uint32_t minVersion;
|
||||
uint32_t maxVersion;
|
||||
uint32_t currVersion;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Construct a new Version Handler object
|
||||
*
|
||||
* @param config The configuration to use
|
||||
*/
|
||||
explicit VersionHandler(util::Config const& config)
|
||||
: apiVersionParser_(
|
||||
config.valueOr("default", API_VERSION_DEFAULT),
|
||||
@@ -56,6 +64,12 @@ public:
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
|
||||
/**
|
||||
* @brief Process the version command
|
||||
*
|
||||
* @param ctx The context of the request
|
||||
* @return The result of the command
|
||||
*/
|
||||
Result
|
||||
process([[maybe_unused]] Context const& ctx) const
|
||||
{
|
||||
|
||||
@@ -31,6 +31,17 @@
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* @brief Assert that a condition is true
|
||||
* @note Calls std::exit if the condition is false
|
||||
*
|
||||
* @tparam Args The format argument types
|
||||
* @param location The location of the assertion
|
||||
* @param expression The expression to assert
|
||||
* @param condition The condition to assert
|
||||
* @param format The format string
|
||||
* @param args The format arguments
|
||||
*/
|
||||
template <typename... Args>
|
||||
constexpr void
|
||||
assertImpl(
|
||||
|
||||
@@ -35,6 +35,12 @@ public:
|
||||
using ValueType = NumberType;
|
||||
|
||||
Atomic() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Atomic object
|
||||
*
|
||||
* @param value The initial value
|
||||
*/
|
||||
Atomic(ValueType const value) : value_(value)
|
||||
{
|
||||
}
|
||||
@@ -86,7 +92,7 @@ public:
|
||||
/**
|
||||
* @brief Get the current value
|
||||
*
|
||||
* @return ValueType The current value
|
||||
* @return The current value
|
||||
*/
|
||||
ValueType
|
||||
value() const
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* @brief Iterate over a container in batches
|
||||
*
|
||||
* @param container The container to iterate over
|
||||
* @param batchSize The size of each batch
|
||||
* @param fn The function to call for each batch
|
||||
*/
|
||||
void
|
||||
forEachBatch(std::ranges::forward_range auto&& container, std::size_t batchSize, auto&& fn)
|
||||
{
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* @brief Specifies a number type
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeNumberType = std::is_arithmetic_v<T> && !std::is_same_v<T, bool> && !std::is_const_v<T>;
|
||||
|
||||
|
||||
@@ -53,6 +53,9 @@ namespace util {
|
||||
The implementation is entirely based on boost::outcome_v2::result.
|
||||
*/
|
||||
|
||||
// Documentation is not needed - will be removed as soon as `std::expected` available
|
||||
/** @cond */
|
||||
|
||||
// Exception thrown by an invalid access to Expected.
|
||||
struct bad_expected_access : public std::runtime_error {
|
||||
bad_expected_access() : runtime_error("bad expected access")
|
||||
@@ -64,7 +67,7 @@ namespace impl {
|
||||
|
||||
// Custom policy for Expected. Always throw on an invalid access.
|
||||
struct throw_policy : public boost::outcome_v2::policy::base {
|
||||
template <class Impl>
|
||||
template <typename Impl>
|
||||
static constexpr void
|
||||
wide_value_check(Impl&& self)
|
||||
{
|
||||
@@ -72,7 +75,7 @@ struct throw_policy : public boost::outcome_v2::policy::base {
|
||||
ripple::Throw<bad_expected_access>();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
template <typename Impl>
|
||||
static constexpr void
|
||||
wide_error_check(Impl&& self)
|
||||
{
|
||||
@@ -80,7 +83,7 @@ struct throw_policy : public boost::outcome_v2::policy::base {
|
||||
ripple::Throw<bad_expected_access>();
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
template <typename Impl>
|
||||
static constexpr void
|
||||
wide_exception_check(Impl&& self)
|
||||
{
|
||||
@@ -93,7 +96,7 @@ struct throw_policy : public boost::outcome_v2::policy::base {
|
||||
|
||||
// Definition of Unexpected, which is used to construct the unexpected
|
||||
// return type of an Expected.
|
||||
template <class E>
|
||||
template <typename E>
|
||||
class Unexpected {
|
||||
public:
|
||||
static_assert(!std::is_same_v<E, void>, "E must not be void");
|
||||
@@ -141,7 +144,7 @@ template <typename E, std::size_t N>
|
||||
Unexpected(E (&)[N]) -> Unexpected<E const*>;
|
||||
|
||||
// Definition of Expected. All of the machinery comes from boost::result.
|
||||
template <class T, class E>
|
||||
template <typename T, typename E>
|
||||
class Expected : private boost::outcome_v2::result<T, E, impl::throw_policy> {
|
||||
using Base = boost::outcome_v2::result<T, E, impl::throw_policy>;
|
||||
|
||||
@@ -243,7 +246,7 @@ private:
|
||||
|
||||
// Specialization of Expected<void, E>. Allows returning either success
|
||||
// (without a value) or the reason for the failure.
|
||||
template <class E>
|
||||
template <typename E>
|
||||
class [[nodiscard]] Expected<void, E> : private boost::outcome_v2::result<void, E, impl::throw_policy> {
|
||||
using Base = boost::outcome_v2::result<void, E, impl::throw_policy>;
|
||||
|
||||
@@ -278,4 +281,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** @endcond */
|
||||
|
||||
} // namespace util
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
*/
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* @brief Convert a string to lowercase
|
||||
*
|
||||
* @param str The string to convert
|
||||
* @return The string in lowercase
|
||||
*/
|
||||
inline std::string
|
||||
toLower(std::string str)
|
||||
{
|
||||
@@ -38,6 +44,12 @@ toLower(std::string str)
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a string to uppercase
|
||||
*
|
||||
* @param str The string to convert
|
||||
* @return The string in uppercase
|
||||
*/
|
||||
inline std::string
|
||||
toUpper(std::string str)
|
||||
{
|
||||
|
||||
@@ -34,19 +34,26 @@
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* @brief Returns a string set of all supported ledger entry types.
|
||||
* @brief Returns a string set of all supported ledger entry types
|
||||
*
|
||||
* @return const& The set of ledger entry types
|
||||
*/
|
||||
std::unordered_set<std::string> const&
|
||||
getLedgerEntryTypeStrs();
|
||||
|
||||
/**
|
||||
* @brief Return the ledger type from a string representation.
|
||||
* @brief Return the ledger type from a string representation
|
||||
*
|
||||
* @param entryName The string representation of the ledger entry type
|
||||
* @return The ledger entry type
|
||||
*/
|
||||
ripple::LedgerEntryType
|
||||
getLedgerEntryTypeFromStr(std::string const& entryName);
|
||||
|
||||
/**
|
||||
* @brief Return the list of ledger entry types which will block the account deletion.
|
||||
* @brief Return the list of ledger entry types which will block the account deletion
|
||||
*
|
||||
* @return const& The list of ledger entry types
|
||||
*/
|
||||
std::vector<ripple::LedgerEntryType> const&
|
||||
getDeletionBlockerLedgerTypes();
|
||||
|
||||
@@ -38,6 +38,7 @@ class Lock {
|
||||
ProtectedDataType& data_;
|
||||
|
||||
public:
|
||||
/** @cond */
|
||||
ProtectedDataType const&
|
||||
operator*() const
|
||||
{
|
||||
@@ -73,6 +74,7 @@ public:
|
||||
{
|
||||
return &data_;
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
private:
|
||||
friend class Mutex<std::remove_const_t<ProtectedDataType>>;
|
||||
@@ -95,10 +97,22 @@ class Mutex {
|
||||
public:
|
||||
Mutex() = default;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Mutex object with the given data
|
||||
*
|
||||
* @param data The data to protect
|
||||
*/
|
||||
explicit Mutex(ProtectedDataType data) : data_(std::move(data))
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Make a new Mutex object with the given data
|
||||
*
|
||||
* @tparam Args The types of the arguments to forward to the constructor of the protected data
|
||||
* @param args The arguments to forward to the constructor of the protected data
|
||||
* @return The Mutex object that protects the given data
|
||||
*/
|
||||
template <typename... Args>
|
||||
static Mutex
|
||||
make(Args&&... args)
|
||||
@@ -106,12 +120,22 @@ public:
|
||||
return Mutex{ProtectedDataType{std::forward<Args>(args)...}};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the mutex and get a lock object allowing access to the protected data
|
||||
*
|
||||
* @return A lock on the mutex and a reference to the protected data
|
||||
*/
|
||||
Lock<ProtectedDataType const>
|
||||
lock() const
|
||||
{
|
||||
return Lock<ProtectedDataType const>{mutex_, data_};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the mutex and get a lock object allowing access to the protected data
|
||||
*
|
||||
* @return A lock on the mutex and a reference to the protected data
|
||||
*/
|
||||
Lock<ProtectedDataType>
|
||||
lock()
|
||||
{
|
||||
|
||||
@@ -38,13 +38,16 @@ class RetryStrategy {
|
||||
std::chrono::steady_clock::duration delay_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Retry Strategy object
|
||||
*
|
||||
* @param delay The initial delay value
|
||||
*/
|
||||
RetryStrategy(std::chrono::steady_clock::duration delay);
|
||||
virtual ~RetryStrategy() = default;
|
||||
|
||||
/**
|
||||
* @brief Get the current delay value
|
||||
*
|
||||
* @return std::chrono::steady_clock::duration
|
||||
* @return The current delay value
|
||||
*/
|
||||
std::chrono::steady_clock::duration
|
||||
getDelay() const;
|
||||
@@ -63,9 +66,7 @@ public:
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Compute the next delay value
|
||||
*
|
||||
* @return std::chrono::steady_clock::duration
|
||||
* @return The next computed delay value
|
||||
*/
|
||||
virtual std::chrono::steady_clock::duration
|
||||
nextDelay() const = 0;
|
||||
@@ -81,6 +82,12 @@ class Retry {
|
||||
size_t attemptNumber_ = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Retry object
|
||||
*
|
||||
* @param strategy The retry strategy to use
|
||||
* @param strand The strand to use for async operations
|
||||
*/
|
||||
Retry(RetryStrategyPtr strategy, boost::asio::strand<boost::asio::io_context::executor_type> strand);
|
||||
~Retry();
|
||||
|
||||
@@ -112,17 +119,13 @@ public:
|
||||
cancel();
|
||||
|
||||
/**
|
||||
* @brief Get the current attempt number
|
||||
*
|
||||
* @return size_t
|
||||
* @return The current attempt number
|
||||
*/
|
||||
size_t
|
||||
attemptNumber() const;
|
||||
|
||||
/**
|
||||
* @brief Get the current delay value
|
||||
*
|
||||
* @return std::chrono::steady_clock::duration
|
||||
* @return The current delay value
|
||||
*/
|
||||
std::chrono::steady_clock::duration
|
||||
delayValue() const;
|
||||
@@ -135,17 +138,18 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a retry mechanism with exponential backoff strategy
|
||||
*
|
||||
* @param delay The initial delay value
|
||||
* @param maxDelay The maximum delay value
|
||||
* @param strand The strand to use for async operations
|
||||
* @return Retry
|
||||
* @brief A retry strategy that retries while exponentially increasing the delay between attempts
|
||||
*/
|
||||
class ExponentialBackoffStrategy : public RetryStrategy {
|
||||
std::chrono::steady_clock::duration maxDelay_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Exponential Backoff Strategy object
|
||||
*
|
||||
* @param delay The initial delay value
|
||||
* @param maxDelay The maximum delay value
|
||||
*/
|
||||
ExponentialBackoffStrategy(std::chrono::steady_clock::duration delay, std::chrono::steady_clock::duration maxDelay);
|
||||
|
||||
private:
|
||||
@@ -159,7 +163,7 @@ private:
|
||||
* @param delay The initial delay value
|
||||
* @param maxDelay The maximum delay value
|
||||
* @param strand The strand to use for async operations
|
||||
* @return Retry
|
||||
* @return The retry object
|
||||
*/
|
||||
Retry
|
||||
makeRetryExponentialBackoff(
|
||||
|
||||
@@ -43,23 +43,43 @@ using SourceLocationType = std::source_location;
|
||||
using SourceLocationType = std::experimental::source_location;
|
||||
|
||||
#else
|
||||
// A workaround for AppleClang that is lacking source_location atm.
|
||||
// TODO: remove this workaround when all compilers catch up to c++20
|
||||
/**
|
||||
* @brief A class representing the source location of the current code
|
||||
*
|
||||
* @note This is a workaround for AppleClang that is lacking source_location atm.
|
||||
* TODO: remove this class when all compilers catch up to c++20
|
||||
*/
|
||||
class SourceLocation {
|
||||
char const* file_;
|
||||
std::size_t line_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Source Location object
|
||||
*
|
||||
* @param file The file name
|
||||
* @param line The line number
|
||||
*/
|
||||
constexpr SourceLocation(char const* file, std::size_t line) : file_{file}, line_{line}
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the file name
|
||||
*
|
||||
* @return The file name
|
||||
*/
|
||||
constexpr std::string_view
|
||||
file_name() const
|
||||
{
|
||||
return file_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the line number
|
||||
*
|
||||
* @return The line number
|
||||
*/
|
||||
constexpr std::size_t
|
||||
line() const
|
||||
{
|
||||
|
||||
@@ -199,7 +199,7 @@ public:
|
||||
/**
|
||||
* @brief Instantiates the TagDecorator specified by `type_` with parent bound from `parent_`.
|
||||
*
|
||||
* @return std::unique_ptr<BaseTagDecorator> An instance of the requested decorator
|
||||
* @return An instance of the requested decorator
|
||||
*/
|
||||
std::unique_ptr<BaseTagDecorator>
|
||||
make() const;
|
||||
@@ -254,6 +254,7 @@ protected:
|
||||
public:
|
||||
virtual ~Taggable() = default;
|
||||
Taggable(Taggable&&) = default;
|
||||
|
||||
Taggable&
|
||||
operator=(Taggable&&) = default;
|
||||
|
||||
|
||||
@@ -28,6 +28,11 @@
|
||||
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* @brief Get the transaction types in lowercase
|
||||
*
|
||||
* @return The transaction types in lowercase
|
||||
*/
|
||||
[[nodiscard]] std::unordered_set<std::string> const&
|
||||
getTxTypesInLowercase()
|
||||
{
|
||||
|
||||
@@ -41,10 +41,16 @@ namespace util::async {
|
||||
*/
|
||||
class AnyExecutionContext {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new type-erased Execution Context object
|
||||
*
|
||||
* @tparam CtxType The type of the execution context to wrap
|
||||
* @param ctx The execution context to wrap
|
||||
*/
|
||||
template <typename CtxType>
|
||||
requires(not std::is_same_v<std::decay_t<CtxType>, AnyExecutionContext>)
|
||||
/* implicit */ AnyExecutionContext(CtxType&& ctx)
|
||||
: pimpl_{std::make_unique<Model<CtxType>>(std::forward<CtxType>(ctx))}
|
||||
/* implicit */
|
||||
AnyExecutionContext(CtxType&& ctx) : pimpl_{std::make_unique<Model<CtxType>>(std::forward<CtxType>(ctx))}
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,12 @@ namespace util::async {
|
||||
template <typename RetType>
|
||||
class AnyOperation {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new type-erased Operation object
|
||||
*
|
||||
* @tparam OpType The type of the operation to wrap
|
||||
* @param operation The operation to wrap
|
||||
*/
|
||||
template <SomeOperation OpType>
|
||||
requires std::is_same_v<std::decay_t<OpType>, impl::ErasedOperation>
|
||||
/* implicit */ AnyOperation(OpType&& operation) : operation_{std::forward<OpType>(operation)}
|
||||
@@ -60,7 +66,10 @@ public:
|
||||
AnyOperation&
|
||||
operator=(AnyOperation&&) = default;
|
||||
|
||||
/** @brief Wait for the operation to complete */
|
||||
/**
|
||||
* @brief Wait for the operation to complete
|
||||
* @note This will block the current thread until the operation is complete
|
||||
*/
|
||||
void
|
||||
wait() noexcept
|
||||
{
|
||||
@@ -81,7 +90,11 @@ public:
|
||||
operation_.cancel();
|
||||
}
|
||||
|
||||
/** @brief Get the result of the operation */
|
||||
/**
|
||||
* @brief Get the result of the operation
|
||||
*
|
||||
* @return The result of the operation
|
||||
*/
|
||||
[[nodiscard]] util::Expected<RetType, ExecutionError>
|
||||
get()
|
||||
{
|
||||
|
||||
@@ -34,6 +34,12 @@ namespace util::async {
|
||||
*/
|
||||
class AnyStopToken {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new type-erased Stop Token object
|
||||
*
|
||||
* @tparam TokenType The type of the stop token to wrap
|
||||
* @param token The stop token to wrap
|
||||
*/
|
||||
template <SomeStopToken TokenType>
|
||||
requires(not std::is_same_v<std::decay_t<TokenType>, AnyStopToken>)
|
||||
/* implicit */ AnyStopToken(TokenType&& token)
|
||||
@@ -41,6 +47,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/** @cond */
|
||||
~AnyStopToken() = default;
|
||||
|
||||
AnyStopToken(AnyStopToken const& other) : pimpl_{other.pimpl_->clone()}
|
||||
@@ -56,25 +63,37 @@ public:
|
||||
}
|
||||
|
||||
AnyStopToken(AnyStopToken&&) = default;
|
||||
|
||||
AnyStopToken&
|
||||
operator=(AnyStopToken&&) = default;
|
||||
/** @endcond */
|
||||
|
||||
/** @returns true if stop is requested; false otherwise */
|
||||
/**
|
||||
* @brief Check if stop is requested
|
||||
*
|
||||
* @returns true if stop is requested; false otherwise
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
isStopRequested() const noexcept
|
||||
{
|
||||
return pimpl_->isStopRequested();
|
||||
}
|
||||
|
||||
/** @returns true if stop is requested; false otherwise */
|
||||
/**
|
||||
* @brief Check if stop is requested
|
||||
*
|
||||
* @returns true if stop is requested; false otherwise
|
||||
*/
|
||||
[[nodiscard]] operator bool() const noexcept
|
||||
{
|
||||
return isStopRequested();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns The underlying boost::asio::yield_context
|
||||
* @brief Get the underlying boost::asio::yield_context
|
||||
* @note ASSERTs if the stop token is not convertible to boost::asio::yield_context
|
||||
*
|
||||
* @returns The underlying boost::asio::yield_context
|
||||
*/
|
||||
[[nodiscard]] operator boost::asio::yield_context() const
|
||||
{
|
||||
|
||||
@@ -39,6 +39,12 @@ namespace util::async {
|
||||
*/
|
||||
class AnyStrand {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Any Strand object
|
||||
*
|
||||
* @tparam StrandType The type of the strand to wrap
|
||||
* @param strand The strand to wrap
|
||||
*/
|
||||
template <typename StrandType>
|
||||
requires(not std::is_same_v<std::decay_t<StrandType>, AnyStrand>)
|
||||
/* implicit */ AnyStrand(StrandType&& strand)
|
||||
@@ -48,7 +54,12 @@ public:
|
||||
|
||||
~AnyStrand() = default;
|
||||
|
||||
/** @brief Execute a function without a stop token on the strand */
|
||||
/**
|
||||
* @brief Execute a function without a stop token on the strand
|
||||
*
|
||||
* @param fn The function to execute
|
||||
* @return The type-erased operation
|
||||
*/
|
||||
[[nodiscard]] auto
|
||||
execute(SomeHandlerWithoutStopToken auto&& fn)
|
||||
{
|
||||
@@ -67,7 +78,12 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
/** @brief Execute a function taking a stop token on the strand */
|
||||
/**
|
||||
* @brief Execute a function taking a stop token on the strand
|
||||
*
|
||||
* @param fn The function to execute
|
||||
* @return The type-erased operation
|
||||
*/
|
||||
[[nodiscard]] auto
|
||||
execute(SomeHandlerWith<AnyStopToken> auto&& fn)
|
||||
{
|
||||
@@ -86,7 +102,13 @@ public:
|
||||
);
|
||||
}
|
||||
|
||||
/** @brief Execute a function taking a stop token on the strand with a timeout */
|
||||
/**
|
||||
* @brief Execute a function taking a stop token on the strand with a timeout
|
||||
*
|
||||
* @param fn The function to execute
|
||||
* @param timeout The timeout for the function
|
||||
* @return The type-erased operation
|
||||
*/
|
||||
[[nodiscard]] auto
|
||||
execute(SomeHandlerWith<AnyStopToken> auto&& fn, SomeStdDuration auto timeout)
|
||||
{
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
namespace util::async {
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for an entity that can be stopped
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeStoppable = requires(T v) {
|
||||
{
|
||||
@@ -34,6 +37,9 @@ concept SomeStoppable = requires(T v) {
|
||||
} -> std::same_as<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for an entity that can be cancelled
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeCancellable = requires(T v) {
|
||||
{
|
||||
@@ -41,6 +47,9 @@ concept SomeCancellable = requires(T v) {
|
||||
} -> std::same_as<void>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for an operation
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeOperation = requires(T v) {
|
||||
{
|
||||
@@ -51,12 +60,21 @@ concept SomeOperation = requires(T v) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for an operation that can be stopped
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeStoppableOperation = SomeOperation<T> and SomeStoppable<T>;
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for an operation that can be cancelled
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeCancellableOperation = SomeOperation<T> and SomeCancellable<T>;
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for an outcome (promise)
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeOutcome = requires(T v) {
|
||||
{
|
||||
@@ -64,6 +82,9 @@ concept SomeOutcome = requires(T v) {
|
||||
} -> SomeOperation;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for a stop token
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeStopToken = requires(T v) {
|
||||
{
|
||||
@@ -71,6 +92,9 @@ concept SomeStopToken = requires(T v) {
|
||||
} -> std::same_as<bool>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for a stop token that internally uses a boost::asio::yield_context
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeYieldStopSource = requires(T v, boost::asio::yield_context yield) {
|
||||
{
|
||||
@@ -78,6 +102,9 @@ concept SomeYieldStopSource = requires(T v, boost::asio::yield_context yield) {
|
||||
} -> SomeStopToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for a simple stop token
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeSimpleStopSource = requires(T v) {
|
||||
{
|
||||
@@ -85,9 +112,15 @@ concept SomeSimpleStopSource = requires(T v) {
|
||||
} -> SomeStopToken;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for a stop source
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeStopSource = (SomeSimpleStopSource<T> or SomeYieldStopSource<T>)and SomeStoppable<T>;
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for a provider of stop sources
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeStopSourceProvider = requires(T v) {
|
||||
{
|
||||
@@ -95,9 +128,15 @@ concept SomeStopSourceProvider = requires(T v) {
|
||||
} -> SomeStopSource;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for an outcome (promise) that can be stopped
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeStoppableOutcome = SomeOutcome<T> and SomeStopSourceProvider<T>;
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for a handler that can be stopped
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeHandlerWithoutStopToken = requires(T fn) {
|
||||
{
|
||||
@@ -105,6 +144,9 @@ concept SomeHandlerWithoutStopToken = requires(T fn) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies the interface for a handler that can be invoked with the specified args
|
||||
*/
|
||||
template <typename T, typename... Args>
|
||||
concept SomeHandlerWith = requires(T fn) {
|
||||
{
|
||||
@@ -112,6 +154,9 @@ concept SomeHandlerWith = requires(T fn) {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies that the type must be some std::duration
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeStdDuration = requires {
|
||||
// Thank you Ed Catmur for this trick.
|
||||
@@ -121,6 +166,9 @@ concept SomeStdDuration = requires {
|
||||
) {}(std::type_identity<T>());
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Specifies that the type must be some std::duration wrapped in an optional
|
||||
*/
|
||||
template <typename T>
|
||||
concept SomeOptStdDuration = requires(T v) { SomeStdDuration<decltype(v.value())>; };
|
||||
|
||||
|
||||
@@ -32,6 +32,12 @@ namespace util::async {
|
||||
* @brief Error channel type for async operation of any ExecutionContext
|
||||
*/
|
||||
struct ExecutionError {
|
||||
/**
|
||||
* @brief Construct a new Execution Error object
|
||||
*
|
||||
* @param tid The thread id
|
||||
* @param msg The error message
|
||||
*/
|
||||
ExecutionError(std::string tid, std::string msg)
|
||||
: message{fmt::format("Thread {} exit with exception: {}", std::move(tid), std::move(msg))}
|
||||
{
|
||||
@@ -44,7 +50,12 @@ struct ExecutionError {
|
||||
ExecutionError&
|
||||
operator=(ExecutionError const&) = default;
|
||||
|
||||
operator char const*() const noexcept
|
||||
/**
|
||||
* @brief Conversion to string
|
||||
*
|
||||
* @return The error message as a C string
|
||||
*/
|
||||
[[nodiscard]] operator char const*() const noexcept
|
||||
{
|
||||
return message.c_str();
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
}
|
||||
|
||||
BasicOperation(BasicOperation&&) = default;
|
||||
|
||||
BasicOperation(BasicOperation const&) = delete;
|
||||
|
||||
[[nodiscard]] auto
|
||||
@@ -136,6 +137,11 @@ class StoppableOperation : public impl::BasicOperation<StoppableOutcome<RetType,
|
||||
StopSourceType stopSource_;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Stoppable Operation object
|
||||
*
|
||||
* @param outcome The outcome to wrap
|
||||
*/
|
||||
explicit StoppableOperation(OutcomeType* outcome)
|
||||
: impl::BasicOperation<OutcomeType>(outcome), stopSource_(outcome->getStopSource())
|
||||
{
|
||||
|
||||
@@ -48,23 +48,34 @@ public:
|
||||
|
||||
BasicOutcome() = default;
|
||||
BasicOutcome(BasicOutcome&&) = default;
|
||||
|
||||
BasicOutcome(BasicOutcome const&) = delete;
|
||||
|
||||
/** @brief Sets the value on the inner `promise` */
|
||||
/**
|
||||
* @brief Sets the value on the inner `promise`
|
||||
*
|
||||
* @param val The value to set
|
||||
*/
|
||||
void
|
||||
setValue(std::convertible_to<RetType> auto&& val)
|
||||
{
|
||||
promise_.set_value(std::forward<decltype(val)>(val));
|
||||
}
|
||||
|
||||
/** @brief Sets the value channel for void operations */
|
||||
/**
|
||||
* @brief Sets the value channel for void operations
|
||||
*/
|
||||
void
|
||||
setValue()
|
||||
{
|
||||
promise_.set_value({});
|
||||
}
|
||||
|
||||
/** @brief Get the `future` for the inner `promise` */
|
||||
/**
|
||||
* @brief Get the `future` for the inner `promise`
|
||||
*
|
||||
* @return The standard future matching the inner `promise`
|
||||
*/
|
||||
[[nodiscard]] std::future<RetType>
|
||||
getStdFuture()
|
||||
{
|
||||
@@ -82,7 +93,11 @@ public:
|
||||
template <typename RetType>
|
||||
class Outcome : public impl::BasicOutcome<RetType> {
|
||||
public:
|
||||
/** @brief Gets the unstoppable operation for this outcome */
|
||||
/**
|
||||
* @brief Gets the unstoppable operation for this outcome
|
||||
*
|
||||
* @return An unstoppable operation for this outcome
|
||||
*/
|
||||
[[nodiscard]] impl::BasicOperation<Outcome>
|
||||
getOperation()
|
||||
{
|
||||
@@ -102,14 +117,22 @@ private:
|
||||
StopSourceType stopSource_;
|
||||
|
||||
public:
|
||||
/** @brief Gets the stoppable operation for this outcome */
|
||||
/**
|
||||
* @brief Gets the stoppable operation for this outcome
|
||||
*
|
||||
* @return A stoppable operation for this outcome
|
||||
*/
|
||||
[[nodiscard]] StoppableOperation<RetType, StopSourceType>
|
||||
getOperation()
|
||||
{
|
||||
return StoppableOperation<RetType, StopSourceType>{this};
|
||||
}
|
||||
|
||||
/** @brief Gets the stop source for this outcome */
|
||||
/**
|
||||
* @brief Gets the stop source for this outcome
|
||||
*
|
||||
* @return The stop source
|
||||
*/
|
||||
[[nodiscard]] StopSourceType&
|
||||
getStopSource()
|
||||
{
|
||||
|
||||
@@ -42,6 +42,16 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
/**
|
||||
* @brief This namespace implements an async framework built on top of execution contexts
|
||||
*
|
||||
* There are multiple execution contexts available, each with its own set of features and trade-offs.
|
||||
*
|
||||
* @see util::async::CoroExecutionContext
|
||||
* @see util::async::PoolExecutionContext
|
||||
* @see util::async::SyncExecutionContext
|
||||
* @see util::async::SystemExecutionContext
|
||||
*/
|
||||
namespace util::async {
|
||||
namespace impl {
|
||||
|
||||
@@ -84,12 +94,17 @@ template <
|
||||
typename ErrorHandlerType = impl::DefaultErrorHandler>
|
||||
class BasicExecutionContext {
|
||||
ContextType context_;
|
||||
|
||||
/** @cond */
|
||||
friend impl::AssociatedExecutorExtractor;
|
||||
/** @endcond */
|
||||
|
||||
public:
|
||||
/** @brief Whether operations on this execution context are noexcept */
|
||||
static constexpr bool isNoexcept = noexcept(ErrorHandlerType::wrap([](auto&) { throw 0; }));
|
||||
|
||||
using ContextHolderType = ContextType;
|
||||
|
||||
using ExecutorType = typename ContextHolderType::Executor;
|
||||
|
||||
template <typename T>
|
||||
@@ -110,7 +125,12 @@ public:
|
||||
|
||||
using Timer = typename ContextHolderType::Timer;
|
||||
|
||||
// note: scheduled operations are always stoppable
|
||||
/**
|
||||
* @brief Create a new execution context with the given number of threads.
|
||||
*
|
||||
* Note: scheduled operations are always stoppable
|
||||
* @tparam T The type of the value returned by operations
|
||||
*/
|
||||
template <typename T>
|
||||
using ScheduledOperation = ScheduledOperation<BasicExecutionContext, StoppableOperation<T>>;
|
||||
|
||||
@@ -290,6 +310,8 @@ public:
|
||||
|
||||
/**
|
||||
* @brief Create a strand for this execution context
|
||||
*
|
||||
* @return A strand for this execution context
|
||||
*/
|
||||
[[nodiscard]] Strand
|
||||
makeStrand()
|
||||
@@ -311,7 +333,7 @@ public:
|
||||
* @brief A Boost.Coroutine-based (asio yield_context) execution context.
|
||||
*
|
||||
* This execution context uses `asio::spawn` to create a coroutine per executed operation.
|
||||
* The stop token that is sent to the lambda to execute is @ref impl::YieldContextStopSource::Token
|
||||
* The stop token that is sent to the lambda to execute is YieldContextStopSource::Token
|
||||
* and is special in the way that each time your code checks `token.isStopRequested()` the coroutine will
|
||||
* be suspended and other work such as timers and/or other operations in the queue will get a chance to run.
|
||||
* This makes it possible to have 1 thread in the execution context and still be able to execute operations AND timers
|
||||
|
||||
@@ -31,6 +31,11 @@ namespace util::async {
|
||||
*/
|
||||
class SystemExecutionContext {
|
||||
public:
|
||||
/**
|
||||
* @brief Get the instance of the system execution context
|
||||
*
|
||||
* @return Reference to the global system execution context
|
||||
*/
|
||||
[[nodiscard]] static auto&
|
||||
instance()
|
||||
{
|
||||
|
||||
@@ -63,8 +63,8 @@ public:
|
||||
|
||||
public:
|
||||
Token(Token const&) = default;
|
||||
Token(Token&&) = default;
|
||||
|
||||
Token(Token&&) = default;
|
||||
[[nodiscard]] bool
|
||||
isStopRequested() const noexcept
|
||||
{
|
||||
@@ -111,8 +111,8 @@ public:
|
||||
|
||||
public:
|
||||
Token(Token const&) = default;
|
||||
Token(Token&&) = default;
|
||||
|
||||
Token(Token&&) = default;
|
||||
[[nodiscard]] bool
|
||||
isStopRequested() const noexcept
|
||||
{
|
||||
|
||||
@@ -60,6 +60,7 @@ public:
|
||||
|
||||
~BasicStrand() = default;
|
||||
BasicStrand(BasicStrand&&) = default;
|
||||
|
||||
BasicStrand(BasicStrand const&) = delete;
|
||||
|
||||
[[nodiscard]] auto
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
}
|
||||
|
||||
SteadyTimer(SteadyTimer&&) = default;
|
||||
|
||||
SteadyTimer(SteadyTimer const&) = delete;
|
||||
|
||||
void
|
||||
|
||||
@@ -37,8 +37,8 @@ class Any {
|
||||
public:
|
||||
Any() = default;
|
||||
Any(Any const&) = default;
|
||||
Any(Any&&) = default;
|
||||
|
||||
Any(Any&&) = default;
|
||||
// note: this needs to be `auto` instead of `std::any` because of a bug in gcc 11.4
|
||||
Any(auto&& v)
|
||||
requires(std::is_same_v<std::decay_t<decltype(v)>, std::any>)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user