Add support for DomainID in MPTokenIssuance transactions (#5509)

This change adds support for `DomainID` to existing transactions `MPTokenIssuanceCreate` and `MPTokenIssuanceSet`.

In #5224 `DomainID` was added as an access control mechanism for `SingleAssetVault`. The actual implementation of this feature lies in `MPToken` and `MPTokenIssuance`, hence it makes sense to enable the use of `DomainID` also in `MPTokenIssuanceCreate` and `MPTokenIssuanceSet`, following same rules as in Vault:

* `MPTokenIssuanceCreate` and `MPTokenIssuanceSet` can only set `DomainID` if flag `MPTRequireAuth` is set.
* `MPTokenIssuanceCreate` requires that `DomainID` be a non-zero, uint256 number.
* `MPTokenIssuanceSet` allows `DomainID` to be zero (or empty) in which case it will remove `DomainID` from the `MPTokenIssuance` object.

The change is amendment-gated by `SingleAssetVault`. This is a non-breaking change because `SingleAssetVault` amendment is `Supported::no`, i.e. at this moment considered a work in progress, which cannot be enabled on the network.
This commit is contained in:
Bronek Kozicki
2025-07-23 18:21:30 +01:00
committed by GitHub
parent 433eeabfa5
commit 80d82c5b2b
7 changed files with 615 additions and 67 deletions

View File

@@ -19,6 +19,7 @@
#include <test/jtx.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/jss.h>
namespace ripple {
@@ -99,6 +100,8 @@ MPTTester::create(MPTCreate const& arg)
jv[sfMPTokenMetadata] = strHex(*arg.metadata);
if (arg.maxAmt)
jv[sfMaximumAmount] = std::to_string(*arg.maxAmt);
if (arg.domainID)
jv[sfDomainID] = to_string(*arg.domainID);
if (submit(arg, jv) != tesSUCCESS)
{
// Verify issuance doesn't exist
@@ -235,6 +238,8 @@ MPTTester::set(MPTSet const& arg)
jv[sfHolder] = arg.holder->human();
if (arg.delegate)
jv[sfDelegate] = arg.delegate->human();
if (arg.domainID)
jv[sfDomainID] = to_string(*arg.domainID);
if (submit(arg, jv) == tesSUCCESS && arg.flags.value_or(0))
{
auto require = [&](std::optional<Account> const& holder,
@@ -272,6 +277,16 @@ MPTTester::forObject(
return false;
}
[[nodiscard]] bool
MPTTester::checkDomainID(std::optional<uint256> expected) const
{
return forObject([&](SLEP const& sle) -> bool {
if (sle->isFieldPresent(sfDomainID))
return expected == sle->getFieldH256(sfDomainID);
return (!expected.has_value());
});
}
[[nodiscard]] bool
MPTTester::checkMPTokenAmount(
Account const& holder_,