Refactor 3: Transactors

This commit is contained in:
Ed Hennis
2025-05-16 16:08:20 +01:00
committed by Bronek Kozicki
parent 937b67cbc0
commit 4fe3ec8a08
102 changed files with 1125 additions and 863 deletions

View File

@@ -3328,7 +3328,7 @@ private:
env.current()->rules(),
tapNONE,
env.journal);
auto pf = AMMBid::preflight(pfctx);
auto pf = Transactor::preflight<AMMBid>(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<AMMBid>(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<AMMBid>(pfctx);
BEAST_EXPECT(pf == temBAD_AMM_TOKENS);
}
}

View File

@@ -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<Issue>(), ctx.tx[sfAsset2].get<Issue>()))
{
@@ -80,7 +74,7 @@ AMMBid::preflight(PreflightContext const& ctx)
}
}
return preflight2(ctx);
return tesSUCCESS;
}
TER

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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<Issue>(), ctx.tx[sfAsset2].get<Issue>()))
{
@@ -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

View File

@@ -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);

View File

@@ -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<STAmount>

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}
//------------------------------------------------------------------------------

View File

@@ -36,7 +36,7 @@ public:
}
static NotTEC
preflight(PreflightContext const& ctx);
doPreflight(PreflightContext const& ctx);
static TER
preclaim(PreclaimContext const& ctx);

View File

@@ -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

View File

@@ -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);

View File

@@ -33,11 +33,12 @@
namespace ripple {
template <>
NotTEC
Change::preflight(PreflightContext const& ctx)
Transactor::preflight<Change>(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);

View File

@@ -33,9 +33,6 @@ public:
{
}
static NotTEC
preflight(PreflightContext const& ctx);
TER
doApply() override;
void

View File

@@ -75,25 +75,28 @@ preflightHelper<MPTIssue>(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(
[&]<typename T>(T const&) { return preflightHelper<T>(ctx); },
ctx.tx[sfAmount].asset().value());
!isTesSuccess(ret))
return ret;
return preflight2(ctx);
return tesSUCCESS;
}
template <ValidIssueType T>

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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
} // namespace ripple

View File

@@ -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
#endif

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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<int>(authArrPresent) + static_cast<int>(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<int>(authArrPresent) + static_cast<int>(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

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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<MPTID, TER>

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -38,22 +38,26 @@ extractNFTokenFlagsFromTxFlags(std::uint32_t txFlags)
return static_cast<std::uint16_t>(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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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<MPTIssue>();
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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -34,7 +34,7 @@ public:
}
static NotTEC
preflight(PreflightContext const& ctx);
doPreflight(PreflightContext const& ctx);
static XRPAmount
calculateBaseFee(ReadView const& view, STTx const& tx);

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -34,13 +34,14 @@
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/Protocol.h>
#include <xrpl/protocol/TxFlags.h>
#include <xrpl/protocol/UintTypes.h>
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<Slice> 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,

View File

@@ -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 <class T>
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<Slice> const& slice, std::size_t maxLength);
template <class T>
static bool
validNumericRange(std::optional<T> value, T max, T min = {});
template <class T, class Unit>
static bool
validNumericRange(
std::optional<T> value,
unit::ValueUnit<Unit, T> max,
unit::ValueUnit<Unit, T> min = {});
private:
std::pair<TER, XRPAmount>
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<Change>(PreflightContext const& ctx);
template <class T>
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 <class T>
bool
Transactor::validNumericRange(std::optional<T> value, T max, T min)
{
if (!value)
return true;
return value >= min && value <= max;
}
template <class T, class Unit>
bool
Transactor::validNumericRange(
std::optional<T> value,
unit::ValueUnit<Unit, T> max,
unit::ValueUnit<Unit, T> min)
{
return validNumericRange(value, max.value(), min.value());
}
} // namespace ripple

View File

@@ -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

View File

@@ -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);

View File

@@ -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<MPTIssue>())
{
auto mptID = vaultAsset.get<MPTIssue>().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<Issue>())
{
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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -1209,17 +1209,8 @@ toClaim(STTx const& tx)
template <class TAttestation>
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 <class TAttestation>
@@ -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<Attestations::AttestationClaim>(ctx);
return ctx.rules.enabled(featureXChainBridge);
}
NotTEC
XChainAddClaimAttestation::doPreflight(PreflightContext const& ctx)
{
return attestationDoPreflight<Attestations::AttestationClaim>(ctx);
}
TER
@@ -2153,10 +2141,16 @@ XChainAddClaimAttestation::doApply()
//------------------------------------------------------------------------------
NotTEC
XChainAddAccountCreateAttestation::preflight(PreflightContext const& ctx)
bool
XChainAddAccountCreateAttestation::isEnabled(PreflightContext const& ctx)
{
return attestationPreflight<Attestations::AttestationCreateAccount>(ctx);
return ctx.rules.enabled(featureXChainBridge);
}
NotTEC
XChainAddAccountCreateAttestation::doPreflight(PreflightContext const& ctx)
{
return attestationDoPreflight<Attestations::AttestationCreateAccount>(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

Some files were not shown because too many files have changed in this diff Show More