From 18b2feea3a3d5e9a8296e935b0330a99dcd0592f Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 22 Jun 2026 13:31:07 -0700 Subject: [PATCH] fix tests --- .../transactors/token/MPTokenIssuanceSet.cpp | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp b/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp index fb10d39784..daad845312 100644 --- a/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp +++ b/src/libxrpl/tx/transactors/token/MPTokenIssuanceSet.cpp @@ -80,9 +80,10 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) auto const hasAuditorElGamalKey = ctx.tx.isFieldPresent(sfAuditorEncryptionKey); auto const txFlags = ctx.tx.getFlags(); - auto const mutatePrivacy = mutableFlags && - (((*mutableFlags & (tmfMPTSetCanConfidentialAmount | tmfMPTClearCanConfidentialAmount))) != - 0u); + auto const mutablePrivacyFlags = mutableFlags + ? (*mutableFlags & (tmfMPTSetCanConfidentialAmount | tmfMPTClearCanConfidentialAmount)) + : 0u; + auto const mutatePrivacy = mutablePrivacyFlags != 0u; auto const hasDomain = ctx.tx.isFieldPresent(sfDomainID); auto const hasHolder = ctx.tx.isFieldPresent(sfHolder); @@ -131,6 +132,10 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) if (transferFee && *transferFee > kMaxTransferFee) return temBAD_TRANSFER_FEE; + if (transferFee && *transferFee > 0u && + (mutablePrivacyFlags & tmfMPTSetCanConfidentialAmount) != 0u) + return temBAD_TRANSFER_FEE; + if (metadata && metadata->length() > kMaxMpTokenMetadataLength) return temMALFORMED; @@ -138,6 +143,10 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) { if ((*mutableFlags == 0u) || ((*mutableFlags & tmfMPTokenIssuanceSetMutableMask) != 0u)) return temINVALID_FLAG; + + if (mutablePrivacyFlags == + (tmfMPTSetCanConfidentialAmount | tmfMPTClearCanConfidentialAmount)) + return temINVALID_FLAG; } } @@ -220,12 +229,18 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx) }; auto const mutableFlags = ctx.tx[~sfMutableFlags]; + auto const mutablePrivacyFlags = mutableFlags + ? (*mutableFlags & (tmfMPTSetCanConfidentialAmount | tmfMPTClearCanConfidentialAmount)) + : 0u; if (mutableFlags) { if (std::ranges::any_of(kMptMutabilityFlags, [mutableFlags, &isMutableFlag](auto const& f) { return !isMutableFlag(f.canEnableFlag) && ((*mutableFlags & f.setFlag) != 0u); })) return tecNO_PERMISSION; + + if (mutablePrivacyFlags != 0u && isMutableFlag(lsmfMPTCannotMutateCanConfidentialAmount)) + return tecNO_PERMISSION; } if (!isMutableFlag(lsmfMPTCanMutateMetadata) && ctx.tx.isFieldPresent(sfMPTokenMetadata)) @@ -265,7 +280,11 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx) // Check if the transaction is enabling confidential amounts bool const enablesConfidentialAmount = - mutableFlags && ((*mutableFlags & tmfMPTSetCanConfidentialAmount) != 0u); + (mutablePrivacyFlags & tmfMPTSetCanConfidentialAmount) != 0u; + + if (enablesConfidentialAmount && sleMptIssuance->isFieldPresent(sfTransferFee) && + (*sleMptIssuance)[sfTransferFee] > 0u) + return tecNO_PERMISSION; // Encryption keys can only be set if confidential amounts are already // enabled on the issuance OR if the transaction is enabling it @@ -283,7 +302,7 @@ MPTokenIssuanceSet::preclaim(PreclaimContext const& ctx) // cannot upload key if there's circulating supply of COA if ((ctx.tx.isFieldPresent(sfIssuerEncryptionKey) || - ctx.tx.isFieldPresent(sfAuditorEncryptionKey)) && + ctx.tx.isFieldPresent(sfAuditorEncryptionKey) || mutablePrivacyFlags != 0u) && (*sleMptIssuance)[~sfConfidentialOutstandingAmount].value_or(0) > 0) { return tecNO_PERMISSION; // LCOV_EXCL_LINE @@ -333,6 +352,15 @@ MPTokenIssuanceSet::doApply() flagsOut |= f.ledgerFlag; } } + + if ((mutableFlags & tmfMPTSetCanConfidentialAmount) != 0u) + { + flagsOut |= lsfMPTCanConfidentialAmount; + } + else if ((mutableFlags & tmfMPTClearCanConfidentialAmount) != 0u) + { + flagsOut &= ~lsfMPTCanConfidentialAmount; + } } if (flagsIn != flagsOut)