mirror of
https://github.com/XRPLF/clio.git
synced 2026-08-23 05:30:51 +00:00
feat: Support filtering txns by mpt_issuance_id (#3153)
Adds an optional `mpt_issuance_id ` field to Account_tx so that users can filter Account transactions if the transaction is involved in a specific `mpt_issuance_id `
This commit is contained in:
@@ -155,6 +155,25 @@ getMPTokenIssuanceTxsFromTx(xrpl::TxMeta const& txMeta, xrpl::STTx const& sttx)
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
referencesMptIssuance(
|
||||
xrpl::TxMeta const& txMeta,
|
||||
xrpl::STTx const& sttx,
|
||||
xrpl::uint192 const& mptIssuanceID
|
||||
)
|
||||
{
|
||||
if (txMeta.getResultTER() == xrpl::tesSUCCESS) {
|
||||
for (auto const& node : txMeta.getNodes()) {
|
||||
if (getMPTokenIssuanceIDFromNode(node) == mptIssuanceID)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
MPTokenIssuanceIDs issuanceIDs;
|
||||
addMPTokenIssuanceIDsFromTx(issuanceIDs, sttx);
|
||||
return issuanceIDs.contains(mptIssuanceID);
|
||||
}
|
||||
|
||||
std::optional<MPTHolderData>
|
||||
getMPTHolderFromObj(std::string const& key, std::string const& blob)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "data/DBHelpers.hpp"
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TxMeta.h>
|
||||
|
||||
@@ -51,4 +52,23 @@ getMPTHolderFromObj(std::string const& key, std::string const& blob);
|
||||
std::vector<MPTokenIssuanceTransactionsData>
|
||||
getMPTokenIssuanceTxsFromTx(xrpl::TxMeta const& txMeta, xrpl::STTx const& sttx);
|
||||
|
||||
/**
|
||||
* @brief Check whether a transaction references a specific MPT issuance.
|
||||
*
|
||||
* @note Scans the same sources as getMPTokenIssuanceTxsFromTx (metadata's affected
|
||||
* MPTokenIssuance/MPToken nodes, and the transaction's own MPTokenIssuanceID/MPT issue fields), but
|
||||
* exits as soon as a match is found instead of collecting every distinct issuance touched.
|
||||
*
|
||||
* @param txMeta Transaction metadata.
|
||||
* @param sttx The transaction.
|
||||
* @param mptIssuanceID The MPT issuance to check for.
|
||||
* @return true if the transaction references mptIssuanceID.
|
||||
*/
|
||||
bool
|
||||
referencesMptIssuance(
|
||||
xrpl::TxMeta const& txMeta,
|
||||
xrpl::STTx const& sttx,
|
||||
xrpl::uint192 const& mptIssuanceID
|
||||
);
|
||||
|
||||
} // namespace etl
|
||||
|
||||
@@ -58,4 +58,4 @@ target_sources(
|
||||
handlers/VaultInfo.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(clio_rpc PUBLIC clio_util clio_data)
|
||||
target_link_libraries(clio_rpc PUBLIC clio_util clio_data clio_etl)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "rpc/handlers/AccountTx.hpp"
|
||||
|
||||
#include "data/Types.hpp"
|
||||
#include "etl/MPTHelpers.hpp"
|
||||
#include "rpc/Errors.hpp"
|
||||
#include "rpc/JS.hpp"
|
||||
#include "rpc/RPCHelpers.hpp"
|
||||
@@ -16,6 +17,7 @@
|
||||
#include <boost/json/value.hpp>
|
||||
#include <boost/json/value_from.hpp>
|
||||
#include <boost/json/value_to.hpp>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/basics/strHex.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
@@ -128,6 +130,10 @@ AccountTxHandler::process(AccountTxHandler::Input const& input, Context const& c
|
||||
if (retCursor)
|
||||
response.marker = {.ledger = retCursor->ledgerSequence, .seq = retCursor->transactionIndex};
|
||||
|
||||
std::optional<xrpl::uint192> mptIssuanceFilter;
|
||||
if (input.mptIssuanceId)
|
||||
mptIssuanceFilter = xrpl::uint192{input.mptIssuanceId->c_str()};
|
||||
|
||||
for (auto const& txnPlusMeta : blobs) {
|
||||
// over the range
|
||||
if ((txnPlusMeta.ledgerSequence < minIndex && !input.forward) ||
|
||||
@@ -142,6 +148,14 @@ AccountTxHandler::process(AccountTxHandler::Input const& input, Context const& c
|
||||
|
||||
boost::json::object obj;
|
||||
|
||||
// Skip all Txns where the specified filter mpt_id doesn't match the query
|
||||
if (mptIssuanceFilter) {
|
||||
auto const [sttx, txMeta] =
|
||||
deserializeTxPlusMeta(txnPlusMeta, txnPlusMeta.ledgerSequence);
|
||||
if (!etl::referencesMptIssuance(*txMeta, *sttx, *mptIssuanceFilter))
|
||||
continue;
|
||||
}
|
||||
|
||||
// if binary is false or transactionType is specified, we need to expand the transaction
|
||||
if (!input.binary || input.transactionTypeInLowercase.has_value()) {
|
||||
auto [txn, meta] = toExpandedJson(txnPlusMeta, ctx.apiVersion, NFTokenjson::ENABLE);
|
||||
@@ -298,6 +312,11 @@ tag_invoke(boost::json::value_to_tag<AccountTxHandler::Input>, boost::json::valu
|
||||
boost::json::value_to<std::string>(jsonObject.at("tx_type"));
|
||||
}
|
||||
|
||||
if (jsonObject.contains(JS(mpt_issuance_id))) {
|
||||
input.mptIssuanceId =
|
||||
boost::json::value_to<std::string>(jsonObject.at(JS(mpt_issuance_id)));
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ public:
|
||||
std::optional<uint32_t> limit;
|
||||
std::optional<Marker> marker;
|
||||
std::optional<std::string> transactionTypeInLowercase;
|
||||
std::optional<std::string> mptIssuanceId;
|
||||
};
|
||||
|
||||
using Result = HandlerReturnType<Output>;
|
||||
@@ -141,6 +142,7 @@ public:
|
||||
typesKeysInLowercase.cbegin(), typesKeysInLowercase.cend()
|
||||
),
|
||||
},
|
||||
{JS(mpt_issuance_id), validation::CustomValidators::uint192HexStringValidator},
|
||||
};
|
||||
|
||||
static auto const kRpcSpec = RpcSpec{
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerHeader.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
Reference in New Issue
Block a user