refactor: Add common helper function for injected metadata fields in RPCs (#5706)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Mayukha Vadari <mvadari@gmail.com>
Co-authored-by: Mayukha Vadari <mvadari@ripple.com>
Co-authored-by: Timur Yalymov <36795566+tyalymov@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
This commit is contained in:
Copilot
2026-08-31 17:21:25 +00:00
committed by GitHub
parent 9a7c5ea593
commit fac20a06f3
12 changed files with 259 additions and 155 deletions

View File

@@ -30,15 +30,14 @@ This section contains changes targeting a future version.
- `account_tx`: Added an optional `delegate` request object to filter delegated transactions. The object requires `delegate_filter`, which must be either `actor` for transactions owned by the requested account but signed by another account, or `authorizer` for transactions signed by the requested account on behalf of another account. The optional `counter_party` account narrows the results to a specific signer/delegate for `actor` or a specific owner/delegator for `authorizer`. Malformed `delegate`, `delegate_filter`, and `counter_party` values return standard invalid field errors, and invalid account IDs return `actMalformed`.
When paginating delegate-filtered queries, a marker from a delegate-filtered query includes a `delegate` flag and is only valid for follow-up requests that also supply `delegate` (mixing marker conventions returns `invalidParams`). Because filtering is applied after the ledger scan, a page may contain fewer results than `limit` (possibly zero) while still returning a marker, so callers must continue until no marker is present.
- `ledger_entry`, `account_objects`: The `Delegate` ledger entry now includes an optional `DestinationNode` field, which stores the index into the authorized account's owner directory. This field is present on entries created after bidirectional directory tracking was introduced and may appear in RPC responses for those entries. ([#6681](https://github.com/XRPLF/rippled/pull/6681))
- `server_definitions`: Added the following new sections to the response ([#6321](https://github.com/XRPLF/rippled/pull/6321)):
- `TRANSACTION_FORMATS`: Describes the fields and their optionality for each transaction type, including common fields shared across all transactions.
- `LEDGER_ENTRY_FORMATS`: Describes the fields and their optionality for each ledger entry type, including common fields shared across all ledger entries.
- `TRANSACTION_FLAGS`: Maps transaction type names to their supported flags and flag values.
- `LEDGER_ENTRY_FLAGS`: Maps ledger entry type names to their flags and flag values.
- `ACCOUNT_SET_FLAGS`: Maps AccountSet flag names (asf flags) to their numeric values.
- `ledger`: `nftoken_id`, `nftoken_ids`, and `offer_id` are now included in transaction metadata when transactions are expanded (`expand`, or admin-only `full`), matching the `tx`, `account_tx`, and `subscribe` (`transactions` stream) responses. ([#5706](https://github.com/XRPLF/rippled/pull/5706))
### Bugfixes
@@ -59,6 +58,7 @@ This section contains changes targeting a future version.
- `vault_info`: `vault_id` and `owner` must now be strings, matching how `ledger_entry` reads the same fields. An object or an array in either field previously produced an internal error, and a number was silently converted to its decimal text; `vault_id` now returns `invalidParams` and `owner` returns `actMalformed`. [#8015](https://github.com/XRPLF/rippled/pull/8015)
- `gateway_balances`: The `account` and `ident` fields now return an `invalidParams` error if the value is not a string, instead of an `internal` error. [#7655](https://github.com/XRPLF/rippled/pull/7655)
- `account_lines`: The `peer` field now returns an error if the value is not a string. [#7728](https://github.com/XRPLF/rippled/pull/7728)
- `ledger`: `delivered_amount` is now included in the metadata of successful `AccountDelete` transactions when transactions are expanded (`expand`, or admin-only `full`). Previously it was only added for `Payment` and `CheckCash`, which made `ledger` inconsistent with `tx` and `account_tx`. [#5706](https://github.com/XRPLF/rippled/pull/5706)
## XRP Ledger server version 3.1.0

View File

@@ -1,19 +0,0 @@
#pragma once
#include <xrpl/json/json_forwards.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TxMeta.h>
#include <memory>
namespace xrpl::rpc {
/**
* Adds common synthetic fields to transaction-related JSON responses
*/
/** @{ */
void
insertNFTSyntheticInJson(json::Value&, std::shared_ptr<STTx const> const&, TxMeta const&);
/** @} */
} // namespace xrpl::rpc

View File

@@ -1,24 +0,0 @@
#include <xrpl/protocol/NFTSyntheticSerializer.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/NFTokenID.h>
#include <xrpl/protocol/NFTokenOfferID.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/protocol/jss.h>
#include <memory>
namespace xrpl::rpc {
void
insertNFTSyntheticInJson(
json::Value& response,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{
insertNFTokenID(response[jss::meta], transaction, transactionMeta);
insertNFTokenOfferID(response[jss::meta], transaction, transactionMeta);
}
} // namespace xrpl::rpc

View File

@@ -29,6 +29,8 @@
#include <xrpl/basics/chrono.h>
#include <xrpl/basics/strHex.h>
#include <xrpl/beast/unit_test/suite.h>
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/ReadView.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
@@ -67,7 +69,8 @@ private:
// We can't use env.meta() here, because meta() doesn't include
// delivered_amount.
env.close();
json::Value const meta = env.rpc("tx", txHash)[jss::result][jss::meta];
json::Value const txResult = env.rpc("tx", txHash)[jss::result];
json::Value const meta = txResult[jss::meta];
// Expect there to be a DeliveredAmount field.
if (!BEAST_EXPECT(meta.isMember(sfDeliveredAmount.jsonName)))
@@ -78,6 +81,21 @@ private:
json::Value const jsonExpect{amount.getJson(JsonOptions::Values::None)};
BEAST_EXPECT(meta[sfDeliveredAmount.jsonName] == jsonExpect);
BEAST_EXPECT(meta[jss::delivered_amount] == jsonExpect);
// The `ledger` RPC (with expanded transactions) should also report
// delivered_amount for this transaction, matching the `tx` RPC.
json::Value ledgerParams;
ledgerParams[jss::ledger_index] = txResult[jss::ledger_index].asUInt();
ledgerParams[jss::transactions] = true;
ledgerParams[jss::expand] = true;
auto const ledgerResult = env.rpc("json", "ledger", to_string(ledgerParams));
auto const& ledgerTx = ledgerResult[jss::result][jss::ledger][jss::transactions][0u];
BEAST_EXPECT(ledgerTx[jss::hash].asString() == txHash);
json::Value const& ledgerMeta = ledgerTx[jss::metaData];
BEAST_EXPECT(ledgerMeta[sfDeliveredAmount.jsonName] == jsonExpect);
BEAST_EXPECT(ledgerMeta[jss::delivered_amount] == jsonExpect);
}
// Helper function to create a payment channel.

View File

@@ -29,6 +29,7 @@
#include <xrpl/json/json_value.h>
#include <xrpl/json/to_string.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/protocol/ApiVersion.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Protocol.h>
@@ -6326,84 +6327,162 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite
env.fund(XRP(10000), alice, bob, broker);
env.close();
// Verify `nftoken_id` value equals to the NFTokenID that was
// changed in the most recent NFTokenMint or NFTokenAcceptOffer
// transaction
auto verifyNFTokenID = [&](uint256 const& actualNftID) {
// Transaction metadata is not always reported under the same field
// name: the `ledger` RPC uses `metaData`, the others use `meta`.
auto const getMeta = [](json::Value const& tx) -> json::Value const* {
if (tx.isMember(jss::meta))
return &tx[jss::meta];
if (tx.isMember(jss::metaData))
return &tx[jss::metaData];
return nullptr;
};
// Neither is the transaction hash: api_version 1 nests the
// transaction under `tx`, later versions use `tx_json`, and some
// responses put the hash on the entry itself.
auto const getHash = [](json::Value const& entry) -> std::string {
if (entry.isMember(jss::tx) && entry[jss::tx].isMember(jss::hash))
return entry[jss::tx][jss::hash].asString();
if (entry.isMember(jss::tx_json) && entry[jss::tx_json].isMember(jss::hash))
return entry[jss::tx_json][jss::hash].asString();
return entry[jss::hash].asString();
};
// Run `verifyMeta` against the metadata of the most recent
// transaction as reported by the `tx`, `ledger` and `account_tx`
// RPCs, so that the synthetic fields are checked in every response
// that carries them. Runs under both api_version 1 (`tx`/`meta`)
// and the latest api_version (`tx_json`/synthetic fields alongside
// it), since the two versions place fields differently.
auto verifyMetaInAllResponses = [&](auto verifyMeta) {
// Get the hash for the most recent transaction.
std::string const txHash{
env.tx()->getJson(JsonOptions::Values::None)[jss::hash].asString()};
env.close();
json::Value const meta = env.rpc("tx", txHash)[jss::result][jss::meta];
// Expect nftokens_id field
if (!BEAST_EXPECT(meta.isMember(jss::nftoken_id)))
return;
for (unsigned const apiVersion :
{unsigned{rpc::kApiMinimumSupportedVersion},
unsigned{rpc::kApiMaximumSupportedVersion}})
{
// Test 1: Check tx RPC response
json::Value const txResult = env.rpc(apiVersion, "tx", txHash)[jss::result];
verifyMeta(txResult[jss::meta]);
// Check the value of NFT ID in the meta with the
// actual value
uint256 nftID;
BEAST_EXPECT(nftID.parseHex(meta[jss::nftoken_id].asString()));
BEAST_EXPECT(nftID == actualNftID);
// Test 2: Check ledger RPC response with expanded
// transactions
json::Value ledgerParams;
ledgerParams[jss::ledger_index] = txResult[jss::ledger_index].asUInt();
ledgerParams[jss::transactions] = true;
ledgerParams[jss::expand] = true;
auto const ledgerResult =
env.rpc(apiVersion, "json", "ledger", to_string(ledgerParams));
auto const& ledgerTx =
ledgerResult[jss::result][jss::ledger][jss::transactions][0u];
// Verify transaction hash matches
BEAST_EXPECT(getHash(ledgerTx) == txHash);
if (auto const* meta = getMeta(ledgerTx); BEAST_EXPECT(meta != nullptr))
verifyMeta(*meta);
// Test 3: Check account_tx RPC response
// The transaction is not necessarily alice's, so query
// account_tx for the account that actually submitted it.
json::Value accountTxParams;
accountTxParams[jss::account] = txResult.isMember(jss::tx_json)
? txResult[jss::tx_json][jss::Account].asString()
: txResult[jss::Account].asString();
auto const accountTxResult =
env.rpc(apiVersion, "json", "account_tx", to_string(accountTxParams));
// account_tx ordering is not guaranteed, so find our
// transaction by hash rather than assuming it is the most
// recent one.
json::Value const* accountTx = nullptr;
for (auto const& entry : accountTxResult[jss::result][jss::transactions])
{
if (getHash(entry) == txHash)
{
accountTx = &entry;
break;
}
}
if (!BEAST_EXPECT(accountTx != nullptr))
continue;
if (auto const* meta = getMeta(*accountTx); BEAST_EXPECT(meta != nullptr))
verifyMeta(*meta);
}
};
// Verify `nftoken_id` value equals to the NFTokenID that was
// changed in the most recent NFTokenMint or NFTokenAcceptOffer
// transaction
auto verifyNFTokenID = [&](uint256 const& actualNftID) {
verifyMetaInAllResponses([&](json::Value const& meta) {
// Expect nftoken_id field
if (!BEAST_EXPECT(meta.isMember(jss::nftoken_id)))
return;
// Check the value of NFT ID matches
uint256 nftID;
BEAST_EXPECT(nftID.parseHex(meta[jss::nftoken_id].asString()));
BEAST_EXPECT(nftID == actualNftID);
});
};
// Verify `nftoken_ids` value equals to the NFTokenIDs that were
// changed in the most recent NFTokenCancelOffer transaction
auto verifyNFTokenIDsInCancelOffer = [&](std::vector<uint256> actualNftIDs) {
// Get the hash for the most recent transaction.
std::string const txHash{
env.tx()->getJson(JsonOptions::Values::None)[jss::hash].asString()};
env.close();
json::Value const meta = env.rpc("tx", txHash)[jss::result][jss::meta];
// Expect nftokens_ids field and verify the values
if (!BEAST_EXPECT(meta.isMember(jss::nftoken_ids)))
return;
// Convert NFT IDs from json::Value to uint256
std::vector<uint256> metaIDs;
std::transform(
meta[jss::nftoken_ids].begin(),
meta[jss::nftoken_ids].end(),
std::back_inserter(metaIDs),
[this](json::Value id) {
uint256 nftID;
BEAST_EXPECT(nftID.parseHex(id.asString()));
return nftID;
});
// Sort both array to prepare for comparison
std::ranges::sort(metaIDs);
// Sort to prepare for comparison
std::ranges::sort(actualNftIDs);
// Make sure the expect number of NFTs is correct
BEAST_EXPECT(metaIDs.size() == actualNftIDs.size());
verifyMetaInAllResponses([&](json::Value const& meta) {
// Expect nftoken_ids field and verify the values
if (!BEAST_EXPECT(meta.isMember(jss::nftoken_ids)))
return;
// Check the value of NFT ID in the meta with the
// actual values
for (size_t i = 0; i < metaIDs.size(); ++i)
BEAST_EXPECT(metaIDs[i] == actualNftIDs[i]);
// Convert NFT IDs from json::Value to uint256
std::vector<uint256> metaIDs;
std::transform(
meta[jss::nftoken_ids].begin(),
meta[jss::nftoken_ids].end(),
std::back_inserter(metaIDs),
[this](json::Value id) {
uint256 nftID;
BEAST_EXPECT(nftID.parseHex(id.asString()));
return nftID;
});
std::ranges::sort(metaIDs);
// Make sure the expect number of NFTs is correct
if (!BEAST_EXPECT(metaIDs.size() == actualNftIDs.size()))
return;
// Check the value of NFT ID in the meta with the
// actual values
for (size_t i = 0; i < metaIDs.size(); ++i)
BEAST_EXPECT(metaIDs[i] == actualNftIDs[i]);
});
};
// Verify `offer_id` value equals to the offerID that was
// changed in the most recent NFTokenCreateOffer tx
auto verifyNFTokenOfferID = [&](uint256 const& offerID) {
// Get the hash for the most recent transaction.
std::string const txHash{
env.tx()->getJson(JsonOptions::Values::None)[jss::hash].asString()};
verifyMetaInAllResponses([&](json::Value const& meta) {
// Expect offer_id field and verify the value
if (!BEAST_EXPECT(meta.isMember(jss::offer_id)))
return;
env.close();
json::Value const meta = env.rpc("tx", txHash)[jss::result][jss::meta];
// Expect offer_id field and verify the value
if (!BEAST_EXPECT(meta.isMember(jss::offer_id)))
return;
uint256 metaOfferID;
BEAST_EXPECT(metaOfferID.parseHex(meta[jss::offer_id].asString()));
BEAST_EXPECT(metaOfferID == offerID);
uint256 metaOfferID;
BEAST_EXPECT(metaOfferID.parseHex(meta[jss::offer_id].asString()));
BEAST_EXPECT(metaOfferID == offerID);
});
};
// Check new fields in tx meta when for all NFTtransactions

View File

@@ -4,8 +4,7 @@
#include <xrpld/app/misc/DeliverMax.h>
#include <xrpld/app/misc/TxQ.h>
#include <xrpld/rpc/Context.h>
#include <xrpld/rpc/DeliveredAmount.h>
#include <xrpld/rpc/MPTokenIssuanceID.h>
#include <xrpld/rpc/detail/SyntheticFields.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
@@ -19,6 +18,7 @@
#include <xrpl/protocol/LedgerHeader.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxFormats.h>
@@ -141,19 +141,12 @@ fillJsonTx(
{
txJson[jss::meta] = stMeta->getJson(JsonOptions::Values::None);
// If applicable, insert delivered amount
if (txnType == ttPAYMENT || txnType == ttCHECK_CASH)
{
rpc::insertDeliveredAmount(
txJson[jss::meta],
fill.ledger,
txn,
{txn->getTransactionID(), fill.ledger.seq(), *stMeta});
}
// If applicable, insert mpt issuance id
rpc::insertMPTokenIssuanceID(
txJson[jss::meta], txn, {txn->getTransactionID(), fill.ledger.seq(), *stMeta});
// Insert all synthetic fields
rpc::insertAllSyntheticInJson(
txJson[jss::meta],
fill.ledger,
txn,
{txn->getTransactionID(), fill.ledger.seq(), *stMeta});
}
if (!fill.ledger.open())
@@ -177,19 +170,12 @@ fillJsonTx(
{
txJson[jss::metaData] = stMeta->getJson(JsonOptions::Values::None);
// If applicable, insert delivered amount
if (txnType == ttPAYMENT || txnType == ttCHECK_CASH)
{
rpc::insertDeliveredAmount(
txJson[jss::metaData],
fill.ledger,
txn,
{txn->getTransactionID(), fill.ledger.seq(), *stMeta});
}
// If applicable, insert mpt issuance id
rpc::insertMPTokenIssuanceID(
txJson[jss::metaData], txn, {txn->getTransactionID(), fill.ledger.seq(), *stMeta});
// Insert all synthetic fields
rpc::insertAllSyntheticInJson(
txJson[jss::metaData],
fill.ledger,
txn,
{txn->getTransactionID(), fill.ledger.seq(), *stMeta});
}
}

View File

@@ -28,9 +28,8 @@
#include <xrpld/overlay/predicates.h>
#include <xrpld/rpc/BookChanges.h>
#include <xrpld/rpc/CTID.h>
#include <xrpld/rpc/DeliveredAmount.h>
#include <xrpld/rpc/MPTokenIssuanceID.h>
#include <xrpld/rpc/ServerHandler.h>
#include <xrpld/rpc/detail/SyntheticFields.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/ToString.h>
@@ -92,7 +91,6 @@
#include <xrpl/protocol/MPTAmount.h>
#include <xrpl/protocol/MPTIssue.h>
#include <xrpl/protocol/MultiApiJson.h>
#include <xrpl/protocol/NFTSyntheticSerializer.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/RPCErr.h>
@@ -3467,9 +3465,7 @@ NetworkOPsImp::transJson(
if (meta)
{
jvObj[jss::meta] = meta->get().getJson(JsonOptions::Values::None);
rpc::insertDeliveredAmount(jvObj[jss::meta], *ledger, transaction, meta->get());
rpc::insertNFTSyntheticInJson(jvObj, transaction, meta->get());
rpc::insertMPTokenIssuanceID(jvObj[jss::meta], transaction, meta->get());
rpc::insertAllSyntheticInJson(jvObj[jss::meta], *ledger, transaction, meta->get());
}
// add CTID where the needed data for it exists

View File

@@ -0,0 +1,40 @@
#include <xrpld/rpc/detail/SyntheticFields.h>
#include <xrpld/rpc/DeliveredAmount.h>
#include <xrpld/rpc/MPTokenIssuanceID.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/NFTokenID.h>
#include <xrpl/protocol/NFTokenOfferID.h>
#include <memory>
namespace xrpl::rpc {
void
insertAllSyntheticInJson(
json::Value& metadata,
ReadView const& ledger,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{
insertDeliveredAmount(metadata, ledger, transaction, transactionMeta);
insertNFTokenID(metadata, transaction, transactionMeta);
insertNFTokenOfferID(metadata, transaction, transactionMeta);
insertMPTokenIssuanceID(metadata, transaction, transactionMeta);
}
void
insertAllSyntheticInJson(
json::Value& metadata,
JsonContext const& context,
std::shared_ptr<STTx const> const& transaction,
TxMeta const& transactionMeta)
{
insertDeliveredAmount(metadata, context, transaction, transactionMeta);
insertNFTokenID(metadata, transaction, transactionMeta);
insertNFTokenOfferID(metadata, transaction, transactionMeta);
insertMPTokenIssuanceID(metadata, transaction, transactionMeta);
}
} // namespace xrpl::rpc

View File

@@ -0,0 +1,39 @@
#pragma once
#include <xrpl/json/json_forwards.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TxMeta.h>
#include <memory>
namespace xrpl {
class ReadView;
namespace rpc {
struct JsonContext;
/**
* Adds all synthetic fields to transaction metadata JSON.
* This includes delivered amount, NFT synthetic fields, and MPToken issuance
* ID.
*/
/** @{ */
void
insertAllSyntheticInJson(
json::Value& metadata,
ReadView const&,
std::shared_ptr<STTx const> const&,
TxMeta const&);
void
insertAllSyntheticInJson(
json::Value& metadata,
JsonContext const&,
std::shared_ptr<STTx const> const&,
TxMeta const&);
/** @} */
} // namespace rpc
} // namespace xrpl

View File

@@ -4,12 +4,11 @@
#include <xrpld/app/misc/Transaction.h>
#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
#include <xrpld/rpc/Context.h>
#include <xrpld/rpc/DeliveredAmount.h>
#include <xrpld/rpc/MPTokenIssuanceID.h>
#include <xrpld/rpc/Role.h>
#include <xrpld/rpc/Status.h>
#include <xrpld/rpc/detail/RPCHelpers.h>
#include <xrpld/rpc/detail/RPCLedgerHelpers.h>
#include <xrpld/rpc/detail/SyntheticFields.h>
#include <xrpld/rpc/detail/Tuning.h>
#include <xrpl/basics/Log.h>
@@ -22,7 +21,6 @@
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/LedgerShortcut.h>
#include <xrpl/protocol/NFTSyntheticSerializer.h>
#include <xrpl/protocol/RPCErr.h>
#include <xrpl/protocol/RippleLedgerHash.h>
#include <xrpl/protocol/jss.h>
@@ -378,9 +376,7 @@ populateJsonResponse(
if (txnMeta)
{
jvObj[jss::meta] = txnMeta->getJson(JsonOptions::Values::IncludeDate);
insertDeliveredAmount(jvObj[jss::meta], context, txn, *txnMeta);
rpc::insertNFTSyntheticInJson(jvObj, sttx, *txnMeta);
rpc::insertMPTokenIssuanceID(jvObj[jss::meta], sttx, *txnMeta);
rpc::insertAllSyntheticInJson(jvObj[jss::meta], context, sttx, *txnMeta);
}
else
{

View File

@@ -4,7 +4,7 @@
#include <xrpld/app/misc/TxQ.h>
#include <xrpld/rpc/Context.h>
#include <xrpld/rpc/DeliveredAmount.h>
#include <xrpld/rpc/MPTokenIssuanceID.h>
#include <xrpld/rpc/detail/SyntheticFields.h>
#include <xrpld/rpc/detail/TransactionSign.h>
#include <xrpl/basics/Log.h>
@@ -20,7 +20,6 @@
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/NFTSyntheticSerializer.h>
#include <xrpl/protocol/RPCErr.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STParsedJSON.h>
@@ -290,12 +289,8 @@ simulateTxn(rpc::JsonContext& context, std::shared_ptr<Transaction> transaction)
else
{
jvResult[jss::meta] = result.metadata->getJson(JsonOptions::Values::None);
rpc::insertDeliveredAmount(
rpc::insertAllSyntheticInJson(
jvResult[jss::meta], view, transaction->getSTransaction(), *result.metadata);
rpc::insertNFTSyntheticInJson(
jvResult, transaction->getSTransaction(), *result.metadata);
rpc::insertMPTokenIssuanceID(
jvResult[jss::meta], transaction->getSTransaction(), *result.metadata);
}
}

View File

@@ -5,8 +5,9 @@
#include <xrpld/rpc/CTID.h>
#include <xrpld/rpc/Context.h>
#include <xrpld/rpc/DeliveredAmount.h>
#include <xrpld/rpc/MPTokenIssuanceID.h>
#include <xrpld/rpc/Status.h>
#include <xrpld/rpc/detail/RPCHelpers.h>
#include <xrpld/rpc/detail/SyntheticFields.h>
#include <xrpl/basics/Blob.h>
#include <xrpl/basics/RangeSet.h>
@@ -18,7 +19,6 @@
#include <xrpl/core/NetworkIDService.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/NFTSyntheticSerializer.h>
#include <xrpl/protocol/RPCErr.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h>
@@ -253,9 +253,7 @@ populateJsonResponse(
if (meta)
{
response[jss::meta] = meta->getJson(JsonOptions::Values::None);
insertDeliveredAmount(response[jss::meta], context, result.txn, *meta);
rpc::insertNFTSyntheticInJson(response, sttx, *meta);
rpc::insertMPTokenIssuanceID(response[jss::meta], sttx, *meta);
rpc::insertAllSyntheticInJson(response[jss::meta], context, sttx, *meta);
}
}
response[jss::validated] = result.validated;