Rippled Audit

Transaction Validations

As detailed in the last section, through use of views, specific transactions can modify Serializable Ledger Entrys (STLedgerEntry or SLE) to be written to the persistent ledger in the manner described above. This can only take place after a series of checks broken down into several stages take place

TxQ::apply enforces a long series of rules on the transaction:

  1. preflight and preclaim checks do not prohibit the transaction from going through (see below)
  2. Verifies sequence numbers are sane, the TX sequence is the expected value, is correctly replacing another, or all necessary sequences are present
  3. Fees are set appropriately (if the fee is >= the required fee level the TX will be applied to the open ledger immediately, else it will be queued)
  4. If queueing the TX, it can be queued and the queue is not full

TxQ::apply description - src/ripple/app/misc/impl/TxQ.cpp

548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
/*
    How the decision to apply, queue, or reject is made:
    0. Is `featureFeeEscalation` enabled?
        Yes: Continue to next step.
        No: Fallback to `ripple::apply`. Stop.
    1. Does `preflight` indicate that the tx is valid?
        No: Return the `TER` from `preflight`. Stop.
        Yes: Continue to next step.
    2. Is there already a tx for the same account with the
            same sequence number in the queue?
        Yes: Is `txn`'s fee `retrySequencePercent` higher than the
                queued transaction's fee? And is this the last tx
                in the queue for that account, or are both txs
                non-blockers?
            Yes: Remove the queued transaction. Continue to next
                step.
            No: Reject `txn` with `telCAN_NOT_QUEUE_FEE`. Stop.
        No: Continue to next step.
    3. Does this tx have the expected sequence number for the
            account?
        Yes: Continue to next step.
        No: Are all the intervening sequence numbers also in the
                queue?
            No: Continue to the next step. (We expect the next
                step to return `terPRE_SEQ`, but won't short
                circuit that logic.)
            Yes: Is the fee more than `multiTxnPercent` higher
                    than the previous tx?
                No: Reject with `telINSUF_FEE_P`. Stop.
                Yes: Are any of the prior sequence txs blockers?
                    Yes: Reject with `telCAN_NOT_QUEUE_BLOCKED`. Stop.
                    No: Are the fees in-flight of the other
                            queued txs >= than the account
                            balance or minimum account reserve?
                        Yes: Reject with `telCAN_NOT_QUEUE_BALANCE`. Stop.
                        No: Create a throwaway sandbox `View`. Modify
                            the account's sequence number to match
                            the tx (avoid `terPRE_SEQ`), and decrease
                            the account balance by the total fees and
                            maximum spend of the other in-flight txs.
                            Continue to the next step.
    4. Does `preclaim` indicate that the account is likely to claim
            a fee (using the throwaway sandbox `View` created above,
            if appropriate)?
        No: Return the `TER` from `preclaim`. Stop.
        Yes: Continue to the next step.
    5. Did we create a throwaway sandbox `View`?
        Yes: Continue to the next step.
        No: Is the `txn`s fee level >= the required fee level?
            Yes: `txn` can be applied to the open ledger. Pass
                it to `doApply()` and return that result.
            No: Continue to the next step.
    6. Can the tx be held in the queue? (See TxQ::canBeHeld).
            No: Reject `txn` with `telCAN_NOT_QUEUE_FULL`
                if not. Stop.
            Yes: Continue to the next step.
    7. Is the queue full?
        No: Continue to the next step.
        Yes: Is the `txn`'s fee level higher than the end /
                lowest fee level item's fee level?
            Yes: Remove the end item. Continue to the next step.
            No: Reject `txn` with a low fee TER code.
    8. Put `txn` in the queue.
*/

The preflight and preclaim calls impose additional assertions of transactions so as to be appled. Both stages employ TX-specific checks by invoking the same-named methods on the transaction classes themselves, though preclaim invokes the following methods in addition:

  • TX::checkSeq - ensures transaction is properly sequence
  • TX::checkFee - ensures tx pays necessary fee and source account has sufficient balance to pay fees
  • TX::checkSign - validates transaction signature(s)

invoke_preclaim - src/ripple/app/tx/impl/applySteps.cpp

78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
template<class T>
static
TER
invoke_preclaim(PreclaimContext const& ctx)
{
    // If the transactor requires a valid account and the transaction doesn't
    // list one, preflight will have already a flagged a failure.
    auto const id = ctx.tx.getAccountID(sfAccount);

    if (id != beast::zero)
    {
        TER result = T::checkSeq(ctx);

        if (result != tesSUCCESS)
            return result;

        result = T::checkFee(ctx,
            calculateBaseFee(ctx.view, ctx.tx));

        if (result != tesSUCCESS)
            return result;

        result = T::checkSign(ctx);

        if (result != tesSUCCESS)
            return result;

    }

    return T::preclaim(ctx);
}

These check* methods are implemented in the base Transactor class which all TransactionTypes derive from, though may be overridden in any subclass to impose additional requirements.

In the next section we will start looking at specific transactions, beginning with Payments, and the specific validations and ledger-modifications they entail.

<<Back Home >>Next