RIP-7711: Validation-Execution Separation in Native Account Abstraction
A change in the order of execution of frames of RIP-7560 transactions inside a block that enables efficient block building
Abstract
This proposal provides block builders with a mechanism to isolate validation from execution for a set of RIP-7560 transactions. By doing so we simplify the task of filling a block gas space with RIP-7560 transactions and prevent potential denial-of-service attacks against block builders.
On "single sequencer" Layer 2 chains that do not have a "transaction mempool" in a traditional sense, this proposal provides no benefit compared to the original RIP-7560. It is required for DoS mitigation on every chain that does rely on a public mempool for block building, however.
Motivation
The AA_TX_TYPE
transaction type that is defined in RIP-7560 completely separates transaction validity
on a protocol level from ECDSA signatures or any other protocol-defined rules, instead allowing account's EVM code
to determine a validity of a transaction.
This validation EVM code, however, may be affected by any observable state change within a block.
A block builder trying to include a set of AA_TX_TYPE
transactions may face a challenge of finding a combination
that fits together without invalidating each other.
The block builder has to execute the entire body of one transaction before picking the next one. Additionally, it is not feasible to apply any limitations on the transaction execution, while it is expected that the validation code will be constrained by the block builder with a ruleset like ERC-7562.
This document proposes a mechanism for block builder to specify a set of AA_TX_TYPE
transactions that are guaranteed
to fit together due to a fact that all of their validation frames are executed consecutively first,
before their respective execution frames.
Specification
Non-atomic validation and execution transaction type
These transactions are completely identical to regular RIP-7560 transactions with the exceptions of being composed into "AA transaction bundles".
It is important for the wallets to explicitly opt into this feature by accepting the BUNDLE_TRANSACTION_TYPE
,
as some Smart Contract Accounts
may be created in a way that relies on atomicity between validation and execution phases.
AA transaction bundles
In AA transaction bundles, all validation state changes apply before all execution ones.
Filling a block with AA transactions must not be a challenge for the block builder.
However, if each transaction during its execution can alter any state that affects the validity of another transaction
in the mempool, the block builder will be forced to revalidate all transactions in the mempool after each inclusion.
Transactions of BUNDLE_TRANSACTION_TYPE
type mitigate the inherent computational complexity of building a block that
contains AA_TX_TYPE
transactions.
With BUNDLE_TRANSACTION_TYPE
transactions, all the validation frames
of an uninterrupted sequence of AA transactions are run first,
and all the execution frames are run immediately after that.
Validation code sandboxing
Even with RIP-7711, validation frames of a BUNDLE_TRANSACTION_TYPE
transactions bundle can invalidate
other transactions in the same bundle.
We define a mechanism to prevent cross-validation dependencies by applying
certain rules for the mempool transactions which is fully described in ERC-7562.
This is equivalent to the mechanism used by the ERC-4337 UserOperations mempool.
A builder that chooses not to enforce the rules from ERC-7562 must take care to re-validate each transaction against the mid-block state at the position where it is being included into a block. Otherwise, the resulting block is likely to end up being invalid.
Block structure diagram
Here is a visual representation of a block that contains multiple Account Abstraction Transactions. The validation parts of AA transactions are executed as separate transactions, but are not represented as separate transactions in the block data.
The structure of a block containing multiple RIP-7711 Native Account Abstraction Transactions
For comparison, this is the diagram of a similar block using RIP-7560 transactions:
The structure of a block containing multiple RIP-7560 Transactions
Transaction execution context
Note that some behaviours in the EVM depend on the transaction context. These behaviours are:
- Costs of the
SSTORE
opcode per EIP-2200 - Costs of accessing cold addresses and slots per EIP-2929
- Values available within the transient storage per EIP-1163
- Maximum amount of gas refund assigned after the execution per EIP-3529
These features are not affected by the separation of the transaction into multiple frames. Meaning, for example, that a value set with TSTORE in one frame will remain available in the next one, and different transactions will have independent values held in TSTORE slots.
Behaviour of the SELFDESTRUCT
opcode
The only exception to the rule defined in the Transaction execution context
section is the availability of the SELFDESTRUCT
opcode as defined by EIP-6780.
Using SELFDESTRUCT
is only allowed within the same frame the contract was created in.
Unused gas penalty charge
A penalty of UNUSED_GAS_PENALTY
percent of the unused callGasLimit
and paymasterPostOpGasLimit
is charged from the
transaction sender
or paymaster
.
This penalty is applied to the execution frame and the postPaymasterTransaction
separately.
The unused gas is calculated as following for the corresponding frames:
Note that the unusedExecutionGasPenalty
is added to the actualGasUsed
right after the
execution frame completes and before it is passed to the the postPaymasterTransaction
frame.
The unusedPostOpGasPenalty
is added to the actualGasUsed
after the postPaymasterTransaction
.
Rationale
Unused gas penalty charge
Transactions of type BUNDLE_TRANSACTION_TYPE
that reserve a lot of gas for themselves using validationGasLimit
,
paymasterGasLimit
and callGasLimit
fields but do not use the reserved gas present a challenge for
block builders. This is especially demanding in case a gas used by a transaction can be significantly different
based on its position within a block, as such transactions may cause the block builder to iterate its algorithm
many times until a fully utilized block is discovered.
The effects of allowing transactions to specify unrestricted gas limits is shown on this diagram:
Breaking up a transaction flow into non-atomic pieces
While changing the transaction flow is a departure from the norm for Ethereum transactions, in practice this change is both very useful and not very complex.
The validation frames can be easily constrained with both gas limits and opcode bans. The entire validation section of a correctly built bundle can therefore be protected from containing mutually exclusive transactions. The task of building a block becomes efficient and can be parallelized with no risk of DoS attacks.
For the EVM implementation the validation frames behave almost identical to a standalone transaction, so there are no expected difficulties with implementing this proposal.
Backwards Compatibility
The non-atomic flow of an RIP-7711 transaction requires attention from the Smart Contract Account developers to ensure the accounts cannot be left in a broken state between the validation and execution frames.
However, as ERC-4337 has a very similar execution flow for UserOperations, it is a known property of Account Abstractions and all existing code is likely to be compatible with RIP-7711 with only some minor modifications.
Security Considerations
Attacks on validation-execution separation
Accounts in RIP-7560 are instructed not to expect the validation and execution to be atomic. However, wallets may be implemented with an incorrect assumption that nothing can happen between validation and execution phases, which is wrong.
The state that exists at the end of the validation frame may be observed or modified by unrelated contracts before the execution frame begins. Smart Contract Account developers contracts must ensure that their code does not make any false assumptions.
Copyright
Copyright and related rights waived via CC0.