mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-23 23:20:33 +00:00
Merge remote-tracking branch 'origin/develop' into merge-develop-sponsor
This commit is contained in:
@@ -37,6 +37,8 @@ reduceOffer(auto const& amount)
|
||||
|
||||
enum class IsDeposit : bool { No = false, Yes = true };
|
||||
|
||||
inline Number const kAMMInvariantRelativeTolerance{1, -11};
|
||||
|
||||
/** Calculate LP Tokens given AMM pool reserves.
|
||||
* @param asset1 AMM one side of the pool reserve
|
||||
* @param asset2 AMM another side of the pool reserve
|
||||
@@ -738,6 +740,30 @@ ammPoolHolds(
|
||||
AuthHandling authHandling,
|
||||
beast::Journal const j);
|
||||
|
||||
/** Check AMM pool product invariant after an AMM operation that changes LP tokens
|
||||
* (deposit/withdraw/clawback) from an already calculated pool product mean.
|
||||
* Returns tecPRECISION_LOSS if poolProductMean < newLPTokenBalance beyond the
|
||||
* invariant tolerance,
|
||||
* tesSUCCESS otherwise. Skips check when newLPTokenBalance is zero (last withdrawal).
|
||||
*/
|
||||
TER
|
||||
checkAMMPrecisionLoss(Number const& poolProductMean, STAmount const& newLPTokenBalance);
|
||||
|
||||
/** Check AMM pool product invariant after an AMM operation that changes LP tokens
|
||||
* (deposit/withdraw/clawback).
|
||||
* Returns tecPRECISION_LOSS if sqrt(asset1 * asset2) < newLPTokenBalance beyond
|
||||
* the invariant tolerance,
|
||||
* tesSUCCESS otherwise. Skips check when newLPTokenBalance is zero (last withdrawal).
|
||||
*/
|
||||
TER
|
||||
checkAMMPrecisionLoss(
|
||||
ReadView const& view,
|
||||
AccountID const& ammAccountID,
|
||||
Asset const& asset1,
|
||||
Asset const& asset2,
|
||||
STAmount const& newLPTokenBalance,
|
||||
beast::Journal const j);
|
||||
|
||||
/** Get AMM pool and LP token balances. If both optIssue are
|
||||
* provided then they are used as the AMM token pair issues.
|
||||
* Otherwise the missing issues are fetched from ammSle.
|
||||
|
||||
@@ -23,13 +23,9 @@ checkTxPermission(SLE::const_ref delegate, STTx const& tx);
|
||||
* @param delegate The delegate account.
|
||||
* @param type Used to determine which granted granular permissions to load,
|
||||
* based on the transaction type.
|
||||
* @param granularPermissions Granted granular permissions tied to the
|
||||
* transaction type.
|
||||
* @return the granted granular permissions tied to the transaction type.
|
||||
*/
|
||||
void
|
||||
loadGranularPermission(
|
||||
SLE::const_ref delegate,
|
||||
TxType const& type,
|
||||
std::unordered_set<GranularPermissionType>& granularPermissions);
|
||||
std::unordered_set<GranularPermissionType>
|
||||
getGranularPermission(SLE::const_ref delegate, TxType const& type);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -180,12 +180,12 @@ enum LedgerEntryType : std::uint16_t {
|
||||
LSF_FLAG(lsfMPTCanClawback, 0x00000040)) \
|
||||
\
|
||||
LEDGER_OBJECT(MPTokenIssuanceMutable, \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanLock, 0x00000002) \
|
||||
LSF_FLAG(lsmfMPTCanMutateRequireAuth, 0x00000004) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanEscrow, 0x00000008) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanTrade, 0x00000010) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanTransfer, 0x00000020) \
|
||||
LSF_FLAG(lsmfMPTCanMutateCanClawback, 0x00000040) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanLock, 0x00000002) \
|
||||
LSF_FLAG(lsmfMPTCanEnableRequireAuth, 0x00000004) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanEscrow, 0x00000008) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanTrade, 0x00000010) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanTransfer, 0x00000020) \
|
||||
LSF_FLAG(lsmfMPTCanEnableCanClawback, 0x00000040) \
|
||||
LSF_FLAG(lsmfMPTCanMutateMetadata, 0x00010000) \
|
||||
LSF_FLAG(lsmfMPTCanMutateTransferFee, 0x00020000)) \
|
||||
\
|
||||
|
||||
@@ -7,8 +7,13 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class STTx;
|
||||
|
||||
/**
|
||||
* We have both transaction type permissions and granular type permissions.
|
||||
* Since we will reuse the TransactionFormats to parse the Transaction
|
||||
@@ -19,15 +24,15 @@ namespace xrpl {
|
||||
// Macro-generated, complex
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
|
||||
enum GranularPermissionType : std::uint32_t {
|
||||
#pragma push_macro("PERMISSION")
|
||||
#undef PERMISSION
|
||||
#pragma push_macro("GRANULAR_PERMISSION")
|
||||
#undef GRANULAR_PERMISSION
|
||||
|
||||
#define PERMISSION(type, txType, value) type = (value),
|
||||
#define GRANULAR_PERMISSION(name, txType, value, ...) name = (value),
|
||||
|
||||
#include <xrpl/protocol/detail/permissions.macro>
|
||||
|
||||
#undef PERMISSION
|
||||
#pragma pop_macro("PERMISSION")
|
||||
#undef GRANULAR_PERMISSION
|
||||
#pragma pop_macro("GRANULAR_PERMISSION")
|
||||
};
|
||||
|
||||
// Injected bare enumerators (xrpl::delegable / xrpl::notDelegable) are required by preprocessor
|
||||
@@ -40,15 +45,30 @@ class Permission
|
||||
private:
|
||||
Permission();
|
||||
|
||||
std::unordered_map<std::uint16_t, uint256> txFeatureMap_;
|
||||
struct GranularPermissionEntry
|
||||
{
|
||||
std::string name;
|
||||
TxType txType;
|
||||
std::uint32_t permittedFlags;
|
||||
SOTemplate permittedFields;
|
||||
|
||||
std::unordered_map<std::uint16_t, Delegation> delegableTx_;
|
||||
GranularPermissionEntry(
|
||||
std::string name,
|
||||
TxType txType,
|
||||
std::uint32_t permittedFlags,
|
||||
std::vector<SOElement> fields);
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, GranularPermissionType> granularPermissionMap_;
|
||||
struct TxDelegationEntry
|
||||
{
|
||||
uint256 amendment;
|
||||
Delegation delegable{NotDelegable};
|
||||
};
|
||||
|
||||
std::unordered_map<GranularPermissionType, std::string> granularNameMap_;
|
||||
|
||||
std::unordered_map<GranularPermissionType, TxType> granularTxTypeMap_;
|
||||
std::unordered_set<TxType> granularTxTypes_;
|
||||
std::unordered_map<TxType, TxDelegationEntry> txDelegationMap_;
|
||||
std::unordered_map<std::string, GranularPermissionType> granularPermissionsByName_;
|
||||
std::unordered_map<GranularPermissionType, GranularPermissionEntry> granularPermissions_;
|
||||
|
||||
public:
|
||||
static Permission const&
|
||||
@@ -59,30 +79,52 @@ public:
|
||||
operator=(Permission const&) = delete;
|
||||
|
||||
[[nodiscard]] std::optional<std::string>
|
||||
getPermissionName(std::uint32_t const value) const;
|
||||
getPermissionName(std::uint32_t value) const;
|
||||
|
||||
[[nodiscard]] std::optional<std::uint32_t>
|
||||
getGranularValue(std::string const& name) const;
|
||||
|
||||
[[nodiscard]] std::optional<std::string>
|
||||
getGranularName(GranularPermissionType const& value) const;
|
||||
getGranularName(GranularPermissionType value) const;
|
||||
|
||||
[[nodiscard]] std::optional<TxType>
|
||||
getGranularTxType(GranularPermissionType const& gpType) const;
|
||||
getGranularTxType(GranularPermissionType gpType) const;
|
||||
|
||||
// Returns a reference to avoid copying uint256 - 32 bytes. std::optional
|
||||
// cannot hold references directly, so std::reference_wrapper is used.
|
||||
[[nodiscard]] std::optional<std::reference_wrapper<uint256 const>>
|
||||
getTxFeature(TxType txType) const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
isDelegable(std::uint32_t const& permissionValue, Rules const& rules) const;
|
||||
isDelegable(std::uint32_t permissionValue, Rules const& rules) const;
|
||||
|
||||
[[nodiscard]] bool
|
||||
hasGranularPermissions(TxType txType) const;
|
||||
|
||||
// for tx level permission, permission value is equal to tx type plus one
|
||||
static uint32_t
|
||||
txToPermissionType(TxType const& type);
|
||||
[[nodiscard]] static uint32_t
|
||||
txToPermissionType(TxType type);
|
||||
|
||||
// tx type value is permission value minus one
|
||||
static TxType
|
||||
permissionToTxType(uint32_t const& value);
|
||||
[[nodiscard]] static TxType
|
||||
permissionToTxType(std::uint32_t value);
|
||||
|
||||
/**
|
||||
* @brief Verifies a delegated transaction against its granular permission template.
|
||||
*
|
||||
* @note WARNING: Do not move this check before standard transaction-level
|
||||
* format checks, which is in preclaim. This function assumes the transaction's
|
||||
* base structural integrity (fees, sequence, signatures) has already been
|
||||
* validated.
|
||||
*
|
||||
* @param tx The transaction to verify.
|
||||
* @param heldPermissions The granular permissions that the sender hold.
|
||||
* @return true if the transaction fields and flags comply with the granular template.
|
||||
*/
|
||||
[[nodiscard]] bool
|
||||
checkGranularSandbox(
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldPermissions) const;
|
||||
};
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -359,38 +359,32 @@ inline constexpr FlagValue tfSponsorshipSetPermissionMask =
|
||||
|
||||
// MPTokenIssuanceCreate MutableFlags:
|
||||
// Indicating specific fields or flags may be changed after issuance.
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanLock = lsmfMPTCanMutateCanLock;
|
||||
inline constexpr FlagValue tmfMPTCanMutateRequireAuth = lsmfMPTCanMutateRequireAuth;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanEscrow = lsmfMPTCanMutateCanEscrow;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanTrade = lsmfMPTCanMutateCanTrade;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanTransfer = lsmfMPTCanMutateCanTransfer;
|
||||
inline constexpr FlagValue tmfMPTCanMutateCanClawback = lsmfMPTCanMutateCanClawback;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanLock = lsmfMPTCanEnableCanLock;
|
||||
inline constexpr FlagValue tmfMPTCanEnableRequireAuth = lsmfMPTCanEnableRequireAuth;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanEscrow = lsmfMPTCanEnableCanEscrow;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanTrade = lsmfMPTCanEnableCanTrade;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanTransfer = lsmfMPTCanEnableCanTransfer;
|
||||
inline constexpr FlagValue tmfMPTCanEnableCanClawback = lsmfMPTCanEnableCanClawback;
|
||||
inline constexpr FlagValue tmfMPTCanMutateMetadata = lsmfMPTCanMutateMetadata;
|
||||
inline constexpr FlagValue tmfMPTCanMutateTransferFee = lsmfMPTCanMutateTransferFee;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceCreateMutableMask =
|
||||
~(tmfMPTCanMutateCanLock | tmfMPTCanMutateRequireAuth | tmfMPTCanMutateCanEscrow |
|
||||
tmfMPTCanMutateCanTrade | tmfMPTCanMutateCanTransfer | tmfMPTCanMutateCanClawback |
|
||||
~(tmfMPTCanEnableCanLock | tmfMPTCanEnableRequireAuth | tmfMPTCanEnableCanEscrow |
|
||||
tmfMPTCanEnableCanTrade | tmfMPTCanEnableCanTransfer | tmfMPTCanEnableCanClawback |
|
||||
tmfMPTCanMutateMetadata | tmfMPTCanMutateTransferFee);
|
||||
|
||||
// MPTokenIssuanceSet MutableFlags:
|
||||
// Set or Clear flags.
|
||||
// Enable mutable capability flags. These flags are one-way: once enabled,
|
||||
// the corresponding capability cannot be disabled by MPTokenIssuanceSet.
|
||||
|
||||
inline constexpr FlagValue tmfMPTSetCanLock = 0x00000001;
|
||||
inline constexpr FlagValue tmfMPTClearCanLock = 0x00000002;
|
||||
inline constexpr FlagValue tmfMPTSetRequireAuth = 0x00000004;
|
||||
inline constexpr FlagValue tmfMPTClearRequireAuth = 0x00000008;
|
||||
inline constexpr FlagValue tmfMPTSetCanEscrow = 0x00000010;
|
||||
inline constexpr FlagValue tmfMPTClearCanEscrow = 0x00000020;
|
||||
inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000040;
|
||||
inline constexpr FlagValue tmfMPTClearCanTrade = 0x00000080;
|
||||
inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000100;
|
||||
inline constexpr FlagValue tmfMPTClearCanTransfer = 0x00000200;
|
||||
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000400;
|
||||
inline constexpr FlagValue tmfMPTClearCanClawback = 0x00000800;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask = ~(
|
||||
tmfMPTSetCanLock | tmfMPTClearCanLock | tmfMPTSetRequireAuth | tmfMPTClearRequireAuth |
|
||||
tmfMPTSetCanEscrow | tmfMPTClearCanEscrow | tmfMPTSetCanTrade | tmfMPTClearCanTrade |
|
||||
tmfMPTSetCanTransfer | tmfMPTClearCanTransfer | tmfMPTSetCanClawback | tmfMPTClearCanClawback);
|
||||
inline constexpr FlagValue tmfMPTSetRequireAuth = 0x00000002;
|
||||
inline constexpr FlagValue tmfMPTSetCanEscrow = 0x00000004;
|
||||
inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000008;
|
||||
inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000010;
|
||||
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000020;
|
||||
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask =
|
||||
~(tmfMPTSetCanLock | tmfMPTSetRequireAuth | tmfMPTSetCanEscrow | tmfMPTSetCanTrade |
|
||||
tmfMPTSetCanTransfer | tmfMPTSetCanClawback);
|
||||
|
||||
// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between accounts allowed a
|
||||
// TrustLine to be added to the issuer of that token without explicit permission from that issuer.
|
||||
|
||||
@@ -22,10 +22,10 @@ XRPL_FEATURE(MPTokensV2, Supported::No, VoteBehavior::DefaultN
|
||||
XRPL_FIX (Cleanup3_1_3, Supported::Yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (BatchInnerSigs, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(LendingProtocol, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegationV1_1, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PermissionDelegationV1_1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (DirectoryLimit, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (IncludeKeyletFields, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DynamicMPT, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(DynamicMPT, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (TokenEscrowV1, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PriceOracleOrder, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (MPTDeliveredAmount, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -1,55 +1,80 @@
|
||||
#if !defined(PERMISSION)
|
||||
#error "undefined macro: PERMISSION"
|
||||
#if !defined(GRANULAR_PERMISSION)
|
||||
#error "undefined macro: GRANULAR_PERMISSION"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* PERMISSION(name, type, txType, value)
|
||||
* GRANULAR_PERMISSION(name, txType, value, allowedFlags, allowedFields)
|
||||
*
|
||||
* This macro defines a permission:
|
||||
* name: the name of the permission.
|
||||
* type: the GranularPermissionType enum.
|
||||
* txType: the corresponding TxType for this permission.
|
||||
* value: the uint32 numeric value for the enum type.
|
||||
* Defines a granular permission:
|
||||
* name: the granular permission name.
|
||||
* txType: the corresponding TxType for this permission.
|
||||
* value: the uint32 numeric value for the enum type.
|
||||
* allowedFlags: transaction flags permitted under this permission.
|
||||
* allowedFields: transaction fields permitted under this permission.
|
||||
*/
|
||||
|
||||
/** This permission grants the delegated account the ability to authorize a trustline. */
|
||||
PERMISSION(TrustlineAuthorize, ttTRUST_SET, 65537)
|
||||
/** Grants the ability to authorize a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineAuthorize, ttTRUST_SET, 65537, tfUniversal | tfSetfAuth,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to freeze a trustline. */
|
||||
PERMISSION(TrustlineFreeze, ttTRUST_SET, 65538)
|
||||
/** Grants the ability to freeze a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineFreeze, ttTRUST_SET, 65538, tfUniversal | tfSetFreeze,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to unfreeze a trustline. */
|
||||
PERMISSION(TrustlineUnfreeze, ttTRUST_SET, 65539)
|
||||
/** Grants the ability to unfreeze a trustline. */
|
||||
GRANULAR_PERMISSION(TrustlineUnfreeze, ttTRUST_SET, 65539, tfUniversal | tfClearFreeze,
|
||||
({{sfLimitAmount, SoeRequired}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set Domain. */
|
||||
PERMISSION(AccountDomainSet, ttACCOUNT_SET, 65540)
|
||||
/** Grants the ability to set Domain. */
|
||||
GRANULAR_PERMISSION(AccountDomainSet, ttACCOUNT_SET, 65540, tfUniversal,
|
||||
({{sfDomain, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set EmailHashSet. */
|
||||
PERMISSION(AccountEmailHashSet, ttACCOUNT_SET, 65541)
|
||||
/** Grants the ability to set EmailHash. */
|
||||
GRANULAR_PERMISSION(AccountEmailHashSet, ttACCOUNT_SET, 65541, tfUniversal,
|
||||
({{sfEmailHash, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set MessageKey. */
|
||||
PERMISSION(AccountMessageKeySet, ttACCOUNT_SET, 65542)
|
||||
/** Grants the ability to set MessageKey. */
|
||||
GRANULAR_PERMISSION(AccountMessageKeySet, ttACCOUNT_SET, 65542, tfUniversal,
|
||||
({{sfMessageKey, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set TransferRate. */
|
||||
PERMISSION(AccountTransferRateSet, ttACCOUNT_SET, 65543)
|
||||
/** Grants the ability to set TransferRate. */
|
||||
GRANULAR_PERMISSION(AccountTransferRateSet, ttACCOUNT_SET, 65543, tfUniversal,
|
||||
({{sfTransferRate, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set TickSize. */
|
||||
PERMISSION(AccountTickSizeSet, ttACCOUNT_SET, 65544)
|
||||
/** Grants the ability to set TickSize. */
|
||||
GRANULAR_PERMISSION(AccountTickSizeSet, ttACCOUNT_SET, 65544, tfUniversal,
|
||||
({{sfTickSize, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to mint payment, which means sending a payment for a currency where the sending account is the issuer. */
|
||||
PERMISSION(PaymentMint, ttPAYMENT, 65545)
|
||||
/** Grants the ability to mint payment (sending account is the issuer). Cross-currency payments are disallowed. */
|
||||
GRANULAR_PERMISSION(PaymentMint, ttPAYMENT, 65545, tfUniversal,
|
||||
({{sfDestination, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfSendMax, SoeOptional},
|
||||
{sfInvoiceID, SoeOptional},
|
||||
{sfDestinationTag, SoeOptional},
|
||||
{sfCredentialIDs, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to burn payment, which means sending a payment for a currency where the destination account is the issuer */
|
||||
PERMISSION(PaymentBurn, ttPAYMENT, 65546)
|
||||
/** Grants the ability to burn payment (destination account is the issuer). Cross-currency payments are disallowed. */
|
||||
GRANULAR_PERMISSION(PaymentBurn, ttPAYMENT, 65546, tfUniversal,
|
||||
({{sfDestination, SoeRequired},
|
||||
{sfAmount, SoeRequired},
|
||||
{sfSendMax, SoeOptional},
|
||||
{sfInvoiceID, SoeOptional},
|
||||
{sfDestinationTag, SoeOptional},
|
||||
{sfCredentialIDs, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to lock MPToken. */
|
||||
PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547)
|
||||
/** Grants the ability to lock an MPToken. */
|
||||
GRANULAR_PERMISSION(MPTokenIssuanceLock, ttMPTOKEN_ISSUANCE_SET, 65547, tfUniversal | tfMPTLock,
|
||||
({{sfMPTokenIssuanceID, SoeRequired},
|
||||
{sfHolder, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to unlock MPToken. */
|
||||
PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548)
|
||||
/** Grants the ability to unlock an MPToken. */
|
||||
GRANULAR_PERMISSION(MPTokenIssuanceUnlock, ttMPTOKEN_ISSUANCE_SET, 65548, tfUniversal | tfMPTUnlock,
|
||||
({{sfMPTokenIssuanceID, SoeRequired},
|
||||
{sfHolder, SoeOptional}}))
|
||||
|
||||
/** This permission grants the delegated account the ability to set SponsorFee. */
|
||||
PERMISSION(SponsorFee, ttSPONSORSHIP_SET, 65549)
|
||||
GRANULAR_PERMISSION(SponsorFee, ttSPONSORSHIP_SET, 65549)
|
||||
|
||||
/** This permission grants the delegated account the ability to set SponsorReserve. */
|
||||
PERMISSION(SponsorReserve, ttSPONSORSHIP_SET, 65550)
|
||||
GRANULAR_PERMISSION(SponsorReserve, ttSPONSORSHIP_SET, 65550)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/applySteps.h>
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace xrpl {
|
||||
@@ -237,8 +238,63 @@ public:
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can be overridden to introduce additional semantic constraints beyond the
|
||||
* granular template validation for granular permissions. It is called by the base
|
||||
* invokeCheckPermission method only after the transaction has successfully passed
|
||||
* checkGranularSandbox.
|
||||
*/
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
checkGranularSemantics(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldGranularPermissions)
|
||||
{
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the transaction is authorized to be executed by the delegated account.
|
||||
* This function enforces the strict permission check hierarchy. It is explicitly
|
||||
* designed NOT to be overridden. Derived transactors must instead implement
|
||||
* checkGranularSemantics to add custom validation logic for granular permissions.
|
||||
*
|
||||
* The evaluation proceeds as follows:
|
||||
* - If transaction-level permission is granted, the function immediately returns tesSUCCESS.
|
||||
* - If transaction-level permission is not granted, the function checks whether the transaction
|
||||
* matches the granular permission template defined in permissions.macro. If it does, it then
|
||||
* calls checkGranularSemantics to perform any additional, fine-grained validation.
|
||||
*
|
||||
*/
|
||||
template <class T>
|
||||
static NotTEC
|
||||
invokeCheckPermission(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
// heldGranularPermissions is passed by reference into checkPermission.
|
||||
// It is populated with the sender’s granular permissions only when the sender
|
||||
// lacks tx-level permission but has granular permissions that satisfy the
|
||||
// granular permission template.
|
||||
//
|
||||
// - result is terNO_DELEGATE_PERMISSION: return immediately.
|
||||
// - result is tesSUCCESS and heldGranularPermissions is empty: tx-level permission was
|
||||
// granted, so we returned success before populating it.
|
||||
// - result is tesSUCCESS and heldGranularPermissions is not empty: tx-level permission was
|
||||
// not granted, but the held granular permissions passed checkGranularSandbox, so we proceed
|
||||
// to checkGranularSemantics.
|
||||
//
|
||||
// WARNING: Do not simplify checkPermission to return only
|
||||
// heldGranularPermissions or the ter code. Both the result and the
|
||||
// populated set are required to enforce the strict permission hierarchy
|
||||
// described above.
|
||||
std::unordered_set<GranularPermissionType> heldGranularPermissions;
|
||||
if (NotTEC const result = checkPermission(view, tx, heldGranularPermissions);
|
||||
!isTesSuccess(result) || heldGranularPermissions.empty())
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return T::checkGranularSemantics(view, tx, heldGranularPermissions);
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
checkSponsor(ReadView const& view, STTx const& tx);
|
||||
@@ -371,6 +427,12 @@ protected:
|
||||
unit::ValueUnit<Unit, T> min = unit::ValueUnit<Unit, T>{});
|
||||
|
||||
private:
|
||||
static NotTEC
|
||||
checkPermission(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType>& heldGranularPermissions);
|
||||
|
||||
std::pair<TER, XRPAmount>
|
||||
reset(XRPAmount fee);
|
||||
|
||||
@@ -379,8 +441,13 @@ private:
|
||||
|
||||
TER
|
||||
consumeSeqProxy(SLE::pointer const& sleAccount);
|
||||
|
||||
TER
|
||||
payFee();
|
||||
|
||||
std::tuple<TER, XRPAmount, bool>
|
||||
processPersistentChanges(TER result, XRPAmount fee);
|
||||
|
||||
static NotTEC
|
||||
checkSingleSign(
|
||||
ReadView const& view,
|
||||
@@ -388,6 +455,7 @@ private:
|
||||
AccountID const& idAccount,
|
||||
SLE::const_pointer sleAccount,
|
||||
beast::Journal const j);
|
||||
|
||||
static NotTEC
|
||||
checkMultiSign(
|
||||
ReadView const& view,
|
||||
|
||||
@@ -15,7 +15,9 @@ class ValidAMM
|
||||
std::optional<AccountID> ammAccount_;
|
||||
std::optional<STAmount> lptAMMBalanceAfter_;
|
||||
std::optional<STAmount> lptAMMBalanceBefore_;
|
||||
std::optional<STAmount> lptAMMBalanceBeforeDeletion_;
|
||||
bool ammPoolChanged_{false};
|
||||
bool ammDeleted_{false};
|
||||
|
||||
public:
|
||||
enum class ZeroAllowed : bool { No = false, Yes = true };
|
||||
@@ -35,12 +37,17 @@ private:
|
||||
[[nodiscard]] bool
|
||||
finalizeCreate(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDelete(bool enforce, TER res, beast::Journal const&) const;
|
||||
finalizeDelete(bool enforce, bool enforceAMMDelete, TER res, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDeposit(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
// Includes clawback
|
||||
[[nodiscard]] bool
|
||||
finalizeWithdraw(STTx const&, ReadView const&, bool enforce, beast::Journal const&) const;
|
||||
finalizeWithdraw(
|
||||
STTx const&,
|
||||
ReadView const&,
|
||||
bool enforce,
|
||||
bool enforceAMMDelete,
|
||||
beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
finalizeDEX(bool enforce, beast::Journal const&) const;
|
||||
[[nodiscard]] bool
|
||||
|
||||
@@ -23,9 +23,6 @@ public:
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
|
||||
@@ -32,7 +32,10 @@ public:
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
checkGranularSemantics(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldGranularPermissions);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
@@ -22,9 +22,6 @@ public:
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ public:
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
checkPermission(ReadView const& view, STTx const& tx);
|
||||
checkGranularSemantics(
|
||||
ReadView const& view,
|
||||
STTx const& tx,
|
||||
std::unordered_set<GranularPermissionType> const& heldGranularPermissions);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
Reference in New Issue
Block a user