Add MPTIssue to STIssue (#5200)

Replace Issue in STIssue with Asset. STIssue with MPTIssue is only used in MPT tests.
Will be used in Vault and in transactions with STIssue fields once MPT is integrated into DEX.
This commit is contained in:
Gregory Tsipenyuk
2024-12-16 17:52:48 -05:00
committed by GitHub
parent eabca8439f
commit 5cd72f2431
22 changed files with 463 additions and 143 deletions

View File

@@ -1470,19 +1470,19 @@ class MPToken_test : public beast::unit_test::suite
void
testMPTInvalidInTx(FeatureBitset features)
{
testcase("MPT Amount Invalid in Transaction");
testcase("MPT Issue Invalid in Transaction");
using namespace test::jtx;
// Validate that every transaction with an amount field,
// Validate that every transaction with an amount/issue field,
// which doesn't support MPT, fails.
// keyed by transaction + amount field
// keyed by transaction + amount/issue field
std::set<std::string> txWithAmounts;
for (auto const& format : TxFormats::getInstance())
{
for (auto const& e : format.getSOTemplate())
{
// Transaction has amount fields.
// Transaction has amount/issue fields.
// Exclude pseudo-transaction SetFee. Don't consider
// the Fee field since it's included in every transaction.
if (e.supportMPT() == soeMPTNotSupported &&
@@ -1508,9 +1508,9 @@ class MPToken_test : public beast::unit_test::suite
env.fund(XRP(1'000), alice);
env.fund(XRP(1'000), carol);
auto test = [&](Json::Value const& jv,
std::string const& amtField) {
std::string const& mptField) {
txWithAmounts.erase(
jv[jss::TransactionType].asString() + amtField);
jv[jss::TransactionType].asString() + mptField);
// tx is signed
auto jtx = env.jt(jv);
@@ -1530,8 +1530,27 @@ class MPToken_test : public beast::unit_test::suite
jrr = env.rpc("json", "sign", to_string(jv1));
BEAST_EXPECT(jrr[jss::result][jss::error] == "invalidParams");
};
// All transactions with sfAmount, which don't support MPT
// and transactions with amount fields, which can't be MPT
auto toSFieldRef = [](SField const& field) {
return std::ref(field);
};
auto setMPTFields = [&](SField const& field,
Json::Value& jv,
bool withAmount = true) {
jv[jss::Asset] = to_json(xrpIssue());
jv[jss::Asset2] = to_json(USD.issue());
if (withAmount)
jv[field.fieldName] =
USD(10).value().getJson(JsonOptions::none);
if (field == sfAsset)
jv[jss::Asset] = to_json(mpt.get<MPTIssue>());
else if (field == sfAsset2)
jv[jss::Asset2] = to_json(mpt.get<MPTIssue>());
else
jv[field.fieldName] = mpt.getJson(JsonOptions::none);
};
// All transactions with sfAmount, which don't support MPT.
// Transactions with amount fields, which can't be MPT.
// Transactions with issue fields, which can't be MPT.
// AMMCreate
auto ammCreate = [&](SField const& field) {
@@ -1554,58 +1573,84 @@ class MPToken_test : public beast::unit_test::suite
Json::Value jv;
jv[jss::TransactionType] = jss::AMMDeposit;
jv[jss::Account] = alice.human();
jv[jss::Asset] = to_json(xrpIssue());
jv[jss::Asset2] = to_json(USD.issue());
jv[field.fieldName] = mpt.getJson(JsonOptions::none);
jv[jss::Flags] = tfSingleAsset;
setMPTFields(field, jv);
test(jv, field.fieldName);
};
for (SField const& field :
{std::ref(sfAmount),
std::ref(sfAmount2),
std::ref(sfEPrice),
std::ref(sfLPTokenOut)})
{toSFieldRef(sfAmount),
toSFieldRef(sfAmount2),
toSFieldRef(sfEPrice),
toSFieldRef(sfLPTokenOut),
toSFieldRef(sfAsset),
toSFieldRef(sfAsset2)})
ammDeposit(field);
// AMMWithdraw
auto ammWithdraw = [&](SField const& field) {
Json::Value jv;
jv[jss::TransactionType] = jss::AMMWithdraw;
jv[jss::Account] = alice.human();
jv[jss::Asset] = to_json(xrpIssue());
jv[jss::Asset2] = to_json(USD.issue());
jv[jss::Flags] = tfSingleAsset;
jv[field.fieldName] = mpt.getJson(JsonOptions::none);
setMPTFields(field, jv);
test(jv, field.fieldName);
};
ammWithdraw(sfAmount);
for (SField const& field :
{std::ref(sfAmount2),
std::ref(sfEPrice),
std::ref(sfLPTokenIn)})
{toSFieldRef(sfAmount2),
toSFieldRef(sfEPrice),
toSFieldRef(sfLPTokenIn),
toSFieldRef(sfAsset),
toSFieldRef(sfAsset2)})
ammWithdraw(field);
// AMMBid
auto ammBid = [&](SField const& field) {
Json::Value jv;
jv[jss::TransactionType] = jss::AMMBid;
jv[jss::Account] = alice.human();
jv[jss::Asset] = to_json(xrpIssue());
jv[jss::Asset2] = to_json(USD.issue());
jv[field.fieldName] = mpt.getJson(JsonOptions::none);
setMPTFields(field, jv);
test(jv, field.fieldName);
};
ammBid(sfBidMin);
ammBid(sfBidMax);
for (SField const& field :
{toSFieldRef(sfBidMin),
toSFieldRef(sfBidMax),
toSFieldRef(sfAsset),
toSFieldRef(sfAsset2)})
ammBid(field);
// AMMClawback
{
auto ammClawback = [&](SField const& field) {
Json::Value jv;
jv[jss::TransactionType] = jss::AMMClawback;
jv[jss::Account] = alice.human();
jv[jss::Holder] = carol.human();
jv[jss::Asset] = to_json(xrpIssue());
jv[jss::Asset2] = to_json(USD.issue());
jv[jss::Amount] = mpt.getJson(JsonOptions::none);
test(jv, jss::Amount.c_str());
}
setMPTFields(field, jv);
test(jv, field.fieldName);
};
for (SField const& field :
{toSFieldRef(sfAmount),
toSFieldRef(sfAsset),
toSFieldRef(sfAsset2)})
ammClawback(field);
// AMMDelete
auto ammDelete = [&](SField const& field) {
Json::Value jv;
jv[jss::TransactionType] = jss::AMMDelete;
jv[jss::Account] = alice.human();
setMPTFields(field, jv, false);
test(jv, field.fieldName);
};
ammDelete(sfAsset);
ammDelete(sfAsset2);
// AMMVote
auto ammVote = [&](SField const& field) {
Json::Value jv;
jv[jss::TransactionType] = jss::AMMVote;
jv[jss::Account] = alice.human();
jv[jss::TradingFee] = 100;
setMPTFields(field, jv, false);
test(jv, field.fieldName);
};
ammVote(sfAsset);
ammVote(sfAsset2);
// CheckCash
auto checkCash = [&](SField const& field) {
Json::Value jv;