diff --git a/src/test/app/AMM_test.cpp b/src/test/app/AMM_test.cpp index 9d926fdcc1..a07a5eb1a2 100644 --- a/src/test/app/AMM_test.cpp +++ b/src/test/app/AMM_test.cpp @@ -3328,7 +3328,7 @@ private: env.current()->rules(), tapNONE, env.journal); - auto pf = AMMBid::preflight(pfctx); + auto pf = Transactor::preflight(pfctx); BEAST_EXPECT(pf == temDISABLED); env.app().config().features.insert(featureAMM); } @@ -3343,7 +3343,7 @@ private: env.current()->rules(), tapNONE, env.journal); - auto pf = AMMBid::preflight(pfctx); + auto pf = Transactor::preflight(pfctx); BEAST_EXPECT(pf != tesSUCCESS); } @@ -3358,7 +3358,7 @@ private: env.current()->rules(), tapNONE, env.journal); - auto pf = AMMBid::preflight(pfctx); + auto pf = Transactor::preflight(pfctx); BEAST_EXPECT(pf == temBAD_AMM_TOKENS); } } diff --git a/src/xrpld/app/tx/detail/AMMBid.cpp b/src/xrpld/app/tx/detail/AMMBid.cpp index 6fec46be90..f64e90013b 100644 --- a/src/xrpld/app/tx/detail/AMMBid.cpp +++ b/src/xrpld/app/tx/detail/AMMBid.cpp @@ -30,21 +30,15 @@ namespace ripple { -NotTEC -AMMBid::preflight(PreflightContext const& ctx) +bool +AMMBid::isEnabled(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "AMM Bid: invalid flags."; - return temINVALID_FLAG; - } + return ammEnabled(ctx.rules); +} +NotTEC +AMMBid::doPreflight(PreflightContext const& ctx) +{ if (auto const res = invalidAMMAssetPair( ctx.tx[sfAsset].get(), ctx.tx[sfAsset2].get())) { @@ -80,7 +74,7 @@ AMMBid::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMBid.h b/src/xrpld/app/tx/detail/AMMBid.h index 4bb3a2adfd..9260ae78f2 100644 --- a/src/xrpld/app/tx/detail/AMMBid.h +++ b/src/xrpld/app/tx/detail/AMMBid.h @@ -71,8 +71,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMClawback.cpp b/src/xrpld/app/tx/detail/AMMClawback.cpp index 64a42374ec..527af9b471 100644 --- a/src/xrpld/app/tx/detail/AMMClawback.cpp +++ b/src/xrpld/app/tx/detail/AMMClawback.cpp @@ -33,19 +33,21 @@ namespace ripple { -NotTEC -AMMClawback::preflight(PreflightContext const& ctx) +bool +AMMClawback::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureAMMClawback)) - return temDISABLED; + return ctx.rules.enabled(featureAMMClawback); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; // LCOV_EXCL_LINE - - auto const flags = ctx.tx.getFlags(); - if (flags & tfAMMClawbackMask) - return temINVALID_FLAG; +std::uint32_t +AMMClawback::getFlagsMask(PreflightContext const& ctx) +{ + return tfAMMClawbackMask; +} +NotTEC +AMMClawback::doPreflight(PreflightContext const& ctx) +{ AccountID const issuer = ctx.tx[sfAccount]; AccountID const holder = ctx.tx[sfHolder]; @@ -63,6 +65,8 @@ AMMClawback::preflight(PreflightContext const& ctx) if (isXRP(asset)) return temMALFORMED; + auto const flags = ctx.tx.getFlags(); + if (flags & tfClawTwoAssets && asset.account != asset2.account) { JLOG(ctx.j.trace()) @@ -88,7 +92,7 @@ AMMClawback::preflight(PreflightContext const& ctx) if (clawAmount && *clawAmount <= beast::zero) return temBAD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMClawback.h b/src/xrpld/app/tx/detail/AMMClawback.h index fdcfc53e2c..828d07343b 100644 --- a/src/xrpld/app/tx/detail/AMMClawback.h +++ b/src/xrpld/app/tx/detail/AMMClawback.h @@ -33,8 +33,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMCreate.cpp b/src/xrpld/app/tx/detail/AMMCreate.cpp index 95cb5bf2e6..0f14fb3ac6 100644 --- a/src/xrpld/app/tx/detail/AMMCreate.cpp +++ b/src/xrpld/app/tx/detail/AMMCreate.cpp @@ -31,21 +31,15 @@ namespace ripple { -NotTEC -AMMCreate::preflight(PreflightContext const& ctx) +bool +AMMCreate::isEnabled(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "AMM Instance: invalid flags."; - return temINVALID_FLAG; - } + return ammEnabled(ctx.rules); +} +NotTEC +AMMCreate::doPreflight(PreflightContext const& ctx) +{ auto const amount = ctx.tx[sfAmount]; auto const amount2 = ctx.tx[sfAmount2]; @@ -74,14 +68,14 @@ AMMCreate::preflight(PreflightContext const& ctx) return temBAD_FEE; } - return preflight2(ctx); + return tesSUCCESS; } XRPAmount AMMCreate::calculateBaseFee(ReadView const& view, STTx const& tx) { // The fee required for AMMCreate is one owner reserve. - return view.fees().increment; + return calculateOwnerReserveFee(view, tx); } TER diff --git a/src/xrpld/app/tx/detail/AMMCreate.h b/src/xrpld/app/tx/detail/AMMCreate.h index 189d66a55a..f6313dd8af 100644 --- a/src/xrpld/app/tx/detail/AMMCreate.h +++ b/src/xrpld/app/tx/detail/AMMCreate.h @@ -63,8 +63,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/AMMDelete.cpp b/src/xrpld/app/tx/detail/AMMDelete.cpp index 28d56eab98..172a33073e 100644 --- a/src/xrpld/app/tx/detail/AMMDelete.cpp +++ b/src/xrpld/app/tx/detail/AMMDelete.cpp @@ -27,22 +27,16 @@ namespace ripple { -NotTEC -AMMDelete::preflight(PreflightContext const& ctx) +bool +AMMDelete::isEnabled(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; + return ammEnabled(ctx.rules); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "AMM Delete: invalid flags."; - return temINVALID_FLAG; - } - - return preflight2(ctx); +NotTEC +AMMDelete::doPreflight(PreflightContext const& ctx) +{ + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMDelete.h b/src/xrpld/app/tx/detail/AMMDelete.h index 19885b1dad..87abf92c27 100644 --- a/src/xrpld/app/tx/detail/AMMDelete.h +++ b/src/xrpld/app/tx/detail/AMMDelete.h @@ -39,8 +39,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMDeposit.cpp b/src/xrpld/app/tx/detail/AMMDeposit.cpp index 6a718a3f04..cdd36c80fe 100644 --- a/src/xrpld/app/tx/detail/AMMDeposit.cpp +++ b/src/xrpld/app/tx/detail/AMMDeposit.cpp @@ -29,21 +29,23 @@ namespace ripple { -NotTEC -AMMDeposit::preflight(PreflightContext const& ctx) +bool +AMMDeposit::isEnabled(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; + return ammEnabled(ctx.rules); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +AMMDeposit::getFlagsMask(PreflightContext const& ctx) +{ + return tfDepositMask; +} + +NotTEC +AMMDeposit::doPreflight(PreflightContext const& ctx) +{ auto const flags = ctx.tx.getFlags(); - if (flags & tfDepositMask) - { - JLOG(ctx.j.debug()) << "AMM Deposit: invalid flags."; - return temINVALID_FLAG; - } auto const amount = ctx.tx[~sfAmount]; auto const amount2 = ctx.tx[~sfAmount2]; @@ -159,7 +161,7 @@ AMMDeposit::preflight(PreflightContext const& ctx) return temBAD_FEE; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMDeposit.h b/src/xrpld/app/tx/detail/AMMDeposit.h index 0acb1dd9ab..982c2d8abd 100644 --- a/src/xrpld/app/tx/detail/AMMDeposit.h +++ b/src/xrpld/app/tx/detail/AMMDeposit.h @@ -68,8 +68,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMVote.cpp b/src/xrpld/app/tx/detail/AMMVote.cpp index 84d0905a22..ca3435449d 100644 --- a/src/xrpld/app/tx/detail/AMMVote.cpp +++ b/src/xrpld/app/tx/detail/AMMVote.cpp @@ -27,15 +27,15 @@ namespace ripple { -NotTEC -AMMVote::preflight(PreflightContext const& ctx) +bool +AMMVote::isEnabled(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return ammEnabled(ctx.rules); +} +NotTEC +AMMVote::doPreflight(PreflightContext const& ctx) +{ if (auto const res = invalidAMMAssetPair( ctx.tx[sfAsset].get(), ctx.tx[sfAsset2].get())) { @@ -43,19 +43,13 @@ AMMVote::preflight(PreflightContext const& ctx) return res; } - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "AMM Vote: invalid flags."; - return temINVALID_FLAG; - } - if (ctx.tx[sfTradingFee] > TRADING_FEE_THRESHOLD) { JLOG(ctx.j.debug()) << "AMM Vote: invalid trading fee."; return temBAD_FEE; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/AMMVote.h b/src/xrpld/app/tx/detail/AMMVote.h index 2bee01aff5..bc94517961 100644 --- a/src/xrpld/app/tx/detail/AMMVote.h +++ b/src/xrpld/app/tx/detail/AMMVote.h @@ -56,8 +56,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/AMMWithdraw.cpp b/src/xrpld/app/tx/detail/AMMWithdraw.cpp index 586f453c6f..68e46cfb9b 100644 --- a/src/xrpld/app/tx/detail/AMMWithdraw.cpp +++ b/src/xrpld/app/tx/detail/AMMWithdraw.cpp @@ -28,21 +28,22 @@ namespace ripple { -NotTEC -AMMWithdraw::preflight(PreflightContext const& ctx) +bool +AMMWithdraw::isEnabled(PreflightContext const& ctx) { - if (!ammEnabled(ctx.rules)) - return temDISABLED; + return ammEnabled(ctx.rules); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +AMMWithdraw::getFlagsMask(PreflightContext const& ctx) +{ + return tfWithdrawMask; +} +NotTEC +AMMWithdraw::doPreflight(PreflightContext const& ctx) +{ auto const flags = ctx.tx.getFlags(); - if (flags & tfWithdrawMask) - { - JLOG(ctx.j.debug()) << "AMM Withdraw: invalid flags."; - return temINVALID_FLAG; - } auto const amount = ctx.tx[~sfAmount]; auto const amount2 = ctx.tx[~sfAmount2]; @@ -150,7 +151,7 @@ AMMWithdraw::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } static std::optional diff --git a/src/xrpld/app/tx/detail/AMMWithdraw.h b/src/xrpld/app/tx/detail/AMMWithdraw.h index ae9328cb05..7e6397f535 100644 --- a/src/xrpld/app/tx/detail/AMMWithdraw.h +++ b/src/xrpld/app/tx/detail/AMMWithdraw.h @@ -75,8 +75,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/CancelCheck.cpp b/src/xrpld/app/tx/detail/CancelCheck.cpp index cfa3bd10e2..15b647446b 100644 --- a/src/xrpld/app/tx/detail/CancelCheck.cpp +++ b/src/xrpld/app/tx/detail/CancelCheck.cpp @@ -29,24 +29,16 @@ namespace ripple { -NotTEC -CancelCheck::preflight(PreflightContext const& ctx) +bool +CancelCheck::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureChecks)) - return temDISABLED; + return ctx.rules.enabled(featureChecks); +} - NotTEC const ret{preflight1(ctx)}; - if (!isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - // There are no flags (other than universal) for CreateCheck yet. - JLOG(ctx.j.warn()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - - return preflight2(ctx); +NotTEC +CancelCheck::doPreflight(PreflightContext const& ctx) +{ + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/CancelCheck.h b/src/xrpld/app/tx/detail/CancelCheck.h index d9b70f919c..3b40d24008 100644 --- a/src/xrpld/app/tx/detail/CancelCheck.h +++ b/src/xrpld/app/tx/detail/CancelCheck.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/CancelOffer.cpp b/src/xrpld/app/tx/detail/CancelOffer.cpp index 004ae1e8b9..6141f63e48 100644 --- a/src/xrpld/app/tx/detail/CancelOffer.cpp +++ b/src/xrpld/app/tx/detail/CancelOffer.cpp @@ -26,27 +26,15 @@ namespace ripple { NotTEC -CancelOffer::preflight(PreflightContext const& ctx) +CancelOffer::doPreflight(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - auto const uTxFlags = ctx.tx.getFlags(); - - if (uTxFlags & tfUniversalMask) - { - JLOG(ctx.j.trace()) << "Malformed transaction: " - << "Invalid flags set."; - return temINVALID_FLAG; - } - if (!ctx.tx[sfOfferSequence]) { JLOG(ctx.j.trace()) << "CancelOffer::preflight: missing sequence"; return temBAD_SEQUENCE; } - return preflight2(ctx); + return tesSUCCESS; } //------------------------------------------------------------------------------ diff --git a/src/xrpld/app/tx/detail/CancelOffer.h b/src/xrpld/app/tx/detail/CancelOffer.h index 0813dd0aef..8632115026 100644 --- a/src/xrpld/app/tx/detail/CancelOffer.h +++ b/src/xrpld/app/tx/detail/CancelOffer.h @@ -36,7 +36,7 @@ public: } static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/CashCheck.cpp b/src/xrpld/app/tx/detail/CashCheck.cpp index cccda83a68..5ab84f0524 100644 --- a/src/xrpld/app/tx/detail/CashCheck.cpp +++ b/src/xrpld/app/tx/detail/CashCheck.cpp @@ -32,23 +32,15 @@ namespace ripple { -NotTEC -CashCheck::preflight(PreflightContext const& ctx) +bool +CashCheck::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureChecks)) - return temDISABLED; - - NotTEC const ret{preflight1(ctx)}; - if (!isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - // There are no flags (other than universal) for CashCheck yet. - JLOG(ctx.j.warn()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } + return ctx.rules.enabled(featureChecks); +} +NotTEC +CashCheck::doPreflight(PreflightContext const& ctx) +{ // Exactly one of Amount or DeliverMin must be present. auto const optAmount = ctx.tx[~sfAmount]; auto const optDeliverMin = ctx.tx[~sfDeliverMin]; @@ -76,7 +68,7 @@ CashCheck::preflight(PreflightContext const& ctx) return temBAD_CURRENCY; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/CashCheck.h b/src/xrpld/app/tx/detail/CashCheck.h index da7ef22e3c..5dbd21a8e3 100644 --- a/src/xrpld/app/tx/detail/CashCheck.h +++ b/src/xrpld/app/tx/detail/CashCheck.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/Change.cpp b/src/xrpld/app/tx/detail/Change.cpp index 1392d84c08..f1e95a376f 100644 --- a/src/xrpld/app/tx/detail/Change.cpp +++ b/src/xrpld/app/tx/detail/Change.cpp @@ -33,11 +33,12 @@ namespace ripple { +template <> NotTEC -Change::preflight(PreflightContext const& ctx) +Transactor::preflight(PreflightContext const& ctx) { - auto const ret = preflight0(ctx); - if (!isTesSuccess(ret)) + // 0 means "Allow any flags" + if (auto const ret = preflight0(ctx, 0)) return ret; auto account = ctx.tx.getAccountID(sfAccount); diff --git a/src/xrpld/app/tx/detail/Change.h b/src/xrpld/app/tx/detail/Change.h index d710827dd6..7b8fbf3421 100644 --- a/src/xrpld/app/tx/detail/Change.h +++ b/src/xrpld/app/tx/detail/Change.h @@ -33,9 +33,6 @@ public: { } - static NotTEC - preflight(PreflightContext const& ctx); - TER doApply() override; void diff --git a/src/xrpld/app/tx/detail/Clawback.cpp b/src/xrpld/app/tx/detail/Clawback.cpp index 41ab1256fb..0375b6b718 100644 --- a/src/xrpld/app/tx/detail/Clawback.cpp +++ b/src/xrpld/app/tx/detail/Clawback.cpp @@ -75,25 +75,28 @@ preflightHelper(PreflightContext const& ctx) return tesSUCCESS; } -NotTEC -Clawback::preflight(PreflightContext const& ctx) +bool +Clawback::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureClawback)) - return temDISABLED; + return ctx.rules.enabled(featureClawback); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfClawbackMask) - return temINVALID_FLAG; +std::uint32_t +Clawback::getFlagsMask(PreflightContext const& ctx) +{ + return tfClawbackMask; +} +NotTEC +Clawback::doPreflight(PreflightContext const& ctx) +{ if (auto const ret = std::visit( [&](T const&) { return preflightHelper(ctx); }, ctx.tx[sfAmount].asset().value()); !isTesSuccess(ret)) return ret; - return preflight2(ctx); + return tesSUCCESS; } template diff --git a/src/xrpld/app/tx/detail/Clawback.h b/src/xrpld/app/tx/detail/Clawback.h index d908a2e4ef..6353c79a55 100644 --- a/src/xrpld/app/tx/detail/Clawback.h +++ b/src/xrpld/app/tx/detail/Clawback.h @@ -33,8 +33,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/CreateCheck.cpp b/src/xrpld/app/tx/detail/CreateCheck.cpp index 9baceef944..7b19629230 100644 --- a/src/xrpld/app/tx/detail/CreateCheck.cpp +++ b/src/xrpld/app/tx/detail/CreateCheck.cpp @@ -28,22 +28,15 @@ namespace ripple { -NotTEC -CreateCheck::preflight(PreflightContext const& ctx) +bool +CreateCheck::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureChecks)) - return temDISABLED; + return ctx.rules.enabled(featureChecks); +} - NotTEC const ret{preflight1(ctx)}; - if (!isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - // There are no flags (other than universal) for CreateCheck yet. - JLOG(ctx.j.warn()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } +NotTEC +CreateCheck::doPreflight(PreflightContext const& ctx) +{ if (ctx.tx[sfAccount] == ctx.tx[sfDestination]) { // They wrote a check to themselves. @@ -76,7 +69,7 @@ CreateCheck::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/CreateCheck.h b/src/xrpld/app/tx/detail/CreateCheck.h index 0e414ce012..cb794332ca 100644 --- a/src/xrpld/app/tx/detail/CreateCheck.h +++ b/src/xrpld/app/tx/detail/CreateCheck.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/CreateOffer.cpp b/src/xrpld/app/tx/detail/CreateOffer.cpp index d9bd57ec3c..ab6c0c1fbb 100644 --- a/src/xrpld/app/tx/detail/CreateOffer.cpp +++ b/src/xrpld/app/tx/detail/CreateOffer.cpp @@ -39,23 +39,20 @@ CreateOffer::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, calculateMaxXRPSpend(ctx.tx)}; } -NotTEC -CreateOffer::preflight(PreflightContext const& ctx) +std::uint32_t +CreateOffer::getFlagsMask(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return tfOfferCreateMask; +} +NotTEC +CreateOffer::doPreflight(PreflightContext const& ctx) +{ auto& tx = ctx.tx; auto& j = ctx.j; std::uint32_t const uTxFlags = tx.getFlags(); - if (uTxFlags & tfOfferCreateMask) - { - JLOG(j.debug()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - bool const bImmediateOrCancel(uTxFlags & tfImmediateOrCancel); bool const bFillOrKill(uTxFlags & tfFillOrKill); @@ -122,7 +119,7 @@ CreateOffer::preflight(PreflightContext const& ctx) return temBAD_ISSUER; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/CreateOffer.h b/src/xrpld/app/tx/detail/CreateOffer.h index 35808c78fe..d654c14042 100644 --- a/src/xrpld/app/tx/detail/CreateOffer.h +++ b/src/xrpld/app/tx/detail/CreateOffer.h @@ -44,9 +44,12 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + /** Enforce constraints beyond those of the Transactor base class. */ static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); /** Enforce constraints beyond those of the Transactor base class. */ static TER diff --git a/src/xrpld/app/tx/detail/CreateTicket.cpp b/src/xrpld/app/tx/detail/CreateTicket.cpp index 594335f489..254cf68555 100644 --- a/src/xrpld/app/tx/detail/CreateTicket.cpp +++ b/src/xrpld/app/tx/detail/CreateTicket.cpp @@ -33,23 +33,20 @@ CreateTicket::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, ctx.tx[sfTicketCount]}; } -NotTEC -CreateTicket::preflight(PreflightContext const& ctx) +bool +CreateTicket::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureTicketBatch)) - return temDISABLED; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureTicketBatch); +} +NotTEC +CreateTicket::doPreflight(PreflightContext const& ctx) +{ if (std::uint32_t const count = ctx.tx[sfTicketCount]; count < minValidCount || count > maxValidCount) return temINVALID_COUNT; - if (NotTEC const ret{preflight1(ctx)}; !isTesSuccess(ret)) - return ret; - - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/CreateTicket.h b/src/xrpld/app/tx/detail/CreateTicket.h index 86cf91bb5a..746daf7c56 100644 --- a/src/xrpld/app/tx/detail/CreateTicket.h +++ b/src/xrpld/app/tx/detail/CreateTicket.h @@ -69,9 +69,12 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static bool + isEnabled(PreflightContext const& ctx); + /** Enforce constraints beyond those of the Transactor base class. */ static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); /** Enforce constraints beyond those of the Transactor base class. */ static TER diff --git a/src/xrpld/app/tx/detail/Credentials.cpp b/src/xrpld/app/tx/detail/Credentials.cpp index 73c397cf37..83873a9612 100644 --- a/src/xrpld/app/tx/detail/Credentials.cpp +++ b/src/xrpld/app/tx/detail/Credentials.cpp @@ -48,28 +48,25 @@ using namespace credentials; // ------- CREATE -------------------------- -NotTEC -CredentialCreate::preflight(PreflightContext const& ctx) +bool +CredentialCreate::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureCredentials)) - { - JLOG(ctx.j.trace()) << "featureCredentials is disabled."; - return temDISABLED; - } + return ctx.rules.enabled(featureCredentials); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +CredentialCreate::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; +} +NotTEC +CredentialCreate::doPreflight(PreflightContext const& ctx) +{ auto const& tx = ctx.tx; auto& j = ctx.j; - if (ctx.rules.enabled(fixInvalidTxFlags) && - (tx.getFlags() & tfUniversalMask)) - { - JLOG(ctx.j.debug()) << "CredentialCreate: invalid flags."; - return temINVALID_FLAG; - } - if (!tx[sfSubject]) { JLOG(j.trace()) << "Malformed transaction: Invalid Subject"; @@ -91,7 +88,7 @@ CredentialCreate::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -202,25 +199,22 @@ CredentialCreate::doApply() } // ------- DELETE -------------------------- -NotTEC -CredentialDelete::preflight(PreflightContext const& ctx) +bool +CredentialDelete::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureCredentials)) - { - JLOG(ctx.j.trace()) << "featureCredentials is disabled."; - return temDISABLED; - } + return ctx.rules.enabled(featureCredentials); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.rules.enabled(fixInvalidTxFlags) && - (ctx.tx.getFlags() & tfUniversalMask)) - { - JLOG(ctx.j.debug()) << "CredentialDelete: invalid flags."; - return temINVALID_FLAG; - } +std::uint32_t +CredentialDelete::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; +} +NotTEC +CredentialDelete::doPreflight(PreflightContext const& ctx) +{ auto const subject = ctx.tx[~sfSubject]; auto const issuer = ctx.tx[~sfIssuer]; @@ -248,7 +242,7 @@ CredentialDelete::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -289,25 +283,22 @@ CredentialDelete::doApply() // ------- APPLY -------------------------- -NotTEC -CredentialAccept::preflight(PreflightContext const& ctx) +bool +CredentialAccept::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureCredentials)) - { - JLOG(ctx.j.trace()) << "featureCredentials is disabled."; - return temDISABLED; - } + return ctx.rules.enabled(featureCredentials); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.rules.enabled(fixInvalidTxFlags) && - (ctx.tx.getFlags() & tfUniversalMask)) - { - JLOG(ctx.j.debug()) << "CredentialAccept: invalid flags."; - return temINVALID_FLAG; - } +std::uint32_t +CredentialAccept::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; +} +NotTEC +CredentialAccept::doPreflight(PreflightContext const& ctx) +{ if (!ctx.tx[sfIssuer]) { JLOG(ctx.j.trace()) << "Malformed transaction: Issuer field zeroed."; @@ -322,7 +313,7 @@ CredentialAccept::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/Credentials.h b/src/xrpld/app/tx/detail/Credentials.h index 5b4acb3998..ee19c5c0a3 100644 --- a/src/xrpld/app/tx/detail/Credentials.h +++ b/src/xrpld/app/tx/detail/Credentials.h @@ -33,8 +33,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -54,8 +60,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -75,8 +87,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/DID.cpp b/src/xrpld/app/tx/detail/DID.cpp index 31ce7c8770..d74c9733ae 100644 --- a/src/xrpld/app/tx/detail/DID.cpp +++ b/src/xrpld/app/tx/detail/DID.cpp @@ -42,18 +42,15 @@ namespace ripple { //------------------------------------------------------------------------------ -NotTEC -DIDSet::preflight(PreflightContext const& ctx) +bool +DIDSet::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureDID)) - return temDISABLED; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return ctx.rules.enabled(featureDID); +} +NotTEC +DIDSet::doPreflight(PreflightContext const& ctx) +{ if (!ctx.tx.isFieldPresent(sfURI) && !ctx.tx.isFieldPresent(sfDIDDocument) && !ctx.tx.isFieldPresent(sfData)) return temEMPTY_DID; @@ -74,7 +71,7 @@ DIDSet::preflight(PreflightContext const& ctx) isTooLong(sfData, maxDIDAttestationLength)) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -171,19 +168,16 @@ DIDSet::doApply() return addSLE(ctx_, sleDID, account_); } -NotTEC -DIDDelete::preflight(PreflightContext const& ctx) +bool +DIDDelete::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureDID)) - return temDISABLED; + return ctx.rules.enabled(featureDID); +} - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - return preflight2(ctx); +NotTEC +DIDDelete::doPreflight(PreflightContext const& ctx) +{ + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/DID.h b/src/xrpld/app/tx/detail/DID.h index 54ae6630f2..1995176d17 100644 --- a/src/xrpld/app/tx/detail/DID.h +++ b/src/xrpld/app/tx/detail/DID.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); TER doApply() override; @@ -51,8 +54,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER deleteSLE(ApplyContext& ctx, Keylet sleKeylet, AccountID const owner); diff --git a/src/xrpld/app/tx/detail/DelegateSet.cpp b/src/xrpld/app/tx/detail/DelegateSet.cpp index d93ed6fa96..07ebc83893 100644 --- a/src/xrpld/app/tx/detail/DelegateSet.cpp +++ b/src/xrpld/app/tx/detail/DelegateSet.cpp @@ -28,15 +28,15 @@ namespace ripple { -NotTEC -DelegateSet::preflight(PreflightContext const& ctx) +bool +DelegateSet::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePermissionDelegation)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return ctx.rules.enabled(featurePermissionDelegation); +} +NotTEC +DelegateSet::doPreflight(PreflightContext const& ctx) +{ auto const& permissions = ctx.tx.getFieldArray(sfPermissions); if (permissions.size() > permissionMaxSize) return temARRAY_TOO_LARGE; @@ -53,7 +53,7 @@ DelegateSet::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -159,4 +159,4 @@ DelegateSet::deleteDelegate( return tesSUCCESS; } -} // namespace ripple \ No newline at end of file +} // namespace ripple diff --git a/src/xrpld/app/tx/detail/DelegateSet.h b/src/xrpld/app/tx/detail/DelegateSet.h index 6b01d63281..87166ab5fb 100644 --- a/src/xrpld/app/tx/detail/DelegateSet.h +++ b/src/xrpld/app/tx/detail/DelegateSet.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -53,4 +56,4 @@ public: } // namespace ripple -#endif \ No newline at end of file +#endif diff --git a/src/xrpld/app/tx/detail/DeleteAccount.cpp b/src/xrpld/app/tx/detail/DeleteAccount.cpp index a2a9769d43..e27c31b670 100644 --- a/src/xrpld/app/tx/detail/DeleteAccount.cpp +++ b/src/xrpld/app/tx/detail/DeleteAccount.cpp @@ -38,22 +38,19 @@ namespace ripple { -NotTEC -DeleteAccount::preflight(PreflightContext const& ctx) +bool +DeleteAccount::isEnabled(PreflightContext const& ctx) { if (!ctx.rules.enabled(featureDeletableAccounts)) - return temDISABLED; + return false; - if (ctx.tx.isFieldPresent(sfCredentialIDs) && - !ctx.rules.enabled(featureCredentials)) - return temDISABLED; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return !ctx.tx.isFieldPresent(sfCredentialIDs) || + ctx.rules.enabled(featureCredentials); +} +NotTEC +DeleteAccount::doPreflight(PreflightContext const& ctx) +{ if (ctx.tx[sfAccount] == ctx.tx[sfDestination]) // An account cannot be deleted and give itself the resulting XRP. return temDST_IS_SRC; @@ -61,14 +58,14 @@ DeleteAccount::preflight(PreflightContext const& ctx) if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err)) return err; - return preflight2(ctx); + return tesSUCCESS; } XRPAmount DeleteAccount::calculateBaseFee(ReadView const& view, STTx const& tx) { // The fee required for AccountDelete is one owner reserve. - return view.fees().increment; + return calculateOwnerReserveFee(view, tx); } namespace { diff --git a/src/xrpld/app/tx/detail/DeleteAccount.h b/src/xrpld/app/tx/detail/DeleteAccount.h index c9d3305562..42946bfc27 100644 --- a/src/xrpld/app/tx/detail/DeleteAccount.h +++ b/src/xrpld/app/tx/detail/DeleteAccount.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/DeleteOracle.cpp b/src/xrpld/app/tx/detail/DeleteOracle.cpp index 78e3d55230..2e49877d9b 100644 --- a/src/xrpld/app/tx/detail/DeleteOracle.cpp +++ b/src/xrpld/app/tx/detail/DeleteOracle.cpp @@ -26,22 +26,16 @@ namespace ripple { -NotTEC -DeleteOracle::preflight(PreflightContext const& ctx) +bool +DeleteOracle::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePriceOracle)) - return temDISABLED; + return ctx.rules.enabled(featurePriceOracle); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "Oracle Delete: invalid flags."; - return temINVALID_FLAG; - } - - return preflight2(ctx); +NotTEC +DeleteOracle::doPreflight(PreflightContext const& ctx) +{ + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/DeleteOracle.h b/src/xrpld/app/tx/detail/DeleteOracle.h index bbbfc6f525..87183268ff 100644 --- a/src/xrpld/app/tx/detail/DeleteOracle.h +++ b/src/xrpld/app/tx/detail/DeleteOracle.h @@ -42,8 +42,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/DepositPreauth.cpp b/src/xrpld/app/tx/detail/DepositPreauth.cpp index f10f09b38f..a1bdafa852 100644 --- a/src/xrpld/app/tx/detail/DepositPreauth.cpp +++ b/src/xrpld/app/tx/detail/DepositPreauth.cpp @@ -30,11 +30,11 @@ namespace ripple { -NotTEC -DepositPreauth::preflight(PreflightContext const& ctx) +bool +DepositPreauth::isEnabled(PreflightContext const& ctx) { if (!ctx.rules.enabled(featureDepositPreauth)) - return temDISABLED; + return false; bool const authArrPresent = ctx.tx.isFieldPresent(sfAuthorizeCredentials); bool const unauthArrPresent = @@ -42,19 +42,17 @@ DepositPreauth::preflight(PreflightContext const& ctx) int const authCredPresent = static_cast(authArrPresent) + static_cast(unauthArrPresent); - if (authCredPresent && !ctx.rules.enabled(featureCredentials)) - return temDISABLED; + return !authCredPresent || ctx.rules.enabled(featureCredentials); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - auto& tx = ctx.tx; - - if (tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.trace()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } +NotTEC +DepositPreauth::doPreflight(PreflightContext const& ctx) +{ + bool const authArrPresent = ctx.tx.isFieldPresent(sfAuthorizeCredentials); + bool const unauthArrPresent = + ctx.tx.isFieldPresent(sfUnauthorizeCredentials); + int const authCredPresent = + static_cast(authArrPresent) + static_cast(unauthArrPresent); auto const optAuth = ctx.tx[~sfAuthorize]; auto const optUnauth = ctx.tx[~sfUnauthorize]; @@ -102,7 +100,7 @@ DepositPreauth::preflight(PreflightContext const& ctx) return err; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/DepositPreauth.h b/src/xrpld/app/tx/detail/DepositPreauth.h index 76a7c08073..3d969b8df4 100644 --- a/src/xrpld/app/tx/detail/DepositPreauth.h +++ b/src/xrpld/app/tx/detail/DepositPreauth.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/Escrow.cpp b/src/xrpld/app/tx/detail/Escrow.cpp index 0b58957fcf..a3491f479b 100644 --- a/src/xrpld/app/tx/detail/Escrow.cpp +++ b/src/xrpld/app/tx/detail/Escrow.cpp @@ -82,15 +82,16 @@ EscrowCreate::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()}; } -NotTEC -EscrowCreate::preflight(PreflightContext const& ctx) +std::uint32_t +EscrowCreate::getFlagsMask(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} +NotTEC +EscrowCreate::doPreflight(PreflightContext const& ctx) +{ if (!isXRP(ctx.tx[sfAmount])) return temBAD_AMOUNT; @@ -139,7 +140,7 @@ EscrowCreate::preflight(PreflightContext const& ctx) return temDISABLED; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -293,19 +294,23 @@ checkCondition(Slice f, Slice c) return validate(*fulfillment, *condition); } -NotTEC -EscrowFinish::preflight(PreflightContext const& ctx) +bool +EscrowFinish::isEnabled(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return !ctx.tx.isFieldPresent(sfCredentialIDs) || + ctx.rules.enabled(featureCredentials); +} - if (ctx.tx.isFieldPresent(sfCredentialIDs) && - !ctx.rules.enabled(featureCredentials)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +EscrowFinish::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} +NotTEC +EscrowFinish::doPreflight(PreflightContext const& ctx) +{ auto const cb = ctx.tx[~sfCondition]; auto const fb = ctx.tx[~sfFulfillment]; @@ -317,7 +322,7 @@ EscrowFinish::preflight(PreflightContext const& ctx) // Verify the transaction signature. If it doesn't work // then don't do any more work. { - auto const ret = preflight2(ctx); + auto const ret = detail::preflight2(ctx); if (!isTesSuccess(ret)) return ret; } @@ -512,16 +517,17 @@ EscrowFinish::doApply() //------------------------------------------------------------------------------ -NotTEC -EscrowCancel::preflight(PreflightContext const& ctx) +std::uint32_t +EscrowCancel::getFlagsMask(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - return preflight2(ctx); +NotTEC +EscrowCancel::doPreflight(PreflightContext const& ctx) +{ + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/Escrow.h b/src/xrpld/app/tx/detail/Escrow.h index 78acdbee00..f857fea9cb 100644 --- a/src/xrpld/app/tx/detail/Escrow.h +++ b/src/xrpld/app/tx/detail/Escrow.h @@ -36,8 +36,11 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -57,8 +60,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); @@ -81,8 +90,11 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); TER doApply() override; diff --git a/src/xrpld/app/tx/detail/LedgerStateFix.cpp b/src/xrpld/app/tx/detail/LedgerStateFix.cpp index 008d9b6ae7..680cc30d95 100644 --- a/src/xrpld/app/tx/detail/LedgerStateFix.cpp +++ b/src/xrpld/app/tx/detail/LedgerStateFix.cpp @@ -27,18 +27,15 @@ namespace ripple { -NotTEC -LedgerStateFix::preflight(PreflightContext const& ctx) +bool +LedgerStateFix::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(fixNFTokenPageLinks)) - return temDISABLED; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return ctx.rules.enabled(fixNFTokenPageLinks); +} +NotTEC +LedgerStateFix::doPreflight(PreflightContext const& ctx) +{ switch (ctx.tx[sfLedgerFixType]) { case FixType::nfTokenPageLink: @@ -50,7 +47,7 @@ LedgerStateFix::preflight(PreflightContext const& ctx) return tefINVALID_LEDGER_FIX_TYPE; } - return preflight2(ctx); + return tesSUCCESS; } XRPAmount @@ -58,7 +55,7 @@ LedgerStateFix::calculateBaseFee(ReadView const& view, STTx const& tx) { // The fee required for LedgerStateFix is one owner reserve, just like // the fee for AccountDelete. - return view.fees().increment; + return calculateOwnerReserveFee(view, tx); } TER diff --git a/src/xrpld/app/tx/detail/LedgerStateFix.h b/src/xrpld/app/tx/detail/LedgerStateFix.h index bff51a723c..e67dfd26c9 100644 --- a/src/xrpld/app/tx/detail/LedgerStateFix.h +++ b/src/xrpld/app/tx/detail/LedgerStateFix.h @@ -37,8 +37,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp b/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp index 748c05869f..1fec7d9c3e 100644 --- a/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp +++ b/src/xrpld/app/tx/detail/MPTokenAuthorize.cpp @@ -26,22 +26,25 @@ namespace ripple { -NotTEC -MPTokenAuthorize::preflight(PreflightContext const& ctx) +bool +MPTokenAuthorize::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; + return ctx.rules.enabled(featureMPTokensV1); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfMPTokenAuthorizeMask) - return temINVALID_FLAG; +std::uint32_t +MPTokenAuthorize::getFlagsMask(PreflightContext const& ctx) +{ + return tfMPTokenAuthorizeMask; +} +NotTEC +MPTokenAuthorize::doPreflight(PreflightContext const& ctx) +{ if (ctx.tx[sfAccount] == ctx.tx[~sfHolder]) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/MPTokenAuthorize.h b/src/xrpld/app/tx/detail/MPTokenAuthorize.h index e2b135a22a..5651dbf075 100644 --- a/src/xrpld/app/tx/detail/MPTokenAuthorize.h +++ b/src/xrpld/app/tx/detail/MPTokenAuthorize.h @@ -42,8 +42,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp b/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp index 1b96b27f24..8f751015d8 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.cpp @@ -25,18 +25,21 @@ namespace ripple { -NotTEC -MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) +bool +MPTokenIssuanceCreate::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; + return ctx.rules.enabled(featureMPTokensV1); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfMPTokenIssuanceCreateMask) - return temINVALID_FLAG; +std::uint32_t +MPTokenIssuanceCreate::getFlagsMask(PreflightContext const& ctx) +{ + return tfMPTokenIssuanceCreateMask; +} +NotTEC +MPTokenIssuanceCreate::doPreflight(PreflightContext const& ctx) +{ if (auto const fee = ctx.tx[~sfTransferFee]) { if (fee > maxTransferFee) @@ -64,7 +67,7 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx) if (maxAmt > maxMPTokenAmount) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } Expected diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h b/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h index ea01908dff..3df61d52ce 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceCreate.h @@ -49,8 +49,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); TER doApply() override; diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp index d06ea3473e..3705f8dd6e 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.cpp @@ -25,20 +25,22 @@ namespace ripple { -NotTEC -MPTokenIssuanceDestroy::preflight(PreflightContext const& ctx) +bool +MPTokenIssuanceDestroy::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; + return ctx.rules.enabled(featureMPTokensV1); +} - // check flags - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +MPTokenIssuanceDestroy::getFlagsMask(PreflightContext const& ctx) +{ + return tfMPTokenIssuanceDestroyMask; +} - if (ctx.tx.getFlags() & tfMPTokenIssuanceDestroyMask) - return temINVALID_FLAG; - - return preflight2(ctx); +NotTEC +MPTokenIssuanceDestroy::doPreflight(PreflightContext const& ctx) +{ + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.h b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.h index 69abb99feb..8718caf5b5 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.h +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceDestroy.h @@ -33,8 +33,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp index 85a1f6cf1a..399d24ccd8 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.cpp @@ -25,22 +25,25 @@ namespace ripple { -NotTEC -MPTokenIssuanceSet::preflight(PreflightContext const& ctx) +bool +MPTokenIssuanceSet::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; + return ctx.rules.enabled(featureMPTokensV1); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +MPTokenIssuanceSet::getFlagsMask(PreflightContext const& ctx) +{ + return tfMPTokenIssuanceSetMask; +} +NotTEC +MPTokenIssuanceSet::doPreflight(PreflightContext const& ctx) +{ auto const txFlags = ctx.tx.getFlags(); - // check flags - if (txFlags & tfMPTokenIssuanceSetMask) - return temINVALID_FLAG; // fails if both flags are set - else if ((txFlags & tfMPTLock) && (txFlags & tfMPTUnlock)) + if ((txFlags & tfMPTLock) && (txFlags & tfMPTUnlock)) return temINVALID_FLAG; auto const accountID = ctx.tx[sfAccount]; @@ -48,7 +51,7 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx) if (holderID && accountID == holderID) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.h b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.h index 5b3db0e75b..ac2b2fa6da 100644 --- a/src/xrpld/app/tx/detail/MPTokenIssuanceSet.h +++ b/src/xrpld/app/tx/detail/MPTokenIssuanceSet.h @@ -33,8 +33,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER checkPermission(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp index 4c5fdb7683..194d6f9b52 100644 --- a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp +++ b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.cpp @@ -27,18 +27,21 @@ namespace ripple { -NotTEC -NFTokenAcceptOffer::preflight(PreflightContext const& ctx) +bool +NFTokenAcceptOffer::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; + return ctx.rules.enabled(featureNonFungibleTokensV1); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfNFTokenAcceptOfferMask) - return temINVALID_FLAG; +std::uint32_t +NFTokenAcceptOffer::getFlagsMask(PreflightContext const& ctx) +{ + return tfNFTokenAcceptOfferMask; +} +NotTEC +NFTokenAcceptOffer::doPreflight(PreflightContext const& ctx) +{ auto const bo = ctx.tx[~sfNFTokenBuyOffer]; auto const so = ctx.tx[~sfNFTokenSellOffer]; @@ -57,7 +60,7 @@ NFTokenAcceptOffer::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.h b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.h index 6a594e2b2c..7effde2d45 100644 --- a/src/xrpld/app/tx/detail/NFTokenAcceptOffer.h +++ b/src/xrpld/app/tx/detail/NFTokenAcceptOffer.h @@ -59,8 +59,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenBurn.cpp b/src/xrpld/app/tx/detail/NFTokenBurn.cpp index 947a663f92..4948ef7f2a 100644 --- a/src/xrpld/app/tx/detail/NFTokenBurn.cpp +++ b/src/xrpld/app/tx/detail/NFTokenBurn.cpp @@ -26,19 +26,16 @@ namespace ripple { -NotTEC -NFTokenBurn::preflight(PreflightContext const& ctx) +bool +NFTokenBurn::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; + return ctx.rules.enabled(featureNonFungibleTokensV1); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - return preflight2(ctx); +NotTEC +NFTokenBurn::doPreflight(PreflightContext const& ctx) +{ + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenBurn.h b/src/xrpld/app/tx/detail/NFTokenBurn.h index 3f5296c217..ff930c1be7 100644 --- a/src/xrpld/app/tx/detail/NFTokenBurn.h +++ b/src/xrpld/app/tx/detail/NFTokenBurn.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp b/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp index f6072bc953..5c6c406d2d 100644 --- a/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp +++ b/src/xrpld/app/tx/detail/NFTokenCancelOffer.cpp @@ -28,18 +28,21 @@ namespace ripple { -NotTEC -NFTokenCancelOffer::preflight(PreflightContext const& ctx) +bool +NFTokenCancelOffer::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; + return ctx.rules.enabled(featureNonFungibleTokensV1); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfNFTokenCancelOfferMask) - return temINVALID_FLAG; +std::uint32_t +NFTokenCancelOffer::getFlagsMask(PreflightContext const& ctx) +{ + return tfNFTokenCancelOfferMask; +} +NotTEC +NFTokenCancelOffer::doPreflight(PreflightContext const& ctx) +{ if (auto const& ids = ctx.tx[sfNFTokenOffers]; ids.empty() || (ids.size() > maxTokenOfferCancelCount)) return temMALFORMED; @@ -51,7 +54,7 @@ NFTokenCancelOffer::preflight(PreflightContext const& ctx) if (std::adjacent_find(ids.begin(), ids.end()) != ids.end()) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenCancelOffer.h b/src/xrpld/app/tx/detail/NFTokenCancelOffer.h index d460675711..e112dce6f8 100644 --- a/src/xrpld/app/tx/detail/NFTokenCancelOffer.h +++ b/src/xrpld/app/tx/detail/NFTokenCancelOffer.h @@ -33,8 +33,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp b/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp index 8e1a026415..46baaf7f49 100644 --- a/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp +++ b/src/xrpld/app/tx/detail/NFTokenCreateOffer.cpp @@ -26,20 +26,23 @@ namespace ripple { -NotTEC -NFTokenCreateOffer::preflight(PreflightContext const& ctx) +bool +NFTokenCreateOffer::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; + return ctx.rules.enabled(featureNonFungibleTokensV1); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +NFTokenCreateOffer::getFlagsMask(PreflightContext const& ctx) +{ + return tfNFTokenCreateOfferMask; +} +NotTEC +NFTokenCreateOffer::doPreflight(PreflightContext const& ctx) +{ auto const txFlags = ctx.tx.getFlags(); - if (txFlags & tfNFTokenCreateOfferMask) - return temINVALID_FLAG; - auto const nftFlags = nft::getFlags(ctx.tx[sfNFTokenID]); // Use implementation shared with NFTokenMint @@ -55,7 +58,7 @@ NFTokenCreateOffer::preflight(PreflightContext const& ctx) !isTesSuccess(notTec)) return notTec; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenCreateOffer.h b/src/xrpld/app/tx/detail/NFTokenCreateOffer.h index 075a5a712f..fb1b6a575f 100644 --- a/src/xrpld/app/tx/detail/NFTokenCreateOffer.h +++ b/src/xrpld/app/tx/detail/NFTokenCreateOffer.h @@ -33,8 +33,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenMint.cpp b/src/xrpld/app/tx/detail/NFTokenMint.cpp index 42b551b3a4..3dcad38ee1 100644 --- a/src/xrpld/app/tx/detail/NFTokenMint.cpp +++ b/src/xrpld/app/tx/detail/NFTokenMint.cpp @@ -38,22 +38,26 @@ extractNFTokenFlagsFromTxFlags(std::uint32_t txFlags) return static_cast(txFlags & 0x0000FFFF); } -NotTEC -NFTokenMint::preflight(PreflightContext const& ctx) +static bool +hasOfferFields(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1)) - return temDISABLED; - - bool const hasOfferFields = ctx.tx.isFieldPresent(sfAmount) || + return ctx.tx.isFieldPresent(sfAmount) || ctx.tx.isFieldPresent(sfDestination) || ctx.tx.isFieldPresent(sfExpiration); +} - if (!ctx.rules.enabled(featureNFTokenMintOffer) && hasOfferFields) - return temDISABLED; +bool +NFTokenMint::isEnabled(PreflightContext const& ctx) +{ + if (!ctx.rules.enabled(featureNonFungibleTokensV1)) + return false; - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return ctx.rules.enabled(featureNFTokenMintOffer) || !hasOfferFields(ctx); +} +std::uint32_t +NFTokenMint::getFlagsMask(PreflightContext const& ctx) +{ // Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between // accounts allowed a TrustLine to be added to the issuer of that token // without explicit permission from that issuer. This was enabled by @@ -67,7 +71,7 @@ NFTokenMint::preflight(PreflightContext const& ctx) // The fixRemoveNFTokenAutoTrustLine amendment disables minting with the // tfTrustLine flag as a way to prevent the attack. But until the // amendment passes we still need to keep the old behavior available. - std::uint32_t const NFTokenMintMask = + std::uint32_t const nfTokenMintMask = ctx.rules.enabled(fixRemoveNFTokenAutoTrustLine) // if featureDynamicNFT enabled then new flag allowing mutable URI // available @@ -76,9 +80,12 @@ NFTokenMint::preflight(PreflightContext const& ctx) : ctx.rules.enabled(featureDynamicNFT) ? tfNFTokenMintOldMaskWithMutable : tfNFTokenMintOldMask; - if (ctx.tx.getFlags() & NFTokenMintMask) - return temINVALID_FLAG; + return nfTokenMintMask; +} +NotTEC +NFTokenMint::doPreflight(PreflightContext const& ctx) +{ if (auto const f = ctx.tx[~sfTransferFee]) { if (f > maxTransferFee) @@ -100,7 +107,7 @@ NFTokenMint::preflight(PreflightContext const& ctx) return temMALFORMED; } - if (hasOfferFields) + if (hasOfferFields(ctx)) { // The Amount field must be present if either the Destination or // Expiration fields are present. @@ -123,7 +130,7 @@ NFTokenMint::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } uint256 diff --git a/src/xrpld/app/tx/detail/NFTokenMint.h b/src/xrpld/app/tx/detail/NFTokenMint.h index f606120c54..4af7448532 100644 --- a/src/xrpld/app/tx/detail/NFTokenMint.h +++ b/src/xrpld/app/tx/detail/NFTokenMint.h @@ -36,8 +36,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/NFTokenModify.cpp b/src/xrpld/app/tx/detail/NFTokenModify.cpp index a3803c423b..54f26387b1 100644 --- a/src/xrpld/app/tx/detail/NFTokenModify.cpp +++ b/src/xrpld/app/tx/detail/NFTokenModify.cpp @@ -25,19 +25,16 @@ namespace ripple { -NotTEC -NFTokenModify::preflight(PreflightContext const& ctx) +bool +NFTokenModify::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureNonFungibleTokensV1_1) || - !ctx.rules.enabled(featureDynamicNFT)) - return temDISABLED; - - if (NotTEC const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureNonFungibleTokensV1_1) && + ctx.rules.enabled(featureDynamicNFT); +} +NotTEC +NFTokenModify::doPreflight(PreflightContext const& ctx) +{ if (auto owner = ctx.tx[~sfOwner]; owner == ctx.tx[sfAccount]) return temMALFORMED; @@ -47,7 +44,7 @@ NFTokenModify::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/NFTokenModify.h b/src/xrpld/app/tx/detail/NFTokenModify.h index 0d1e72ade1..a0936c6af1 100644 --- a/src/xrpld/app/tx/detail/NFTokenModify.h +++ b/src/xrpld/app/tx/detail/NFTokenModify.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/PayChan.cpp b/src/xrpld/app/tx/detail/PayChan.cpp index a42902f6ac..47fcae6ef5 100644 --- a/src/xrpld/app/tx/detail/PayChan.cpp +++ b/src/xrpld/app/tx/detail/PayChan.cpp @@ -171,15 +171,16 @@ PayChanCreate::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()}; } -NotTEC -PayChanCreate::preflight(PreflightContext const& ctx) +std::uint32_t +PayChanCreate::getFlagsMask(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} +NotTEC +PayChanCreate::doPreflight(PreflightContext const& ctx) +{ if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero)) return temBAD_AMOUNT; @@ -189,7 +190,7 @@ PayChanCreate::preflight(PreflightContext const& ctx) if (!publicKeyType(ctx.tx[sfPublicKey])) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -326,19 +327,20 @@ PayChanFund::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, ctx.tx[sfAmount].xrp()}; } -NotTEC -PayChanFund::preflight(PreflightContext const& ctx) +std::uint32_t +PayChanFund::getFlagsMask(PreflightContext const& ctx) { - if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfUniversalMask : 0; +} +NotTEC +PayChanFund::doPreflight(PreflightContext const& ctx) +{ if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero)) return temBAD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -416,16 +418,23 @@ PayChanFund::doApply() //------------------------------------------------------------------------------ -NotTEC -PayChanClaim::preflight(PreflightContext const& ctx) +bool +PayChanClaim::isEnabled(PreflightContext const& ctx) { - if (ctx.tx.isFieldPresent(sfCredentialIDs) && - !ctx.rules.enabled(featureCredentials)) - return temDISABLED; + return !ctx.tx.isFieldPresent(sfCredentialIDs) || + ctx.rules.enabled(featureCredentials); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +PayChanClaim::getFlagsMask(PreflightContext const& ctx) +{ + // 0 means "Allow any flags" + return ctx.rules.enabled(fix1543) ? tfPayChanClaimMask : 0; +} +NotTEC +PayChanClaim::doPreflight(PreflightContext const& ctx) +{ auto const bal = ctx.tx[~sfBalance]; if (bal && (!isXRP(*bal) || *bal <= beast::zero)) return temBAD_AMOUNT; @@ -440,9 +449,6 @@ PayChanClaim::preflight(PreflightContext const& ctx) { auto const flags = ctx.tx.getFlags(); - if (ctx.rules.enabled(fix1543) && (flags & tfPayChanClaimMask)) - return temINVALID_FLAG; - if ((flags & tfClose) && (flags & tfRenew)) return temMALFORMED; } @@ -476,7 +482,7 @@ PayChanClaim::preflight(PreflightContext const& ctx) if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err)) return err; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/PayChan.h b/src/xrpld/app/tx/detail/PayChan.h index 2e09c473dc..1faa34499b 100644 --- a/src/xrpld/app/tx/detail/PayChan.h +++ b/src/xrpld/app/tx/detail/PayChan.h @@ -36,8 +36,11 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -62,8 +65,11 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); TER doApply() override; @@ -82,8 +88,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/Payment.cpp b/src/xrpld/app/tx/detail/Payment.cpp index a97e472841..1b6573181f 100644 --- a/src/xrpld/app/tx/detail/Payment.cpp +++ b/src/xrpld/app/tx/detail/Payment.cpp @@ -64,16 +64,27 @@ getMaxSourceAmount( dstAmount < beast::zero); } -NotTEC -Payment::preflight(PreflightContext const& ctx) +bool +Payment::isEnabled(PreflightContext const& ctx) { - if (ctx.tx.isFieldPresent(sfCredentialIDs) && - !ctx.rules.enabled(featureCredentials)) - return temDISABLED; + return !ctx.tx.isFieldPresent(sfCredentialIDs) || + ctx.rules.enabled(featureCredentials); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; +std::uint32_t +Payment::getFlagsMask(PreflightContext const& ctx) +{ + auto& tx = ctx.tx; + STAmount const dstAmount(tx.getFieldAmount(sfAmount)); + bool const mptDirect = dstAmount.holds(); + + return mptDirect ? tfMPTPaymentMask : tfPaymentMask; +} + +NotTEC +Payment::doPreflight(PreflightContext const& ctx) +{ auto& tx = ctx.tx; auto& j = ctx.j; @@ -85,14 +96,6 @@ Payment::preflight(PreflightContext const& ctx) std::uint32_t const txFlags = tx.getFlags(); - std::uint32_t paymentMask = mptDirect ? tfMPTPaymentMask : tfPaymentMask; - - if (txFlags & paymentMask) - { - JLOG(j.trace()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - if (mptDirect && ctx.tx.isFieldPresent(sfPaths)) return temMALFORMED; @@ -236,7 +239,7 @@ Payment::preflight(PreflightContext const& ctx) if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err)) return err; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/Payment.h b/src/xrpld/app/tx/detail/Payment.h index 010a2453cf..577b7827ae 100644 --- a/src/xrpld/app/tx/detail/Payment.h +++ b/src/xrpld/app/tx/detail/Payment.h @@ -42,8 +42,14 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER checkPermission(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp b/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp index 64c498b68b..d89831dfe0 100644 --- a/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp +++ b/src/xrpld/app/tx/detail/PermissionedDomainDelete.cpp @@ -24,26 +24,20 @@ namespace ripple { -NotTEC -PermissionedDomainDelete::preflight(PreflightContext const& ctx) +bool +PermissionedDomainDelete::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePermissionedDomains)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "PermissionedDomainDelete: invalid flags."; - return temINVALID_FLAG; - } + return ctx.rules.enabled(featurePermissionedDomains); +} +NotTEC +PermissionedDomainDelete::doPreflight(PreflightContext const& ctx) +{ auto const domain = ctx.tx.getFieldH256(sfDomainID); if (domain == beast::zero) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/PermissionedDomainDelete.h b/src/xrpld/app/tx/detail/PermissionedDomainDelete.h index 8b5fa68e59..574a99bffa 100644 --- a/src/xrpld/app/tx/detail/PermissionedDomainDelete.h +++ b/src/xrpld/app/tx/detail/PermissionedDomainDelete.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp b/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp index 6e2df2a082..98aedb7304 100644 --- a/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp +++ b/src/xrpld/app/tx/detail/PermissionedDomainSet.cpp @@ -28,22 +28,16 @@ namespace ripple { -NotTEC -PermissionedDomainSet::preflight(PreflightContext const& ctx) +bool +PermissionedDomainSet::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePermissionedDomains) || - !ctx.rules.enabled(featureCredentials)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - { - JLOG(ctx.j.debug()) << "PermissionedDomainSet: invalid flags."; - return temINVALID_FLAG; - } + return ctx.rules.enabled(featurePermissionedDomains) && + ctx.rules.enabled(featureCredentials); +} +NotTEC +PermissionedDomainSet::doPreflight(PreflightContext const& ctx) +{ if (auto err = credentials::checkArray( ctx.tx.getFieldArray(sfAcceptedCredentials), maxPermissionedDomainCredentialsArraySize, @@ -55,7 +49,7 @@ PermissionedDomainSet::preflight(PreflightContext const& ctx) if (domain && *domain == beast::zero) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/PermissionedDomainSet.h b/src/xrpld/app/tx/detail/PermissionedDomainSet.h index 502d576e32..94761bae26 100644 --- a/src/xrpld/app/tx/detail/PermissionedDomainSet.h +++ b/src/xrpld/app/tx/detail/PermissionedDomainSet.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/SetAccount.cpp b/src/xrpld/app/tx/detail/SetAccount.cpp index 599819151a..f24ddd38cd 100644 --- a/src/xrpld/app/tx/detail/SetAccount.cpp +++ b/src/xrpld/app/tx/detail/SetAccount.cpp @@ -57,23 +57,20 @@ SetAccount::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, getTxConsequencesCategory(ctx.tx)}; } -NotTEC -SetAccount::preflight(PreflightContext const& ctx) +std::uint32_t +SetAccount::getFlagsMask(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return tfAccountSetMask; +} +NotTEC +SetAccount::doPreflight(PreflightContext const& ctx) +{ auto& tx = ctx.tx; auto& j = ctx.j; std::uint32_t const uTxFlags = tx.getFlags(); - if (uTxFlags & tfAccountSetMask) - { - JLOG(j.trace()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - std::uint32_t const uSetFlag = tx.getFieldU32(sfSetFlag); std::uint32_t const uClearFlag = tx.getFieldU32(sfClearFlag); @@ -186,7 +183,7 @@ SetAccount::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetAccount.h b/src/xrpld/app/tx/detail/SetAccount.h index ed4242c250..a16d2e0cdf 100644 --- a/src/xrpld/app/tx/detail/SetAccount.h +++ b/src/xrpld/app/tx/detail/SetAccount.h @@ -38,8 +38,11 @@ public: static TxConsequences makeTxConsequences(PreflightContext const& ctx); + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER checkPermission(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/SetOracle.cpp b/src/xrpld/app/tx/detail/SetOracle.cpp index 8559c3e7b9..4f6b9b700e 100644 --- a/src/xrpld/app/tx/detail/SetOracle.cpp +++ b/src/xrpld/app/tx/detail/SetOracle.cpp @@ -36,18 +36,15 @@ tokenPairKey(STObject const& pair) pair.getFieldCurrency(sfQuoteAsset).currency()); } -NotTEC -SetOracle::preflight(PreflightContext const& ctx) +bool +SetOracle::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featurePriceOracle)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featurePriceOracle); +} +NotTEC +SetOracle::doPreflight(PreflightContext const& ctx) +{ auto const& dataSeries = ctx.tx.getFieldArray(sfPriceDataSeries); if (dataSeries.empty()) return temARRAY_EMPTY; @@ -64,7 +61,7 @@ SetOracle::preflight(PreflightContext const& ctx) isInvalidLength(sfAssetClass, maxOracleSymbolClass)) return temMALFORMED; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetOracle.h b/src/xrpld/app/tx/detail/SetOracle.h index 656b656019..a35ef74c4c 100644 --- a/src/xrpld/app/tx/detail/SetOracle.h +++ b/src/xrpld/app/tx/detail/SetOracle.h @@ -42,8 +42,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/SetRegularKey.cpp b/src/xrpld/app/tx/detail/SetRegularKey.cpp index 92d130a15a..f4d04ec1c1 100644 --- a/src/xrpld/app/tx/detail/SetRegularKey.cpp +++ b/src/xrpld/app/tx/detail/SetRegularKey.cpp @@ -49,20 +49,8 @@ SetRegularKey::calculateBaseFee(ReadView const& view, STTx const& tx) } NotTEC -SetRegularKey::preflight(PreflightContext const& ctx) +SetRegularKey::doPreflight(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - std::uint32_t const uTxFlags = ctx.tx.getFlags(); - - if (uTxFlags & tfUniversalMask) - { - JLOG(ctx.j.trace()) << "Malformed transaction: Invalid flags set."; - - return temINVALID_FLAG; - } - if (ctx.rules.enabled(fixMasterKeyAsRegularKey) && ctx.tx.isFieldPresent(sfRegularKey) && (ctx.tx.getAccountID(sfRegularKey) == ctx.tx.getAccountID(sfAccount))) @@ -70,7 +58,7 @@ SetRegularKey::preflight(PreflightContext const& ctx) return temBAD_REGKEY; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetRegularKey.h b/src/xrpld/app/tx/detail/SetRegularKey.h index 055748aa25..00b9e47169 100644 --- a/src/xrpld/app/tx/detail/SetRegularKey.h +++ b/src/xrpld/app/tx/detail/SetRegularKey.h @@ -34,7 +34,7 @@ public: } static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/SetSignerList.cpp b/src/xrpld/app/tx/detail/SetSignerList.cpp index 4a1ee703a0..191b947560 100644 --- a/src/xrpld/app/tx/detail/SetSignerList.cpp +++ b/src/xrpld/app/tx/detail/SetSignerList.cpp @@ -77,19 +77,16 @@ SetSignerList::determineOperation( return std::make_tuple(tesSUCCESS, quorum, sign, op); } -NotTEC -SetSignerList::preflight(PreflightContext const& ctx) +std::uint32_t +SetSignerList::getFlagsMask(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.rules.enabled(fixInvalidTxFlags) && - (ctx.tx.getFlags() & tfUniversalMask)) - { - JLOG(ctx.j.debug()) << "SetSignerList: invalid flags."; - return temINVALID_FLAG; - } + // 0 means "Allow any flags" + return ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0; +} +NotTEC +SetSignerList::doPreflight(PreflightContext const& ctx) +{ auto const result = determineOperation(ctx.tx, ctx.flags, ctx.j); if (std::get<0>(result) != tesSUCCESS) @@ -119,7 +116,7 @@ SetSignerList::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetSignerList.h b/src/xrpld/app/tx/detail/SetSignerList.h index 1827aca975..575db5a127 100644 --- a/src/xrpld/app/tx/detail/SetSignerList.h +++ b/src/xrpld/app/tx/detail/SetSignerList.h @@ -51,8 +51,11 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); TER doApply() override; diff --git a/src/xrpld/app/tx/detail/SetTrust.cpp b/src/xrpld/app/tx/detail/SetTrust.cpp index 5e83c201fa..ed9528036a 100644 --- a/src/xrpld/app/tx/detail/SetTrust.cpp +++ b/src/xrpld/app/tx/detail/SetTrust.cpp @@ -67,23 +67,20 @@ computeFreezeFlags( namespace ripple { -NotTEC -SetTrust::preflight(PreflightContext const& ctx) +std::uint32_t +SetTrust::getFlagsMask(PreflightContext const& ctx) { - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; + return tfTrustSetMask; +} +NotTEC +SetTrust::doPreflight(PreflightContext const& ctx) +{ auto& tx = ctx.tx; auto& j = ctx.j; std::uint32_t const uTxFlags = tx.getFlags(); - if (uTxFlags & tfTrustSetMask) - { - JLOG(j.trace()) << "Malformed transaction: Invalid flags set."; - return temINVALID_FLAG; - } - if (!ctx.rules.enabled(featureDeepFreeze)) { // Even though the deep freeze flags are included in the @@ -127,7 +124,7 @@ SetTrust::preflight(PreflightContext const& ctx) return temDST_NEEDED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/SetTrust.h b/src/xrpld/app/tx/detail/SetTrust.h index a0476918ac..d7ca54d1dc 100644 --- a/src/xrpld/app/tx/detail/SetTrust.h +++ b/src/xrpld/app/tx/detail/SetTrust.h @@ -35,8 +35,11 @@ public: { } + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER checkPermission(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/Transactor.cpp b/src/xrpld/app/tx/detail/Transactor.cpp index 56d3302f46..33b899d823 100644 --- a/src/xrpld/app/tx/detail/Transactor.cpp +++ b/src/xrpld/app/tx/detail/Transactor.cpp @@ -34,13 +34,14 @@ #include #include #include +#include #include namespace ripple { /** Performs early sanity checks on the txid */ NotTEC -preflight0(PreflightContext const& ctx) +preflight0(PreflightContext const& ctx, std::uint32_t flagMask) { if (!isPseudoTx(ctx.tx) || ctx.tx.isFieldPresent(sfNetworkID)) { @@ -75,12 +76,38 @@ preflight0(PreflightContext const& ctx) return temINVALID; } + if (ctx.tx.getFlags() & flagMask) + { + JLOG(ctx.j.debug()) + << ctx.tx.peekAtField(sfTransactionType).getFullText() + << ": invalid flags."; + return temINVALID_FLAG; + } + + return tesSUCCESS; +} + +namespace detail { + +/** Checks the validity of the transactor signing key. + * + * Normally called from preflight1. + */ +NotTEC +preflightCheckSigningKey(STObject const& sigObject, beast::Journal j) +{ + if (auto const spk = sigObject.getFieldVL(sfSigningPubKey); + !spk.empty() && !publicKeyType(makeSlice(spk))) + { + JLOG(j.debug()) << "preflightCheckSigningKey: invalid signing key"; + return temBAD_SIGNATURE; + } return tesSUCCESS; } /** Performs early sanity checks on the account and fee fields */ NotTEC -preflight1(PreflightContext const& ctx) +preflight1(PreflightContext const& ctx, std::uint32_t flagMask) { // This is inappropriate in preflight0, because only Change transactions // skip this function, and those do not allow an sfTicketSequence field. @@ -99,8 +126,7 @@ preflight1(PreflightContext const& ctx) return temBAD_SIGNER; } - auto const ret = preflight0(ctx); - if (!isTesSuccess(ret)) + if (auto const ret = preflight0(ctx, flagMask)) return ret; auto const id = ctx.tx.getAccountID(sfAccount); @@ -118,13 +144,8 @@ preflight1(PreflightContext const& ctx) return temBAD_FEE; } - auto const spk = ctx.tx.getSigningPubKey(); - - if (!spk.empty() && !publicKeyType(makeSlice(spk))) - { - JLOG(ctx.j.debug()) << "preflight1: invalid signing key"; - return temBAD_SIGNATURE; - } + if (auto const ret = preflightCheckSigningKey(ctx.tx, ctx.j)) + return ret; // An AccountTxnID field constrains transaction ordering more than the // Sequence field. Tickets, on the other hand, reduce ordering @@ -181,6 +202,8 @@ preflight2(PreflightContext const& ctx) return tesSUCCESS; } +} // namespace detail + //------------------------------------------------------------------------------ PreflightContext::PreflightContext( @@ -203,6 +226,22 @@ Transactor::Transactor(ApplyContext& ctx) { } +bool +Transactor::validDataLength( + std::optional const& slice, + std::size_t maxLength) +{ + if (!slice) + return true; + return !slice->empty() && slice->length() <= maxLength; +} + +std::uint32_t +Transactor::getFlagsMask(PreflightContext const& ctx) +{ + return tfUniversalMask; +} + TER Transactor::checkPermission(ReadView const& view, STTx const& tx) { @@ -237,6 +276,18 @@ Transactor::calculateBaseFee(ReadView const& view, STTx const& tx) return baseFee + (signerCount * baseFee); } +// Returns the fee in fee units, not scaled for load. +XRPAmount +Transactor::calculateOwnerReserveFee(ReadView const& view, STTx const& tx) +{ + // One reserve increment is typically much greater than one base fee. + XRPL_ASSERT( + view.fees().increment > view.fees().base * 100, + "ripple::Transactor::calculateOwnerReserveFee : Owner reserve is much " + "greater than base fee"); + return view.fees().increment; +} + XRPAmount Transactor::minimumFee( Application& app, diff --git a/src/xrpld/app/tx/detail/Transactor.h b/src/xrpld/app/tx/detail/Transactor.h index 88ccdb8db7..ba33e0cd13 100644 --- a/src/xrpld/app/tx/detail/Transactor.h +++ b/src/xrpld/app/tx/detail/Transactor.h @@ -84,6 +84,8 @@ public: class TxConsequences; struct PreflightResult; +// Needed for preflight specialization +class Change; class Transactor { @@ -145,6 +147,24 @@ public: static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); + /* Do NOT define a preflight function in a derived class. + Instead, define + + // Optional if the transaction is gated on an amendment + static bool + isEnabled(PreflightContext const& ctx); + + // Optional if the transaction uses any flags other than tfUniversal + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + + static NotTEC + doPreflight(PreflightContext const& ctx); + */ + template + static NotTEC + preflight(PreflightContext const& ctx); + static TER preclaim(PreclaimContext const& ctx) { @@ -193,6 +213,32 @@ protected: Fees const& fees, ApplyFlags flags); + // Returns the fee in fee units, not scaled for load. + static XRPAmount + calculateOwnerReserveFee(ReadView const& view, STTx const& tx); + + // Base class always returns true + static bool + isEnabled(PreflightContext const& ctx); + + // Base class always returns tfUniversalMask + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + + static bool + validDataLength(std::optional const& slice, std::size_t maxLength); + + template + static bool + validNumericRange(std::optional value, T max, T min = {}); + + template + static bool + validNumericRange( + std::optional value, + unit::ValueUnit max, + unit::ValueUnit min = {}); + private: std::pair reset(XRPAmount fee); @@ -209,17 +255,76 @@ private: void trapTransaction(uint256) const; }; -/** Performs early sanity checks on the txid */ -NotTEC -preflight0(PreflightContext const& ctx); +inline bool +Transactor::isEnabled(PreflightContext const& ctx) +{ + return true; +} -/** Performs early sanity checks on the account and fee fields */ +/** Performs early sanity checks on the txid and flags */ NotTEC -preflight1(PreflightContext const& ctx); +preflight0(PreflightContext const& ctx, std::uint32_t flagMask); + +namespace detail { + +/** Checks the validity of the transactor signing key. + * + * Normally called from preflight1 with ctx.tx. + */ +NotTEC +preflightCheckSigningKey(STObject const& sigObject, beast::Journal j); + +/** Performs early sanity checks on the account and fee fields. + + (And passes flagMask to preflight0) +*/ +NotTEC +preflight1(PreflightContext const& ctx, std::uint32_t flagMask); /** Checks whether the signature appears valid */ NotTEC preflight2(PreflightContext const& ctx); +} // namespace detail + +// Defined in Change.cpp +template <> +NotTEC +Transactor::preflight(PreflightContext const& ctx); + +template +NotTEC +Transactor::preflight(PreflightContext const& ctx) +{ + if (!T::isEnabled(ctx)) + return temDISABLED; + + if (auto const ret = ripple::detail::preflight1(ctx, T::getFlagsMask(ctx))) + return ret; + + if (auto const ret = T::doPreflight(ctx)) + return ret; + + return ripple::detail::preflight2(ctx); +} + +template +bool +Transactor::validNumericRange(std::optional value, T max, T min) +{ + if (!value) + return true; + return value >= min && value <= max; +} + +template +bool +Transactor::validNumericRange( + std::optional value, + unit::ValueUnit max, + unit::ValueUnit min) +{ + return validNumericRange(value, max.value(), min.value()); +} } // namespace ripple diff --git a/src/xrpld/app/tx/detail/VaultClawback.cpp b/src/xrpld/app/tx/detail/VaultClawback.cpp index f9bd0c7629..39d068e58d 100644 --- a/src/xrpld/app/tx/detail/VaultClawback.cpp +++ b/src/xrpld/app/tx/detail/VaultClawback.cpp @@ -30,18 +30,15 @@ namespace ripple { -NotTEC -VaultClawback::preflight(PreflightContext const& ctx) +bool +VaultClawback::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureSingleAssetVault); +} +NotTEC +VaultClawback::doPreflight(PreflightContext const& ctx) +{ if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultClawback: zero/empty vault ID."; @@ -76,7 +73,7 @@ VaultClawback::preflight(PreflightContext const& ctx) } } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultClawback.h b/src/xrpld/app/tx/detail/VaultClawback.h index 65f0164686..58ee97db46 100644 --- a/src/xrpld/app/tx/detail/VaultClawback.h +++ b/src/xrpld/app/tx/detail/VaultClawback.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/VaultCreate.cpp b/src/xrpld/app/tx/detail/VaultCreate.cpp index cb6a994e7e..835201cb5f 100644 --- a/src/xrpld/app/tx/detail/VaultCreate.cpp +++ b/src/xrpld/app/tx/detail/VaultCreate.cpp @@ -33,28 +33,28 @@ namespace ripple { -NotTEC -VaultCreate::preflight(PreflightContext const& ctx) +bool +VaultCreate::isEnabled(PreflightContext const& ctx) { if (!ctx.rules.enabled(featureSingleAssetVault) || !ctx.rules.enabled(featureMPTokensV1)) - return temDISABLED; + return false; - if (ctx.tx.isFieldPresent(sfDomainID) && - !ctx.rules.enabled(featurePermissionedDomains)) - return temDISABLED; + return !ctx.tx.isFieldPresent(sfDomainID) || + ctx.rules.enabled(featurePermissionedDomains); +} - if (auto const ter = preflight1(ctx)) - return ter; +std::uint32_t +VaultCreate::getFlagsMask(PreflightContext const& ctx) +{ + return tfVaultCreateMask; +} - if (ctx.tx.getFlags() & tfVaultCreateMask) - return temINVALID_FLAG; - - if (auto const data = ctx.tx[~sfData]) - { - if (data->empty() || data->length() > maxDataPayloadLength) - return temMALFORMED; - } +NotTEC +VaultCreate::doPreflight(PreflightContext const& ctx) +{ + if (!validDataLength(ctx.tx[~sfData], maxDataPayloadLength)) + return temMALFORMED; if (auto const withdrawalPolicy = ctx.tx[~sfWithdrawalPolicy]) { @@ -84,14 +84,14 @@ VaultCreate::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } XRPAmount VaultCreate::calculateBaseFee(ReadView const& view, STTx const& tx) { // One reserve increment is typically much greater than one base fee. - return view.fees().increment; + return calculateOwnerReserveFee(view, tx); } TER @@ -100,32 +100,8 @@ VaultCreate::preclaim(PreclaimContext const& ctx) auto vaultAsset = ctx.tx[sfAsset]; auto account = ctx.tx[sfAccount]; - if (vaultAsset.native()) - ; // No special checks for XRP - else if (vaultAsset.holds()) - { - auto mptID = vaultAsset.get().getMptID(); - auto issuance = ctx.view.read(keylet::mptIssuance(mptID)); - if (!issuance) - return tecOBJECT_NOT_FOUND; - if (!issuance->isFlag(lsfMPTCanTransfer)) - { - // NOTE: flag lsfMPTCanTransfer is immutable, so this is debug in - // VaultCreate only; in other vault function it's an error. - JLOG(ctx.j.debug()) - << "VaultCreate: vault assets are non-transferable."; - return tecNO_AUTH; - } - } - else if (vaultAsset.holds()) - { - auto const issuer = - ctx.view.read(keylet::account(vaultAsset.getIssuer())); - if (!issuer) - return terNO_ACCOUNT; - else if (!issuer->isFlag(lsfDefaultRipple)) - return terNO_RIPPLE; - } + if (auto const ter = canAddHolding(ctx.view, vaultAsset)) + return ter; // Check for pseudo-account issuers - we do not want a vault to hold such // assets (e.g. MPT shares to other vaults or AMM LPTokens) as they would be diff --git a/src/xrpld/app/tx/detail/VaultCreate.h b/src/xrpld/app/tx/detail/VaultCreate.h index 5555644629..effb7cd475 100644 --- a/src/xrpld/app/tx/detail/VaultCreate.h +++ b/src/xrpld/app/tx/detail/VaultCreate.h @@ -33,8 +33,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static XRPAmount calculateBaseFee(ReadView const& view, STTx const& tx); diff --git a/src/xrpld/app/tx/detail/VaultDelete.cpp b/src/xrpld/app/tx/detail/VaultDelete.cpp index 7861e9e9b6..71f1f86bae 100644 --- a/src/xrpld/app/tx/detail/VaultDelete.cpp +++ b/src/xrpld/app/tx/detail/VaultDelete.cpp @@ -27,25 +27,22 @@ namespace ripple { -NotTEC -VaultDelete::preflight(PreflightContext const& ctx) +bool +VaultDelete::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureSingleAssetVault); +} +NotTEC +VaultDelete::doPreflight(PreflightContext const& ctx) +{ if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultDelete: zero/empty vault ID."; return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultDelete.h b/src/xrpld/app/tx/detail/VaultDelete.h index 2b77e84469..aa32db48ab 100644 --- a/src/xrpld/app/tx/detail/VaultDelete.h +++ b/src/xrpld/app/tx/detail/VaultDelete.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/VaultDeposit.cpp b/src/xrpld/app/tx/detail/VaultDeposit.cpp index 0efddb0ff7..847ba06954 100644 --- a/src/xrpld/app/tx/detail/VaultDeposit.cpp +++ b/src/xrpld/app/tx/detail/VaultDeposit.cpp @@ -32,18 +32,15 @@ namespace ripple { -NotTEC -VaultDeposit::preflight(PreflightContext const& ctx) +bool +VaultDeposit::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureSingleAssetVault); +} +NotTEC +VaultDeposit::doPreflight(PreflightContext const& ctx) +{ if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultDeposit: zero/empty vault ID."; @@ -53,7 +50,7 @@ VaultDeposit::preflight(PreflightContext const& ctx) if (ctx.tx[sfAmount] <= beast::zero) return temBAD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultDeposit.h b/src/xrpld/app/tx/detail/VaultDeposit.h index 50515ce3d8..79cd8f4a02 100644 --- a/src/xrpld/app/tx/detail/VaultDeposit.h +++ b/src/xrpld/app/tx/detail/VaultDeposit.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/VaultSet.cpp b/src/xrpld/app/tx/detail/VaultSet.cpp index a13ce6d10e..feec2eb160 100644 --- a/src/xrpld/app/tx/detail/VaultSet.cpp +++ b/src/xrpld/app/tx/detail/VaultSet.cpp @@ -30,28 +30,25 @@ namespace ripple { -NotTEC -VaultSet::preflight(PreflightContext const& ctx) +bool +VaultSet::isEnabled(PreflightContext const& ctx) { if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; + return false; - if (ctx.tx.isFieldPresent(sfDomainID) && - !ctx.rules.enabled(featurePermissionedDomains)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; + return !ctx.tx.isFieldPresent(sfDomainID) || + ctx.rules.enabled(featurePermissionedDomains); +} +NotTEC +VaultSet::doPreflight(PreflightContext const& ctx) +{ if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultSet: zero/empty vault ID."; return temMALFORMED; } - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (auto const data = ctx.tx[~sfData]) { if (data->empty() || data->length() > maxDataPayloadLength) @@ -78,7 +75,7 @@ VaultSet::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultSet.h b/src/xrpld/app/tx/detail/VaultSet.h index f16aa6c284..2e8004bec1 100644 --- a/src/xrpld/app/tx/detail/VaultSet.h +++ b/src/xrpld/app/tx/detail/VaultSet.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/VaultWithdraw.cpp b/src/xrpld/app/tx/detail/VaultWithdraw.cpp index 7a8605cdbd..32ae9fce1c 100644 --- a/src/xrpld/app/tx/detail/VaultWithdraw.cpp +++ b/src/xrpld/app/tx/detail/VaultWithdraw.cpp @@ -30,18 +30,15 @@ namespace ripple { -NotTEC -VaultWithdraw::preflight(PreflightContext const& ctx) +bool +VaultWithdraw::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureSingleAssetVault)) - return temDISABLED; - - if (auto const ter = preflight1(ctx)) - return ter; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureSingleAssetVault); +} +NotTEC +VaultWithdraw::doPreflight(PreflightContext const& ctx) +{ if (ctx.tx[sfVaultID] == beast::zero) { JLOG(ctx.j.debug()) << "VaultWithdraw: zero/empty vault ID."; @@ -58,7 +55,7 @@ VaultWithdraw::preflight(PreflightContext const& ctx) return temMALFORMED; } - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/VaultWithdraw.h b/src/xrpld/app/tx/detail/VaultWithdraw.h index 0b713d403b..9ac9e420ea 100644 --- a/src/xrpld/app/tx/detail/VaultWithdraw.h +++ b/src/xrpld/app/tx/detail/VaultWithdraw.h @@ -33,8 +33,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/XChainBridge.cpp b/src/xrpld/app/tx/detail/XChainBridge.cpp index 5fa03557e5..fa188c45c5 100644 --- a/src/xrpld/app/tx/detail/XChainBridge.cpp +++ b/src/xrpld/app/tx/detail/XChainBridge.cpp @@ -1209,17 +1209,8 @@ toClaim(STTx const& tx) template NotTEC -attestationPreflight(PreflightContext const& ctx) +attestationDoPreflight(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; - if (!publicKeyType(ctx.tx[sfPublicKey])) return temMALFORMED; @@ -1240,7 +1231,7 @@ attestationPreflight(PreflightContext const& ctx) if (att->sendingAmount.issue() != expectedIssue) return temXCHAIN_BAD_PROOF; - return preflight2(ctx); + return tesSUCCESS; } template @@ -1375,18 +1366,15 @@ attestationDoApply(ApplyContext& ctx) } // namespace //------------------------------------------------------------------------------ -NotTEC -XChainCreateBridge::preflight(PreflightContext const& ctx) +bool +XChainCreateBridge::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureXChainBridge); +} +NotTEC +XChainCreateBridge::doPreflight(PreflightContext const& ctx) +{ auto const account = ctx.tx[sfAccount]; auto const reward = ctx.tx[sfSignatureReward]; auto const minAccountCreate = ctx.tx[~sfMinAccountCreateAmount]; @@ -1456,7 +1444,7 @@ XChainCreateBridge::preflight(PreflightContext const& ctx) return temXCHAIN_BRIDGE_BAD_ISSUES; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -1556,18 +1544,21 @@ XChainCreateBridge::doApply() //------------------------------------------------------------------------------ -NotTEC -BridgeModify::preflight(PreflightContext const& ctx) +bool +BridgeModify::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; + return ctx.rules.enabled(featureXChainBridge); +} - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfBridgeModifyMask) - return temINVALID_FLAG; +std::uint32_t +BridgeModify::getFlagsMask(PreflightContext const& ctx) +{ + return tfBridgeModifyMask; +} +NotTEC +BridgeModify::doPreflight(PreflightContext const& ctx) +{ auto const account = ctx.tx[sfAccount]; auto const reward = ctx.tx[~sfSignatureReward]; auto const minAccountCreate = ctx.tx[~sfMinAccountCreateAmount]; @@ -1606,7 +1597,7 @@ BridgeModify::preflight(PreflightContext const& ctx) return temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -1666,18 +1657,15 @@ BridgeModify::doApply() //------------------------------------------------------------------------------ -NotTEC -XChainClaim::preflight(PreflightContext const& ctx) +bool +XChainClaim::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureXChainBridge); +} +NotTEC +XChainClaim::doPreflight(PreflightContext const& ctx) +{ STXChainBridge const bridgeSpec = ctx.tx[sfXChainBridge]; auto const amount = ctx.tx[sfAmount]; @@ -1688,7 +1676,7 @@ XChainClaim::preflight(PreflightContext const& ctx) return temBAD_AMOUNT; } - return preflight2(ctx); + return tesSUCCESS; } TER @@ -1904,18 +1892,15 @@ XChainCommit::makeTxConsequences(PreflightContext const& ctx) return TxConsequences{ctx.tx, maxSpend}; } -NotTEC -XChainCommit::preflight(PreflightContext const& ctx) +bool +XChainCommit::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureXChainBridge); +} +NotTEC +XChainCommit::doPreflight(PreflightContext const& ctx) +{ auto const amount = ctx.tx[sfAmount]; auto const bridgeSpec = ctx.tx[sfXChainBridge]; @@ -1926,7 +1911,7 @@ XChainCommit::preflight(PreflightContext const& ctx) amount.issue() != bridgeSpec.issuingChainIssue()) return temBAD_ISSUER; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -2018,24 +2003,21 @@ XChainCommit::doApply() //------------------------------------------------------------------------------ -NotTEC -XChainCreateClaimID::preflight(PreflightContext const& ctx) +bool +XChainCreateClaimID::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureXChainBridge); +} +NotTEC +XChainCreateClaimID::doPreflight(PreflightContext const& ctx) +{ auto const reward = ctx.tx[sfSignatureReward]; if (!isXRP(reward) || reward.signum() < 0 || !isLegalNet(reward)) return temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER @@ -2133,10 +2115,16 @@ XChainCreateClaimID::doApply() //------------------------------------------------------------------------------ -NotTEC -XChainAddClaimAttestation::preflight(PreflightContext const& ctx) +bool +XChainAddClaimAttestation::isEnabled(PreflightContext const& ctx) { - return attestationPreflight(ctx); + return ctx.rules.enabled(featureXChainBridge); +} + +NotTEC +XChainAddClaimAttestation::doPreflight(PreflightContext const& ctx) +{ + return attestationDoPreflight(ctx); } TER @@ -2153,10 +2141,16 @@ XChainAddClaimAttestation::doApply() //------------------------------------------------------------------------------ -NotTEC -XChainAddAccountCreateAttestation::preflight(PreflightContext const& ctx) +bool +XChainAddAccountCreateAttestation::isEnabled(PreflightContext const& ctx) { - return attestationPreflight(ctx); + return ctx.rules.enabled(featureXChainBridge); +} + +NotTEC +XChainAddAccountCreateAttestation::doPreflight(PreflightContext const& ctx) +{ + return attestationDoPreflight(ctx); } TER @@ -2173,18 +2167,15 @@ XChainAddAccountCreateAttestation::doApply() //------------------------------------------------------------------------------ -NotTEC -XChainCreateAccountCommit::preflight(PreflightContext const& ctx) +bool +XChainCreateAccountCommit::isEnabled(PreflightContext const& ctx) { - if (!ctx.rules.enabled(featureXChainBridge)) - return temDISABLED; - - if (auto const ret = preflight1(ctx); !isTesSuccess(ret)) - return ret; - - if (ctx.tx.getFlags() & tfUniversalMask) - return temINVALID_FLAG; + return ctx.rules.enabled(featureXChainBridge); +} +NotTEC +XChainCreateAccountCommit::doPreflight(PreflightContext const& ctx) +{ auto const amount = ctx.tx[sfAmount]; if (amount.signum() <= 0 || !amount.native()) @@ -2197,7 +2188,7 @@ XChainCreateAccountCommit::preflight(PreflightContext const& ctx) if (reward.issue() != amount.issue()) return temBAD_AMOUNT; - return preflight2(ctx); + return tesSUCCESS; } TER diff --git a/src/xrpld/app/tx/detail/XChainBridge.h b/src/xrpld/app/tx/detail/XChainBridge.h index 82b64cc0e3..b116418023 100644 --- a/src/xrpld/app/tx/detail/XChainBridge.h +++ b/src/xrpld/app/tx/detail/XChainBridge.h @@ -39,8 +39,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -58,8 +61,14 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + + static std::uint32_t + getFlagsMask(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -91,8 +100,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -118,8 +130,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -147,8 +162,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -176,8 +194,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -197,8 +218,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); @@ -241,8 +265,11 @@ public: { } + static bool + isEnabled(PreflightContext const& ctx); + static NotTEC - preflight(PreflightContext const& ctx); + doPreflight(PreflightContext const& ctx); static TER preclaim(PreclaimContext const& ctx); diff --git a/src/xrpld/app/tx/detail/applySteps.cpp b/src/xrpld/app/tx/detail/applySteps.cpp index 32745f703d..476021cbd6 100644 --- a/src/xrpld/app/tx/detail/applySteps.cpp +++ b/src/xrpld/app/tx/detail/applySteps.cpp @@ -120,7 +120,7 @@ invoke_preflight(PreflightContext const& ctx) try { return with_txn_type(ctx.tx.getTxnType(), [&]() { - auto const tec = T::preflight(ctx); + auto const tec = Transactor::preflight(ctx); return std::make_pair( tec, isTesSuccess(tec) ? consequences_helper(ctx)