mirror of
https://github.com/XRPLF/clio.git
synced 2026-08-19 11:40:53 +00:00
111 lines
3.3 KiB
C++
111 lines
3.3 KiB
C++
#include "etl/MPTHelpers.hpp"
|
|
|
|
#include "data/DBHelpers.hpp"
|
|
#include "util/Assert.hpp"
|
|
#include "util/MPTIssuanceUtils.hpp"
|
|
|
|
#include <xrpl/basics/base_uint.h>
|
|
#include <xrpl/protocol/LedgerFormats.h>
|
|
#include <xrpl/protocol/SField.h>
|
|
#include <xrpl/protocol/STLedgerEntry.h>
|
|
#include <xrpl/protocol/STObject.h>
|
|
#include <xrpl/protocol/STTx.h>
|
|
#include <xrpl/protocol/Serializer.h>
|
|
#include <xrpl/protocol/TER.h>
|
|
#include <xrpl/protocol/TxMeta.h>
|
|
|
|
#include <optional>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace etl {
|
|
|
|
std::vector<MPTHolderData>
|
|
getMPTHolderFromTx(xrpl::TxMeta const& txMeta, xrpl::STTx const&)
|
|
{
|
|
if (txMeta.getResultTER() != xrpl::tesSUCCESS)
|
|
return {};
|
|
|
|
std::vector<MPTHolderData> holders;
|
|
|
|
for (xrpl::STObject const& node : txMeta.getNodes()) {
|
|
if (node.getFieldU16(xrpl::sfLedgerEntryType) != xrpl::ltMPTOKEN)
|
|
continue;
|
|
|
|
if (node.getFName() == xrpl::sfCreatedNode) {
|
|
auto const& newMPT = node.peekAtField(xrpl::sfNewFields).downcast<xrpl::STObject>();
|
|
holders.push_back(
|
|
MPTHolderData{
|
|
.mptID = newMPT[xrpl::sfMPTokenIssuanceID],
|
|
.holder = newMPT.getAccountID(xrpl::sfAccount)
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
return holders;
|
|
}
|
|
|
|
std::vector<MPTokenIssuanceTransactionsData>
|
|
getMPTokenIssuanceTxsFromTx(xrpl::TxMeta const& txMeta, xrpl::STTx const& sttx)
|
|
{
|
|
// Collect each distinct issuance only once per transaction; the same set of affected accounts
|
|
// is attached to every record produced below.
|
|
util::MPTokenIssuanceIDs issuanceIDs;
|
|
|
|
if (txMeta.getResultTER() == xrpl::tesSUCCESS) {
|
|
for (auto const& node : txMeta.getNodes()) {
|
|
if (auto const issuanceID = util::getMPTokenIssuanceIDFromNode(node);
|
|
issuanceID.has_value()) {
|
|
issuanceIDs.insert(*issuanceID);
|
|
}
|
|
}
|
|
}
|
|
|
|
util::addMPTokenIssuanceIDsFromTx(issuanceIDs, sttx);
|
|
|
|
if (issuanceIDs.empty())
|
|
return {};
|
|
|
|
auto const accounts = txMeta.getAffectedAccounts();
|
|
|
|
std::vector<MPTokenIssuanceTransactionsData> result;
|
|
result.reserve(issuanceIDs.size());
|
|
for (auto const& issuanceID : issuanceIDs) {
|
|
result.push_back(
|
|
MPTokenIssuanceTransactionsData{
|
|
.mptIssuanceID = issuanceID,
|
|
.accounts = accounts,
|
|
.ledgerSequence = txMeta.getLgrSeq(),
|
|
.transactionIndex = txMeta.getIndex(),
|
|
.txHash = sttx.getTransactionID()
|
|
}
|
|
);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::optional<MPTHolderData>
|
|
getMPTHolderFromObj(std::string const& key, std::string const& blob)
|
|
{
|
|
// https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0033-multi-purpose-tokens#2121-mptoken-ledger-identifier
|
|
ASSERT(
|
|
key.size() == xrpl::uint256::size(),
|
|
"The size of the key is expected to fit uint256 exactly"
|
|
);
|
|
|
|
xrpl::STLedgerEntry const sle = xrpl::STLedgerEntry(
|
|
xrpl::SerialIter{blob.data(), blob.size()}, xrpl::uint256::fromVoid(key.data())
|
|
);
|
|
|
|
if (sle.getFieldU16(xrpl::sfLedgerEntryType) != xrpl::ltMPTOKEN)
|
|
return std::nullopt;
|
|
|
|
auto const mptIssuanceID = sle[xrpl::sfMPTokenIssuanceID];
|
|
auto const holder = sle.getAccountID(xrpl::sfAccount);
|
|
|
|
return MPTHolderData{.mptID = mptIssuanceID, .holder = holder};
|
|
}
|
|
|
|
} // namespace etl
|