Add additional metadata to simulate response (#5754)

This commit is contained in:
tequ
2025-09-11 23:17:06 +09:00
committed by GitHub
parent fbd60fc000
commit e6f8bc720f
2 changed files with 118 additions and 0 deletions

View File

@@ -131,6 +131,32 @@ class Simulate_test : public beast::unit_test::suite
std::to_string(env.current()->txCount()));
}
void
testTxJsonMetadataField(
jtx::Env& env,
Json::Value const& tx,
std::function<void(
Json::Value const&,
Json::Value const&,
Json::Value const&)> const& validate,
Json::Value const& expectedMetadataKey,
bool testSerialized = true)
{
env.close();
Json::Value params;
params[jss::tx_json] = tx;
validate(
env.rpc("json", "simulate", to_string(params)),
tx,
expectedMetadataKey);
validate(env.rpc("simulate", to_string(tx)), tx, expectedMetadataKey);
BEAST_EXPECTS(
env.current()->txCount() == 0,
std::to_string(env.current()->txCount()));
}
Json::Value
getJsonMetadata(Json::Value txResult) const
{
@@ -1186,6 +1212,83 @@ class Simulate_test : public beast::unit_test::suite
}
}
void
testSuccessfulTransactionAdditionalMetadata()
{
testcase("Successful transaction with additional metadata");
using namespace jtx;
Env env{*this, envconfig([&](std::unique_ptr<Config> cfg) {
cfg->NETWORK_ID = 1025;
return cfg;
})};
Account const alice("alice");
env.fund(XRP(10000), alice);
env.close();
{
auto validateOutput = [&](Json::Value const& resp,
Json::Value const& tx,
Json::Value const& expectedMetadataKey) {
auto result = resp[jss::result];
BEAST_EXPECT(result[jss::engine_result] == "tesSUCCESS");
BEAST_EXPECT(result[jss::engine_result_code] == 0);
BEAST_EXPECT(
result[jss::engine_result_message] ==
"The simulated transaction would have been applied.");
if (BEAST_EXPECT(
result.isMember(jss::meta) ||
result.isMember(jss::meta_blob)))
{
Json::Value const metadata = getJsonMetadata(result);
BEAST_EXPECT(metadata[sfTransactionIndex.jsonName] == 0);
BEAST_EXPECT(
metadata[sfTransactionResult.jsonName] == "tesSUCCESS");
BEAST_EXPECT(
metadata.isMember(expectedMetadataKey.asString()));
}
};
{
Json::Value tx;
tx[jss::Account] = env.master.human();
tx[jss::TransactionType] = jss::Payment;
tx[sfDestination] = alice.human();
tx[sfAmount] = "100";
// test delivered amount
testTxJsonMetadataField(
env, tx, validateOutput, jss::delivered_amount);
}
{
Json::Value tx;
tx[jss::Account] = env.master.human();
tx[jss::TransactionType] = jss::NFTokenMint;
tx[sfNFTokenTaxon] = 1;
// test nft synthetic
testTxJsonMetadataField(
env, tx, validateOutput, jss::nftoken_id);
}
{
Json::Value tx;
tx[jss::Account] = env.master.human();
tx[jss::TransactionType] = jss::MPTokenIssuanceCreate;
// test mpt issuance id
testTxJsonMetadataField(
env, tx, validateOutput, jss::mpt_issuance_id);
}
}
}
public:
void
run() override
@@ -1202,6 +1305,7 @@ public:
testMultisignedBadPubKey();
testDeleteExpiredCredentials();
testSuccessfulTransactionNetworkID();
testSuccessfulTransactionAdditionalMetadata();
}
};

View File

@@ -24,10 +24,13 @@
#include <xrpld/app/misc/TxQ.h>
#include <xrpld/app/tx/apply.h>
#include <xrpld/rpc/Context.h>
#include <xrpld/rpc/DeliveredAmount.h>
#include <xrpld/rpc/GRPCHandlers.h>
#include <xrpld/rpc/MPTokenIssuanceID.h>
#include <xrpld/rpc/detail/TransactionSign.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/NFTSyntheticSerializer.h>
#include <xrpl/protocol/RPCErr.h>
#include <xrpl/protocol/STParsedJSON.h>
#include <xrpl/resource/Fees.h>
@@ -272,6 +275,17 @@ simulateTxn(RPC::JsonContext& context, std::shared_ptr<Transaction> transaction)
else
{
jvResult[jss::meta] = result.metadata->getJson(JsonOptions::none);
RPC::insertDeliveredAmount(
jvResult[jss::meta],
view,
transaction->getSTransaction(),
*result.metadata);
RPC::insertNFTSyntheticInJson(
jvResult, transaction->getSTransaction(), *result.metadata);
RPC::insertMPTokenIssuanceID(
jvResult[jss::meta],
transaction->getSTransaction(),
*result.metadata);
}
}