mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-31 02:50:24 +00:00
refactor: Check transaction flags in preflight0
- Adds a flagMask parameter to preflight1 so that it's impossible to forget to check flags. - Also adds a short hash prefix to all Transactor log messages.
This commit is contained in:
@@ -632,6 +632,13 @@ to_string(base_uint<Bits, Tag> const& a)
|
||||
return strHex(a.cbegin(), a.cend());
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline std::string
|
||||
to_short_string(base_uint<Bits, Tag> const& a)
|
||||
{
|
||||
return to_string(a).substr(0, 8) + "...";
|
||||
}
|
||||
|
||||
template <std::size_t Bits, class Tag>
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& out, base_uint<Bits, Tag> const& u)
|
||||
|
||||
@@ -123,6 +123,8 @@ constexpr std::uint32_t tfTrustSetMask =
|
||||
// EnableAmendment flags:
|
||||
constexpr std::uint32_t tfGotMajority = 0x00010000;
|
||||
constexpr std::uint32_t tfLostMajority = 0x00020000;
|
||||
constexpr std::uint32_t tfChangeMask =
|
||||
~( tfUniversal | tfGotMajority | tfLostMajority);
|
||||
|
||||
// PaymentChannelClaim flags:
|
||||
constexpr std::uint32_t tfRenew = 0x00010000;
|
||||
|
||||
@@ -508,6 +508,7 @@ TRANSACTION(ttVAULT_CLAWBACK, 69, VaultClawback, ({
|
||||
{sfAmount, soeOPTIONAL, soeMPTSupported},
|
||||
}))
|
||||
|
||||
#if 0
|
||||
/** This transaction creates and updates a Loan Broker */
|
||||
TRANSACTION(ttLOAN_BROKER_SET, 70, LoanBrokerSet, ({
|
||||
{sfVaultID, soeREQUIRED},
|
||||
@@ -537,7 +538,7 @@ TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 73, LoanBrokerCoverWithdraw, ({
|
||||
}))
|
||||
|
||||
/** This transaction creates a Loan */
|
||||
TRANSACTION(ttLOAN_CREATE, 74, LoanCreate, ({
|
||||
TRANSACTION(ttLOAN_SET, 74, LoanSet, ({
|
||||
{sfLoanBrokerID, soeREQUIRED},
|
||||
{sfData, soeOPTIONAL},
|
||||
{sfCounterparty, soeOPTIONAL},
|
||||
@@ -555,6 +556,7 @@ TRANSACTION(ttLOAN_CREATE, 74, LoanCreate, ({
|
||||
{sfPaymentInterval, soeOPTIONAL},
|
||||
{sfGracePeriod, soeOPTIONAL},
|
||||
}))
|
||||
#endif
|
||||
|
||||
/** This system-generated transaction type is used to update the status of the various amendments.
|
||||
|
||||
|
||||
@@ -152,6 +152,7 @@ struct base_uint_test : beast::unit_test::suite
|
||||
uset.insert(u);
|
||||
BEAST_EXPECT(raw.size() == u.size());
|
||||
BEAST_EXPECT(to_string(u) == "0102030405060708090A0B0C");
|
||||
BEAST_EXPECT(to_short_string(u) == "01020304...");
|
||||
BEAST_EXPECT(*u.data() == 1);
|
||||
BEAST_EXPECT(u.signum() == 1);
|
||||
BEAST_EXPECT(!!u);
|
||||
@@ -174,6 +175,7 @@ struct base_uint_test : beast::unit_test::suite
|
||||
test96 v{~u};
|
||||
uset.insert(v);
|
||||
BEAST_EXPECT(to_string(v) == "FEFDFCFBFAF9F8F7F6F5F4F3");
|
||||
BEAST_EXPECT(to_short_string(v) == "FEFDFCFB...");
|
||||
BEAST_EXPECT(*v.data() == 0xfe);
|
||||
BEAST_EXPECT(v.signum() == 1);
|
||||
BEAST_EXPECT(!!v);
|
||||
@@ -194,6 +196,7 @@ struct base_uint_test : beast::unit_test::suite
|
||||
test96 z{beast::zero};
|
||||
uset.insert(z);
|
||||
BEAST_EXPECT(to_string(z) == "000000000000000000000000");
|
||||
BEAST_EXPECT(to_short_string(z) == "00000000...");
|
||||
BEAST_EXPECT(*z.data() == 0);
|
||||
BEAST_EXPECT(*z.begin() == 0);
|
||||
BEAST_EXPECT(*std::prev(z.end(), 1) == 0);
|
||||
@@ -214,6 +217,7 @@ struct base_uint_test : beast::unit_test::suite
|
||||
BEAST_EXPECT(n == z);
|
||||
n--;
|
||||
BEAST_EXPECT(to_string(n) == "FFFFFFFFFFFFFFFFFFFFFFFF");
|
||||
BEAST_EXPECT(to_short_string(n) == "FFFFFFFF...");
|
||||
n = beast::zero;
|
||||
BEAST_EXPECT(n == z);
|
||||
|
||||
@@ -224,6 +228,7 @@ struct base_uint_test : beast::unit_test::suite
|
||||
test96 x{zm1 ^ zp1};
|
||||
uset.insert(x);
|
||||
BEAST_EXPECTS(to_string(x) == "FFFFFFFFFFFFFFFFFFFFFFFE", to_string(x));
|
||||
BEAST_EXPECTS(to_short_string(x) == "FFFFFFFF...", to_short_string(x));
|
||||
|
||||
BEAST_EXPECT(uset.size() == 4);
|
||||
|
||||
|
||||
@@ -36,15 +36,9 @@ AMMBid::preflight(PreflightContext const& ctx)
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Bid: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
if (auto const res = invalidAMMAssetPair(
|
||||
ctx.tx[sfAsset].get<Issue>(), ctx.tx[sfAsset2].get<Issue>()))
|
||||
{
|
||||
|
||||
@@ -39,13 +39,9 @@ AMMClawback::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureAMMClawback))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfAMMClawbackMask))
|
||||
return ret; // LCOV_EXCL_LINE
|
||||
|
||||
auto const flags = ctx.tx.getFlags();
|
||||
if (flags & tfAMMClawbackMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
AccountID const issuer = ctx.tx[sfAccount];
|
||||
AccountID const holder = ctx.tx[sfHolder];
|
||||
|
||||
@@ -63,6 +59,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())
|
||||
|
||||
@@ -37,15 +37,9 @@ AMMCreate::preflight(PreflightContext const& ctx)
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Instance: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
auto const amount = ctx.tx[sfAmount];
|
||||
auto const amount2 = ctx.tx[sfAmount2];
|
||||
|
||||
|
||||
@@ -33,15 +33,9 @@ AMMDelete::preflight(PreflightContext const& ctx)
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "AMM Delete: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
return preflight2(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,15 +35,10 @@ AMMDeposit::preflight(PreflightContext const& ctx)
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfDepositMask))
|
||||
return ret;
|
||||
|
||||
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];
|
||||
|
||||
@@ -33,7 +33,7 @@ AMMVote::preflight(PreflightContext const& ctx)
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (auto const res = invalidAMMAssetPair(
|
||||
@@ -43,12 +43,6 @@ 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.";
|
||||
|
||||
@@ -34,15 +34,10 @@ AMMWithdraw::preflight(PreflightContext const& ctx)
|
||||
if (!ammEnabled(ctx.rules))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfWithdrawMask))
|
||||
return ret;
|
||||
|
||||
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];
|
||||
|
||||
@@ -35,17 +35,9 @@ CancelCheck::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureChecks))
|
||||
return temDISABLED;
|
||||
|
||||
NotTEC const ret{preflight1(ctx)};
|
||||
if (!isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,18 +28,9 @@ namespace ripple {
|
||||
NotTEC
|
||||
CancelOffer::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
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";
|
||||
|
||||
@@ -38,17 +38,9 @@ CashCheck::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureChecks))
|
||||
return temDISABLED;
|
||||
|
||||
NotTEC const ret{preflight1(ctx)};
|
||||
if (!isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
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;
|
||||
}
|
||||
|
||||
// Exactly one of Amount or DeliverMin must be present.
|
||||
auto const optAmount = ctx.tx[~sfAmount];
|
||||
auto const optDeliverMin = ctx.tx[~sfDeliverMin];
|
||||
|
||||
@@ -36,8 +36,12 @@ namespace ripple {
|
||||
NotTEC
|
||||
Change::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
auto const ret = preflight0(ctx);
|
||||
if (!isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
// The check for tfChangeMask is gated by LendingProtocol because that
|
||||
// feature introduced this parameter, and it's not worth adding another
|
||||
// amendment just for this.
|
||||
if (auto const ret = preflight0(
|
||||
ctx, ctx.rules.enabled(featureLendingProtocol) ? tfChangeMask : 0))
|
||||
return ret;
|
||||
|
||||
auto account = ctx.tx.getAccountID(sfAccount);
|
||||
|
||||
@@ -81,12 +81,9 @@ Clawback::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureClawback))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfClawbackMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfClawbackMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const ret = std::visit(
|
||||
[&]<typename T>(T const&) { return preflightHelper<T>(ctx); },
|
||||
ctx.tx[sfAmount].asset().value());
|
||||
|
||||
@@ -34,16 +34,9 @@ CreateCheck::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureChecks))
|
||||
return temDISABLED;
|
||||
|
||||
NotTEC const ret{preflight1(ctx)};
|
||||
if (!isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
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;
|
||||
}
|
||||
if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
|
||||
{
|
||||
// They wrote a check to themselves.
|
||||
|
||||
@@ -42,7 +42,7 @@ CreateOffer::makeTxConsequences(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
CreateOffer::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfOfferCreateMask))
|
||||
return ret;
|
||||
|
||||
auto& tx = ctx.tx;
|
||||
@@ -50,12 +50,6 @@ CreateOffer::preflight(PreflightContext const& ctx)
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -39,16 +39,13 @@ CreateTicket::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureTicketBatch))
|
||||
return temDISABLED;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
if (NotTEC const ret{preflight1(ctx, tfUniversalMask)})
|
||||
return ret;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,19 +57,14 @@ CredentialCreate::preflight(PreflightContext const& ctx)
|
||||
return temDISABLED;
|
||||
}
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret = preflight1(
|
||||
ctx, ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
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";
|
||||
@@ -211,16 +206,11 @@ CredentialDelete::preflight(PreflightContext const& ctx)
|
||||
return temDISABLED;
|
||||
}
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret = preflight1(
|
||||
ctx, ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
if (ctx.rules.enabled(fixInvalidTxFlags) &&
|
||||
(ctx.tx.getFlags() & tfUniversalMask))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "CredentialDelete: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
auto const subject = ctx.tx[~sfSubject];
|
||||
auto const issuer = ctx.tx[~sfIssuer];
|
||||
|
||||
@@ -298,16 +288,11 @@ CredentialAccept::preflight(PreflightContext const& ctx)
|
||||
return temDISABLED;
|
||||
}
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret = preflight1(
|
||||
ctx, ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
if (ctx.rules.enabled(fixInvalidTxFlags) &&
|
||||
(ctx.tx.getFlags() & tfUniversalMask))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "CredentialAccept: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
if (!ctx.tx[sfIssuer])
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: Issuer field zeroed.";
|
||||
|
||||
@@ -48,10 +48,7 @@ DIDSet::preflight(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))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (!ctx.tx.isFieldPresent(sfURI) &&
|
||||
@@ -177,10 +174,7 @@ DIDDelete::preflight(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))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
return preflight2(ctx);
|
||||
|
||||
@@ -47,10 +47,7 @@ DeleteAccount::preflight(PreflightContext const& ctx)
|
||||
!ctx.rules.enabled(featureCredentials))
|
||||
return temDISABLED;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx[sfAccount] == ctx.tx[sfDestination])
|
||||
|
||||
@@ -32,15 +32,9 @@ DeleteOracle::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featurePriceOracle))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "Oracle Delete: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
return preflight2(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,17 +45,9 @@ DepositPreauth::preflight(PreflightContext const& ctx)
|
||||
if (authCredPresent && !ctx.rules.enabled(featureCredentials))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
auto& tx = ctx.tx;
|
||||
|
||||
if (tx.getFlags() & tfUniversalMask)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Malformed transaction: Invalid flags set.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
auto const optAuth = ctx.tx[~sfAuthorize];
|
||||
auto const optUnauth = ctx.tx[~sfUnauthorize];
|
||||
int const authPresent = static_cast<int>(optAuth.has_value()) +
|
||||
|
||||
@@ -85,10 +85,9 @@ EscrowCreate::makeTxConsequences(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
EscrowCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret =
|
||||
preflight1(ctx, ctx.rules.enabled(fix1543) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
if (!isXRP(ctx.tx[sfAmount]))
|
||||
@@ -296,14 +295,13 @@ checkCondition(Slice f, Slice c)
|
||||
NotTEC
|
||||
EscrowFinish::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (ctx.tx.isFieldPresent(sfCredentialIDs) &&
|
||||
!ctx.rules.enabled(featureCredentials))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret =
|
||||
preflight1(ctx, ctx.rules.enabled(fix1543) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
auto const cb = ctx.tx[~sfCondition];
|
||||
@@ -515,10 +513,9 @@ EscrowFinish::doApply()
|
||||
NotTEC
|
||||
EscrowCancel::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret =
|
||||
preflight1(ctx, ctx.rules.enabled(fix1543) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
return preflight2(ctx);
|
||||
|
||||
@@ -1660,8 +1660,8 @@ NoModifiedUnmodifiableFields::finalize(
|
||||
fieldChanged(before, after, sfCloseInterestRate) ||
|
||||
fieldChanged(before, after, sfOverpaymentInterestRate) ||
|
||||
fieldChanged(before, after, sfStartDate) ||
|
||||
fieldChanged(before, after, sfPaymentInterval)
|
||||
fieldChanged(before, after, sfGracePeriod);
|
||||
fieldChanged(before, after, sfPaymentInterval) ||
|
||||
fieldChanged(before, after, sfGracePeriod);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
|
||||
@@ -33,10 +33,7 @@ LedgerStateFix::preflight(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))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
switch (ctx.tx[sfLedgerFixType])
|
||||
|
||||
@@ -32,12 +32,9 @@ MPTokenAuthorize::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureMPTokensV1))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfMPTokenAuthorizeMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfMPTokenAuthorizeMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (ctx.tx[sfAccount] == ctx.tx[~sfHolder])
|
||||
return temMALFORMED;
|
||||
|
||||
|
||||
@@ -31,12 +31,9 @@ MPTokenIssuanceCreate::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureMPTokensV1))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfMPTokenIssuanceCreateMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfMPTokenIssuanceCreateMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const fee = ctx.tx[~sfTransferFee])
|
||||
{
|
||||
if (fee > maxTransferFee)
|
||||
|
||||
@@ -32,12 +32,9 @@ MPTokenIssuanceDestroy::preflight(PreflightContext const& ctx)
|
||||
return temDISABLED;
|
||||
|
||||
// check flags
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfMPTokenIssuanceDestroyMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfMPTokenIssuanceDestroyMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
return preflight2(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,16 +30,13 @@ MPTokenIssuanceSet::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureMPTokensV1))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfMPTokenIssuanceSetMask))
|
||||
return ret;
|
||||
|
||||
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];
|
||||
|
||||
@@ -33,12 +33,9 @@ NFTokenAcceptOffer::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureNonFungibleTokensV1))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfNFTokenAcceptOfferMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfNFTokenAcceptOfferMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
auto const bo = ctx.tx[~sfNFTokenBuyOffer];
|
||||
auto const so = ctx.tx[~sfNFTokenSellOffer];
|
||||
|
||||
|
||||
@@ -32,12 +32,9 @@ NFTokenBurn::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureNonFungibleTokensV1))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
return preflight2(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,9 @@ NFTokenCancelOffer::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureNonFungibleTokensV1))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfNFTokenCancelOfferMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfNFTokenCancelOfferMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const& ids = ctx.tx[sfNFTokenOffers];
|
||||
ids.empty() || (ids.size() > maxTokenOfferCancelCount))
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -32,14 +32,11 @@ NFTokenCreateOffer::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureNonFungibleTokensV1))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfNFTokenCreateOfferMask))
|
||||
return ret;
|
||||
|
||||
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
|
||||
|
||||
@@ -51,9 +51,6 @@ NFTokenMint::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureNFTokenMintOffer) && hasOfferFields)
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
// 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 +64,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,8 +73,8 @@ NFTokenMint::preflight(PreflightContext const& ctx)
|
||||
: ctx.rules.enabled(featureDynamicNFT) ? tfNFTokenMintOldMaskWithMutable
|
||||
: tfNFTokenMintOldMask;
|
||||
|
||||
if (ctx.tx.getFlags() & NFTokenMintMask)
|
||||
return temINVALID_FLAG;
|
||||
if (auto const ret = preflight1(ctx, nfTokenMintMask))
|
||||
return ret;
|
||||
|
||||
if (auto const f = ctx.tx[~sfTransferFee])
|
||||
{
|
||||
|
||||
@@ -32,12 +32,9 @@ NFTokenModify::preflight(PreflightContext const& ctx)
|
||||
!ctx.rules.enabled(featureDynamicNFT))
|
||||
return temDISABLED;
|
||||
|
||||
if (NotTEC const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (NotTEC const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto owner = ctx.tx[~sfOwner]; owner == ctx.tx[sfAccount])
|
||||
return temMALFORMED;
|
||||
|
||||
|
||||
@@ -174,10 +174,9 @@ PayChanCreate::makeTxConsequences(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
PayChanCreate::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret =
|
||||
preflight1(ctx, ctx.rules.enabled(fix1543) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
|
||||
@@ -329,10 +328,9 @@ PayChanFund::makeTxConsequences(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
PayChanFund::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (ctx.rules.enabled(fix1543) && ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret =
|
||||
preflight1(ctx, ctx.rules.enabled(fix1543) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
if (!isXRP(ctx.tx[sfAmount]) || (ctx.tx[sfAmount] <= beast::zero))
|
||||
@@ -423,7 +421,9 @@ PayChanClaim::preflight(PreflightContext const& ctx)
|
||||
!ctx.rules.enabled(featureCredentials))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret = preflight1(
|
||||
ctx, ctx.rules.enabled(fix1543) ? tfPayChanClaimMask : 0))
|
||||
return ret;
|
||||
|
||||
auto const bal = ctx.tx[~sfBalance];
|
||||
@@ -440,9 +440,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;
|
||||
}
|
||||
|
||||
@@ -70,28 +70,21 @@ Payment::preflight(PreflightContext const& ctx)
|
||||
!ctx.rules.enabled(featureCredentials))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
auto& tx = ctx.tx;
|
||||
auto& j = ctx.j;
|
||||
|
||||
STAmount const dstAmount(tx.getFieldAmount(sfAmount));
|
||||
bool const mptDirect = dstAmount.holds<MPTIssue>();
|
||||
|
||||
if (auto const ret =
|
||||
preflight1(ctx, mptDirect ? tfMPTPaymentMask : tfPaymentMask))
|
||||
return ret;
|
||||
|
||||
if (mptDirect && !ctx.rules.enabled(featureMPTokensV1))
|
||||
return temDISABLED;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -30,15 +30,9 @@ PermissionedDomainDelete::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featurePermissionedDomains))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "PermissionedDomainDelete: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
auto const domain = ctx.tx.getFieldH256(sfDomainID);
|
||||
if (domain == beast::zero)
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -35,15 +35,9 @@ PermissionedDomainSet::preflight(PreflightContext const& ctx)
|
||||
!ctx.rules.enabled(featureCredentials))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "PermissionedDomainSet: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
if (auto err = credentials::checkArray(
|
||||
ctx.tx.getFieldArray(sfAcceptedCredentials),
|
||||
maxPermissionedDomainCredentialsArraySize,
|
||||
|
||||
@@ -59,7 +59,7 @@ SetAccount::makeTxConsequences(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
SetAccount::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfAccountSetMask))
|
||||
return ret;
|
||||
|
||||
auto& tx = ctx.tx;
|
||||
@@ -67,12 +67,6 @@ SetAccount::preflight(PreflightContext const& ctx)
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -42,12 +42,9 @@ SetOracle::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featurePriceOracle))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
auto const& dataSeries = ctx.tx.getFieldArray(sfPriceDataSeries);
|
||||
if (dataSeries.empty())
|
||||
return temARRAY_EMPTY;
|
||||
|
||||
@@ -51,18 +51,9 @@ SetRegularKey::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
NotTEC
|
||||
SetRegularKey::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
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)))
|
||||
|
||||
@@ -80,16 +80,11 @@ SetSignerList::determineOperation(
|
||||
NotTEC
|
||||
SetSignerList::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
// 0 means "Allow any flags"
|
||||
if (auto const ret = preflight1(
|
||||
ctx, ctx.rules.enabled(fixInvalidTxFlags) ? tfUniversalMask : 0))
|
||||
return ret;
|
||||
|
||||
if (ctx.rules.enabled(fixInvalidTxFlags) &&
|
||||
(ctx.tx.getFlags() & tfUniversalMask))
|
||||
{
|
||||
JLOG(ctx.j.debug()) << "SetSignerList: invalid flags.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
auto const result = determineOperation(ctx.tx, ctx.flags, ctx.j);
|
||||
|
||||
if (std::get<0>(result) != tesSUCCESS)
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace ripple {
|
||||
NotTEC
|
||||
SetTrust::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfTrustSetMask))
|
||||
return ret;
|
||||
|
||||
auto& tx = ctx.tx;
|
||||
@@ -77,12 +77,6 @@ SetTrust::preflight(PreflightContext const& ctx)
|
||||
|
||||
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
|
||||
|
||||
@@ -39,7 +39,7 @@ 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))
|
||||
{
|
||||
@@ -74,12 +74,20 @@ 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;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
@@ -89,7 +97,7 @@ preflight1(PreflightContext const& ctx)
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
auto const ret = preflight0(ctx);
|
||||
auto const ret = preflight0(ctx, flagMask);
|
||||
if (!isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
@@ -186,7 +194,10 @@ PreflightContext::PreflightContext(
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Transactor::Transactor(ApplyContext& ctx)
|
||||
: ctx_(ctx), j_(ctx.journal), account_(ctx.tx.getAccountID(sfAccount))
|
||||
: ctx_(ctx)
|
||||
, sink_(ctx.journal, to_short_string(ctx.tx.getTransactionID()) + " ")
|
||||
, j_(sink_)
|
||||
, account_(ctx.tx.getAccountID(sfAccount))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <xrpld/app/tx/detail/ApplyContext.h>
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/beast/utility/WrappedSink.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -87,6 +88,7 @@ class Transactor
|
||||
{
|
||||
protected:
|
||||
ApplyContext& ctx_;
|
||||
beast::WrappedSink sink_;
|
||||
beast::Journal const j_;
|
||||
|
||||
AccountID const account_;
|
||||
@@ -203,13 +205,16 @@ private:
|
||||
void trapTransaction(uint256) const;
|
||||
};
|
||||
|
||||
/** Performs early sanity checks on the txid */
|
||||
/** Performs early sanity checks on the txid and flags */
|
||||
NotTEC
|
||||
preflight0(PreflightContext const& ctx);
|
||||
preflight0(PreflightContext const& ctx, std::uint32_t flagMask);
|
||||
|
||||
/** Performs early sanity checks on the account and fee fields */
|
||||
/** Performs early sanity checks on the account and fee fields.
|
||||
|
||||
(And passes flagMask to preflight0)
|
||||
*/
|
||||
NotTEC
|
||||
preflight1(PreflightContext const& ctx);
|
||||
preflight1(PreflightContext const& ctx, std::uint32_t flagMask);
|
||||
|
||||
/** Checks whether the signature appears valid */
|
||||
NotTEC
|
||||
|
||||
@@ -36,12 +36,9 @@ VaultClawback::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureSingleAssetVault))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ter = preflight1(ctx))
|
||||
if (auto const ter = preflight1(ctx, tfUniversalMask))
|
||||
return ter;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (ctx.tx[sfVaultID] == beast::zero)
|
||||
return temMALFORMED;
|
||||
|
||||
|
||||
@@ -44,12 +44,9 @@ VaultCreate::preflight(PreflightContext const& ctx)
|
||||
!ctx.rules.enabled(featurePermissionedDomains))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ter = preflight1(ctx))
|
||||
if (auto const ter = preflight1(ctx, tfVaultCreateMask))
|
||||
return ter;
|
||||
|
||||
if (ctx.tx.getFlags() & tfVaultCreateMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const data = ctx.tx[~sfData])
|
||||
{
|
||||
if (data->empty() || data->length() > maxDataPayloadLength)
|
||||
|
||||
@@ -33,12 +33,9 @@ VaultDelete::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureSingleAssetVault))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ter = preflight1(ctx))
|
||||
if (auto const ter = preflight1(ctx, tfUniversalMask))
|
||||
return ter;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (ctx.tx[sfVaultID] == beast::zero)
|
||||
return temMALFORMED;
|
||||
|
||||
|
||||
@@ -38,12 +38,9 @@ VaultDeposit::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureSingleAssetVault))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ter = preflight1(ctx))
|
||||
if (auto const ter = preflight1(ctx, tfUniversalMask))
|
||||
return ter;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (ctx.tx[sfVaultID] == beast::zero)
|
||||
return temMALFORMED;
|
||||
|
||||
|
||||
@@ -40,15 +40,12 @@ VaultSet::preflight(PreflightContext const& ctx)
|
||||
!ctx.rules.enabled(featurePermissionedDomains))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ter = preflight1(ctx))
|
||||
if (auto const ter = preflight1(ctx, tfUniversalMask))
|
||||
return ter;
|
||||
|
||||
if (ctx.tx[sfVaultID] == beast::zero)
|
||||
return temMALFORMED;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (auto const data = ctx.tx[~sfData])
|
||||
{
|
||||
if (data->empty() || data->length() > maxDataPayloadLength)
|
||||
|
||||
@@ -36,12 +36,9 @@ VaultWithdraw::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureSingleAssetVault))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ter = preflight1(ctx))
|
||||
if (auto const ter = preflight1(ctx, tfUniversalMask))
|
||||
return ter;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (ctx.tx[sfVaultID] == beast::zero)
|
||||
return temMALFORMED;
|
||||
|
||||
|
||||
@@ -1214,12 +1214,9 @@ attestationPreflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureXChainBridge))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
if (!publicKeyType(ctx.tx[sfPublicKey]))
|
||||
return temMALFORMED;
|
||||
|
||||
@@ -1381,12 +1378,9 @@ XChainCreateBridge::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureXChainBridge))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
auto const account = ctx.tx[sfAccount];
|
||||
auto const reward = ctx.tx[sfSignatureReward];
|
||||
auto const minAccountCreate = ctx.tx[~sfMinAccountCreateAmount];
|
||||
@@ -1562,12 +1556,9 @@ BridgeModify::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureXChainBridge))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfBridgeModifyMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfBridgeModifyMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
auto const account = ctx.tx[sfAccount];
|
||||
auto const reward = ctx.tx[~sfSignatureReward];
|
||||
auto const minAccountCreate = ctx.tx[~sfMinAccountCreateAmount];
|
||||
@@ -1672,12 +1663,9 @@ XChainClaim::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureXChainBridge))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
STXChainBridge const bridgeSpec = ctx.tx[sfXChainBridge];
|
||||
auto const amount = ctx.tx[sfAmount];
|
||||
|
||||
@@ -1910,12 +1898,9 @@ XChainCommit::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureXChainBridge))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
auto const amount = ctx.tx[sfAmount];
|
||||
auto const bridgeSpec = ctx.tx[sfXChainBridge];
|
||||
|
||||
@@ -2024,12 +2009,9 @@ XChainCreateClaimID::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureXChainBridge))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
auto const reward = ctx.tx[sfSignatureReward];
|
||||
|
||||
if (!isXRP(reward) || reward.signum() < 0 || !isLegalNet(reward))
|
||||
@@ -2179,12 +2161,9 @@ XChainCreateAccountCommit::preflight(PreflightContext const& ctx)
|
||||
if (!ctx.rules.enabled(featureXChainBridge))
|
||||
return temDISABLED;
|
||||
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
if (auto const ret = preflight1(ctx, tfUniversalMask))
|
||||
return ret;
|
||||
|
||||
if (ctx.tx.getFlags() & tfUniversalMask)
|
||||
return temINVALID_FLAG;
|
||||
|
||||
auto const amount = ctx.tx[sfAmount];
|
||||
|
||||
if (amount.signum() <= 0 || !amount.native())
|
||||
|
||||
Reference in New Issue
Block a user