diff --git a/include/xrpl/protocol/Feature.h b/include/xrpl/protocol/Feature.h index 304cac5bc6..75add39af9 100644 --- a/include/xrpl/protocol/Feature.h +++ b/include/xrpl/protocol/Feature.h @@ -61,6 +61,13 @@ * 2) The feature is not in the ledger (has always been marked as * Supported::no) and the code to support it has been removed * + * If we want to discontinue a feature that we've never fully supported and + * the feature has never been enabled, we should remove all the related + * code, and mark the feature as "abandoned". To do this: + * + * 1) Open features.macro, move the feature to the abandoned section and + * change the macro to XRPL_ABANDON + * * When a feature has been enabled for several years, the conditional code * may be removed, and the feature "retired". To retire a feature: * @@ -93,10 +100,13 @@ namespace detail { #undef XRPL_FIX #pragma push_macro("XRPL_RETIRE") #undef XRPL_RETIRE +#pragma push_macro("XRPL_ABANDON") +#undef XRPL_ABANDON #define XRPL_FEATURE(name, supported, vote) +1 #define XRPL_FIX(name, supported, vote) +1 #define XRPL_RETIRE(name) +1 +#define XRPL_ABANDON(name) +1 // This value SHOULD be equal to the number of amendments registered in // Feature.cpp. Because it's only used to reserve storage, and determine how @@ -113,6 +123,8 @@ static constexpr std::size_t numFeatures = #pragma pop_macro("XRPL_FIX") #undef XRPL_FEATURE #pragma pop_macro("XRPL_FEATURE") +#undef XRPL_ABANDON +#pragma pop_macro("XRPL_ABANDON") /** Amendments that this server supports and the default voting behavior. Whether they are enabled depends on the Rules defined in the validated @@ -354,10 +366,13 @@ foreachFeature(FeatureBitset bs, F&& f) #undef XRPL_FIX #pragma push_macro("XRPL_RETIRE") #undef XRPL_RETIRE +#pragma push_macro("XRPL_ABANDON") +#undef XRPL_ABANDON #define XRPL_FEATURE(name, supported, vote) extern uint256 const feature##name; #define XRPL_FIX(name, supported, vote) extern uint256 const fix##name; #define XRPL_RETIRE(name) +#define XRPL_ABANDON(name) #include @@ -367,6 +382,8 @@ foreachFeature(FeatureBitset bs, F&& f) #pragma pop_macro("XRPL_FIX") #undef XRPL_FEATURE #pragma pop_macro("XRPL_FEATURE") +#undef XRPL_ABANDON +#pragma pop_macro("XRPL_ABANDON") } // namespace ripple diff --git a/include/xrpl/protocol/detail/features.macro b/include/xrpl/protocol/detail/features.macro index 2442abef7f..3584d8f8cf 100644 --- a/include/xrpl/protocol/detail/features.macro +++ b/include/xrpl/protocol/detail/features.macro @@ -26,6 +26,9 @@ #if !defined(XRPL_RETIRE) #error "undefined macro: XRPL_RETIRE" #endif +#if !defined(XRPL_ABANDON) +#error "undefined macro: XRPL_ABANDON" +#endif // Add new amendments to the top of this list. // Keep it sorted in reverse chronological order. @@ -130,8 +133,11 @@ XRPL_FIX (NFTokenNegOffer, Supported::yes, VoteBehavior::Obsolete) XRPL_FIX (NFTokenDirV1, Supported::yes, VoteBehavior::Obsolete) XRPL_FEATURE(NonFungibleTokensV1, Supported::yes, VoteBehavior::Obsolete) XRPL_FEATURE(CryptoConditionsSuite, Supported::yes, VoteBehavior::Obsolete) -// This sits here temporarily and will be moved to another section soon -XRPL_FEATURE(OwnerPaysFee, Supported::no, VoteBehavior::Obsolete) + +// The following amendments were never supported, never enabled, and +// we've abanded them. These features should never be in the ledger, +// and we've removed all the related code. +XRPL_ABANDON(OwnerPaysFee) // The following amendments have been active for at least two years. Their // pre-amendment code has been removed and the identifiers are deprecated. diff --git a/src/libxrpl/protocol/Feature.cpp b/src/libxrpl/protocol/Feature.cpp index e6442d2663..478b155387 100644 --- a/src/libxrpl/protocol/Feature.cpp +++ b/src/libxrpl/protocol/Feature.cpp @@ -398,6 +398,14 @@ retireFeature(std::string const& name) return registerFeature(name, Supported::yes, VoteBehavior::Obsolete); } +// Abandoned features are not in the ledger and have no code controlled by the +// feature. They were never supported, and cannot be voted on. +uint256 +abandonFeature(std::string const& name) +{ + return registerFeature(name, Supported::no, VoteBehavior::Obsolete); +} + /** Tell FeatureCollections when registration is complete. */ bool registrationIsDone() @@ -432,6 +440,8 @@ featureToName(uint256 const& f) #undef XRPL_FIX #pragma push_macro("XRPL_RETIRE") #undef XRPL_RETIRE +#pragma push_macro("XRPL_ABANDON") +#undef XRPL_ABANDON #define XRPL_FEATURE(name, supported, vote) \ uint256 const feature##name = registerFeature(#name, supported, vote); @@ -443,6 +453,11 @@ featureToName(uint256 const& f) [[deprecated("The referenced amendment has been retired")]] \ [[maybe_unused]] \ uint256 const retired##name = retireFeature(#name); + +#define XRPL_ABANDON(name) \ + [[deprecated("The referenced amendment has been abandoned")]] \ + [[maybe_unused]] \ + uint256 const abandoned##name = abandonFeature(#name); // clang-format on #include @@ -453,6 +468,8 @@ featureToName(uint256 const& f) #pragma pop_macro("XRPL_FIX") #undef XRPL_FEATURE #pragma pop_macro("XRPL_FEATURE") +#undef XRPL_ABANDON +#pragma pop_macro("XRPL_ABANDON") // All of the features should now be registered, since variables in a cpp file // are initialized from top to bottom.