mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add MPT related txns into issuer's account history (#5530)
Currently there is no easy way to track MPT related transactions for the issuer. This change allows MPT transactions to show up on issuer's AccountTx RPC (to align with how IOUs work).
This commit is contained in:
@@ -99,40 +99,6 @@ class TxQPosNegFlows_test : public beast::unit_test::suite
|
||||
return calcMedFeeLevel(feeLevel, feeLevel);
|
||||
}
|
||||
|
||||
static std::unique_ptr<Config>
|
||||
makeConfig(
|
||||
std::map<std::string, std::string> extraTxQ = {},
|
||||
std::map<std::string, std::string> extraVoting = {})
|
||||
{
|
||||
auto p = test::jtx::envconfig();
|
||||
auto& section = p->section("transaction_queue");
|
||||
section.set("ledgers_in_queue", "2");
|
||||
section.set("minimum_queue_size", "2");
|
||||
section.set("min_ledgers_to_compute_size_limit", "3");
|
||||
section.set("max_ledger_counts_to_store", "100");
|
||||
section.set("retry_sequence_percent", "25");
|
||||
section.set("normal_consensus_increase_percent", "0");
|
||||
|
||||
for (auto const& [k, v] : extraTxQ)
|
||||
section.set(k, v);
|
||||
|
||||
// Some tests specify different fee settings that are enabled by
|
||||
// a FeeVote
|
||||
if (!extraVoting.empty())
|
||||
{
|
||||
auto& votingSection = p->section("voting");
|
||||
for (auto const& [k, v] : extraVoting)
|
||||
{
|
||||
votingSection.set(k, v);
|
||||
}
|
||||
|
||||
// In order for the vote to occur, we must run as a validator
|
||||
p->section("validation_seed")
|
||||
.legacy("shUwVw52ofnCUX5m7kPTKzJdr4HEH");
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
initFee(
|
||||
jtx::Env& env,
|
||||
|
||||
@@ -127,6 +127,11 @@ addGrpcConfigWithSecureGateway(
|
||||
std::unique_ptr<Config>,
|
||||
std::string const& secureGateway);
|
||||
|
||||
std::unique_ptr<Config>
|
||||
makeConfig(
|
||||
std::map<std::string, std::string> extraTxQ = {},
|
||||
std::map<std::string, std::string> extraVoting = {});
|
||||
|
||||
} // namespace jtx
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
|
||||
@@ -140,6 +140,39 @@ addGrpcConfigWithSecureGateway(
|
||||
return cfg;
|
||||
}
|
||||
|
||||
std::unique_ptr<Config>
|
||||
makeConfig(
|
||||
std::map<std::string, std::string> extraTxQ,
|
||||
std::map<std::string, std::string> extraVoting)
|
||||
{
|
||||
auto p = test::jtx::envconfig();
|
||||
auto& section = p->section("transaction_queue");
|
||||
section.set("ledgers_in_queue", "2");
|
||||
section.set("minimum_queue_size", "2");
|
||||
section.set("min_ledgers_to_compute_size_limit", "3");
|
||||
section.set("max_ledger_counts_to_store", "100");
|
||||
section.set("retry_sequence_percent", "25");
|
||||
section.set("normal_consensus_increase_percent", "0");
|
||||
|
||||
for (auto const& [k, v] : extraTxQ)
|
||||
section.set(k, v);
|
||||
|
||||
// Some tests specify different fee settings that are enabled by
|
||||
// a FeeVote
|
||||
if (!extraVoting.empty())
|
||||
{
|
||||
auto& votingSection = p->section("voting");
|
||||
for (auto const& [k, v] : extraVoting)
|
||||
{
|
||||
votingSection.set(k, v);
|
||||
}
|
||||
|
||||
// In order for the vote to occur, we must run as a validator
|
||||
p->section("validation_seed").legacy("shUwVw52ofnCUX5m7kPTKzJdr4HEH");
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
} // namespace jtx
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <test/jtx.h>
|
||||
#include <test/jtx/envconfig.h>
|
||||
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
#include <xrpl/beast/unit_test/suite.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/TxFlags.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
#include <boost/container/flat_set.hpp>
|
||||
@@ -753,6 +756,85 @@ class AccountTx_test : public beast::unit_test::suite
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testMPT()
|
||||
{
|
||||
testcase("MPT");
|
||||
|
||||
using namespace test::jtx;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
auto cfg = makeConfig();
|
||||
cfg->FEES.reference_fee = 10;
|
||||
Env env(*this, std::move(cfg));
|
||||
|
||||
Account const alice{"alice"};
|
||||
Account const bob{"bob"};
|
||||
Account const carol{"carol"};
|
||||
|
||||
MPTTester mptAlice(env, alice, {.holders = {bob, carol}});
|
||||
|
||||
// check the latest mpt-related txn is in alice's account history
|
||||
auto const checkAliceAcctTx = [&](size_t size,
|
||||
Json::StaticString txType) {
|
||||
Json::Value params;
|
||||
params[jss::account] = alice.human();
|
||||
params[jss::limit] = 100;
|
||||
auto const jv =
|
||||
env.rpc("json", "account_tx", to_string(params))[jss::result];
|
||||
|
||||
BEAST_EXPECT(jv[jss::transactions].size() == size);
|
||||
auto const& tx0(jv[jss::transactions][0u][jss::tx]);
|
||||
BEAST_EXPECT(tx0[jss::TransactionType] == txType);
|
||||
|
||||
std::string const txHash{
|
||||
env.tx()->getJson(JsonOptions::none)[jss::hash].asString()};
|
||||
BEAST_EXPECT(tx0[jss::hash] == txHash);
|
||||
};
|
||||
|
||||
// alice creates issuance
|
||||
mptAlice.create(
|
||||
{.ownerCount = 1,
|
||||
.holderCount = 0,
|
||||
.flags = tfMPTCanClawback | tfMPTRequireAuth | tfMPTCanTransfer});
|
||||
|
||||
checkAliceAcctTx(3, jss::MPTokenIssuanceCreate);
|
||||
|
||||
// bob creates a MPToken;
|
||||
mptAlice.authorize({.account = bob});
|
||||
checkAliceAcctTx(4, jss::MPTokenAuthorize);
|
||||
env.close();
|
||||
|
||||
// TODO: windows pipeline fails validation for the hardcoded ledger hash
|
||||
// due to having different test config, it can be uncommented after
|
||||
// figuring out what happened
|
||||
//
|
||||
// ledger hash should be fixed regardless any change to account history
|
||||
// BEAST_EXPECT(
|
||||
// to_string(env.closed()->info().hash) ==
|
||||
// "0BD507BB87D3C0E73B462485E6E381798A8C82FC49BF17FE39C60E08A1AF035D");
|
||||
|
||||
// alice authorizes bob
|
||||
mptAlice.authorize({.account = alice, .holder = bob});
|
||||
checkAliceAcctTx(5, jss::MPTokenAuthorize);
|
||||
|
||||
// carol creates a MPToken;
|
||||
mptAlice.authorize({.account = carol});
|
||||
checkAliceAcctTx(6, jss::MPTokenAuthorize);
|
||||
|
||||
// alice authorizes carol
|
||||
mptAlice.authorize({.account = alice, .holder = carol});
|
||||
checkAliceAcctTx(7, jss::MPTokenAuthorize);
|
||||
|
||||
// alice pays bob 100 tokens
|
||||
mptAlice.pay(alice, bob, 100);
|
||||
checkAliceAcctTx(8, jss::Payment);
|
||||
|
||||
// bob pays carol 10 tokens
|
||||
mptAlice.pay(bob, carol, 10);
|
||||
checkAliceAcctTx(9, jss::Payment);
|
||||
}
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
@@ -761,6 +843,7 @@ public:
|
||||
std::bind_front(&AccountTx_test::testParameters, this));
|
||||
testContents();
|
||||
testAccountDelete();
|
||||
testMPT();
|
||||
}
|
||||
};
|
||||
BEAST_DEFINE_TESTSUITE(AccountTx, rpc, ripple);
|
||||
|
||||
Reference in New Issue
Block a user