xrpld
Loading...
Searching...
No Matches
Transactor.h
1#pragma once
2
3#include <xrpl/basics/Slice.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/beast/utility/Journal.h>
6#include <xrpl/beast/utility/WrappedSink.h>
7#include <xrpl/beast/utility/instrumentation.h>
8#include <xrpl/core/ServiceRegistry.h>
9#include <xrpl/ledger/ApplyView.h>
10#include <xrpl/ledger/ReadView.h>
11#include <xrpl/protocol/AccountID.h>
12#include <xrpl/protocol/Fees.h>
13#include <xrpl/protocol/Keylet.h>
14#include <xrpl/protocol/Permissions.h>
15#include <xrpl/protocol/Rules.h>
16#include <xrpl/protocol/SField.h>
17#include <xrpl/protocol/STObject.h>
18#include <xrpl/protocol/TER.h>
19#include <xrpl/protocol/Units.h>
20#include <xrpl/protocol/XRPAmount.h>
21#include <xrpl/tx/ApplyContext.h>
22#include <xrpl/tx/applySteps.h>
23#include <xrpl/tx/invariants/InvariantRunner.h>
24
25#include <cstddef>
26#include <cstdint>
27#include <functional>
28#include <optional>
29#include <tuple>
30#include <unordered_set>
31#include <utility>
32
33namespace xrpl {
34
39{
40public:
42 STTx const& tx;
43 Rules const rules;
47
50 STTx const& tx,
56 , tx(tx)
57 , rules(std::move(rules))
58 , flags(flags)
60 , j(j)
61 {
62 XRPL_ASSERT((flags & TapBatch) == TapBatch, "Batch apply flag should be set");
63 XRPL_ASSERT_IF(
65 (flags & TapDryRun) != TapNone,
66 "xrpl::PreflightContext : proposal preflight implies dry run");
67 }
68
71 STTx const& tx,
75 : registry(registry), tx(tx), rules(std::move(rules)), flags(flags), j(j)
76 {
77 XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
78 XRPL_ASSERT_IF(
80 (flags & TapDryRun) != TapNone,
81 "xrpl::PreflightContext : proposal preflight implies dry run");
82 }
83
85 operator=(PreflightContext const&) = delete;
86};
87
92{
93public:
95 ReadView const& view;
98 STTx const& tx;
101
104 ReadView const& view,
106 STTx const& tx,
111 , view(view)
113 , flags(flags)
114 , tx(tx)
116 , j(j)
117 {
118 XRPL_ASSERT(
119 parentBatchId.has_value() == ((flags & TapBatch) == TapBatch),
120 "Parent Batch ID should be set if batch apply flag is set");
121 }
122
125 ReadView const& view,
127 STTx const& tx,
131 {
132 XRPL_ASSERT((flags & TapBatch) == 0, "Batch apply flag should not be set");
133 }
134
136 operator=(PreclaimContext const&) = delete;
137};
138
139class TxConsequences;
140struct PreflightResult;
141// Needed for preflight specialization
142class Change;
143
150
158
160{
161protected:
165
167 XRPAmount preFeeBalance_{}; // Balance before fees.
168
169public:
170 ~Transactor() override = default;
171 Transactor(Transactor const&) = delete;
173 operator=(Transactor const&) = delete;
174
176
181 operator()();
182
183 ApplyView&
185 {
186 return ctx_.view();
187 }
188
189 [[nodiscard]] ApplyView const&
190 view() const
191 {
192 return ctx_.view();
193 }
194
218
237 [[nodiscard]] TER
238 checkInvariants(TER result, XRPAmount fee, InvariantScope scope);
239
241 /*
242 These static functions are called from invoke_preclaim<Tx>
243 using name hiding to accomplish compile-time polymorphism,
244 so derived classes can override for different or extra
245 functionality. Use with care, as these are not really
246 virtual and so don't have the compiler-time protection that
247 comes with it.
248 */
249
250 static NotTEC
251 checkSeqProxy(ReadView const& view, STTx const& tx, beast::Journal j);
252
253 static NotTEC
255
256 static TER
257 checkFee(PreclaimContext const& ctx, XRPAmount baseFee);
258
259 static NotTEC
260 checkSign(PreclaimContext const& ctx);
261
262 // Returns the fee in fee units, not scaled for load.
263 static XRPAmount
264 calculateBaseFee(ReadView const& view, STTx const& tx);
265
266 // Returns the base fee plus extra base fee units, not scaled for load.
267 static XRPAmount
268 calculateBaseFee(ReadView const& view, STTx const& tx, std::uint32_t extraBaseFeeMultiplier);
269
270 // Exposed for invariant checks (e.g. ValidVault) that need to know which
271 // ledger entry actually pays a transaction's fee, distinguishing an
272 // ordinary sender, a delegate, and pre-funded vs. co-signed fee
273 // sponsorship.
274 static FeePayer
275 getFeePayer(ReadView const& view, STTx const& tx);
276
277 /* Do NOT define an invokePreflight function in a derived class.
278 Instead, define:
279
280 // Optional if the transaction is gated on an amendment that
281 // isn't specified in transactions.macro
282 static bool
283 checkExtraFeatures(PreflightContext const& ctx);
284
285 // Optional if the transaction uses any flags other than tfUniversal
286 static std::uint32_t
287 getFlagsMask(PreflightContext const& ctx);
288
289 // Required, even if it just returns tesSUCCESS.
290 static NotTEC
291 preflight(PreflightContext const& ctx);
292
293 // Optional, rarely needed, if the transaction does any expensive
294 // checks after the signature is verified.
295 static NotTEC preflightSigValidated(PreflightContext const& ctx);
296
297 * Do not try to call preflight1 or preflight2 directly.
298 * Do not check whether relevant amendments are enabled in preflight.
299 Instead, define checkExtraFeatures.
300 * Do not check flags in preflight. Instead, define getFlagsMask.
301 */
302 template <class T>
303 static NotTEC
305
306 static TER
308 {
309 // Most transactors do nothing
310 // after checkSeq/Fee/Sign.
311 return tesSUCCESS;
312 }
313
320 static NotTEC
322 ReadView const& view,
323 STTx const& tx,
324 std::unordered_set<GranularPermissionType> const& heldGranularPermissions)
325 {
326 return tesSUCCESS;
327 }
328
342 template <class T>
343 static NotTEC
345 {
346 // heldGranularPermissions is passed by reference into checkPermission.
347 // It is populated with the sender’s granular permissions only when the sender
348 // lacks tx-level permission but has granular permissions that satisfy the
349 // granular permission template.
350 //
351 // - result is terNO_DELEGATE_PERMISSION: return immediately.
352 // - result is tesSUCCESS and heldGranularPermissions is empty: tx-level permission was
353 // granted, so we returned success before populating it.
354 // - result is tesSUCCESS and heldGranularPermissions is not empty: tx-level permission was
355 // not granted, but the held granular permissions passed checkGranularSandbox, so we proceed
356 // to checkGranularSemantics.
357 //
358 // WARNING: Do not simplify checkPermission to return only
359 // heldGranularPermissions or the ter code. Both the result and the
360 // populated set are required to enforce the strict permission hierarchy
361 // described above.
362 std::unordered_set<GranularPermissionType> heldGranularPermissions;
363 if (NotTEC const result = checkPermission(view, tx, heldGranularPermissions);
364 !isTesSuccess(result) || heldGranularPermissions.empty())
365 {
366 return result;
367 }
368
369 return T::checkGranularSemantics(view, tx, heldGranularPermissions);
370 }
371
372 static NotTEC
373 checkSponsor(ReadView const& view, STTx const& tx);
374
376
377 // Interface used by AccountDelete
378 static TER
381 AccountID const& account,
382 UInt256 const& ticketIndex,
384
385protected:
386 TER
387 apply();
388
389 explicit Transactor(ApplyContext& ctx);
390
391 virtual void
392 preCompute();
393
394 virtual TER
395 doApply() = 0;
396
414 virtual void
416
434 [[nodiscard]] virtual bool
436 STTx const& tx,
437 TER result,
438 XRPAmount fee,
439 ReadView const& view,
440 beast::Journal const& j) = 0;
441
452 static XRPAmount
453 minimumFee(ServiceRegistry& registry, XRPAmount baseFee, Fees const& fees, ApplyFlags flags);
454
455 // Returns the fee in fee units, not scaled for load.
456 static XRPAmount
457 calculateOwnerReserveFee(ReadView const& view, STTx const& tx);
458
459 static NotTEC
460 checkSign(
461 ReadView const& view,
462 ApplyFlags flags,
463 std::optional<UInt256 const> const& parentBatchId,
464 AccountID const& idAccount,
465 STObject const& sigObject,
466 beast::Journal const j,
467 // A batch may carry an inner from an account that an earlier inner
468 // creates, so the signer account need not exist yet; when it does not,
469 // only its own master key may authorize it. Normal transactions require
470 // the account to already exist.
471 bool permitUncreatedAccount = false);
472
473 // Base class always returns true
474 static bool
476
477 // Base class always returns tfUniversalMask
478 static std::uint32_t
479 getFlagsMask(PreflightContext const& ctx);
480
481 // Base class always returns tesSUCCESS
482 static NotTEC
484
485 static bool
486 validDataLength(std::optional<Slice> const& slice, std::size_t maxLength);
487
488 template <class T>
489 static bool
490 validNumericRange(std::optional<T> value, T max, T min = T{});
491
492 template <class T, class Unit>
493 static bool
495 std::optional<T> value,
498
502 template <class T>
503 static bool
504 validNumericMinimum(std::optional<T> value, T min = T{});
505
509 template <class T, class Unit>
510 static bool
512 std::optional<T> value,
513 unit::ValueUnit<Unit, T> min = unit::ValueUnit<Unit, T>{});
514
515 // Signature-authorization helpers. protected so the Batch transactor can
516 // reuse them when validating each BatchSigner in Batch::checkBatchSign.
517 static NotTEC
519 ReadView const& view,
520 AccountID const& idSigner,
521 AccountID const& idAccount,
522 SLE::const_pointer sleAccount,
523 beast::Journal const j);
524
525 static NotTEC
527 ReadView const& view,
528 ApplyFlags flags,
529 AccountID const& id,
530 STObject const& sigObject,
531 beast::Journal const j);
532
533private:
534 static NotTEC
536 ReadView const& view,
537 STTx const& tx,
538 std::unordered_set<GranularPermissionType>& heldGranularPermissions);
539
540 std::pair<TER, XRPAmount>
541 reset(XRPAmount fee);
542
543 TER
544 consumeSeqProxy(SLE::pointer const& sleAccount);
545 TER
546 payFee();
547
548 std::tuple<TER, XRPAmount, bool>
549 processPersistentChanges(TER result, XRPAmount fee);
550
551 void trapTransaction(UInt256) const;
552
561 static NotTEC
562 preflight1(PreflightContext const& ctx, std::uint32_t flagMask);
563
570 static NotTEC
571 preflight2(PreflightContext const& ctx);
572
580 static NotTEC
581 preflightUniversal(PreflightContext const& ctx);
582
592 void
593 visitEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) final
594 {
595 visitInvariantEntry(isDelete, before, after);
596 }
597
598 [[nodiscard]] bool
600 STTx const& tx,
601 TER result,
602 XRPAmount fee,
603 ReadView const& view,
604 beast::Journal const& j) final
605 {
606 return finalizeInvariants(tx, result, fee, view, j);
607 }
608};
609
610inline bool
612{
613 return true;
614}
615
619NotTEC
620preflight0(PreflightContext const& ctx, std::uint32_t flagMask);
621
622namespace detail {
623
629NotTEC
631
639} // namespace detail
640
641// Defined in Change.cpp
642template <>
645
646template <class T>
647NotTEC
649{
650 // Using this lookup does NOT require checking the fixDelegateV1_1. The data
651 // exists regardless of whether it is enabled.
652 auto const feature = Permission::getInstance().getTxFeature(ctx.tx.getTxnType());
653
654 if (feature && !ctx.rules.enabled(*feature))
655 return temDISABLED;
656
657 if (!T::checkExtraFeatures(ctx))
658 return temDISABLED;
659
660 if (auto const ret = preflight1(ctx, T::getFlagsMask(ctx)))
661 return ret;
662
663 if (auto const ret = preflightUniversal(ctx))
664 return ret;
665
666 if (auto const ret = T::preflight(ctx))
667 return ret;
668
669 if (auto const ret = preflight2(ctx))
670 return ret;
671
672 return T::preflightSigValidated(ctx);
673}
674
675template <class T>
676bool
678{
679 if (!value)
680 return true;
681 return value >= min && value <= max;
682}
683
684template <class T, class Unit>
685bool
687 std::optional<T> value,
690{
691 return validNumericRange(value, max.value(), min.value());
692}
693
694template <class T>
695bool
697{
698 if (!value)
699 return true;
700 return value >= min;
701}
702
703template <class T, class Unit>
704bool
709
710} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:44
static Sink & getNullSink()
Returns a Sink which does nothing.
Wraps a Journal::Sink to prefix its output with a string.
Definition WrappedSink.h:19
State information when applying a tx.
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:141
std::optional< std::reference_wrapper< UInt256 const > > getTxFeature(TxType txType) const
static Permission const & getInstance()
A view into a ledger.
Definition ReadView.h:41
Rules controlling protocol behavior.
Definition Rules.h:40
bool enabled(UInt256 const &feature) const
Returns true if a feature is enabled.
Definition Rules.cpp:182
std::shared_ptr< STLedgerEntry > pointer
std::shared_ptr< STLedgerEntry const > const & ConstRef
std::shared_ptr< STLedgerEntry const > const_pointer
TxType getTxnType() const
Definition STTx.h:250
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)
~Transactor() override=default
static TER checkFee(PreclaimContext const &ctx, XRPAmount baseFee)
static NotTEC invokePreflight(PreflightContext const &ctx)
Definition Transactor.h:648
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:321
virtual void visitInvariantEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after)=0
Inspect a single ledger entry modified by this transaction.
Transactor & operator=(Transactor const &)=delete
beast::WrappedSink sink_
Definition Transactor.h:163
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 NotTEC checkSponsor(ReadView const &view, STTx const &tx)
static XRPAmount calculateOwnerReserveFee(ReadView const &view, STTx const &tx)
ApplyResult operator()()
Process the transaction.
TER checkInvariants(TER result, XRPAmount fee, InvariantScope scope)
Check all invariants for the current transaction.
static bool validNumericMinimum(std::optional< T > value, T min=T{})
Minimum will usually be zero.
Definition Transactor.h:696
void trapTransaction(UInt256) const
static NotTEC preflightSigValidated(PreflightContext const &ctx)
static NotTEC checkSeqProxy(ReadView const &view, STTx const &tx, beast::Journal j)
beast::Journal const j_
Definition Transactor.h:164
static TER preclaim(PreclaimContext const &ctx)
Definition Transactor.h:307
virtual TER doApply()=0
InvariantScope
Which invariant layers to check.
Definition Transactor.h:217
static FeePayer getFeePayer(ReadView const &view, STTx const &tx)
static NotTEC preflight2(PreflightContext const &ctx)
Checks whether the signature appears valid.
static bool checkExtraFeatures(PreflightContext const &ctx)
Definition Transactor.h:611
static NotTEC checkSingleSign(ReadView const &view, AccountID const &idSigner, AccountID const &idAccount, SLE::const_pointer sleAccount, beast::Journal const j)
ApplyView & view()
Definition Transactor.h:184
Transactor(Transactor const &)=delete
static NotTEC preflightUniversal(PreflightContext const &ctx)
Universal validations.
static XRPAmount calculateBaseFee(ReadView const &view, STTx const &tx)
AccountID const accountID_
Definition Transactor.h:166
static NotTEC checkPriorTxAndLastLedger(PreclaimContext const &ctx)
XRPAmount preFeeBalance_
Definition Transactor.h:167
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:344
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:162
ApplyView const & view() const
Definition Transactor.h:190
void visitEntry(bool isDelete, SLE::ConstRef before, SLE::ConstRef after) final
Bridges the two-phase TxInvariantCheck interface to this transactor's visitInvariantEntry/finalizeInv...
Definition Transactor.h:593
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:677
static TER ticketDelete(ApplyView &view, AccountID const &account, UInt256 const &ticketIndex, beast::Journal j)
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.
bool finalize(STTx const &tx, TER result, XRPAmount fee, ReadView const &view, beast::Journal const &j) final
Called after all entries have been visited.
Definition Transactor.h:599
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:53
Runtime interface for a transaction-specific invariant check.
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
TypedField< STAmount > SF_AMOUNT
Definition SField.h:358
BaseUInt< 256 > UInt256
Definition base_uint.h:580
TERSubset< CanCvtToNotTEC > NotTEC
Definition TER.h:614
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:644
ApplyFlags
Definition ApplyView.h:27
@ TapDryRun
Definition ApplyView.h:46
@ TapProposal
Definition ApplyView.h:53
@ TapNone
Definition ApplyView.h:28
@ TapBatch
Definition ApplyView.h:42
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
@ temDISABLED
Definition TER.h:102
bool isTesSuccess(TER x) noexcept
Definition TER.h:683
TERSubset< CanCvtToTER > TER
Definition TER.h:654
NotTEC preflight0(PreflightContext const &ctx, std::uint32_t flagMask)
Performs early sanity checks on the txid and flags.
FeePayerType
Definition Transactor.h:144
@ tesSUCCESS
Definition TER.h:250
FeePayerType type
Definition Transactor.h:156
SF_AMOUNT const & balanceField
Definition Transactor.h:155
AccountID id
Definition Transactor.h:153
Reflects the fee settings for a particular ledger.
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:20
State information when determining if a tx is likely to claim a fee.
Definition Transactor.h:92
ReadView const & view
Definition Transactor.h:95
std::reference_wrapper< ServiceRegistry > registry
Definition Transactor.h:94
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:102
std::optional< UInt256 const > const parentBatchId
Definition Transactor.h:99
PreclaimContext(ServiceRegistry &registry, ReadView const &view, TER preflightResult, STTx const &tx, ApplyFlags flags, beast::Journal j=beast::Journal{beast::Journal::getNullSink()})
Definition Transactor.h:123
PreclaimContext & operator=(PreclaimContext const &)=delete
beast::Journal const j
Definition Transactor.h:100
State information when preflighting a tx.
Definition Transactor.h:39
PreflightContext(ServiceRegistry &registry, STTx const &tx, UInt256 parentBatchId, Rules rules, ApplyFlags flags, beast::Journal j=beast::Journal{beast::Journal::getNullSink()})
Definition Transactor.h:48
PreflightContext(ServiceRegistry &registry, STTx const &tx, Rules rules, ApplyFlags flags, beast::Journal j=beast::Journal{beast::Journal::getNullSink()})
Definition Transactor.h:69
beast::Journal const j
Definition Transactor.h:46
std::optional< UInt256 const > parentBatchId
Definition Transactor.h:45
PreflightContext & operator=(PreflightContext const &)=delete
std::reference_wrapper< ServiceRegistry > registry
Definition Transactor.h:41
Describes the results of the preflight check.
Definition applySteps.h:201