From 8a4bf2dee60e4082b584c1702eabf93225f8da40 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:16:03 +0100 Subject: [PATCH] refactor: Retire fixUniversalNumber amendment (#5962) Signed-off-by: Pratik Mankawde Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) --- include/xrpl/protocol/AMMCore.h | 2 +- include/xrpl/protocol/IOUAmount.h | 33 ---- include/xrpl/protocol/Rules.h | 2 - include/xrpl/protocol/detail/features.macro | 2 +- src/libxrpl/protocol/AMMCore.cpp | 2 +- src/libxrpl/protocol/IOUAmount.cpp | 104 +---------- src/libxrpl/protocol/Rules.cpp | 4 - src/libxrpl/protocol/STAmount.cpp | 188 +++----------------- src/libxrpl/tx/Transactor.cpp | 3 - src/libxrpl/tx/apply.cpp | 2 - src/libxrpl/tx/applySteps.cpp | 4 +- src/test/app/AMM_test.cpp | 7 +- src/test/app/NFToken_test.cpp | 14 +- src/test/app/OfferMPT_test.cpp | 1 - src/test/app/Offer_test.cpp | 60 +++---- src/test/basics/Number_test.cpp | 1 - src/xrpld/app/misc/detail/TxQ.cpp | 5 - 17 files changed, 55 insertions(+), 379 deletions(-) diff --git a/include/xrpl/protocol/AMMCore.h b/include/xrpl/protocol/AMMCore.h index ced84c4c87..a83c8bfa84 100644 --- a/include/xrpl/protocol/AMMCore.h +++ b/include/xrpl/protocol/AMMCore.h @@ -65,7 +65,7 @@ invalidAMMAssetPair( std::optional ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot); -/** Return true if required AMM amendments are enabled +/** Return true if required AMM amendment is enabled */ bool ammEnabled(Rules const&); diff --git a/include/xrpl/protocol/IOUAmount.h b/include/xrpl/protocol/IOUAmount.h index 9e0fbe38eb..b057f1c245 100644 --- a/include/xrpl/protocol/IOUAmount.h +++ b/include/xrpl/protocol/IOUAmount.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -179,36 +178,4 @@ to_string(IOUAmount const& amount); IOUAmount mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundUp); -// Since many uses of the number class do not have access to a ledger, -// getSTNumberSwitchover needs to be globally accessible. - -bool -getSTNumberSwitchover(); - -void -setSTNumberSwitchover(bool v); - -/** RAII class to set and restore the Number switchover. - */ - -class NumberSO -{ - bool saved_; - -public: - ~NumberSO() - { - setSTNumberSwitchover(saved_); - } - - NumberSO(NumberSO const&) = delete; - NumberSO& - operator=(NumberSO const&) = delete; - - explicit NumberSO(bool v) : saved_(getSTNumberSwitchover()) - { - setSTNumberSwitchover(v); - } -}; - } // namespace xrpl diff --git a/include/xrpl/protocol/Rules.h b/include/xrpl/protocol/Rules.h index 9c17ff2391..47b20756db 100644 --- a/include/xrpl/protocol/Rules.h +++ b/include/xrpl/protocol/Rules.h @@ -122,7 +122,6 @@ private: std::optional saved_; }; -class NumberSO; class NumberMantissaScaleGuard; bool @@ -131,7 +130,6 @@ useRulesGuards(Rules const& rules); void createGuards( Rules const& rules, - std::optional& stNumberSO, std::optional& rulesGuard, std::optional& mantissaScaleGuard); diff --git a/include/xrpl/protocol/detail/features.macro b/include/xrpl/protocol/detail/features.macro index c99c1e5ce8..2b2f24ba53 100644 --- a/include/xrpl/protocol/detail/features.macro +++ b/include/xrpl/protocol/detail/features.macro @@ -64,7 +64,6 @@ XRPL_FIX (DisallowIncomingV1, Supported::Yes, VoteBehavior::DefaultNo XRPL_FEATURE(XChainBridge, Supported::Yes, VoteBehavior::DefaultNo) XRPL_FEATURE(AMM, Supported::Yes, VoteBehavior::DefaultNo) XRPL_FEATURE(Clawback, Supported::Yes, VoteBehavior::DefaultNo) -XRPL_FIX (UniversalNumber, Supported::Yes, VoteBehavior::DefaultNo) XRPL_FEATURE(XRPFees, Supported::Yes, VoteBehavior::DefaultNo) XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::Yes, VoteBehavior::DefaultYes) @@ -112,6 +111,7 @@ XRPL_RETIRE_FIX(RmSmallIncreasedQOffers) XRPL_RETIRE_FIX(STAmountCanonicalize) XRPL_RETIRE_FIX(TakerDryOfferRemoval) XRPL_RETIRE_FIX(TrustLinesToSelf) +XRPL_RETIRE_FIX(UniversalNumber) XRPL_RETIRE_FEATURE(Checks) XRPL_RETIRE_FEATURE(CheckCashMakesTrustLine) diff --git a/src/libxrpl/protocol/AMMCore.cpp b/src/libxrpl/protocol/AMMCore.cpp index eccb581c6d..e58ab29257 100644 --- a/src/libxrpl/protocol/AMMCore.cpp +++ b/src/libxrpl/protocol/AMMCore.cpp @@ -127,7 +127,7 @@ ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot) bool ammEnabled(Rules const& rules) { - return rules.enabled(featureAMM) && rules.enabled(fixUniversalNumber); + return rules.enabled(featureAMM); } } // namespace xrpl diff --git a/src/libxrpl/protocol/IOUAmount.cpp b/src/libxrpl/protocol/IOUAmount.cpp index d214995809..acbf6724e1 100644 --- a/src/libxrpl/protocol/IOUAmount.cpp +++ b/src/libxrpl/protocol/IOUAmount.cpp @@ -1,6 +1,5 @@ #include -#include #include #include #include @@ -17,29 +16,6 @@ namespace xrpl { -namespace { - -// Use a static inside a function to help prevent order-of-initialization issues -LocalValue& -getStaticSTNumberSwitchover() -{ - static LocalValue kR{true}; - return kR; -} -} // namespace - -bool -getSTNumberSwitchover() -{ - return *getStaticSTNumberSwitchover(); -} - -void -setSTNumberSwitchover(bool v) -{ - *getStaticSTNumberSwitchover() = v; -} - /* The range for the mantissa when normalized */ // log(2^63,10) ~ 18.96 // @@ -75,56 +51,20 @@ IOUAmount::normalize() return; } - if (getSTNumberSwitchover()) - { - Number const v{mantissa_, exponent_}; - *this = fromNumber(v); - if (exponent_ > kMaxExponent) - Throw("value overflow"); - if (exponent_ < kMinExponent) - *this = beast::kZero; - return; - } - - bool const negative = (mantissa_ < 0); - - if (negative) - mantissa_ = -mantissa_; - - while ((mantissa_ < kMinMantissa) && (exponent_ > kMinExponent)) - { - mantissa_ *= 10; - --exponent_; - } - - while (mantissa_ > kMaxMantissa) - { - if (exponent_ >= kMaxExponent) - Throw("IOUAmount::normalize"); - - mantissa_ /= 10; - ++exponent_; - } - - if ((exponent_ < kMinExponent) || (mantissa_ < kMinMantissa)) - { - *this = beast::kZero; - return; - } - - if (exponent_ > kMaxExponent) - Throw("value overflow"); - - if (negative) - mantissa_ = -mantissa_; + Number const v{mantissa_, exponent_}; + *this = IOUAmount(v); } IOUAmount::IOUAmount(Number const& other) : IOUAmount(fromNumber(other)) { if (exponent_ > kMaxExponent) + { Throw("value overflow"); + } if (exponent_ < kMinExponent) + { *this = beast::kZero; + } } IOUAmount& @@ -139,37 +79,7 @@ IOUAmount::operator+=(IOUAmount const& other) return *this; } - if (getSTNumberSwitchover()) - { - *this = IOUAmount{Number{*this} + Number{other}}; - return *this; - } - auto m = other.mantissa_; - auto e = other.exponent_; - - while (exponent_ < e) - { - mantissa_ /= 10; - ++exponent_; - } - - while (e < exponent_) - { - m /= 10; - ++e; - } - - // This addition cannot overflow an std::int64_t but we may throw from - // normalize if the result isn't representable. - mantissa_ += m; - - if (mantissa_ >= -10 && mantissa_ <= 10) - { - *this = beast::kZero; - return *this; - } - - normalize(); + *this = IOUAmount{Number{*this} + Number{other}}; return *this; } diff --git a/src/libxrpl/protocol/Rules.cpp b/src/libxrpl/protocol/Rules.cpp index 08a95145eb..e0968ea868 100644 --- a/src/libxrpl/protocol/Rules.cpp +++ b/src/libxrpl/protocol/Rules.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -83,15 +82,12 @@ useRulesGuards(Rules const& rules) void createGuards( Rules const& rules, - std::optional& stNumberSO, std::optional& rulesGuard, std::optional& mantissaScaleGuard) { if (useRulesGuards(rules)) { // raii classes for the current ledger rules. - // fixUniversalNumber predates the rulesGuard and should be replaced. - stNumberSO.emplace(rules.enabled(fixUniversalNumber)); rulesGuard.emplace(rules); } else diff --git a/src/libxrpl/protocol/STAmount.cpp b/src/libxrpl/protocol/STAmount.cpp index 1ba9cd042f..449efc9543 100644 --- a/src/libxrpl/protocol/STAmount.cpp +++ b/src/libxrpl/protocol/STAmount.cpp @@ -388,47 +388,9 @@ operator+(STAmount const& v1, STAmount const& v2) if (v1.holds()) return {v1.asset_, v1.mpt().value() + v2.mpt().value()}; - if (getSTNumberSwitchover()) - { - auto x = v1; - x = v1.iou() + v2.iou(); - return x; - } - - int ov1 = v1.exponent(), ov2 = v2.exponent(); - std::int64_t vv1 = static_cast(v1.mantissa()); - std::int64_t vv2 = static_cast(v2.mantissa()); - - if (v1.negative()) - vv1 = -vv1; - - if (v2.negative()) - vv2 = -vv2; - - while (ov1 < ov2) - { - vv1 /= 10; - ++ov1; - } - - while (ov2 < ov1) - { - vv2 /= 10; - ++ov2; - } - - // This addition cannot overflow an std::int64_t. It can overflow an - // STAmount and the constructor will throw. - - std::int64_t const fv = vv1 + vv2; - - if ((fv >= -10) && (fv <= 10)) - return {v1.getFName(), v1.asset()}; - - if (fv >= 0) - return STAmount{v1.getFName(), v1.asset(), static_cast(fv), ov1, false}; - - return STAmount{v1.getFName(), v1.asset(), static_cast(-fv), ov1, true}; + auto x = v1; + x = v1.iou() + v2.iou(); + return x; } STAmount @@ -877,53 +839,25 @@ STAmount::canonicalize() if (asset_.holds() && offset_ > 18) Throw("MPT amount out of range"); - if (getSTNumberSwitchover()) + Number const num(isNegative_, value_, offset_, Number::Unchecked{}); + auto set = [&](auto const& val) { + auto const value = val.value(); + isNegative_ = value < 0; + value_ = isNegative_ ? -value : value; + }; + if (native()) { - Number const num(isNegative_, value_, offset_, Number::Unchecked{}); - auto set = [&](auto const& val) { - auto const value = val.value(); - isNegative_ = value < 0; - value_ = isNegative_ ? -value : value; - }; - if (native()) - { - set(XRPAmount{num}); - } - else if (asset_.holds()) - { - set(MPTAmount{num}); - } - else - { - Throw("Unknown integral asset type"); - } - offset_ = 0; + set(XRPAmount{num}); + } + else if (asset_.holds()) + { + set(MPTAmount{num}); } else { - while (offset_ < 0) - { - value_ /= 10; - ++offset_; - } - - while (offset_ > 0) - { - // N.B. do not move the overflow check to after the - // multiplication - if (native() && value_ > kMaxNativeN) - { - Throw("Native currency amount out of range"); - } - else if (!native() && value_ > kMaxMpTokenAmount) - { - Throw("MPT amount out of range"); - } - - value_ *= 10; - --offset_; - } + Throw("Unknown integral asset type"); // LCOV_EXCL_LINE } + offset_ = 0; if (native() && value_ > kMaxNativeN) { @@ -937,53 +871,7 @@ STAmount::canonicalize() return; } - if (getSTNumberSwitchover()) - { - *this = iou(); - return; - } - - if (value_ == 0) - { - offset_ = -100; - isNegative_ = false; - return; - } - - while ((value_ < kMinValue) && (offset_ > kMinOffset)) - { - value_ *= 10; - --offset_; - } - - while (value_ > kMaxValue) - { - if (offset_ >= kMaxOffset) - Throw("value overflow"); - - value_ /= 10; - ++offset_; - } - - if ((offset_ < kMinOffset) || (value_ < kMinValue)) - { - value_ = 0; - isNegative_ = false; - offset_ = -100; - return; - } - - if (offset_ > kMaxOffset) - Throw("value overflow"); - - XRPL_ASSERT( - (value_ == 0) || ((value_ >= kMinValue) && (value_ <= kMaxValue)), - "xrpl::STAmount::canonicalize : value inside range"); - XRPL_ASSERT( - (value_ == 0) || ((offset_ >= kMinOffset) && (offset_ <= kMaxOffset)), - "xrpl::STAmount::canonicalize : offset inside range"); - XRPL_ASSERT( - (value_ != 0) || (offset_ != -100), "xrpl::STAmount::canonicalize : value or offset set"); + *this = iou(); } void @@ -1395,44 +1283,8 @@ multiply(STAmount const& v1, STAmount const& v2, Asset const& asset) return STAmount(asset, minV * maxV); } - if (getSTNumberSwitchover()) - { - auto const r = Number{v1} * Number{v2}; - return STAmount{asset, r}; - } - - std::uint64_t value1 = v1.mantissa(); - std::uint64_t value2 = v2.mantissa(); - int offset1 = v1.exponent(); - int offset2 = v2.exponent(); - - if (v1.integral()) - { - while (value1 < STAmount::kMinValue) - { - value1 *= 10; - --offset1; - } - } - - if (v2.integral()) - { - while (value2 < STAmount::kMinValue) - { - value2 *= 10; - --offset2; - } - } - - // We multiply the two mantissas (each is between 10^15 - // and 10^16), so their product is in the 10^30 to 10^32 - // range. Dividing their product by 10^14 maintains the - // precision, by scaling the result to 10^16 to 10^18. - return STAmount( - asset, - muldiv(value1, value2, kTenTO14) + 7, - offset1 + offset2 + 14, - v1.negative() != v2.negative()); + auto const r = Number{v1} * Number{v2}; + return STAmount{asset, r}; } // This is the legacy version of canonicalizeRound. It's been in use diff --git a/src/libxrpl/tx/Transactor.cpp b/src/libxrpl/tx/Transactor.cpp index 51541cc2e3..68d3f36916 100644 --- a/src/libxrpl/tx/Transactor.cpp +++ b/src/libxrpl/tx/Transactor.cpp @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -1199,8 +1198,6 @@ Transactor::operator()() // with_txn_type(). // // raii classes for the current ledger rules. - // fixUniversalNumber predate the rulesGuard and should be replaced. - NumberSO const stNumberSO{view().rules().enabled(fixUniversalNumber)}; CurrentTransactionRulesGuard const currentTransactionRulesGuard(view().rules()); #ifdef DEBUG diff --git a/src/libxrpl/tx/apply.cpp b/src/libxrpl/tx/apply.cpp index 0fc0275eb0..b70cb0d345 100644 --- a/src/libxrpl/tx/apply.cpp +++ b/src/libxrpl/tx/apply.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -133,7 +132,6 @@ template ApplyResult apply(ServiceRegistry& registry, OpenView& view, PreflightChecks&& preflightChecks) { - NumberSO const stNumberSO{view.rules().enabled(fixUniversalNumber)}; return doApply(preclaim(preflightChecks(), registry, view), registry, view); } diff --git a/src/libxrpl/tx/applySteps.cpp b/src/libxrpl/tx/applySteps.cpp index 217fdd717f..336bb2004b 100644 --- a/src/libxrpl/tx/applySteps.cpp +++ b/src/libxrpl/tx/applySteps.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -70,10 +69,9 @@ withTxnType(Rules const& rules, TxType txnType, F&& f) // // See also Transactor::operator(). // - std::optional stNumberSO; std::optional rulesGuard; std::optional mantissaScaleGuard; - createGuards(rules, stNumberSO, rulesGuard, mantissaScaleGuard); + createGuards(rules, rulesGuard, mantissaScaleGuard); switch (txnType) { diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index 64972c24ab..e3a1cc935f 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -4333,15 +4333,10 @@ private: testAmendment() { testcase("Amendment"); - FeatureBitset const all{testableAmendments()}; - FeatureBitset const noAMM{all - featureAMM}; - FeatureBitset const noNumber{all - fixUniversalNumber}; - FeatureBitset const noAMMAndNumber{all - featureAMM - fixUniversalNumber}; using namespace jtx; + Env env{*this, testableAmendments() - featureAMM}; - for (auto const& feature : {noAMM, noNumber, noAMMAndNumber}) { - Env env{*this, feature}; fund(env, gw_, {alice_}, {USD(1'000)}, Fund::All); AMM amm(env, alice_, XRP(1'000), USD(1'000), Ter(temDISABLED)); diff --git a/src/test/app/NFToken_test.cpp b/src/test/app/NFToken_test.cpp index 269bc72c53..ba8f09c449 100644 --- a/src/test/app/NFToken_test.cpp +++ b/src/test/app/NFToken_test.cpp @@ -2236,17 +2236,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite // See the impact of rounding when the nft is sold for small amounts // of drops. - for (auto numberSwitchOver : {true}) { - if (numberSwitchOver) - { - env.enableFeature(fixUniversalNumber); - } - else - { - env.disableFeature(fixUniversalNumber); - } - // An nft with a transfer fee of 1 basis point. uint256 const nftID = token::getNextID(env, alice, 0u, tfTransferable, 1); env(token::mint(alice), Txflags(tfTransferable), token::XferFee(1)); @@ -2268,7 +2258,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite // minter sells to carol. The payment is just small enough that // alice does not get any transfer fee. - auto pmt = numberSwitchOver ? drops(50000) : drops(99999); + auto pmt = drops(50000); STAmount carolBalance = env.balance(carol); uint256 const minterSellOfferIndex = keylet::nftoffer(minter, env.seq(minter)).key; env(token::createOffer(minter, nftID, pmt), Txflags(tfSellNFToken)); @@ -2285,7 +2275,7 @@ class NFTokenBaseUtil_test : public beast::unit_test::Suite // transfer that enables a transfer fee of 1 basis point. STAmount beckyBalance = env.balance(becky); uint256 const beckyBuyOfferIndex = keylet::nftoffer(becky, env.seq(becky)).key; - pmt = numberSwitchOver ? drops(50001) : drops(100000); + pmt = drops(50001); env(token::createOffer(becky, nftID, pmt), token::Owner(carol)); env.close(); env(token::acceptBuyOffer(carol, beckyBuyOfferIndex)); diff --git a/src/test/app/OfferMPT_test.cpp b/src/test/app/OfferMPT_test.cpp index e0f2f4eab0..ed0b2ffbe3 100644 --- a/src/test/app/OfferMPT_test.cpp +++ b/src/test/app/OfferMPT_test.cpp @@ -1827,7 +1827,6 @@ public: using namespace jtx; Env env{*this, features}; - env.enableFeature(fixUniversalNumber); auto const gw = Account{"gateway"}; auto const alice = Account{"alice"}; diff --git a/src/test/app/Offer_test.cpp b/src/test/app/Offer_test.cpp index 83c58884e0..7382f4f090 100644 --- a/src/test/app/Offer_test.cpp +++ b/src/test/app/Offer_test.cpp @@ -1973,54 +1973,36 @@ public: using namespace jtx; - for (auto numberSwitchOver : {false, true}) - { - Env env{*this, features}; - if (numberSwitchOver) - { - env.enableFeature(fixUniversalNumber); - } - else - { - env.disableFeature(fixUniversalNumber); - } + Env env{*this, features}; - auto const gw = Account{"gateway"}; - auto const alice = Account{"alice"}; - auto const bob = Account{"bob"}; - auto const usd = gw["USD"]; + auto const gw = Account{"gateway"}; + auto const alice = Account{"alice"}; + auto const bob = Account{"bob"}; + auto const usd = gw["USD"]; - env.fund(XRP(10000), gw, alice, bob); - env.close(); + env.fund(XRP(10000), gw, alice, bob); + env.close(); - env(rate(gw, 1.005)); + env(rate(gw, 1.005)); - env(trust(alice, usd(1000))); - env(trust(bob, usd(1000))); - env(trust(gw, alice["USD"](50))); + env(trust(alice, usd(1000))); + env(trust(bob, usd(1000))); + env(trust(gw, alice["USD"](50))); - env(pay(gw, bob, bob["USD"](1))); - env(pay(alice, gw, usd(50))); + env(pay(gw, bob, bob["USD"](1))); + env(pay(alice, gw, usd(50))); - env(trust(gw, alice["USD"](0))); + env(trust(gw, alice["USD"](0))); - env(offer(alice, usd(50), XRP(150000))); - env(offer(bob, XRP(100), usd(0.1))); + env(offer(alice, usd(50), XRP(150000))); + env(offer(bob, XRP(100), usd(0.1))); - auto jrr = ledgerEntryState(env, alice, gw, "USD"); - BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] == "49.96666666666667"); + auto jrr = ledgerEntryState(env, alice, gw, "USD"); + BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] == "49.96666666666667"); - jrr = ledgerEntryState(env, bob, gw, "USD"); - json::Value const bobUSD = jrr[jss::node][sfBalance.fieldName][jss::value]; - if (!numberSwitchOver) - { - BEAST_EXPECT(bobUSD == "-0.966500000033334"); - } - else - { - BEAST_EXPECT(bobUSD == "-0.9665000000333333"); - } - } + jrr = ledgerEntryState(env, bob, gw, "USD"); + json::Value const bobUSD = jrr[jss::node][sfBalance.fieldName][jss::value]; + BEAST_EXPECT(bobUSD == "-0.9665000000333333"); } void diff --git a/src/test/basics/Number_test.cpp b/src/test/basics/Number_test.cpp index f4bd1c9d66..2d2745de14 100644 --- a/src/test/basics/Number_test.cpp +++ b/src/test/basics/Number_test.cpp @@ -1514,7 +1514,6 @@ public: void testToStAmount() { - NumberSO const stNumberSO{true}; Issue const issue; Number const n{7'518'783'80596, -5}; SaveNumberRoundMode const save{Number::setround(Number::RoundingMode::ToNearest)}; diff --git a/src/xrpld/app/misc/detail/TxQ.cpp b/src/xrpld/app/misc/detail/TxQ.cpp index f98580ede4..0326828a70 100644 --- a/src/xrpld/app/misc/detail/TxQ.cpp +++ b/src/xrpld/app/misc/detail/TxQ.cpp @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include #include #include @@ -306,7 +304,6 @@ TxQ::MaybeTx::apply(Application& app, OpenView& view, beast::Journal j) { // If the rules or flags change, preflight again XRPL_ASSERT(pfResult, "xrpl::TxQ::MaybeTx::apply : preflight result is set"); - NumberSO const stNumberSO{view.rules().enabled(fixUniversalNumber)}; // NOLINTBEGIN(bugprone-unchecked-optional-access) assert above if (pfResult->rules != view.rules() || pfResult->flags != flags) @@ -731,8 +728,6 @@ TxQ::apply( ApplyFlags flags, beast::Journal j) { - NumberSO const stNumberSO{view.rules().enabled(fixUniversalNumber)}; - // See if the transaction is valid, properly formed, // etc. before doing potentially expensive queue // replace and multi-transaction operations.