Files
rippled/include/xrpl/tx/ApplyContext.h
2026-07-13 10:40:40 +00:00

169 lines
4.4 KiB
C++

#pragma once
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/core/ServiceRegistry.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ApplyViewImpl.h>
#include <xrpl/ledger/OpenView.h>
#include <xrpl/ledger/RawView.h>
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/protocol/TER.h>
#include <xrpl/protocol/TxMeta.h>
#include <xrpl/protocol/XRPAmount.h>
#include <cstddef>
#include <functional>
#include <optional>
#include <utility>
namespace xrpl {
/**
* State information when applying a tx.
*/
class ApplyContext
{
public:
explicit ApplyContext(
ServiceRegistry& registry,
OpenView& base,
std::optional<uint256 const> const& parentBatchId,
STTx const& tx,
TER preclaimResult,
XRPAmount baseFee,
ApplyFlags flags,
beast::Journal journal = beast::Journal{beast::Journal::getNullSink()});
// Convenience constructor used only by tests that build an ApplyContext
// directly (e.g. invariant checks). Production always uses the parentBatchId
// constructor above; this one fixes parentBatchId to std::nullopt and so is
// never valid for a batch inner (hence the TapBatch assert).
explicit ApplyContext(
ServiceRegistry& registry,
OpenView& base,
STTx const& tx,
TER preclaimResult,
XRPAmount baseFee,
ApplyFlags flags,
beast::Journal journal = beast::Journal{beast::Journal::getNullSink()})
: ApplyContext(registry, base, std::nullopt, tx, preclaimResult, baseFee, flags, journal)
{
XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
}
std::reference_wrapper<ServiceRegistry> registry;
STTx const& tx;
TER const preclaimResult;
XRPAmount const baseFee;
beast::Journal const journal;
ApplyView&
view()
{
return *view_; // NOLINT(bugprone-unchecked-optional-access) view_ emplaced in constructor
}
[[nodiscard]] ApplyView const&
view() const
{
return *view_; // NOLINT(bugprone-unchecked-optional-access) view_ emplaced in constructor
}
// VFALCO Unfortunately this is necessary
RawView&
rawView()
{
return *view_; // NOLINT(bugprone-unchecked-optional-access) view_ emplaced in constructor
}
[[nodiscard]] ApplyFlags const&
flags() const
{
return flags_;
}
/**
* Sets the DeliveredAmount field in the metadata
*/
void
deliver(STAmount const& amount)
{
// NOLINTNEXTLINE(bugprone-unchecked-optional-access) view_ emplaced in constructor
view_->deliver(amount);
}
/**
* Discard changes and start fresh.
*/
void
discard();
/**
* Apply the transaction result to the base.
*/
std::optional<TxMeta> apply(TER);
/**
* Get the number of unapplied changes.
*/
std::size_t
size();
/**
* Visit unapplied changes.
*/
void
visit(
std::function<void(
uint256 const& key,
bool isDelete,
SLE::const_ref before,
SLE::const_ref after)> const& func);
void
destroyXRP(XRPAmount const& fee)
{
// NOLINTNEXTLINE(bugprone-unchecked-optional-access) view_ emplaced in constructor
view_->rawDestroyXRP(fee);
}
/**
* Applies all invariant checkers one by one.
*
* @param result the result generated by processing this transaction.
* @param fee the fee charged for this transaction
* @return the result code that should be returned for this transaction.
*/
TER
checkInvariants(TER const result, XRPAmount const fee);
ApplyViewContext
getApplyViewContext()
{
XRPL_ASSERT(
view_.has_value(),
"xrpl::ApplyContext::getApplyViewContext : view_ emplaced in constructor");
return {.view = *view_, .tx = tx};
}
private:
static TER
failInvariantCheck(TER const result);
template <std::size_t... Is>
TER
checkInvariantsHelper(TER const result, XRPAmount const fee, std::index_sequence<Is...>);
OpenView& base_;
ApplyFlags flags_;
std::optional<ApplyViewImpl> view_;
// The ID of the batch transaction we are executing under, if set.
std::optional<uint256 const> parentBatchId_;
};
} // namespace xrpl