diff --git a/src/ripple/app/tx/impl/Transactor.cpp b/src/ripple/app/tx/impl/Transactor.cpp index 2537e32c5..1b08ab615 100644 --- a/src/ripple/app/tx/impl/Transactor.cpp +++ b/src/ripple/app/tx/impl/Transactor.cpp @@ -1759,8 +1759,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 88404eeae..a2b696bb5 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 @@ private: public: Rules(Rules const&) = default; + Rules(Rules&&) = default; + Rules& operator=(Rules const&) = default; + Rules& + operator=(Rules&&) = default; + Rules() = delete; /** Construct an empty rule set. @@ -91,5 +97,36 @@ public: 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 c8f4720bd..9bb8bd47a 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: