fix: add nft_id and offer_id to txn stream (#2335)

fixes #1804

Co-authored-by: Alex Kremer <akremer@ripple.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
This commit is contained in:
Peter Chen
2025-08-28 06:50:52 -07:00
committed by GitHub
parent 5e7f6bb5bd
commit 2512a9c8e7
2 changed files with 108 additions and 10 deletions

View File

@@ -33,10 +33,12 @@
#include <boost/json/serialize.hpp>
#include <xrpl/basics/chrono.h>
#include <xrpl/basics/strHex.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Book.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/LedgerHeader.h>
#include <xrpl/protocol/NFTSyntheticSerializer.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/TER.h>
@@ -207,6 +209,15 @@ TransactionFeed::pub(
rpc::insertDeliverMaxAlias(pubObj[txKey].as_object(), version);
rpc::insertMPTIssuanceID(pubObj[JS(meta)].as_object(), tx, meta);
Json::Value nftJson;
ripple::insertNFTSyntheticInJson(nftJson, tx, *meta);
auto const nftBoostJson = rpc::toBoostJson(nftJson).as_object();
if (nftBoostJson.contains(JS(meta)) && nftBoostJson.at(JS(meta)).is_object()) {
auto& metaObjInPub = pubObj.at(JS(meta)).as_object();
for (auto const& [k, v] : nftBoostJson.at(JS(meta)).as_object())
metaObjInPub.insert_or_assign(k, v);
}
auto const& metaObj = pubObj[JS(meta)];
ASSERT(metaObj.is_object(), "meta must be an obj in rippled and clio");
if (metaObj.as_object().contains("TransactionIndex") && metaObj.as_object().at("TransactionIndex").is_int64()) {

View File

@@ -30,6 +30,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Book.h>
@@ -40,6 +41,7 @@
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFormats.h>
#include <functional>
#include <memory>
@@ -52,13 +54,14 @@ namespace {
constexpr auto kACCOUNT1 = "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn";
constexpr auto kACCOUNT2 = "rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun";
constexpr auto kLEDGER_HASH = "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC";
constexpr auto kLEDGER_HASH = "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652";
constexpr auto kCURRENCY = "0158415500000000C1F76FF6ECB0BAC600000000";
constexpr auto kISSUER = "rK9DrarGKnVEo2nYp5MfVRXRYf5yRX3mwD";
constexpr auto kTXN_ID = "E6DBAFC99223B42257915A63DFC6B0C032D4070F9A574B255AD97466726FC321";
constexpr auto kAMM_ACCOUNT = "rnW8FAPgpQgA6VoESnVrUVJHBdq9QAtRZs";
constexpr auto kLPTOKEN_CURRENCY = "037C35306B24AAB7FF90848206E003279AA47090";
constexpr auto kNETWORK_ID = 0u;
constexpr auto kNFT_MINT_ID = "000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65";
constexpr auto kTRAN_V1 =
R"JSON({
@@ -105,7 +108,7 @@ constexpr auto kTRAN_V1 =
"status": "closed",
"ledger_index": 33,
"close_time_iso": "2000-01-01T00:00:00Z",
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"engine_result": "tesSUCCESS",
"engine_result_message": "The transaction was applied. Only final in a validated ledger."
@@ -154,13 +157,76 @@ constexpr auto kTRAN_V2 =
"status": "closed",
"ledger_index": 33,
"close_time_iso": "2000-01-01T00:00:00Z",
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"hash": "51D2AAA6B8E4E16EF22F6424854283D8391B56875858A711B8CE4D5B9A422CC2",
"engine_result_code": 0,
"engine_result": "tesSUCCESS",
"engine_result_message": "The transaction was applied. Only final in a validated ledger."
})JSON";
constexpr auto kNFT_MINT_TRAN_V1 =
R"JSON({
"transaction":
{
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "12",
"NFTokenTaxon": 123,
"Sequence": 1,
"SigningPubKey": "74657374",
"TransactionType": "NFTokenMint",
"hash": "D279CDCA424E5A62A67D98B7E15BCC7AE6E162F19BBAE26E1C7D957109452D0E",
"date": 0
},
"meta": {
"AffectedNodes": [
{
"ModifiedNode": {
"FinalFields": {
"NFTokens": [
{
"NFToken": {
"NFTokenID": "000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65",
"URI": "7465737475726C"
}
},
{
"NFToken": {
"NFTokenID": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"URI": "7465737475726C"
}
}
]
},
"LedgerEntryType": "NFTokenPage",
"PreviousFields": {
"NFTokens": [
{
"NFToken": {
"NFTokenID": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"URI": "7465737475726C"
}
}
]
}
}
}
],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS",
"nftoken_id": "000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65"
},
"ctid": "C000002100000000",
"type": "transaction",
"validated": true,
"status": "closed",
"ledger_index": 33,
"close_time_iso": "2000-01-01T00:00:00Z",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"engine_result": "tesSUCCESS",
"engine_result_message": "The transaction was applied. Only final in a validated ledger."
})JSON";
} // namespace
using namespace feed::impl;
@@ -403,7 +469,7 @@ TEST_F(FeedTransactionTest, SubBookV1)
"validated": true,
"status": "closed",
"ledger_index": 33,
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"engine_result": "tesSUCCESS",
"close_time_iso": "2000-01-01T00:00:00Z",
@@ -457,7 +523,7 @@ TEST_F(FeedTransactionTest, SubBookV1)
"validated": true,
"status": "closed",
"ledger_index": 33,
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"engine_result": "tesSUCCESS",
"close_time_iso": "2000-01-01T00:00:00Z",
@@ -508,7 +574,7 @@ TEST_F(FeedTransactionTest, SubBookV1)
"validated": true,
"status": "closed",
"ledger_index": 33,
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"engine_result": "tesSUCCESS",
"close_time_iso": "2000-01-01T00:00:00Z",
@@ -590,7 +656,7 @@ TEST_F(FeedTransactionTest, SubBookV2)
"validated": true,
"status": "closed",
"ledger_index": 33,
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"engine_result": "tesSUCCESS",
"close_time_iso": "2000-01-01T00:00:00Z",
@@ -835,7 +901,7 @@ TEST_F(FeedTransactionTest, PubTransactionWithOwnerFund)
"validated": true,
"status": "closed",
"ledger_index": 33,
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"close_time_iso": "2000-01-01T00:00:00Z",
"engine_result": "tesSUCCESS",
@@ -850,6 +916,27 @@ TEST_F(FeedTransactionTest, PubTransactionWithOwnerFund)
testFeedPtr->pub(trans1, ledgerHeader, backend_, mockAmendmentCenterPtr_, kNETWORK_ID);
}
TEST_F(FeedTransactionTest, PublishesNFTokenMintTx)
{
EXPECT_CALL(*mockSessionPtr, onDisconnect);
testFeedPtr->sub(sessionPtr);
auto const ledgerHeader = createLedgerHeader(kLEDGER_HASH, 33);
// Creates an NFTokenMint transaction
auto const trans = createMintNftTxWithMetadata(kACCOUNT1, 1, 12, 123, kNFT_MINT_ID);
EXPECT_CALL(*mockSessionPtr, apiSubversion).WillOnce(testing::Return(1));
EXPECT_CALL(*mockSessionPtr, send(sharedStringJsonEq(kNFT_MINT_TRAN_V1)));
testFeedPtr->pub(trans, ledgerHeader, backend_, mockAmendmentCenterPtr_, kNETWORK_ID);
testFeedPtr->unsub(sessionPtr);
EXPECT_EQ(testFeedPtr->transactionSubCount(), 0);
testFeedPtr->pub(trans, ledgerHeader, backend_, mockAmendmentCenterPtr_, kNETWORK_ID);
}
static constexpr auto kTRAN_FROZEN =
R"JSON({
"transaction": {
@@ -879,7 +966,7 @@ static constexpr auto kTRAN_FROZEN =
"status": "closed",
"ledger_index": 33,
"close_time_iso": "2000-01-01T00:00:00Z",
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"engine_result": "tesSUCCESS",
"engine_result_message": "The transaction was applied. Only final in a validated ledger."
@@ -1136,7 +1223,7 @@ TEST_F(FeedTransactionTest, PubTransactionWithOwnerFundFrozenLPToken)
"validated": true,
"status": "closed",
"ledger_index": 33,
"ledger_hash": "1B8590C01B0006EDFA9ED60296DD052DC5E90F99659B25014D08E1BC983515BC",
"ledger_hash": "4BC50C9B0D8515D3EAAE1E74B29A95804346C491EE1A95BF25E4AAB854A6A652",
"engine_result_code": 0,
"close_time_iso": "2000-01-01T00:00:00Z",
"engine_result": "tesSUCCESS",