xrpld
Loading...
Searching...
No Matches
Transactor.h
1#pragma once
2
3#include <xrpl/beast/utility/Journal.h>
4#include <xrpl/beast/utility/WrappedSink.h>
5#include <xrpl/protocol/Permissions.h>
6#include <xrpl/protocol/XRPAmount.h>
7#include <xrpl/tx/ApplyContext.h>
8#include <xrpl/tx/applySteps.h>
9
10#include <cstdint>
11#include <tuple>
12#include <utility>
13
14namespace xrpl {
15
18{
19public:
21 STTx const& tx;
22 Rules const rules;
26
29 STTx const& tx,
35 , tx(tx)
36 , rules(std::move(rules))
37 , flags(flags)
39 , j(j)
40 {
41 XRPL_ASSERT((flags & TapBatch) == TapBatch, "Batch apply flag should be set");
42 }
43
46 STTx const& tx,
50 : registry(registry), tx(tx), rules(std::move(rules)), flags(flags), j(j)
51 {
52 XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
53 }
54
56 operator=(PreflightContext const&) = delete;
57};
58
61{
62public:
64 ReadView const& view;
67 STTx const& tx;
70
73 ReadView const& view,
75 STTx const& tx,
80 , view(view)
82 , flags(flags)
83 , tx(tx)
85 , j(j)
86 {
87 XRPL_ASSERT(
88 parentBatchId.has_value() == ((flags & TapBatch) == TapBatch),
89 "Parent Batch ID should be set if batch apply flag is set");
90 }
91
94 ReadView const& view,
96 STTx const& tx,
100 {
101 XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
102 }
103
105 operator=(PreclaimContext const&) = delete;
106};
107
108class TxConsequences;
109struct PreflightResult;
110// Needed for preflight specialization
111class Change;
112
114{
115protected:
119
121 XRPAmount preFeeBalance_{}; // Balance before fees.
122
123public:
124 virtual ~Transactor() = default;
125 Transactor(Transactor const&) = delete;
127 operator=(Transactor const&) = delete;
128
130
133 operator()();
134
135 ApplyView&
137 {
138 return ctx_.view();
139 }
140
141 [[nodiscard]] ApplyView const&
142 view() const
143 {
144 return ctx_.view();
145 }
146
158 [[nodiscard]] TER
159 checkInvariants(TER result, XRPAmount fee);
160
162 /*
163 These static functions are called from invoke_preclaim<Tx>
164 using name hiding to accomplish compile-time polymorphism,
165 so derived classes can override for different or extra
166 functionality. Use with care, as these are not really
167 virtual and so don't have the compiler-time protection that
168 comes with it.
169 */
170
171 static NotTEC
172 checkSeqProxy(ReadView const& view, STTx const& tx, beast::Journal j);
173
174 static NotTEC
176
177 static TER
178 checkFee(PreclaimContext const& ctx, XRPAmount baseFee);
179
180 static NotTEC
181 checkSign(PreclaimContext const& ctx);
182
183 static NotTEC
185
186 // Returns the fee in fee units, not scaled for load.
187 static XRPAmount
188 calculateBaseFee(ReadView const& view, STTx const& tx);
189
190 // Returns the base fee plus extra base fee units, not scaled for load.
191 static XRPAmount
192 calculateBaseFee(ReadView const& view, STTx const& tx, std::uint32_t extraBaseFeeMultiplier);
193
194 /* Do NOT define an invokePreflight function in a derived class.
195 Instead, define:
196
197 // Optional if the transaction is gated on an amendment that
198 // isn't specified in transactions.macro
199 static bool
200 checkExtraFeatures(PreflightContext const& ctx);
201
202 // Optional if the transaction uses any flags other than tfUniversal
203 static std::uint32_t
204 getFlagsMask(PreflightContext const& ctx);
205
206 // Required, even if it just returns tesSUCCESS.
207 static NotTEC
208 preflight(PreflightContext const& ctx);
209
210 // Optional, rarely needed, if the transaction does any expensive
211 // checks after the signature is verified.
212 static NotTEC preflightSigValidated(PreflightContext const& ctx);
213
214 * Do not try to call preflight1 or preflight2 directly.
215 * Do not check whether relevant amendments are enabled in preflight.
216 Instead, define checkExtraFeatures.
217 * Do not check flags in preflight. Instead, define getFlagsMask.
218 */
219 template <class T>
220 static NotTEC
222
223 static TER
225 {
226 // Most transactors do nothing
227 // after checkSeq/Fee/Sign.
228 return tesSUCCESS;
229 }
230
237 static NotTEC
239 ReadView const& view,
240 STTx const& tx,
241 std::unordered_set<GranularPermissionType> const& heldGranularPermissions)
242 {
243 return tesSUCCESS;
244 }
245
259 template <class T>
260 static NotTEC
262 {
263 // heldGranularPermissions is passed by reference into checkPermission.
264 // It is populated with the sender’s granular permissions only when the sender
265 // lacks tx-level permission but has granular permissions that satisfy the
266 // granular permission template.
267 //
268 // - result is terNO_DELEGATE_PERMISSION: return immediately.
269 // - result is tesSUCCESS and heldGranularPermissions is empty: tx-level permission was
270 // granted, so we returned success before populating it.
271 // - result is tesSUCCESS and heldGranularPermissions is not empty: tx-level permission was
272 // not granted, but the held granular permissions passed checkGranularSandbox, so we proceed
273 // to checkGranularSemantics.
274 //
275 // WARNING: Do not simplify checkPermission to return only
276 // heldGranularPermissions or the ter code. Both the result and the
277 // populated set are required to enforce the strict permission hierarchy
278 // described above.
279 std::unordered_set<GranularPermissionType> heldGranularPermissions;
280 if (NotTEC const result = checkPermission(view, tx, heldGranularPermissions);
281 !isTesSuccess(result) || heldGranularPermissions.empty())
282 {
283 return result;
284 }
285
286 return T::checkGranularSemantics(view, tx, heldGranularPermissions);
287 }
288
289
290 // Interface used by AccountDelete
291 static TER
294 AccountID const& account,
295 uint256 const& ticketIndex,
297
298protected:
299 TER
300 apply();
301
302 explicit Transactor(ApplyContext& ctx);
303
304 virtual void
305 preCompute();
306
307 virtual TER
308 doApply() = 0;
309
326 virtual void
328
345 [[nodiscard]] virtual bool
347 STTx const& tx,
348 TER result,
349 XRPAmount fee,
350 ReadView const& view,
351 beast::Journal const& j) = 0;
352
362 static XRPAmount
363 minimumFee(ServiceRegistry& registry, XRPAmount baseFee, Fees const& fees, ApplyFlags flags);
364
365 // Returns the fee in fee units, not scaled for load.
366 static XRPAmount
367 calculateOwnerReserveFee(ReadView const& view, STTx const& tx);
368
369 static NotTEC
370 checkSign(
371 ReadView const& view,
372 ApplyFlags flags,
373 std::optional<uint256 const> const& parentBatchId,
374 AccountID const& idAccount,
375 STObject const& sigObject,
376 beast::Journal const j);
377
378 // Base class always returns true
379 static bool
381
382 // Base class always returns tfUniversalMask
383 static std::uint32_t
384 getFlagsMask(PreflightContext const& ctx);
385
386 // Base class always returns tesSUCCESS
387 static NotTEC
389
390 static bool
391 validDataLength(std::optional<Slice> const& slice, std::size_t maxLength);
392
393 template <class T>
394 static bool
395 validNumericRange(std::optional<T> value, T max, T min = T{});
396
397 template <class T, class Unit>
398 static bool
400 std::optional<T> value,
403
405 template <class T>
406 static bool
407 validNumericMinimum(std::optional<T> value, T min = T{});
408
410 template <class T, class Unit>
411 static bool
413 std::optional<T> value,
414 unit::ValueUnit<Unit, T> min = unit::ValueUnit<Unit, T>{});
415
416private:
417 static NotTEC
419 ReadView const& view,
420 STTx const& tx,
421 std::unordered_set<GranularPermissionType>& heldGranularPermissions);
422
423 std::pair<TER, XRPAmount>
424 reset(XRPAmount fee);
425
426 TER
427 consumeSeqProxy(SLE::pointer const& sleAccount);
428
429 TER
430 payFee();
431
432 std::tuple<TER, XRPAmount, bool>
433 processPersistentChanges(TER result, XRPAmount fee);
434
435 static NotTEC
437 ReadView const& view,
438 AccountID const& idSigner,
439 AccountID const& idAccount,
440 SLE::const_pointer sleAccount,
441 beast::Journal const j);
442
443 static NotTEC
445 ReadView const& view,
446 ApplyFlags flags,
447 AccountID const& id,
448 STObject const& sigObject,
449 beast::Journal const j);
450
451 void trapTransaction(uint256) const;
452
460 static NotTEC
461 preflight1(PreflightContext const& ctx, std::uint32_t flagMask);
462
468 static NotTEC
469 preflight2(PreflightContext const& ctx);
470
477 static NotTEC
478 preflightUniversal(PreflightContext const& ctx);
479
492 [[nodiscard]] TER
493 checkTransactionInvariants(TER result, XRPAmount fee);
494};
495
496inline bool
498{
499 return true;
500}
501
503NotTEC
504preflight0(PreflightContext const& ctx, std::uint32_t flagMask);
505
506namespace detail {
507
512NotTEC
514
521} // namespace detail
522
523// Defined in Change.cpp
524template <>
527
528template <class T>
529NotTEC
531{
532 // Using this lookup does NOT require checking the fixDelegateV1_1. The data
533 // exists regardless of whether it is enabled.
534 auto const feature = Permission::getInstance().getTxFeature(ctx.tx.getTxnType());
535
536 if (feature && !ctx.rules.enabled(*feature))
537 return temDISABLED;
538
539 if (!T::checkExtraFeatures(ctx))
540 return temDISABLED;
541
542 if (auto const ret = preflight1(ctx, T::getFlagsMask(ctx)))
543 return ret;
544
545 if (auto const ret = preflightUniversal(ctx))
546 return ret;
547
548 if (auto const ret = T::preflight(ctx))
549 return ret;
550
551 if (auto const ret = preflight2(ctx))
552 return ret;
553
554 return T::preflightSigValidated(ctx);
555}
556
557template <class T>
558bool
560{
561 if (!value)
562 return true;
563 return value >= min && value <= max;
564}
565
566template <class T, class Unit>
567bool
569 std::optional<T> value,
572{
573 return validNumericRange(value, max.value(), min.value());
574}
575
576template <class T>
577bool
579{
580 if (!value)
581 return true;
582 return value >= min;
583}
584
585template <class T, class Unit>
586bool
591
592} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:38
static Sink & getNullSink()
Returns a Sink which does nothing.
Wraps a Journal::Sink to prefix its output with a string.
Definition WrappedSink.h:16
State information when applying a tx.
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:118
std::optional< std::reference_wrapper< uint256 const > > getTxFeature(TxType txType) const
static Permission const & getInstance()
A view into a ledger.
Definition ReadView.h:31
Rules controlling protocol behavior.
Definition Rules.h:33
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:171
std::shared_ptr< STLedgerEntry > pointer
std::shared_ptr< STLedgerEntry const > const & const_ref
std::shared_ptr< STLedgerEntry const > const_pointer
TxType getTxnType() const
Definition STTx.h:188
Service registry for dependency injection.
static NotTEC preflight1(PreflightContext const &ctx, std::uint32_t flagMask)
Performs early sanity checks on the account and fee fields.
static std::uint32_t getFlagsMask(PreflightContext const &ctx)
TER consumeSeqProxy(SLE::pointer const &sleAccount)
static NotTEC checkPermission(ReadView const &view, STTx const &tx, std::unordered_set< GranularPermissionType > &heldGranularPermissions)
void trapTransaction(uint256) const
static TER checkFee(PreclaimContext const &ctx, XRPAmount baseFee)
static NotTEC invokePreflight(PreflightContext const &ctx)
Definition Transactor.h:530
static NotTEC checkGranularSemantics(ReadView const &view, STTx const &tx, std::unordered_set< GranularPermissionType > const &heldGranularPermissions)
This function can be overridden to introduce additional semantic constraints beyond the granular temp...
Definition Transactor.h:238
Transactor & operator=(Transactor const &)=delete
beast::WrappedSink sink_
Definition Transactor.h:117
static XRPAmount minimumFee(ServiceRegistry &registry, XRPAmount baseFee, Fees const &fees, ApplyFlags flags)
Compute the minimum fee required to process a transaction with a given baseFee based on the current s...
static NotTEC checkSign(PreclaimContext const &ctx)
static XRPAmount calculateOwnerReserveFee(ReadView const &view, STTx const &tx)
ApplyResult operator()()
Process the transaction.
static bool validNumericMinimum(std::optional< T > value, T min=T{})
Minimum will usually be zero.
Definition Transactor.h:578
static NotTEC preflightSigValidated(PreflightContext const &ctx)
static NotTEC checkBatchSign(PreclaimContext const &ctx)
static NotTEC checkSeqProxy(ReadView const &view, STTx const &tx, beast::Journal j)
beast::Journal const j_
Definition Transactor.h:118
static TER preclaim(PreclaimContext const &ctx)
Definition Transactor.h:224
virtual ~Transactor()=default
virtual TER doApply()=0
static NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
static bool checkExtraFeatures(PreflightContext const &ctx)
Definition Transactor.h:497
static NotTEC checkSingleSign(ReadView const &view, AccountID const &idSigner, AccountID const &idAccount, SLE::const_pointer sleAccount, beast::Journal const j)
TER checkTransactionInvariants(TER result, XRPAmount fee)
Check transaction-specific invariants only.
ApplyView & view()
Definition Transactor.h:136
Transactor(Transactor const &)=delete
static NotTEC preflightUniversal(PreflightContext const &ctx)
Universal validations.
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
TER checkInvariants(TER result, XRPAmount fee)
Check all invariants for the current transaction.
AccountID const accountID_
Definition Transactor.h:120
static NotTEC checkPriorTxAndLastLedger(PreclaimContext const &ctx)
XRPAmount preFeeBalance_
Definition Transactor.h:121
static NotTEC invokeCheckPermission(ReadView const &view, STTx const &tx)
Checks whether the transaction is authorized to be executed by the delegated account.
Definition Transactor.h:261
static NotTEC checkMultiSign(ReadView const &view, ApplyFlags flags, AccountID const &id, STObject const &sigObject, beast::Journal const j)
static bool validDataLength(std::optional< Slice > const &slice, std::size_t maxLength)
virtual void preCompute()
ApplyContext & ctx_
Definition Transactor.h:116
ApplyView const & view() const
Definition Transactor.h:142
virtual void visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after)=0
Inspect a single ledger entry modified by this transaction.
std::pair< TER, XRPAmount > reset(XRPAmount fee)
Reset the context, discarding any changes made and adjust the fee.
static bool validNumericRange(std::optional< T > value, T max, T min=T{})
Definition Transactor.h:559
virtual bool finalizeInvariants(STTx const &tx, TER result, XRPAmount fee, ReadView const &view, beast::Journal const &j)=0
Check transaction-specific post-conditions after all entries have been visited.
static TER ticketDelete(ApplyView &view, AccountID const &account, uint256 const &ticketIndex, beast::Journal j)
std::tuple< TER, XRPAmount, bool > processPersistentChanges(TER result, XRPAmount fee)
Class describing the consequences to the account of applying a transaction if the transaction consume...
Definition applySteps.h:38
T empty(T... args)
STL namespace.
std::optional< NotTEC > preflightCheckSimulateKeys(ApplyFlags flags, STObject const &sigObject, beast::Journal j)
Checks the special signing key state needed for simulation.
NotTEC preflightCheckSigningKey(STObject const &sigObject, beast::Journal j)
Checks the validity of the transactor signing key.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:594
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:554
ApplyFlags
Definition ApplyView.h:12
@ TapBatch
Definition ApplyView.h:27
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
@ temDISABLED
Definition TER.h:100
bool isTesSuccess(TER x) noexcept
Definition TER.h:663
TERSubset< CanCvtToTER > TER
Definition TER.h:634
NotTEC preflight0(PreflightContext const &ctx, std::uint32_t flagMask)
Performs early sanity checks on the txid and flags.
BaseUInt< 256 > uint256
Definition base_uint.h:562
@ tesSUCCESS
Definition TER.h:240
Reflects the fee settings for a particular ledger.
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:61
PreclaimContext(ServiceRegistry &registry, ReadView const &view, TER preflightResult, STTx const &tx, ApplyFlags flags, std::optional< uint256 > parentBatchId, beast::Journal j=beast::Journal{beast::Journal::getNullSink()})
Definition Transactor.h:71
ReadView const & view
Definition Transactor.h:64
std::reference_wrapper< ServiceRegistry > registry
Definition Transactor.h:63
PreclaimContext(ServiceRegistry &registry, ReadView const &view, TER preflightResult, STTx const &tx, ApplyFlags flags, beast::Journal j=beast::Journal{beast::Journal::getNullSink()})
Definition Transactor.h:92
PreclaimContext & operator=(PreclaimContext const &)=delete
beast::Journal const j
Definition Transactor.h:69
std::optional< uint256 const > const parentBatchId
Definition Transactor.h:68
State information when preflighting a tx.
Definition Transactor.h:18
PreflightContext(ServiceRegistry &registry, STTx const &tx, Rules rules, ApplyFlags flags, beast::Journal j=beast::Journal{beast::Journal::getNullSink()})
Definition Transactor.h:44
beast::Journal const j
Definition Transactor.h:25
PreflightContext & operator=(PreflightContext const &)=delete
std::optional< uint256 const > parentBatchId
Definition Transactor.h:24
std::reference_wrapper< ServiceRegistry > registry
Definition Transactor.h:20
PreflightContext(ServiceRegistry &registry, STTx const &tx, uint256 parentBatchId, Rules rules, ApplyFlags flags, beast::Journal j=beast::Journal{beast::Journal::getNullSink()})
Definition Transactor.h:27
Describes the results of the preflight check.
Definition applySteps.h:143