From 2220f65cb257bc729ae8f186227adb520f453b76 Mon Sep 17 00:00:00 2001 From: Denis Angell Date: Wed, 10 Jul 2024 12:18:53 +0200 Subject: [PATCH] new feature template --- Builds/CMake/RippledCore.cmake | 2 + src/ripple/app/tx/impl/SetHookDefinition.cpp | 60 +++++++++++++++++++ src/ripple/app/tx/impl/SetHookDefinition.h | 54 +++++++++++++++++ src/ripple/app/tx/impl/applySteps.cpp | 11 ++++ src/ripple/basics/impl/mulDiv.cpp | 2 +- .../container/detail/aged_ordered_container.h | 55 ++++------------- .../detail/aged_unordered_container.h | 55 ++++------------- src/ripple/peerfinder/impl/Bootcache.h | 7 --- src/ripple/peerfinder/impl/Livecache.h | 11 ---- src/ripple/protocol/Feature.h | 3 +- src/ripple/protocol/TxFormats.h | 1 + src/ripple/protocol/impl/Feature.cpp | 1 + src/ripple/protocol/impl/TxFormats.cpp | 13 ++++ src/ripple/protocol/jss.h | 1 + src/ripple/shamap/impl/SHAMapInnerNode.cpp | 2 +- src/test/app/SetHookDefinition_test.cpp | 58 ++++++++++++++++++ 16 files changed, 228 insertions(+), 108 deletions(-) create mode 100644 src/ripple/app/tx/impl/SetHookDefinition.cpp create mode 100644 src/ripple/app/tx/impl/SetHookDefinition.h create mode 100644 src/test/app/SetHookDefinition_test.cpp diff --git a/Builds/CMake/RippledCore.cmake b/Builds/CMake/RippledCore.cmake index 9a211ef9b..0110e4451 100644 --- a/Builds/CMake/RippledCore.cmake +++ b/Builds/CMake/RippledCore.cmake @@ -455,6 +455,7 @@ target_sources (rippled PRIVATE src/ripple/app/tx/impl/Remit.cpp src/ripple/app/tx/impl/SetAccount.cpp src/ripple/app/tx/impl/SetHook.cpp + src/ripple/app/tx/impl/SetHookDefinition.cpp src/ripple/app/tx/impl/SetRegularKey.cpp src/ripple/app/tx/impl/SetSignerList.cpp src/ripple/app/tx/impl/SetTrust.cpp @@ -757,6 +758,7 @@ if (tests) src/test/app/ValidatorList_test.cpp src/test/app/ValidatorSite_test.cpp src/test/app/SetHook_test.cpp + src/test/app/SetHookDefinition_test.cpp src/test/app/SetHookTSH_test.cpp src/test/app/Wildcard_test.cpp src/test/app/XahauGenesis_test.cpp diff --git a/src/ripple/app/tx/impl/SetHookDefinition.cpp b/src/ripple/app/tx/impl/SetHookDefinition.cpp new file mode 100644 index 000000000..b14244b26 --- /dev/null +++ b/src/ripple/app/tx/impl/SetHookDefinition.cpp @@ -0,0 +1,60 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include +#include +#include + +namespace ripple { + +XRPAmount +SetHookDefinition::calculateBaseFee(ReadView const& view, STTx const& tx) +{ + return Transactor::calculateBaseFee(view, tx); +} + +NotTEC +SetHookDefinition::preflight(PreflightContext const& ctx) +{ + if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) + return ret; + + return preflight2(ctx); +} + +TER +SetHookDefinition::preclaim(PreclaimContext const& ctx) +{ + if (!ctx.view.rules().enabled(featureHooksUpdate2)) + return temDISABLED; + + return tesSUCCESS; +} + +TER +SetHookDefinition::doApply() +{ + if (!ctx.view.rules().enabled(featureHooksUpdate2)) + return temDISABLED; + + return tesSUCCESS; +} + +} // namespace ripple diff --git a/src/ripple/app/tx/impl/SetHookDefinition.h b/src/ripple/app/tx/impl/SetHookDefinition.h new file mode 100644 index 000000000..082625a8e --- /dev/null +++ b/src/ripple/app/tx/impl/SetHookDefinition.h @@ -0,0 +1,54 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_TX_SETHOOK_DEFINTION_H_INCLUDED +#define RIPPLE_TX_SETHOOK_DEFINTION_H_INCLUDED + +#include +#include +#include +#include + +namespace ripple { + +class SetHookDefinition : public Transactor +{ +public: + static constexpr ConsequencesFactoryType ConsequencesFactory{Blocker}; + + explicit SetHookDefinition(ApplyContext& ctx) : Transactor(ctx) + { + } + + static XRPAmount + calculateBaseFee(ReadView const& view, STTx const& tx); + + static NotTEC + preflight(PreflightContext const& ctx); + + static TER + preclaim(PreclaimContext const& ctx); + + TER + doApply() override; +}; + +} // namespace ripple + +#endif diff --git a/src/ripple/app/tx/impl/applySteps.cpp b/src/ripple/app/tx/impl/applySteps.cpp index ab2bf30ca..d506f1353 100644 --- a/src/ripple/app/tx/impl/applySteps.cpp +++ b/src/ripple/app/tx/impl/applySteps.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -175,6 +176,8 @@ invoke_preflight(PreflightContext const& ctx) case ttURITOKEN_CREATE_SELL_OFFER: case ttURITOKEN_CANCEL_SELL_OFFER: return invoke_preflight_helper(ctx); + case ttHOOK_SET_DEFINITION: + return invoke_preflight_helper(ctx); default: assert(false); return {temUNKNOWN, TxConsequences{temUNKNOWN}}; @@ -296,6 +299,8 @@ invoke_preclaim(PreclaimContext const& ctx) case ttURITOKEN_CREATE_SELL_OFFER: case ttURITOKEN_CANCEL_SELL_OFFER: return invoke_preclaim(ctx); + case ttHOOK_SET_DEFINITION: + return invoke_preclaim(ctx); default: assert(false); return temUNKNOWN; @@ -379,6 +384,8 @@ invoke_calculateBaseFee(ReadView const& view, STTx const& tx) case ttURITOKEN_CREATE_SELL_OFFER: case ttURITOKEN_CANCEL_SELL_OFFER: return URIToken::calculateBaseFee(view, tx); + case ttHOOK_SET_DEFINITION: + return SetHookDefinition::calculateBaseFee(view, tx); default: return XRPAmount{0}; } @@ -564,6 +571,10 @@ invoke_apply(ApplyContext& ctx) URIToken p(ctx); return p(); } + case ttHOOK_SET_DEFINITION: { + SetHookDefinition p(ctx); + return p(); + } default: assert(false); return {temUNKNOWN, false}; diff --git a/src/ripple/basics/impl/mulDiv.cpp b/src/ripple/basics/impl/mulDiv.cpp index 20e72e047..433c7dddd 100644 --- a/src/ripple/basics/impl/mulDiv.cpp +++ b/src/ripple/basics/impl/mulDiv.cpp @@ -30,7 +30,7 @@ mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div) { using namespace boost::multiprecision; - uint128_t result; + boost::multiprecision::uint128_t result; result = multiply(result, value, mul); result /= div; diff --git a/src/ripple/beast/container/detail/aged_ordered_container.h b/src/ripple/beast/container/detail/aged_ordered_container.h index 23534a26b..10dca962b 100644 --- a/src/ripple/beast/container/detail/aged_ordered_container.h +++ b/src/ripple/beast/container/detail/aged_ordered_container.h @@ -145,111 +145,78 @@ private: }; // VFALCO TODO This should only be enabled for maps. - class pair_value_compare - : public beast::detail::empty_base_optimization -#ifdef _LIBCPP_VERSION - , - public std::binary_function -#endif + class pair_value_compare : public Compare { public: -#ifndef _LIBCPP_VERSION using first_argument = value_type; using second_argument = value_type; using result_type = bool; -#endif bool operator()(value_type const& lhs, value_type const& rhs) const { - return this->member()(lhs.first, rhs.first); + return Compare::operator()(lhs.first, rhs.first); } pair_value_compare() { } - pair_value_compare(pair_value_compare const& other) - : beast::detail::empty_base_optimization(other) + pair_value_compare(pair_value_compare const& other) : Compare(other) { } private: friend aged_ordered_container; - pair_value_compare(Compare const& compare) - : beast::detail::empty_base_optimization(compare) + pair_value_compare(Compare const& compare) : Compare(compare) { } }; // Compares value_type against element, used in insert_check // VFALCO TODO hoist to remove template argument dependencies - class KeyValueCompare - : public beast::detail::empty_base_optimization -#ifdef _LIBCPP_VERSION - , - public std::binary_function -#endif + class KeyValueCompare : public Compare { public: -#ifndef _LIBCPP_VERSION using first_argument = Key; using second_argument = element; using result_type = bool; -#endif KeyValueCompare() = default; - KeyValueCompare(Compare const& compare) - : beast::detail::empty_base_optimization(compare) + KeyValueCompare(Compare const& compare) : Compare(compare) { } - // VFALCO NOTE WE might want only to enable these overloads - // if Compare has is_transparent -#if 0 - template - bool operator() (K const& k, element const& e) const - { - return this->member() (k, extract (e.value)); - } - - template - bool operator() (element const& e, K const& k) const - { - return this->member() (extract (e.value), k); - } -#endif - bool operator()(Key const& k, element const& e) const { - return this->member()(k, extract(e.value)); + return Compare::operator()(k, extract(e.value)); } bool operator()(element const& e, Key const& k) const { - return this->member()(extract(e.value), k); + return Compare::operator()(extract(e.value), k); } bool operator()(element const& x, element const& y) const { - return this->member()(extract(x.value), extract(y.value)); + return Compare::operator()(extract(x.value), extract(y.value)); } Compare& compare() { - return beast::detail::empty_base_optimization::member(); + return *this; } Compare const& compare() const { - return beast::detail::empty_base_optimization::member(); + return *this; } }; diff --git a/src/ripple/beast/container/detail/aged_unordered_container.h b/src/ripple/beast/container/detail/aged_unordered_container.h index 920e6196b..fcdccd2a6 100644 --- a/src/ripple/beast/container/detail/aged_unordered_container.h +++ b/src/ripple/beast/container/detail/aged_unordered_container.h @@ -148,115 +148,84 @@ private: }; // VFALCO TODO hoist to remove template argument dependencies - class ValueHash : private beast::detail::empty_base_optimization -#ifdef _LIBCPP_VERSION - , - public std::unary_function -#endif + class ValueHash : public Hash { public: -#ifndef _LIBCPP_VERSION using argument_type = element; using result_type = size_t; -#endif ValueHash() { } - ValueHash(Hash const& h) - : beast::detail::empty_base_optimization(h) + ValueHash(Hash const& h) : Hash(h) { } std::size_t operator()(element const& e) const { - return this->member()(extract(e.value)); + return Hash::operator()(extract(e.value)); } Hash& hash_function() { - return this->member(); + return *this; } Hash const& hash_function() const { - return this->member(); + return *this; } }; // Compares value_type against element, used in find/insert_check // VFALCO TODO hoist to remove template argument dependencies - class KeyValueEqual - : private beast::detail::empty_base_optimization -#ifdef _LIBCPP_VERSION - , - public std::binary_function -#endif + class KeyValueEqual : public KeyEqual { public: -#ifndef _LIBCPP_VERSION using first_argument_type = Key; using second_argument_type = element; using result_type = bool; -#endif KeyValueEqual() { } - KeyValueEqual(KeyEqual const& keyEqual) - : beast::detail::empty_base_optimization(keyEqual) + KeyValueEqual(KeyEqual const& keyEqual) : KeyEqual(keyEqual) { } - // VFALCO NOTE WE might want only to enable these overloads - // if KeyEqual has is_transparent -#if 0 - template - bool operator() (K const& k, element const& e) const - { - return this->member() (k, extract (e.value)); - } - - template - bool operator() (element const& e, K const& k) const - { - return this->member() (extract (e.value), k); - } -#endif - bool operator()(Key const& k, element const& e) const { - return this->member()(k, extract(e.value)); + return KeyEqual::operator()(k, extract(e.value)); } bool operator()(element const& e, Key const& k) const { - return this->member()(extract(e.value), k); + return KeyEqual::operator()(extract(e.value), k); } bool operator()(element const& lhs, element const& rhs) const { - return this->member()(extract(lhs.value), extract(rhs.value)); + return KeyEqual::operator()(extract(lhs.value), extract(rhs.value)); } KeyEqual& key_eq() { - return this->member(); + return *this; } KeyEqual const& key_eq() const { - return this->member(); + return *this; } }; diff --git a/src/ripple/peerfinder/impl/Bootcache.h b/src/ripple/peerfinder/impl/Bootcache.h index eb6455879..b48f248ae 100644 --- a/src/ripple/peerfinder/impl/Bootcache.h +++ b/src/ripple/peerfinder/impl/Bootcache.h @@ -91,17 +91,10 @@ private: using value_type = map_type::value_type; struct Transform -#ifdef _LIBCPP_VERSION - : std::unary_function< - map_type::right_map::const_iterator::value_type const&, - beast::IP::Endpoint const&> -#endif { -#ifndef _LIBCPP_VERSION using first_argument_type = map_type::right_map::const_iterator::value_type const&; using result_type = beast::IP::Endpoint const&; -#endif explicit Transform() = default; diff --git a/src/ripple/peerfinder/impl/Livecache.h b/src/ripple/peerfinder/impl/Livecache.h index 12e2373fa..8ecd68e84 100644 --- a/src/ripple/peerfinder/impl/Livecache.h +++ b/src/ripple/peerfinder/impl/Livecache.h @@ -69,14 +69,9 @@ public: public: // Iterator transformation to extract the endpoint from Element struct Transform -#ifdef _LIBCPP_VERSION - : public std::unary_function -#endif { -#ifndef _LIBCPP_VERSION using first_argument = Element; using result_type = Endpoint; -#endif explicit Transform() = default; @@ -239,15 +234,9 @@ public: template struct Transform -#ifdef _LIBCPP_VERSION - : public std:: - unary_function> -#endif { -#ifndef _LIBCPP_VERSION using first_argument = typename lists_type::value_type; using result_type = Hop; -#endif explicit Transform() = default; diff --git a/src/ripple/protocol/Feature.h b/src/ripple/protocol/Feature.h index 2d46df876..d65094aae 100644 --- a/src/ripple/protocol/Feature.h +++ b/src/ripple/protocol/Feature.h @@ -74,7 +74,7 @@ namespace detail { // Feature.cpp. Because it's only used to reserve storage, and determine how // large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than // the actual number of amendments. A LogicError on startup will verify this. -static constexpr std::size_t numFeatures = 70; +static constexpr std::size_t numFeatures = 71; /** Amendments that this server supports and the default voting behavior. Whether they are enabled depends on the Rules defined in the validated @@ -358,6 +358,7 @@ extern uint256 const fixXahauV2; extern uint256 const featureRemit; extern uint256 const featureZeroB2M; extern uint256 const fixNSDelete; +extern uint256 const featureHooksUpdate2; } // namespace ripple diff --git a/src/ripple/protocol/TxFormats.h b/src/ripple/protocol/TxFormats.h index 2f287efe5..e0acf0749 100644 --- a/src/ripple/protocol/TxFormats.h +++ b/src/ripple/protocol/TxFormats.h @@ -185,6 +185,7 @@ enum TxType : std::uint16_t ttUNL_MODIFY = 102, ttEMIT_FAILURE = 103, ttUNL_REPORT = 104, + ttHOOK_SET_DEFINITION = 105, }; // clang-format on diff --git a/src/ripple/protocol/impl/Feature.cpp b/src/ripple/protocol/impl/Feature.cpp index 9cf82e316..2ed450a18 100644 --- a/src/ripple/protocol/impl/Feature.cpp +++ b/src/ripple/protocol/impl/Feature.cpp @@ -464,6 +464,7 @@ REGISTER_FIX (fixXahauV2, Supported::yes, VoteBehavior::De REGISTER_FEATURE(Remit, Supported::yes, VoteBehavior::DefaultNo); REGISTER_FEATURE(ZeroB2M, Supported::yes, VoteBehavior::DefaultNo); REGISTER_FIX (fixNSDelete, Supported::yes, VoteBehavior::DefaultNo); +REGISTER_FIX (HooksUpdate2, Supported::yes, VoteBehavior::DefaultNo); // The following amendments are obsolete, but must remain supported // because they could potentially get enabled. diff --git a/src/ripple/protocol/impl/TxFormats.cpp b/src/ripple/protocol/impl/TxFormats.cpp index 6c38711ad..71787e49b 100644 --- a/src/ripple/protocol/impl/TxFormats.cpp +++ b/src/ripple/protocol/impl/TxFormats.cpp @@ -456,6 +456,19 @@ TxFormats::TxFormats() {sfTicketSequence, soeOPTIONAL}, }, commonFields); + + add(jss::SetHookDefinition, + ttHOOK_SET_DEFINITION, + { + {sfCreateCode, soeREQUIRED}, + {sfHookNamespace, soeREQUIRED}, + {sfHookParameters, soeREQUIRED}, + {sfHookGrants, soeOPTIONAL}, + {sfHookOn, soeREQUIRED}, + {sfHookApiVersion, soeREQUIRED}, + {sfFlags, soeREQUIRED}, + }, + commonFields); } TxFormats const& diff --git a/src/ripple/protocol/jss.h b/src/ripple/protocol/jss.h index 824c61a6e..979ee67dd 100644 --- a/src/ripple/protocol/jss.h +++ b/src/ripple/protocol/jss.h @@ -129,6 +129,7 @@ JSS(Sequence); // in/out: TransactionSign; field. JSS(SetFlag); // field. JSS(SetRegularKey); // transaction type. JSS(SetHook); // transaction type. +JSS(SetHookDefinition); // transaction type. JSS(Hook); // ledger type. JSS(HookDefinition); // ledger type. JSS(HookState); // ledger type. diff --git a/src/ripple/shamap/impl/SHAMapInnerNode.cpp b/src/ripple/shamap/impl/SHAMapInnerNode.cpp index 6ea6f47eb..1cac616b0 100644 --- a/src/ripple/shamap/impl/SHAMapInnerNode.cpp +++ b/src/ripple/shamap/impl/SHAMapInnerNode.cpp @@ -398,7 +398,7 @@ SHAMapInnerNode::canonicalizeChild( void SHAMapInnerNode::invariants(bool is_root) const { - unsigned count = 0; + [[maybe_unused]] unsigned count = 0; auto [numAllocated, hashes, children] = hashesAndChildren_.getHashesAndChildren(); diff --git a/src/test/app/SetHookDefinition_test.cpp b/src/test/app/SetHookDefinition_test.cpp new file mode 100644 index 000000000..5ed13bbaa --- /dev/null +++ b/src/test/app/SetHookDefinition_test.cpp @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2016 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include +#include + +namespace ripple { +namespace test { +struct SetHookDefinition_test : public beast::unit_test::suite +{ + void + testEnabled(FeatureBitset features) + { + using namespace test::jtx; + + testcase("Enabled"); + Env env{*this}; + Account const alice = Account("alice"); + env.fund(XRP(1000), alice); + env.close(); + } + + void + testWithFeats(FeatureBitset features) + { + testEnabled(features); + } + +public: + void + run() override + { + using namespace test::jtx; + auto const sa = supported_amendments(); + testWithFeats(sa); + } +}; + +BEAST_DEFINE_TESTSUITE(SetHookDefinition, app, ripple); +} // namespace test +} // namespace ripple