-
Notifications
You must be signed in to change notification settings - Fork 418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update ERC-4337: Extract aggregation to a separate ERC #627
Open
forshtat
wants to merge
9
commits into
ethereum:master
Choose a base branch
from
eth-infinitism:AA-427-extract-aggregation-remove
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 7 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
7c75244
Unused gas penalty only callGasLimit` and `paymasterPostOpGasLimit`
forshtat bdee25c
AA-427: Remove all mentions of 'aggregation' possible
forshtat 8fc969f
Update ERCS/erc-4337.md
forshtat 53c8869
Update ERCS/erc-4337.md
forshtat 7fdb2c6
Update ERCS/erc-4337.md
forshtat 78573a9
Remove mention of JSON-RPC API error codes from core ERC-4337 document
forshtat cef60c5
Merge branch 'master' into AA-427-extract-aggregation-remove
forshtat 8026bb8
Update erc-4337.md
forshtat c4a2dfe
Merge branch 'master' into AA-427-extract-aggregation-remove
drortirosh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,7 +31,6 @@ This proposal takes a different approach, avoiding any adjustments to the consen | |
* Privacy-preserving applications | ||
* Atomic multi-operations (similar goal to [EIP-3074]) | ||
* Pay tx fees with [ERC-20](./eip-20.md) tokens, allow developers to pay fees for their users, and [EIP-3074]-like **sponsored transaction** use cases more generally | ||
* Support aggregated signature (e.g. BLS) | ||
|
||
## Specification | ||
|
||
|
@@ -52,7 +51,6 @@ This proposal takes a different approach, avoiding any adjustments to the consen | |
other kind of PBS (proposer-builder separation) | ||
* The `bundler` can also rely on an experimental `eth_sendRawTransactionConditional` RPC API if it is available. | ||
* **Paymaster** - a helper contract that agrees to pay for the transaction, instead of the sender itself. | ||
* **Aggregator** - a helper contract trusted by accounts to validate an aggregated signature. Bundlers/Clients whitelist the supported aggregators. | ||
|
||
### UserOperation | ||
|
||
|
@@ -102,17 +100,6 @@ The core interface of the entry point contract is as follows: | |
|
||
```solidity | ||
function handleOps(PackedUserOperation[] calldata ops, address payable beneficiary); | ||
|
||
function handleAggregatedOps( | ||
UserOpsPerAggregator[] calldata opsPerAggregator, | ||
address payable beneficiary | ||
); | ||
|
||
struct UserOpsPerAggregator { | ||
PackedUserOperation[] userOps; | ||
IAggregator aggregator; | ||
bytes signature; | ||
} | ||
``` | ||
|
||
### Account Contract Interface | ||
|
@@ -132,18 +119,15 @@ The `userOpHash` is a hash over the userOp (except signature), entryPoint and ch | |
The account: | ||
|
||
* MUST validate the caller is a trusted EntryPoint | ||
* If the account does not support signature aggregation, it MUST validate that the signature is a valid signature of the `userOpHash`, and | ||
* MUST validate that the signature is a valid signature of the `userOpHash`, and | ||
SHOULD return SIG_VALIDATION_FAILED (and not revert) on signature mismatch. Any other error MUST revert. | ||
* MUST pay the entryPoint (caller) at least the "missingAccountFunds" (which might be zero, in case the current account's deposit is high enough) | ||
* The account MAY pay more than this minimum, to cover future transactions (it can always issue `withdrawTo` to retrieve it) | ||
* The return value MUST be packed of `authorizer`, `validUntil` and `validAfter` timestamps. | ||
* authorizer - 0 for valid signature, 1 to mark signature failure. Otherwise, an address of an authorizer contract. This ERC defines a "signature aggregator" as an authorizer. | ||
* authorizer - 0 for valid signature, 1 to mark signature failure. Otherwise, an address of an authorizer contract, as defined in [ERC-XXXX](link). | ||
* `validUntil` is 6-byte timestamp value, or zero for "infinite". The UserOp is valid only up to this time. | ||
* `validAfter` is 6-byte timestamp. The UserOp is valid only after this time. | ||
|
||
An account that works with aggregated signature, should return its signature aggregator address in the "sigAuthorizer" return value of validateUserOp. | ||
It MAY ignore the signature field. | ||
|
||
The account MAY implement the interface `IAccountExecute` | ||
|
||
```solidity | ||
|
@@ -222,11 +206,8 @@ this bundler is supposed to track the `key` and `sequence` pair of the UserOpera | |
|
||
### Required entry point contract functionality | ||
|
||
There are 2 separate entry point methods: `handleOps` and `handleAggregatedOps` | ||
The entry point method is `handleOps`, which handles an array of userOps | ||
|
||
* `handleOps` handles userOps of accounts that don't require any signature aggregator. | ||
* `handleAggregatedOps` can handle a batch that contains userOps of multiple aggregators (and also requests without any aggregator) | ||
* `handleAggregatedOps` performs the same logic below as `handleOps`, but it must transfer the correct aggregator to each userOp, and also must call `validateSignatures` on each aggregator before doing all the per-account validation. | ||
The entry point's `handleOps` function must perform the following steps (we first describe the simpler non-paymaster case). It must make two loops, the **verification loop** and the **execution loop**. In the verification loop, the `handleOps` call must perform the following steps for each `UserOperation`: | ||
|
||
* **Create the account if it does not yet exist**, using the initcode provided in the `UserOperation`. If the account does not exist, _and_ the initcode is empty, or does not deploy a contract at the "sender" address, the call must fail. | ||
|
@@ -322,33 +303,6 @@ When a client receives a `UserOperation`, it must first run some basic sanity ch | |
|
||
If the `UserOperation` object passes these sanity checks, the client must next run the first op simulation, and if the simulation succeeds, the client must add the op to the pool. A second simulation must also happen during bundling to make sure the UserOperation is still valid. | ||
|
||
### Using Signature Aggregator | ||
|
||
A signature aggregator exposes the following interface | ||
|
||
```solidity | ||
interface IAggregator { | ||
|
||
function validateUserOpSignature(PackedUserOperation calldata userOp) | ||
external view returns (bytes memory sigForUserOp); | ||
|
||
function aggregateSignatures(PackedUserOperation[] calldata userOps) external view returns (bytes memory aggregatesSignature); | ||
|
||
function validateSignatures(PackedUserOperation[] calldata userOps, bytes calldata signature) view external; | ||
} | ||
``` | ||
|
||
* An account signifies it uses signature aggregation returning its address from `validateUserOp`. | ||
* During `simulateValidation`, this aggregator is returned to the bundler as part of the `aggregatorInfo` struct. | ||
* The bundler should first accept the aggregator (aggregators must be staked. bundler should verify it is not throttled/banned) | ||
* To accept the UserOp, the bundler must call **validateUserOpSignature()** to validate the userOp's signature. | ||
This method returned an alternate signature (usually empty) that should be used during bundling. | ||
* The bundler MUST call `validateUserOp` a second time on the account with the UserOperation using that returned signature, and make sure it returns the same value. | ||
* **aggregateSignatures()** must aggregate all UserOp signatures into a single value. | ||
* Note that the above methods are helper methods for the bundler. The bundler MAY use a native library to perform the same validation and aggregation logic. | ||
* **validateSignatures()** MUST validate the aggregated signature matches for all UserOperations in the array, and revert otherwise. | ||
This method is called on-chain by `handleOps()` | ||
|
||
### Simulation | ||
|
||
#### Simulation Rationale | ||
|
@@ -357,7 +311,7 @@ To add a UserOperation into the mempool (and later to add it into a bundle) we n | |
In addition, we need to verify that the same will hold true when executed on-chain. | ||
For this purpose, a UserOperation is not allowed to access any information that might change between simulation and execution, such as current block time, number, hash etc. | ||
In addition, a UserOperation is only allowed to access data related to this sender address: Multiple UserOperations should not access the same storage, so it is impossible to invalidate a large number of UserOperations with a single state change. | ||
There are 3 special contracts that interact with the account: the factory (initCode) that deploys the contract, the paymaster that can pay for the gas, and a signature aggregator (described later) | ||
There are 2 special entity contracts that interact with the account: the factory (initCode) that deploys the contract, and the paymaster that can pay for the gas. | ||
Each of these contracts is also restricted in its storage access, to make sure UserOperation validations are isolated. | ||
|
||
#### Simulation Specification: | ||
|
@@ -390,19 +344,15 @@ struct ReturnInfo { | |
bytes paymasterContext; | ||
} | ||
|
||
struct AggregatorStakeInfo { | ||
address aggregator; | ||
StakeInfo stakeInfo; | ||
} | ||
|
||
struct StakeInfo { | ||
uint256 stake; | ||
uint256 unstakeDelaySec; | ||
} | ||
|
||
|
||
``` | ||
|
||
The `AggregatorStakeInfo` structure is further defined in [ERC-XXXX](link). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO fix link when assigned numbers There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. Waiting for ERC-7766 to be merged. |
||
|
||
This method returns `ValidationResult` or revert on validation failure. | ||
The node should drop the UserOperation if the simulation fails (either by revert or by "signature failure") | ||
|
||
|
@@ -413,8 +363,7 @@ The simulated call performs the full validation, by calling: | |
3. if specified a paymaster: `paymaster.validatePaymasterUserOp`. | ||
|
||
The simulateValidation should validate the return value (validationData) returned by the account's `validateUserOp` and paymaster's `validatePaymasterUserOp`. | ||
The account MAY return an aggregator. See [Using Signature Aggregator](#using-signature-aggregator) | ||
The paymaster MUST return either "0" (success) or SIG_VALIDATION_FAILED for aggregator, and not an address. | ||
The paymaster MUST return either "0" (success) or SIG_VALIDATION_FAILED. | ||
Either return value may contain a "validAfter" and "validUntil" timestamps, which is the time-range that this UserOperation is valid on-chain. | ||
A node MAY drop a UserOperation if it expires too soon (e.g. wouldn't make it to the next block) by either the account or paymaster. | ||
If the `ValidationResult` includes `sigFail`, the client SHOULD drop the `UserOperation`. | ||
|
@@ -424,8 +373,8 @@ For the complete procedure see [ERC-7562](./eip-7562.md) | |
|
||
### Alternative Mempools | ||
|
||
The simulation rules above are strict and prevent the ability of paymasters and signature aggregators to grief the system. | ||
However, there might be use cases where specific paymasters (and signature aggregators) can be validated | ||
The simulation rules above are strict and prevent the ability of paymasters to grief the system. | ||
However, there might be use cases where specific paymasters can be validated | ||
(through manual auditing) and verified that they cannot cause any problem, while still require relaxing of the opcode rules. | ||
A bundler cannot simply "whitelist" a request from a specific paymaster: if that paymaster is not accepted by all | ||
bundlers, then its support will be sporadic at best. | ||
|
@@ -442,8 +391,6 @@ During bundling, the bundler should: | |
* Exclude UserOps that access any sender address of another UserOp in the same batch. | ||
* Exclude UserOps that access any address created by another UserOp validation in the same batch (via a factory). | ||
* For each paymaster used in the batch, keep track of the balance while adding UserOps. Ensure that it has sufficient deposit to pay for all the UserOps that use it. | ||
* Sort UserOps by aggregator, to create the lists of UserOps-per-aggregator. | ||
* For each aggregator, run the aggregator-specific code to create aggregated signature, and update the UserOps | ||
|
||
After creating the batch, before including the transaction in a block, the bundler should: | ||
|
||
|
@@ -506,7 +453,7 @@ To prevent such rogue UserOperations, the bundler is required to follow a set of | |
### Reputation Rationale. | ||
|
||
UserOperation's storage access rules prevent them from interfering with each other. | ||
But "global" entities - paymasters, factories and aggregators are accessed by multiple UserOperations, and thus might invalidate multiple previously valid UserOperations. | ||
But "global" entities - paymasters and factories are accessed by multiple UserOperations, and thus might invalidate multiple previously valid UserOperations. | ||
|
||
To prevent abuse, we throttle down (or completely ban for a period of time) an entity that causes invalidation of a large number of UserOperations in the mempool. | ||
To prevent such entities from "Sybil-attack", we require them to stake with the system, and thus make such DoS attack very expensive. | ||
|
@@ -573,25 +520,14 @@ The result `SHOULD` be set to the **userOpHash** if and only if the request pass | |
|
||
* If the UserOperation is valid, the client MUST return the calculated **userOpHash** for it | ||
* in case of failure, MUST return an `error` result object, with `code` and `message`. The error code and message SHOULD be set as follows: | ||
* **code: -32602** - invalid UserOperation struct/fields | ||
* **code: -32500** - transaction rejected by entryPoint's simulateValidation, during wallet creation or validation | ||
* The `message` field MUST be set to the FailedOp's "`AAxx`" error message from the EntryPoint | ||
* **code: -32501** - transaction rejected by paymaster's validatePaymasterUserOp | ||
* The `message` field SHOULD be set to the revert message from the paymaster | ||
* The `data` field MUST contain a `paymaster` value | ||
* **code: -32502** - transaction rejected because of opcode validation | ||
* **code: -32503** - UserOperation out of time-range: either wallet or paymaster returned a time-range, and it has already expired (or will expire soon) | ||
* The `data` field SHOULD contain the `validUntil` and `validAfter` values | ||
* The `data` field SHOULD contain a `paymaster` value, if this error was triggered by the paymaster | ||
* **code: -32504** - transaction rejected because paymaster (or signature aggregator) is throttled/banned | ||
* The `data` field SHOULD contain a `paymaster` or `aggregator` value, depending on the failed entity | ||
* **code: -32505** - transaction rejected because paymaster (or signature aggregator) stake or unstake-delay is too low | ||
* The `data` field SHOULD contain a `paymaster` or `aggregator` value, depending on the failed entity | ||
* The `data` field SHOULD contain a `paymaster` value, depending on the failed entity | ||
* The `data` field SHOULD contain a `paymaster` value, depending on the failed entity | ||
* The `data` field SHOULD contain a `minimumStake` and `minimumUnstakeDelay` | ||
* **code: -32506** - transaction rejected because wallet specified unsupported signature aggregator | ||
* The `data` field SHOULD contain an `aggregator` value | ||
* **code: -32507** - transaction rejected because of wallet signature check failed (or paymaster signature, if the paymaster uses its data as signature) | ||
* **code: -32508** - transaction rejected because paymaster balance can't cover all pending UserOperations. | ||
|
||
##### Example: | ||
|
||
|
@@ -793,7 +729,7 @@ This api must only be available in testing mode and is required by the compatibi | |
|
||
#### * debug_bundler_clearState | ||
|
||
Clears the bundler mempool and reputation data of paymasters/accounts/factories/aggregators. | ||
Clears the bundler mempool and reputation data of paymasters/accounts/factories. | ||
|
||
```json= | ||
# Request | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO fix link when assigned numbers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Waiting for ERC-7766 to be merged.