diff --git a/src/ripple/app/tx/impl/Transactor.cpp b/src/ripple/app/tx/impl/Transactor.cpp index 1affb6fcc56..7dcf3f15ab7 100644 --- a/src/ripple/app/tx/impl/Transactor.cpp +++ b/src/ripple/app/tx/impl/Transactor.cpp @@ -831,8 +831,11 @@ Transactor::operator()() { JLOG(j_.trace()) << "apply: " << ctx_.tx.getTransactionID(); + // raii classes for the current ledger rules. fixSTAmountCanonicalize and + // fixSTAmountCanonicalize predate the rulesGuard and should be replaced. STAmountSO stAmountSO{view().rules().enabled(fixSTAmountCanonicalize)}; NumberSO stNumberSO{view().rules().enabled(fixUniversalNumber)}; + CurrentTransactionRulesGuard currentTransctionRulesGuard(view().rules()); #ifdef DEBUG { diff --git a/src/ripple/protocol/Rules.h b/src/ripple/protocol/Rules.h index 52d01c6f589..f8ff8c00c0c 100644 --- a/src/ripple/protocol/Rules.h +++ b/src/ripple/protocol/Rules.h @@ -23,6 +23,7 @@ #include #include #include + #include namespace ripple { @@ -42,9 +43,14 @@ class Rules public: Rules(Rules const&) = default; + Rules(Rules&&) = default; + Rules& operator=(Rules const&) = default; + Rules& + operator=(Rules&&) = default; + Rules() = delete; /** Construct an empty rule set. @@ -90,5 +96,36 @@ class Rules operator!=(Rules const& other) const; }; +std::optional const& +getCurrentTransactionRules(); + +void +setCurrentTransactionRules(std::optional r); + +/** RAII class to set and restore the current transaction rules + */ +class CurrentTransactionRulesGuard +{ +public: + explicit CurrentTransactionRulesGuard(Rules r) + : saved_(getCurrentTransactionRules()) + { + setCurrentTransactionRules(std::move(r)); + } + + ~CurrentTransactionRulesGuard() + { + setCurrentTransactionRules(saved_); + } + + CurrentTransactionRulesGuard() = delete; + CurrentTransactionRulesGuard(CurrentTransactionRulesGuard const&) = delete; + CurrentTransactionRulesGuard& + operator=(CurrentTransactionRulesGuard const&) = delete; + +private: + std::optional saved_; +}; + } // namespace ripple #endif diff --git a/src/ripple/protocol/impl/Rules.cpp b/src/ripple/protocol/impl/Rules.cpp index c8f4720bd6c..9bb8bd47a8b 100644 --- a/src/ripple/protocol/impl/Rules.cpp +++ b/src/ripple/protocol/impl/Rules.cpp @@ -17,11 +17,36 @@ */ //============================================================================== +#include #include #include +#include + namespace ripple { +namespace { +// Use a static inisde a function to help prevent order-of-initialization issues +LocalValue>& +getCurrentTransactionRulesRef() +{ + static LocalValue> r; + return r; +} +} // namespace + +std::optional const& +getCurrentTransactionRules() +{ + return *getCurrentTransactionRulesRef(); +} + +void +setCurrentTransactionRules(std::optional r) +{ + *getCurrentTransactionRulesRef() = std::move(r); +} + class Rules::Impl { private: