Skip to content

Commit

Permalink
Merge pull request #2 from eth-infinitism/1st_set_of_patches
Browse files Browse the repository at this point in the history
1st set of patches after ETHPrague
  • Loading branch information
forshtat committed Jul 5, 2023
2 parents 31c2891 + 8cb5ff5 commit 4ebda15
Showing 1 changed file with 36 additions and 28 deletions.
64 changes: 36 additions & 28 deletions EIPS/0_eip-aa-native-enshrined.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Constants
| AA_TX_TYPE | 4 |
| AA_ENTRY_POINT | `address(9999)` << current EIP number |
| AA_SENDER_CREATOR | `address(ffff9999)` |
| AA_NONCE_MANAGER | `address(eeee9999)` |
| AA_BASE_GAS_COST | 15000 |
| AA_ECRECOVER_COST | 6000 |

Expand All @@ -66,7 +67,7 @@ A new EIP-2718 transaction with type AA_TX_TYPE is introduced. Transactions of t
```
0x04 || 0x00 || rlp([
chain_id, sender, nonce,
target, value, call_data,
call_data,
paymaster_data, deployer_data,
max_priority_fee_per_gas, max_fee_per_gas,
validBefore, validAfter,
Expand All @@ -82,11 +83,6 @@ First 20 bytes of`paymaster_data` contain the address of a `paymaster` contract.

First 20 bytes of`deployer_data` contain the address of a `deployer` contract.

### NONCE (~~0x48~~) Opcode

A new opcode `NONCE` (~~0x48~~) is introduced, with gas cost `G_base`, which pushes the nonce of the callee onto the
stack.

### Non-sequential nonce support

Before EIP-9999, for accounts with associated code (contracts) the account nonce is only used and incremented
Expand All @@ -99,6 +95,10 @@ The contract account nonce is then defined as a mapping `address account => uint
This approach guarantees unique transaction nonce and hash but removes the requirement of nonce being sequential
numbers.

This mapping is exposed to the EVM in a `NonceManager` precompile contract located at AA_NONCE_MANAGER address.
The precompile input is the `address` of account whose nonce needs to be retrieved.
The returned value is a `uint256` nonce.

Before a valid transaction is being included and applied in a block, the `account[key]` value is incremented.

### Gas fees charged directly from contract address
Expand Down Expand Up @@ -137,7 +137,7 @@ The full list of possible frames tries to replicate the ERC-4337 flow:
- sender deployment frame (once per account)
- sender validation frame (required)
- gas payment validation frame (optional)
- target execution frame (required)
- sender execution frame (required)
- gas payment cleanup frame (optional)

In terms of block validity, all validation and execution frames may read and write any state when included in the block.
Expand Down Expand Up @@ -173,8 +173,6 @@ We define the following Solidity struct to represent the AA transaction on-chain
```solidity
struct TransactionType4 {
address sender;
address target;
uint256 value;
uint256 nonce;
uint256 version;
uint256 validBefore;
Expand All @@ -196,50 +194,51 @@ struct TransactionType4 {
We then define the following Solidity method and the `sender` of the transaction is invoked with a corresponding data:

```solidity
function validateTransaction(TransactionType4 tx, bytes32 txHash) external returns (uint256 validationData);
function validateTransaction(uint256 version, bytes32 txHash, bytes transaction) external returns (bytes validationContext, uint256 validationData);
```

The `transaction` parameter is interpreted as an ABI encoding of `TransactionType4`.
The `version` parameter is added in order to maintain the Solidity method ID in case of changes to this struct
in future revisions of this EIP.

The execution frame must return 32 bytes `validationData` that is interpreted as:

```solidity
abi.encodePacked(isValid)
abi.encodePacked(isValid, validBefore, validAfter)
```

#### Paymaster validation frame

The `paymaster` of the transaction, if specified, is invoked with the following data:

```solidity
function validatePaymasterTransaction(TransactionType4 tx, bytes32 txHash) external returns (bytes context, uint256 validationData);
function validatePaymasterTransaction(uint256 version, bytes32 txHash, bytes transaction) external returns (bytes context, uint256 validationData);
```

The `transaction` parameter is interpreted as an ABI encoding of `TransactionType4`.

The execution frame must return a bytes array that is interpreted as:

```solidity
abi.encode(context, isValid)
abi.encode(context, isValid, validBefore, validAfter)
```

#### Target execution frame

The target execution frame is the first transaction frame that is not bound by the opcode and state access rules.
#### Sender execution frame

The `target` is invoked for execution with the `value`, `call_data` and `call_gas_limit` specified in the transaction
RLP encoding.
We define the following Solidity method and the `sender` of the transaction is invoked with a corresponding data:

For the `target` contract this call is not distinguishable from the existing transaction types.
This means that the `msg.sender == sender` and `tx.origin == sender` for the first frame of the execution.
```solidity
function executeTransaction(bytes calldata, bytes context) external;
```

Making a call directly to the `target` enables the Paymaster to analyze the `call_data` if needed.
This is not possible if the call is made to the `sender` as it can contain an arbitrary interpretation the call data.
In case the `sender` contract needs to execute some additional logic before the execution, it MAY require that
`target == sender` in its validation.
The sender execution frame is the first transaction frame that is not bound by the opcode and state access rules.

The validation frames do not revert if the execution frame reverts.
The cleanup may still be called with a `success: false` flag.

#### Paymaster cleanup frame

After the target execution frame is over the `paymaster` may need to perform some kind of cleanup or bookkeeping.
After the sender execution frame is over the `paymaster` may need to perform some kind of cleanup or bookkeeping.
If the gas payment validation returned a non-zero `context`, the `paymaster` is invoked again, without rules and
restrictions, with the following inputs:

Expand All @@ -256,6 +255,9 @@ On the execution layer, the transaction validity conditions for a block are exte

```
if type(tx) is AccountAbstractionTransaction {
assert Date.now() <= tx.validUntil
assert Date.now() >= tx.validAfter
if (sender.code.length == 0) {
assert deployer_data.length > 20;
deployer := deployer_data[0:20];
Expand All @@ -264,7 +266,6 @@ if type(tx) is AccountAbstractionTransaction {
to: deployer,
input: deployer_data[20:],
gas: sender_deployment_gas_limit);
assert retDeployer.isValid;
assert retDeployer.createdSender == sender;
assert sender.code.lenght > 0;
}
Expand All @@ -277,6 +278,8 @@ if type(tx) is AccountAbstractionTransaction {
to: paymaster,
input: paymasterInput,
gas: paymaster_validation_gas_limit);
assert Date.now() <= retPaymaster.validUntil
assert Date.now() >= retPaymaster.validAfter
assert retPaymaster.isValid;
}
Expand All @@ -286,6 +289,8 @@ if type(tx) is AccountAbstractionTransaction {
to: sender,
input: senderInput,
gas: sender_validation_gas_limit);
assert Date.now() <= retSender.validUntil
assert Date.now() >= retSender.validAfter
assert retSender.isValid;
}
Expand Down Expand Up @@ -316,8 +321,6 @@ They may be propagated in the alternative mempool that allows them explicitly as

### All validation state changes apply before all execution ones

##### TODO: ERC-4337 does this - but I don't know if this is a viable rule for a mainnet block

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.
Expand Down Expand Up @@ -354,6 +357,11 @@ Replace the sender validation frame with default ECDSA signature validation.

The base transaction gas cost in this case is increased by `AA_ECRECOVER_COST`.

The `call_data` parameter in this case is interpreted as following:
```
target || value || data
```

### RPC methods (eth namespace)

#### eth_sendTransaction
Expand Down

0 comments on commit 4ebda15

Please sign in to comment.