xrpld
Loading...
Searching...
No Matches
xrpl::TxInvariantCheck Class Referenceabstract

Runtime interface for a transaction-specific invariant check. More...

#include <InvariantRunner.h>

Inheritance diagram for xrpl::TxInvariantCheck:

Public Member Functions

virtual ~TxInvariantCheck ()=default
virtual void visitEntry (bool isDelete, SLE::ConstRef before, SLE::ConstRef after)=0
 Called for each ledger entry modified by the transaction.
virtual bool finalize (STTx const &tx, TER result, XRPAmount fee, ReadView const &view, beast::Journal const &j)=0
 Called after all entries have been visited.

Detailed Description

Runtime interface for a transaction-specific invariant check.

The free checkInvariants runner drives two layers of checks over a single walk of the modified ledger entries:

  • Protocol checks are the concrete types in InvariantChecks, held in a std::tuple and dispatched statically by a compile-time fold (no virtual calls). They are duck-typed against the two-phase contract described below; see InvariantChecker_PROTOTYPE in InvariantCheck.h.
  • The transaction-specific check is injected at runtime through this interface, so the runner can call it without depending on the concrete transactor type. Transactor implements this interface directly (see Transactor.h) so that the interface's access can stay narrower than Transactor's own public surface: calling through a TxInvariantCheck& (all the runner ever holds) is public, but calling through a Transactor& is not, since Transactor overrides these as private (forwarding to its own protected visitInvariantEntry/finalizeInvariants).

Both layers honour the same two-phase protocol:

Phase 1 — state collection (visitEntry). Called once for each ledger entry created, modified, or deleted by the transaction. Implementations accumulate whatever state they need to evaluate their post-conditions. Must not throw.

Phase 2 — condition evaluation (finalize). Called once after every modified entry has been visited. Returns true if all post-conditions hold, false to fail the transaction.

Rule: invariants must run regardless of transaction result. finalize MUST perform meaningful checks even when the transaction has failed (when result is not tesSUCCESS). A bug or exploit could cause a failed transaction to mutate ledger state in unexpected ways; invariants are the last line of defense.

The typical pattern: an invariant that expects a domain-specific state change (e.g. a Vault being created) should expect that change only when the transaction succeeded. A failed VaultCreate must not have created a Vault.

Rule: privilege-gated checks apply to failed transactions too. Failed transactions carry no privileges. Any privilege-gated assertion must therefore also be enforced for failed transactions.

Definition at line 61 of file InvariantRunner.h.

Constructor & Destructor Documentation

◆ ~TxInvariantCheck()

virtual xrpl::TxInvariantCheck::~TxInvariantCheck ( )
virtualdefault

Member Function Documentation

◆ visitEntry()

virtual void xrpl::TxInvariantCheck::visitEntry ( bool isDelete,
SLE::ConstRef before,
SLE::ConstRef after )
pure virtual

Called for each ledger entry modified by the transaction.

Parameters
isDeletetrue if the SLE is being deleted.
beforethe entry's state before the transaction (nullptr for newly created entries).
afterthe entry's state after the transaction. For deletions this is the SLE being erased; use isDelete rather than a null after to detect deletions. after is never null.

Implemented in xrpl::Transactor.

◆ finalize()

virtual bool xrpl::TxInvariantCheck::finalize ( STTx const & tx,
TER result,
XRPAmount fee,
ReadView const & view,
beast::Journal const & j )
nodiscardpure virtual

Called after all entries have been visited.

Parameters
txthe transaction being applied.
resultthe tentative TER result of the transaction.
feethe fee consumed by the transaction.
viewread-only view of the ledger after the transaction.
jjournal for logging invariant failures.
Returns
true if all invariants hold; false to fail with tecINVARIANT_FAILED / tefINVARIANT_FAILED.

Implemented in xrpl::Transactor.