From 1b295c7c001d4148d9e62db3b96dd660f5a487ca Mon Sep 17 00:00:00 2001 From: Ed Hennis Date: Wed, 10 Sep 2025 20:33:01 -0400 Subject: [PATCH] Use Permission to check if a Transactor is enabled - Adds a Permission::getTxFeature lookup function to find the controlling amendment for a Transactor, if any. - Returns temDISABLED from preflight if there is an amendment and it's not enabled. - Still need to go through and remove all the now-redundant isEnabled functions. --- include/xrpl/protocol/Permissions.h | 3 +++ src/libxrpl/protocol/Permissions.cpp | 21 +++++++++++++++------ src/xrpld/app/tx/detail/Transactor.h | 9 +++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/xrpl/protocol/Permissions.h b/include/xrpl/protocol/Permissions.h index cf49ff7382..924a5af0da 100644 --- a/include/xrpl/protocol/Permissions.h +++ b/include/xrpl/protocol/Permissions.h @@ -83,6 +83,9 @@ public: std::optional getGranularTxType(GranularPermissionType const& gpType) const; + std::optional> const + getTxFeature(TxType txType) const; + bool isDelegatable(std::uint32_t const& permissionValue, Rules const& rules) const; diff --git a/src/libxrpl/protocol/Permissions.cpp b/src/libxrpl/protocol/Permissions.cpp index 781799f128..af4b7e42c4 100644 --- a/src/libxrpl/protocol/Permissions.cpp +++ b/src/libxrpl/protocol/Permissions.cpp @@ -131,6 +131,19 @@ Permission::getGranularTxType(GranularPermissionType const& gpType) const return std::nullopt; } +std::optional> const +Permission::getTxFeature(TxType txType) const +{ + auto const txFeaturesIt = txFeatureMap_.find(txType); + XRPL_ASSERT( + txFeaturesIt != txFeatureMap_.end(), + "ripple::Permissions::isDelegatable : tx exists in txFeatureMap_"); + + if (txFeaturesIt->second == uint256{}) + return std::nullopt; + return txFeaturesIt->second; +} + bool Permission::isDelegatable( std::uint32_t const& permissionValue, @@ -150,16 +163,12 @@ Permission::isDelegatable( if (it == delegatableTx_.end()) return false; - auto const txFeaturesIt = txFeatureMap_.find(txType); - XRPL_ASSERT( - txFeaturesIt != txFeatureMap_.end(), - "ripple::Permissions::isDelegatable : tx exists in txFeatureMap_"); + auto const feature = getTxFeature(txType); // fixDelegateV1_1: Delegation is only allowed if the required amendment // for the transaction is enabled. For transactions that do not require // an amendment, delegation is always allowed. - if (txFeaturesIt->second != uint256{} && - !rules.enabled(txFeaturesIt->second)) + if (feature && !rules.enabled(*feature)) return false; } diff --git a/src/xrpld/app/tx/detail/Transactor.h b/src/xrpld/app/tx/detail/Transactor.h index 29a8df7574..9b5638d9e1 100644 --- a/src/xrpld/app/tx/detail/Transactor.h +++ b/src/xrpld/app/tx/detail/Transactor.h @@ -392,6 +392,15 @@ Transactor::invokePreflight(PreflightContext const& ctx) // TODO: If #5650 is merged, use its transaction -> amendment lookup here to // do a first-pass check. Rewrite or remove any `isEnabled` overloads that // check those default amendments. + + // Using this lookup does NOT require checking the fixDelegateV1_1. The data + // exists regardless of whether it is enabled. + auto const feature = + Permission::getInstance().getTxFeature(ctx.tx.getTxnType()); + + if (feature && !ctx.rules.enabled(*feature)) + return temDISABLED; + if (!T::isEnabled(ctx)) return temDISABLED;