mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-20 11:45:53 +00:00
@@ -206,8 +206,10 @@ TransactionFeed::pub(
|
||||
pubObj[txKey] = rpc::toJson(*tx);
|
||||
pubObj[JS(meta)] = rpc::toJson(*meta);
|
||||
rpc::insertDeliveredAmount(pubObj[JS(meta)].as_object(), tx, meta, txMeta.date);
|
||||
rpc::insertDeliverMaxAlias(pubObj[txKey].as_object(), version);
|
||||
rpc::insertMPTIssuanceID(pubObj[JS(meta)].as_object(), tx, meta);
|
||||
|
||||
auto& txnPubobj = pubObj[txKey].as_object();
|
||||
rpc::insertDeliverMaxAlias(txnPubobj, version);
|
||||
rpc::insertMPTIssuanceID(txnPubobj, meta);
|
||||
|
||||
Json::Value nftJson;
|
||||
ripple::RPC::insertNFTSyntheticInJson(nftJson, tx, *meta);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "web/Context.hpp"
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/asio/spawn.hpp>
|
||||
#include <boost/format/format_fwd.hpp>
|
||||
#include <boost/format/free_funcs.hpp>
|
||||
@@ -262,7 +263,7 @@ toExpandedJson(
|
||||
auto metaJson = toJson(*meta);
|
||||
insertDeliveredAmount(metaJson, txn, meta, blobs.date);
|
||||
insertDeliverMaxAlias(txnJson, apiVersion);
|
||||
insertMPTIssuanceID(metaJson, txn, meta);
|
||||
insertMPTIssuanceID(txnJson, meta);
|
||||
|
||||
if (nftEnabled == NFTokenjson::ENABLE) {
|
||||
Json::Value nftJson;
|
||||
@@ -347,14 +348,15 @@ getMPTIssuanceID(std::shared_ptr<ripple::TxMeta const> const& meta)
|
||||
/**
|
||||
* @brief Check if transaction has a new MPToken created
|
||||
*
|
||||
* @param txn The transaction
|
||||
* @param txnJson The transaction Json
|
||||
* @param meta The metadata
|
||||
* @return true if the transaction can have a mpt_issuance_id
|
||||
*/
|
||||
static bool
|
||||
canHaveMPTIssuanceID(std::shared_ptr<ripple::STTx const> const& txn, std::shared_ptr<ripple::TxMeta const> const& meta)
|
||||
canHaveMPTIssuanceID(boost::json::object const& txnJson, std::shared_ptr<ripple::TxMeta const> const& meta)
|
||||
{
|
||||
if (txn->getTxnType() != ripple::ttMPTOKEN_ISSUANCE_CREATE)
|
||||
if (txnJson.at(JS(TransactionType)).is_string() and
|
||||
not boost::iequals(txnJson.at(JS(TransactionType)).as_string(), JS(MPTokenIssuanceCreate)))
|
||||
return false;
|
||||
|
||||
if (meta->getResultTER() != ripple::tesSUCCESS)
|
||||
@@ -364,17 +366,13 @@ canHaveMPTIssuanceID(std::shared_ptr<ripple::STTx const> const& txn, std::shared
|
||||
}
|
||||
|
||||
bool
|
||||
insertMPTIssuanceID(
|
||||
boost::json::object& metaJson,
|
||||
std::shared_ptr<ripple::STTx const> const& txn,
|
||||
std::shared_ptr<ripple::TxMeta const> const& meta
|
||||
)
|
||||
insertMPTIssuanceID(boost::json::object& txnJson, std::shared_ptr<ripple::TxMeta const> const& meta)
|
||||
{
|
||||
if (!canHaveMPTIssuanceID(txn, meta))
|
||||
if (!canHaveMPTIssuanceID(txnJson, meta))
|
||||
return false;
|
||||
|
||||
if (auto const id = getMPTIssuanceID(meta)) {
|
||||
metaJson[JS(mpt_issuance_id)] = ripple::to_string(*id);
|
||||
txnJson[JS(mpt_issuance_id)] = ripple::to_string(*id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,17 +202,12 @@ insertDeliveredAmount(
|
||||
/**
|
||||
* @brief Add "mpt_issuance_id" into MPTokenIssuanceCreate transaction json.
|
||||
*
|
||||
* @param metaJson The metadata json object to add "MPTokenIssuanceID"
|
||||
* @param txn The transaction object
|
||||
* @param txnJson The transaction Json object
|
||||
* @param meta The metadata object
|
||||
* @return true if the "mpt_issuance_id" is added to the metadata json object
|
||||
*/
|
||||
bool
|
||||
insertMPTIssuanceID(
|
||||
boost::json::object& metaJson,
|
||||
std::shared_ptr<ripple::STTx const> const& txn,
|
||||
std::shared_ptr<ripple::TxMeta const> const& meta
|
||||
);
|
||||
insertMPTIssuanceID(boost::json::object& txnJson, std::shared_ptr<ripple::TxMeta const> const& meta);
|
||||
|
||||
/**
|
||||
* @brief Convert STBase object to JSON
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
|
||||
namespace {
|
||||
constexpr auto kINDEX1 = "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC";
|
||||
ripple::Slice const kSLICE("test", 4);
|
||||
} // namespace
|
||||
|
||||
ripple::AccountID
|
||||
@@ -183,9 +184,7 @@ createPaymentTransactionObject(
|
||||
auto account2 = util::parseBase58Wrapper<ripple::AccountID>(std::string(accountId2));
|
||||
obj.setAccountID(ripple::sfDestination, account2.value());
|
||||
obj.setFieldU32(ripple::sfSequence, seq);
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
obj.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
obj.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -697,9 +696,7 @@ createMintNftTxWithMetadata(
|
||||
// required field for ttNFTOKEN_MINT
|
||||
tx.setFieldU32(ripple::sfNFTokenTaxon, nfTokenTaxon);
|
||||
tx.setFieldU32(ripple::sfSequence, seq);
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
|
||||
// meta
|
||||
ripple::STObject metaObj(ripple::sfTransactionMetaData);
|
||||
@@ -762,9 +759,7 @@ createMintNftTxWithMetadataOfCreatedNode(
|
||||
// required field for ttNFTOKEN_MINT
|
||||
tx.setFieldU32(ripple::sfNFTokenTaxon, nfTokenTaxon);
|
||||
tx.setFieldU32(ripple::sfSequence, seq);
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
if (uri)
|
||||
tx.setFieldVL(ripple::sfURI, ripple::Slice(uri->data(), uri->size()));
|
||||
|
||||
@@ -820,9 +815,7 @@ createNftModifyTxWithMetadata(std::string_view accountId, std::string_view nftID
|
||||
tx.setFieldAmount(ripple::sfFee, amount);
|
||||
tx.setFieldH256(ripple::sfNFTokenID, ripple::uint256{nftID});
|
||||
tx.setFieldU32(ripple::sfSequence, 100);
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
|
||||
if (!uri.empty()) // sfURI should be absent if empty
|
||||
tx.setFieldVL(ripple::sfURI, uri);
|
||||
@@ -880,9 +873,7 @@ createNftBurnTxWithMetadataOfDeletedNode(std::string_view accountId, std::string
|
||||
tx.setFieldAmount(ripple::sfFee, amount);
|
||||
tx.setFieldH256(ripple::sfNFTokenID, ripple::uint256{nftID});
|
||||
tx.setFieldU32(ripple::sfSequence, 100);
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
|
||||
// meta
|
||||
ripple::STObject metaObj(ripple::sfTransactionMetaData);
|
||||
@@ -927,9 +918,7 @@ createNftBurnTxWithMetadataOfModifiedNode(std::string_view accountId, std::strin
|
||||
tx.setFieldAmount(ripple::sfFee, amount);
|
||||
tx.setFieldH256(ripple::sfNFTokenID, ripple::uint256{nftID});
|
||||
tx.setFieldU32(ripple::sfSequence, 100);
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
|
||||
// meta
|
||||
ripple::STObject metaObj(ripple::sfTransactionMetaData);
|
||||
@@ -976,9 +965,7 @@ createAcceptNftBuyerOfferTxWithMetadata(
|
||||
tx.setFieldAmount(ripple::sfFee, amount);
|
||||
tx.setFieldU32(ripple::sfSequence, seq);
|
||||
tx.setFieldH256(ripple::sfNFTokenBuyOffer, ripple::uint256{offerId});
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
|
||||
// meta
|
||||
// create deletedNode with ltNFTOKEN_OFFER
|
||||
@@ -1025,9 +1012,7 @@ createAcceptNftSellerOfferTxWithMetadata(
|
||||
tx.setFieldAmount(ripple::sfFee, amount);
|
||||
tx.setFieldU32(ripple::sfSequence, seq);
|
||||
tx.setFieldH256(ripple::sfNFTokenSellOffer, ripple::uint256{offerId});
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
|
||||
// meta
|
||||
// create deletedNode with ltNFTOKEN_OFFER
|
||||
@@ -1121,9 +1106,7 @@ createCancelNftOffersTxWithMetadata(
|
||||
return ripple::uint256{nftId.c_str()};
|
||||
});
|
||||
tx.setFieldV256(ripple::sfNFTokenOffers, offers);
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
|
||||
// meta
|
||||
// create deletedNode with ltNFTOKEN_OFFER
|
||||
@@ -1172,9 +1155,7 @@ createCreateNftOfferTxWithMetadata(
|
||||
tx.setFieldAmount(ripple::sfAmount, price);
|
||||
tx.setFieldU32(ripple::sfSequence, seq);
|
||||
tx.setFieldH256(ripple::sfNFTokenID, ripple::uint256{nftId});
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
|
||||
// meta
|
||||
// create createdNode with LedgerIndex
|
||||
@@ -1219,9 +1200,7 @@ createOracleSetTxWithMetadata(
|
||||
tx.setFieldU32(ripple::sfLastUpdateTime, lastUpdateTime);
|
||||
tx.setFieldU32(ripple::sfOracleDocumentID, docId);
|
||||
tx.setFieldU32(ripple::sfSequence, seq);
|
||||
char const* key = "test";
|
||||
ripple::Slice const slice(key, 4);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, slice);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
tx.setFieldArray(ripple::sfPriceDataSeries, priceDataSeries);
|
||||
|
||||
// meta
|
||||
@@ -1499,6 +1478,56 @@ createMpTokenObject(std::string_view accountId, ripple::uint192 issuanceID, std:
|
||||
return mptoken;
|
||||
}
|
||||
|
||||
ripple::STObject
|
||||
createMPTIssuanceCreateTx(std::string_view accountId, uint32_t fee, uint32_t seq)
|
||||
{
|
||||
ripple::STObject tx(ripple::sfTransaction);
|
||||
tx.setFieldU16(ripple::sfTransactionType, ripple::ttMPTOKEN_ISSUANCE_CREATE);
|
||||
tx.setAccountID(ripple::sfAccount, getAccountIdWithString(accountId));
|
||||
tx.setFieldAmount(ripple::sfFee, ripple::STAmount(fee, false));
|
||||
tx.setFieldU32(ripple::sfSequence, seq);
|
||||
tx.setFieldVL(ripple::sfSigningPubKey, kSLICE);
|
||||
return tx;
|
||||
}
|
||||
|
||||
data::TransactionAndMetadata
|
||||
createMPTIssuanceCreateTxWithMetadata(std::string_view accountId, uint32_t fee, uint32_t seq)
|
||||
{
|
||||
ripple::STObject tx = createMPTIssuanceCreateTx(accountId, fee, seq);
|
||||
|
||||
ripple::STObject metaObj(ripple::sfTransactionMetaData);
|
||||
metaObj.setFieldU8(ripple::sfTransactionResult, ripple::tesSUCCESS);
|
||||
metaObj.setFieldU32(ripple::sfTransactionIndex, 0);
|
||||
|
||||
ripple::STObject newFields(ripple::sfNewFields);
|
||||
newFields.setAccountID(ripple::sfIssuer, getAccountIdWithString(accountId));
|
||||
newFields.setFieldU16(ripple::sfLedgerEntryType, ripple::ltMPTOKEN_ISSUANCE);
|
||||
newFields.setFieldU32(ripple::sfFlags, 0);
|
||||
newFields.setFieldU32(ripple::sfSequence, seq);
|
||||
newFields.setFieldU64(ripple::sfOwnerNode, 0);
|
||||
newFields.setFieldU64(ripple::sfMaximumAmount, 0);
|
||||
newFields.setFieldU64(ripple::sfOutstandingAmount, 0);
|
||||
newFields.setFieldH256(ripple::sfPreviousTxnID, ripple::uint256{});
|
||||
newFields.setFieldU32(ripple::sfPreviousTxnLgrSeq, 0);
|
||||
std::string_view metadata = "test-meta";
|
||||
ripple::Slice const sliceMetadata(metadata.data(), metadata.size());
|
||||
newFields.setFieldVL(ripple::sfMPTokenMetadata, sliceMetadata);
|
||||
|
||||
ripple::STObject createdNode(ripple::sfCreatedNode);
|
||||
createdNode.setFieldU16(ripple::sfLedgerEntryType, ripple::ltMPTOKEN_ISSUANCE);
|
||||
createdNode.setFieldH256(ripple::sfLedgerIndex, ripple::uint256{});
|
||||
createdNode.emplace_back(std::move(newFields));
|
||||
|
||||
ripple::STArray affectedNodes(ripple::sfAffectedNodes);
|
||||
affectedNodes.push_back(std::move(createdNode));
|
||||
metaObj.setFieldArray(ripple::sfAffectedNodes, affectedNodes);
|
||||
|
||||
data::TransactionAndMetadata ret;
|
||||
ret.transaction = tx.getSerializer().peekData();
|
||||
ret.metadata = metaObj.getSerializer().peekData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
ripple::STObject
|
||||
createPermissionedDomainObject(
|
||||
std::string_view accountId,
|
||||
|
||||
@@ -456,6 +456,12 @@ createMptIssuanceObject(std::string_view accountId, std::uint32_t seq, std::stri
|
||||
[[nodiscard]] ripple::STObject
|
||||
createMpTokenObject(std::string_view accountId, ripple::uint192 issuanceID, std::uint64_t mptAmount = 1);
|
||||
|
||||
[[nodiscard]] ripple::STObject
|
||||
createMPTIssuanceCreateTx(std::string_view accountId, uint32_t fee, uint32_t seq);
|
||||
|
||||
[[nodiscard]] data::TransactionAndMetadata
|
||||
createMPTIssuanceCreateTxWithMetadata(std::string_view accountId, uint32_t fee, uint32_t seq);
|
||||
|
||||
[[nodiscard]] ripple::STObject
|
||||
createPermissionedDomainObject(
|
||||
std::string_view accountId,
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace rpc;
|
||||
@@ -55,6 +56,7 @@ constexpr auto kNFT_ID = "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76
|
||||
constexpr auto kNFT_ID2 = "05FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DA";
|
||||
constexpr auto kNFT_ID3 = "15FB0EB4B899F056FA095537C5817163801F544BAFCEA39C995D76DB4D16F9DF";
|
||||
constexpr auto kINDEX = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC322";
|
||||
constexpr auto kMPT_ISSUANCE_ID = "000000014B4E9C06F24296074F7BC48F92A97916C6DC5EA9";
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -907,9 +909,7 @@ TEST_F(RPCAccountTxHandlerTest, SpecificLedgerIndex)
|
||||
);
|
||||
|
||||
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kMAX_SEQ - 1);
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence).Times(1);
|
||||
ON_CALL(*backend_, fetchLedgerBySequence(kMAX_SEQ - 1, _)).WillByDefault(Return(ledgerHeader));
|
||||
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence(kMAX_SEQ - 1, _)).WillOnce(Return(ledgerHeader));
|
||||
ON_CALL(*mockETLServicePtr_, getETLState).WillByDefault(Return(etl::ETLState{}));
|
||||
|
||||
runSpawn([&, this](auto yield) {
|
||||
@@ -937,8 +937,7 @@ TEST_F(RPCAccountTxHandlerTest, SpecificLedgerIndex)
|
||||
|
||||
TEST_F(RPCAccountTxHandlerTest, SpecificNonexistLedgerIntIndex)
|
||||
{
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence).Times(1);
|
||||
ON_CALL(*backend_, fetchLedgerBySequence(kMAX_SEQ - 1, _)).WillByDefault(Return(std::nullopt));
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence(kMAX_SEQ - 1, _)).WillOnce(Return(std::nullopt));
|
||||
|
||||
runSpawn([&, this](auto yield) {
|
||||
auto const handler = AnyHandler{AccountTxHandler{backend_, mockETLServicePtr_}};
|
||||
@@ -962,8 +961,7 @@ TEST_F(RPCAccountTxHandlerTest, SpecificNonexistLedgerIntIndex)
|
||||
|
||||
TEST_F(RPCAccountTxHandlerTest, SpecificNonexistLedgerStringIndex)
|
||||
{
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence).Times(1);
|
||||
ON_CALL(*backend_, fetchLedgerBySequence(kMAX_SEQ - 1, _)).WillByDefault(Return(std::nullopt));
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence(kMAX_SEQ - 1, _)).WillOnce(Return(std::nullopt));
|
||||
|
||||
runSpawn([&, this](auto yield) {
|
||||
auto const handler = AnyHandler{AccountTxHandler{backend_, mockETLServicePtr_}};
|
||||
@@ -1000,11 +998,10 @@ TEST_F(RPCAccountTxHandlerTest, SpecificLedgerHash)
|
||||
testing::Optional(testing::Eq(TransactionsCursor{kMAX_SEQ - 1, INT32_MAX})),
|
||||
testing::_
|
||||
)
|
||||
)
|
||||
.Times(1);
|
||||
);
|
||||
|
||||
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kMAX_SEQ - 1);
|
||||
EXPECT_CALL(*backend_, fetchLedgerByHash).Times(1);
|
||||
EXPECT_CALL(*backend_, fetchLedgerByHash);
|
||||
ON_CALL(*backend_, fetchLedgerByHash(ripple::uint256{kLEDGER_HASH}, _)).WillByDefault(Return(ledgerHeader));
|
||||
|
||||
ON_CALL(*mockETLServicePtr_, getETLState).WillByDefault(Return(etl::ETLState{}));
|
||||
@@ -1050,8 +1047,7 @@ TEST_F(RPCAccountTxHandlerTest, SpecificLedgerIndexValidated)
|
||||
);
|
||||
|
||||
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kMAX_SEQ);
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence).Times(1);
|
||||
ON_CALL(*backend_, fetchLedgerBySequence(kMAX_SEQ, _)).WillByDefault(Return(ledgerHeader));
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence(kMAX_SEQ, _)).WillOnce(Return(ledgerHeader));
|
||||
|
||||
ON_CALL(*mockETLServicePtr_, getETLState).WillByDefault(Return(etl::ETLState{}));
|
||||
|
||||
@@ -1599,6 +1595,98 @@ TEST_F(RPCAccountTxHandlerTest, NFTTxs_API_v2)
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RPCAccountTxHandlerTest, MPTTxs_API_v2)
|
||||
{
|
||||
auto const out = fmt::format(
|
||||
R"JSON({{
|
||||
"account": "{}",
|
||||
"ledger_index_min": 10,
|
||||
"ledger_index_max": 30,
|
||||
"transactions": [
|
||||
{{
|
||||
"meta": {{
|
||||
"AffectedNodes": [
|
||||
{{
|
||||
"CreatedNode": {{
|
||||
"LedgerEntryType": "MPTokenIssuance",
|
||||
"LedgerIndex": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"NewFields": {{
|
||||
"Flags": 0,
|
||||
"Issuer": "{}",
|
||||
"LedgerEntryType": "MPTokenIssuance",
|
||||
"MPTokenMetadata": "746573742D6D657461",
|
||||
"MaximumAmount": "0",
|
||||
"OutstandingAmount": "0",
|
||||
"OwnerNode": "0",
|
||||
"PreviousTxnID": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"PreviousTxnLgrSeq": 0,
|
||||
"Sequence": 1
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
],
|
||||
"TransactionIndex": 0,
|
||||
"TransactionResult": "tesSUCCESS"
|
||||
}},
|
||||
"hash": "A52221F4003C281D3C83F501F418B55A1F9DC1C6A129EF13E1A8F0E5C008DAE3",
|
||||
"ledger_index": 11,
|
||||
"ledger_hash": "{}",
|
||||
"close_time_iso": "2000-01-01T00:00:00Z",
|
||||
"tx_json": {{
|
||||
"Account": "{}",
|
||||
"Fee": "50",
|
||||
"Sequence": 1,
|
||||
"SigningPubKey": "74657374",
|
||||
"TransactionType": "MPTokenIssuanceCreate",
|
||||
"mpt_issuance_id": "{}",
|
||||
"ledger_index": 11,
|
||||
"ctid": "C000000B00000000",
|
||||
"date": 1
|
||||
}},
|
||||
"validated": true
|
||||
}}
|
||||
],
|
||||
"validated": true
|
||||
}})JSON",
|
||||
kACCOUNT,
|
||||
kACCOUNT,
|
||||
kLEDGER_HASH,
|
||||
kACCOUNT,
|
||||
kMPT_ISSUANCE_ID
|
||||
);
|
||||
|
||||
auto mptTx = createMPTIssuanceCreateTxWithMetadata(kACCOUNT, 50, 1);
|
||||
mptTx.ledgerSequence = kMIN_SEQ + 1;
|
||||
mptTx.date = 1;
|
||||
|
||||
auto transactions = std::vector<TransactionAndMetadata>{std::move(mptTx)};
|
||||
auto const transCursor = TransactionsAndCursor{.txns = std::move(transactions), .cursor = std::nullopt};
|
||||
|
||||
EXPECT_CALL(*backend_, fetchAccountTransactions).WillOnce(Return(transCursor));
|
||||
|
||||
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, kMIN_SEQ + 1);
|
||||
EXPECT_CALL(*backend_, fetchLedgerBySequence(kMIN_SEQ + 1, _)).WillOnce(Return(ledgerHeader));
|
||||
|
||||
runSpawn([&, this](auto yield) {
|
||||
auto const handler = AnyHandler{AccountTxHandler{backend_, mockETLServicePtr_}};
|
||||
static auto const kINPUT = json::parse(
|
||||
fmt::format(
|
||||
R"JSON({{
|
||||
"account": "{}",
|
||||
"ledger_index_min": {},
|
||||
"ledger_index_max": {}
|
||||
}})JSON",
|
||||
kACCOUNT,
|
||||
kMIN_SEQ,
|
||||
kMAX_SEQ
|
||||
)
|
||||
);
|
||||
auto const output = handler.process(kINPUT, Context{.yield = yield, .apiVersion = 2u});
|
||||
ASSERT_TRUE(output);
|
||||
EXPECT_EQ(*output.result, json::parse(out));
|
||||
});
|
||||
}
|
||||
|
||||
struct AccountTxTransactionBundle {
|
||||
std::string testName;
|
||||
std::string testJson;
|
||||
|
||||
Reference in New Issue
Block a user