1#include <xrpl/tx/applySteps.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Number.h>
5#include <xrpl/basics/base_uint.h>
6#include <xrpl/beast/utility/Zero.h>
7#include <xrpl/beast/utility/instrumentation.h>
8#include <xrpl/ledger/ApplyView.h>
9#include <xrpl/ledger/OpenView.h>
10#include <xrpl/protocol/Rules.h>
11#include <xrpl/protocol/SField.h>
12#include <xrpl/protocol/SeqProxy.h>
13#include <xrpl/protocol/TER.h>
14#include <xrpl/protocol/XRPAmount.h>
15#include <xrpl/tx/ApplyContext.h>
16#include <xrpl/tx/Transactor.h>
24#pragma push_macro("TRANSACTION")
28#define TRANSACTION(...)
29#define TRANSACTION_INCLUDE 1
31#include <xrpl/protocol/detail/transactions.macro>
34#pragma pop_macro("TRANSACTION")
39#include <xrpl/core/ServiceRegistry.h>
40#include <xrpl/protocol/TxFormats.h>
46struct UnknownTxnType : std::exception
49 UnknownTxnType(
TxType t) : txnType{t}
58withTxnType(
Rules const& rules,
TxType txnType, F&& f)
73 std::optional<CurrentTransactionRulesGuard> rulesGuard;
74 std::optional<NumberMantissaScaleGuard> mantissaScaleGuard;
79#pragma push_macro("TRANSACTION")
82#define TRANSACTION(tag, value, name, ...) \
84 return f.template operator()<name>();
86#include <xrpl/protocol/detail/transactions.macro>
89#pragma pop_macro("TRANSACTION")
91 throw UnknownTxnType(txnType);
129 return T::makeTxConsequences(ctx);
138 auto const tec = Transactor::invokePreflight<T>(ctx);
139 return std::make_pair(
140 tec, isTesSuccess(tec) ? consequencesHelper<T>(ctx) : TxConsequences{tec});
143 catch (UnknownTxnType
const& e)
147 JLOG(ctx.
j.
fatal()) <<
"Unknown transaction type in preflight: " << e.txnType;
148 UNREACHABLE(
"xrpl::invokePreflight : unknown transaction type");
174 auto const id = ctx.tx.getAccountID(sfAccount);
176 if (id != beast::kZero)
178 if (NotTEC const preSigResult = [&]() -> NotTEC {
179 if (NotTEC const result = T::checkSeqProxy(ctx.view, ctx.tx, ctx.j))
182 if (NotTEC const result = T::checkPriorTxAndLastLedger(ctx))
185 if (NotTEC const result = T::checkSponsor(ctx.view, ctx.tx))
188 if (NotTEC const result =
189 Transactor::invokeCheckPermission<T>(ctx.view, ctx.tx))
192 if (NotTEC const result = T::checkSign(ctx))
200 auto const baseFee = calculateBaseFee(ctx.view, ctx.tx);
202 return baseFee.error();
204 if (TER const result = T::checkFee(ctx, *baseFee))
208 return T::preclaim(ctx);
211 catch (UnknownTxnType
const& e)
215 JLOG(ctx.
j.
fatal()) <<
"Unknown transaction type in preclaim: " << e.txnType;
216 UNREACHABLE(
"xrpl::invokePreclaim : unknown transaction type");
237static std::expected<XRPAmount, TER>
243 return T::calculateBaseFee(view, tx);
246 catch (UnknownTxnType
const&)
249 UNREACHABLE(
"xrpl::invoke_calculateBaseFee : unknown transaction type");
256 <<
" threw an exception: " << e.
what();
262 <<
" threw an unknown exception";
275 !
isTesSuccess(pfResult),
"xrpl::TxConsequences::TxConsequences : is not tesSUCCESS");
280 ,
fee_(tx[sfFee].native() && !tx[sfFee].negative() ? tx[sfFee].xrp() :
beast::kZero)
312 catch (UnknownTxnType
const& e)
316 JLOG(ctx.
journal.
fatal()) <<
"Unknown transaction type in apply: " << e.txnType;
317 UNREACHABLE(
"xrpl::invokeApply : unknown transaction type");
331 return std::make_unique<T>(ctx);
352 JLOG(j.
fatal()) <<
"apply (preflight): TapProposal set without TapDryRun.";
363 JLOG(j.
fatal()) <<
"apply (preflight): " << e.
what();
383 JLOG(j.
fatal()) <<
"apply (preflight): TapProposal set without TapDryRun.";
394 JLOG(j.
fatal()) <<
"apply (preflight): " << e.
what();
405 return Transactor::invokeCheckPermission<T>(view, tx);
409 catch (UnknownTxnType
const& e)
412 JLOG(
debugLog().fatal()) <<
"Unknown transaction type in invokeCheckPermission: "
414 UNREACHABLE(
"xrpl::invokeCheckPermission : unknown transaction type");
426 auto secondFlight = [&]() {
434 preflightResult.
flags,
442 preflightResult.
flags,
452 secondFlight.parentBatchId,
462 preflightResult.
flags,
470 return {*ctx, ctx->preflightResult};
475 JLOG(ctx->j.fatal()) <<
"apply (preclaim): " << e.
what();
480std::expected<XRPAmount, TER>
504 return {preclaimResult.
ter,
false};
512 JLOG(preclaimResult.
j.
error())
513 <<
"apply: could not compute base fee: " <<
transToken(baseFee.error());
525 preclaimResult.
flags,
531 JLOG(preclaimResult.
j.
fatal()) <<
"apply: " << e.
what();
A generic endpoint for log messages.
State information when applying a tx.
beast::Journal const journal
Writable ledger view that accumulates state and tx changes.
Rules const & rules() const override
Returns the tx processing rules.
virtual Rules const & rules() const =0
Returns the tx processing rules.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
Rules controlling protocol behavior.
TxType getTxnType() const
UInt256 getTransactionID() const
A type that represents either a sequence value or a ticket value.
Service registry for dependency injection.
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
Class describing the consequences to the account of applying a transaction if the transaction consume...
TxConsequences(NotTEC pfResult)
std::uint32_t sequencesConsumed_
Number of sequences consumed.
Category
Describes how the transaction affects subsequent transactions.
@ Blocker
Affects the ability of subsequent transactions to claim a fee.
XRPAmount potentialSpend_
Does NOT include the fee.
bool isBlocker_
Describes how the transaction affects subsequent transactions.
std::uint32_t sequencesConsumed() const
Sequences consumed.
XRPAmount const & potentialSpend() const
Potential Spend.
SeqProxy seqProx_
SeqProxy of transaction.
XRPAmount fee_
Transaction fee.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
PreflightResult preflight(ServiceRegistry ®istry, Rules const &rules, STTx const &tx, ApplyFlags flags, beast::Journal j)
Gate a transaction based on static information.
TxType
Transaction type identifiers.
PreclaimResult preclaim(PreflightResult const &preflightResult, ServiceRegistry ®istry, OpenView const &view)
Gate a transaction based on static ledger information.
std::expected< XRPAmount, TER > calculateBaseFee(ReadView const &view, STTx const &tx)
Compute only the expected base fee for a transaction.
beast::Journal debugLog()
Returns a debug journal.
static TER invokePreclaim(PreclaimContext const &ctx)
TxConsequences consequencesHelper(PreflightContext const &ctx)
void createGuards(Rules const &rules, std::optional< CurrentTransactionRulesGuard > &rulesGuard, std::optional< NumberMantissaScaleGuard > &mantissaScaleGuard)
std::string transToken(TER code)
static std::pair< NotTEC, TxConsequences > invokePreflight(PreflightContext const &ctx)
TERSubset< CanCvtToNotTEC > NotTEC
static std::expected< XRPAmount, TER > invokeCalculateBaseFee(ReadView const &view, STTx const &tx)
Calculates the base fee for a given transaction.
std::unique_ptr< Transactor > makeTransactor(ApplyContext &ctx)
XRPAmount calculateDefaultBaseFee(ReadView const &view, STTx const &tx)
Return the minimum fee that an "ordinary" transaction would pay.
NotTEC invokeCheckPermission(ReadView const &view, STTx const &tx)
Type-erased overload of Transactor::invokeCheckPermission.
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER
static ApplyResult invokeApply(ApplyContext &ctx)
ApplyResult doApply(PreclaimResult const &preclaimResult, ServiceRegistry ®istry, OpenView &view)
Apply a prechecked transaction to an OpenView.
State information when determining if a tx is likely to claim a fee.
Describes the results of the preclaim check.
ReadView const & view
From the input - the ledger view.
TER const ter
Intermediate transaction result.
ApplyFlags const flags
From the input - the flags.
STTx const & tx
From the input - the transaction.
std::optional< UInt256 const > const parentBatchId
From the input - the batch identifier, if part of a batch.
beast::Journal const j
From the input - the journal.
bool const likelyToClaimFee
Success flag - whether the transaction is likely to claim a fee.
State information when preflighting a tx.
Describes the results of the preflight check.
beast::Journal const j
From the input - the journal.
ApplyFlags const flags
From the input - the flags.
Rules const rules
From the input - the rules.
NotTEC const ter
Intermediate transaction result.
STTx const & tx
From the input - the transaction.
std::optional< UInt256 const > const parentBatchId
From the input - the batch identifier, if part of a batch.