Skip to content

Latest commit

 

History

History
180 lines (147 loc) · 8.03 KB

cap-0022.md

File metadata and controls

180 lines (147 loc) · 8.03 KB

Preamble

CAP: 0022
Title: Invalid transactions must have no effects
Author: David Mazières
Status: Draft
Created: 2019-06-20
Discussion: https://groups.google.com/forum/#!topic/stellar-dev/NtCwqWwAxRA
Protocol version: TBD

Simple Summary

Invalid transactions lack sufficient signatures for proper authorization, have sequence numbers that have already been used, or have invalid time bounds. Certain edge conditions cause invalid transactions to be included in the transaction set produced by consensus. Currently, Stellar executes and fails invalid transactions in the transaction set, which changes ledger state by increasing sequence numbers and debiting transaction fees. This specification changes Stellar so that invalid transactions have no effect on the ledger.

Motivation

Allowing invalid--especially unauthorized--transactions to change ledger state can lead to vulnerabilities in higher-layer protocols. Consider a protocol in which two parties, A and B, execute a transaction that contributes funds to an escrow account E and makes E into a 2-of-2 multisig account. The parties might be willing to this given post-dated pre-signed transactions T1, T2 on E that allow each of A and B to recover escrowed funds after a certain delay. Unfortunately, if the previous owner of E can cause an invalid (unauthorized) transaction to use up T1's sequence number, one of the two users will be unable to recover funds.

Goals Alignment

The changes described in this document help network security by preventing unauthorized transactions from changing account state. They also help scalability by facilitating the design of robust payment channels.

Abstract

We define three categories of transaction: successful, failed, and invalid. Invalid transactions must never change ledger state, even if they are included in the transaction set output by consensus. New, conservative restrictions rule out current ways of passing invalid transactions through consensus. However, if invalid transactions do make it through consensus through oversight or subsequently added features, they must have no effects on the ledger.

Specification

We define the following categories of transaction at the time of execution:

  • A successful transaction is one that meets all transaction- and operation-level prerequisites at the time of its execution. The effects of a successful transaction's operations are applied to the ledger. Successful transactions yield a result in which TransactionResult.code is txSUCCESS. This document does not change which transactions are considered successful or the effects of executing such transactions.

  • A failed transaction meets all valid transaction-level preconditions, including a valid transaction-level source account, valid sequence number, valid time bounds, and low signing weight for the source account. However, one or more of a failed transaction's operations cannot execute---for instance because the destination of a PAYMENT no longer exists. Failed transactions increase the sequence number of the transaction-level sourceAccount, charge a fee to the transaction-level sourceAccount, and yield a result with TransactionResult.code txFAILED.

  • An invalid transaction fails to meet transaction-level preconditions at the time of execution, for instance because the sequence number is invalid or the signatures are insufficient to meet the sourceAccount's low signing threshold. Currently, invalid transactions are executed just like failed ones. This document changes that behavior so that invalid transactions no longer have an effect on the ledger and do not produce a TransactionResult. If an invalid transaction later becomes valid, it may be included again in a subsequent ledger.

A ledger that contains too many invalid transactions will reduce the number of operations available to successful transactions and negatively impact the ledger. Since the source of an invalid transaction does not incur any transaction cost, and since it may be difficult in the general case to decide if a transaction is valid at the time its fee is charged, we place restrictions on the composition of the transaction set in a single ledger. These rules are conservative; they may force two valid transactions that could have succeeded in the same ledger to be included in different ledgers.

If a transaction set S contains a transaction T, we use S[<=T] to denote the subset of S consisting of transactions with the same sourceAccount as T and a seqNum less than or equal to that of T (a set that includes T itself). A set S is admissible, and hence can be a candidate for the consensus transaction set, if all of the following hold for each transaction T in S:

  • T's sourceAccount must exist and must have sufficient funds to pay the offered transaction fees for all of S[<=T]. (This restriction exists today.)

  • T's sequence number will be valid if all other transactions in S[<=T] are executed. (This restriction exists today, and among other things implies a transaction set may not include a transaction with a stale sequence number or two distinct transactions with the same source account and sequence number.)

  • Any transaction in S other than T that contains a SET_OPTIONS or BUMP_SEQUENCE operation on T's sourceAccount must have the same sourceAccount as T and a greater sequence number than T. This guarantees that a SET_OPTIONS or BUMP_SEQUENCE on T's sourceAccount cannot be ordered before T. This new restriction specified by this document is not enforced today.

In addition to placing these restrictions on transaction sets, we restore the behavior prior to BUMP_SEQUENCE in which sequence numbers are increased at exactly the same time that the fee is debited, before any operations are executed. Currently, fees are charged up front before any operations from any transactions execute, while sequence numbers are increased at the time an operation executes. Now that we know a BUMP_SEQUENCE cannot be ordered before an operation on the source account whose sequence is being bumped, we can increase the sequence numbers up front when charging fees.

Design Rationale

This design prevents people who are no longer authorized signers an on account from affecting the account state. However, it does so in a way that avoids the ability to clog the ledger with invalid transactions.

Backwards Incompatibilities

There are some minor incompatibilities that should not impact users. First, certain invalid transactions will no longer execute as failed transactions because they will not execute at all. However, in all such cases, there was no guarantee the transactions would execute anyway, because they could only execute when they happened to land in the same ledger as another transaction with a SET_OPTIONS or BUMP_SEQUENCE operation. Hence the most likely effect of this change is to thwart attacks on vulnerable higher-layer protocols.

Second, certain transactions can no longer execute in the same ledger. Again, there is never a guarantee that an operation can execute in a particular ledger, so applications could not have relied on this happening anyway.

Finally, sequence number increases will appear in TransactionMetaV1.txChanges instead of TransactionMetaV1.operations[0]. This should be more intuitive.

Security Concerns

The changes outlined in this document should for the most part improve security by providing more consistent authorization of changes to accounts. The one potential risk is that attackers could clog the network with invalid transactions without paying nearly the corresponding amount of transaction fees. That risk is mitigated by the restrictions on transaction sets, but is something that must be kept in mind when future CAPs add additional operations.

Any future operations or other transaction features added to the network that can render transactions invalid may need to revise the transaction set restrictions to prevent invalid transactions from being admissible.

Test Cases

None yet.

Implementation

None yet.