diff --git a/RIPS/rip-9998.md b/RIPS/rip-9998.md new file mode 100644 index 0000000..34aff31 --- /dev/null +++ b/RIPS/rip-9998.md @@ -0,0 +1,312 @@ +--- +eip: 0 +title: Aggregation for Native Account Abstraction +description: Aggregation allows Smart Contract Accounts to share a single signature data between multiple AA transactions. +author: Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn) +discussions-to: https://www.google.com/ +status: Draft +type: Standards Track +category: Core +created: 2023-09-01 +requires: 7560 +--- + +## Abstract + +RIP-7560 defined a native way to achieve Account Abstraction on Ethereum. However, one big limitation remains: +each transaction must carry its own `signature` or other form of validation input in order to be included. + +We propose an extension to the RIP-7560 that introduces a validation frame that is shared by multiple transactions. + +This addition follows the design of [ERC-4337](./eip-4337) signature aggregation and will enable +Ethereum transactions to natively support sharing validation inputs for the first time. + +## Motivation + +Using validation schemes that allow signature aggregation enables significant optimisations and savings on +gas for execution and transaction data cost. This is especially relevant in the context of rollups that publish data on +the Ethereum mainnet. + +Another reason to support aggregation for transactions is snark aggregation. +Some signature schemes, such as the ones relying on `secp256r1`, are expensive to verify. +An aggregated zero-knowledge proof that the signatures of a large number of transactions were verified +may be cheaper to verify on-chain than verifying each of them separately. + +## Specification + +### Transaction version AA_TX_TYPE_AGGREGATED_SIG with aggregated signature data + +A new special version of RIP-7560 Transaction called `AA_TX_TYPE_AGGREGATED_SIG` is introduced to carry +the aggregated signature data: + +``` + +0x04 || 0x01 || rlp([chainId, transactionCount, aggregator, aggregatedSignature, aggregatedSigValidationGasLimit, accessList]) + +``` + +All on-chain computations that take place during the aggregated signature validation happen within the context +of this transaction. + +### Calculation of Transaction Type AA_TX_TYPE_AGGREGATED_SIG hash + +``` + +keccak256(0x04 || 0x01 || rlp(transaction_payload) + +``` + +### Bundles of aggregated transactions + +As aggregated transactions share their signatures, they form a set of transactions that are only valid together and in +a given order. We refer to this set of transactions as "aggregated bundle". + +Upon inclusion in a block, each bundle consists of the single "Aggregator validation transaction" and an arbitrary +number of individual aggregated AA transactions. + +There may be an arbitrary number of bundles in an Ethereum block, using same or different `aggregator` addresses. + +### Aggregator validation transaction + +The aggregator validation transaction must run after all validations of the `AA_TX_TYPE` transactions +that are authorized by this `aggregator`, but before these transactions' execution. + +If the execution of this transaction results in a revert the block is INVALID. + +We define the following Solidity method and the `aggregator` of the transaction is invoked with a corresponding data: + +```solidity + +function validateSignatures(uint256 version, bytes[] aggregatedTransactions, bytes aggregatedSignature) external view; + +``` + +The `aggregatedTransactions` parameter is interpreted as an array of `TransactionType4` structs. + +It contains an array of all transactions within a bundle that are verified by the `aggregator`. +The transactions' individual `signature` parameters are replaced with the `signatureReplacement` as described below. + +The entire amount of gas consumed by this transaction is referred to as `gasUsedByAggregator`. + + +![](../assets/rip-9998/block_overview.png) +*The structure of a block containing multiple Native Account Abstraction Transactions with an Aggregator* + + +### Individual transaction validity + +We define the following Solidity method in the `aggregator` contract defined in the transaction: + +```solidity + +function validateTransactionSignature(uint256 version, bytes transaction) external view returns (bytes signatureReplacement); + +``` + +The `transaction` parameter is interpreted as a `TransactionType4` struct. + +This function is only ever executed in a view mode to the `aggregator` and it reverts if the signature validation fails. +The gas limit of this view-only frame can be set to the block gas limit. + +Individual transactions are validated for the purposes of mempool propagation and block building by running the +validation steps in the following order: + +* `sender` deployment frame (once per account) +* `sender` validation frame (required) +* `paymaster` validation frame (optional) +* `aggregator` individual signature validation frame (required) + +When block builder is running the 'aggregator individual signature validation frame', it MUST use this frame's +return value as `signatureReplacement` and replace the `signature` transaction parameter with `signatureReplacement` +when the transaction is being included in the block. + +This step allows the `aggregator` to provide any necessary context or metadata to the `sender` validation step without +having to provide the entire signature that has been verified by the `aggregator` already. + +### Generating aggregated signatures + +It is the block builder's job to combine an array of transaction signatures into a single aggregated signature. +Not all signature schemes have solidity implementations for aggregation, therefore not all block producers will be able +to include all kinds of aggregated transactions. + +The `aggregator` contract MAY include an implementation for the aggregation by accepting the following view call: + +```solidity + +function aggregateSignatures(uint256 version, bytes transactions) external returns (bytes aggregatedSignature); + +``` + +The `transactions` parameter is interpreted as an array of `TransactionType4` structs. + +This call returns a value used as `aggregatedSignature` elsewhere. Aggregator MUST revert this call if it is unable to +calculate this value. + +Note that the mempool MUST only include aggregated AA transactions for `aggregators` that have an implementation +of `aggregateSignatures` function. + +A block builder MAY calculate this value using any alternative way. +If the aggregator does not implement `aggregateSignatures` function it is up to block builder to add +support for this `aggregator` and its signature scheme. + +### Execution layer validity of a block with aggregated transactions included + +The `validateAccountAbstractionTransaction` function's logic is not modified compared to RIP-7560. + +On the execution layer, the block transactions validity conditions are extended as follows: + +``` + +if type(tx) is AccountAbstractionTransaction { + if (tx.version == AA_AGGREGATED_SIG_TX_VERSION){ + aggregatedTxs := collectTransactions(tx.transactionCount) + aggregatedSignature := aggregateSig(aggregatedTxs) + aggregatorInput := ABI.encodeWithSelector('validateSignatures()', aggregatedTxs, aggregatedSignature) + gasUsedByAggregator := evm.Call( + from: AA_ENTRY_POINT, + to: tx.aggreagor, + input: aggregatorInput, + gas: config.aa_aggregated_sig_validation_gas_limit) + else if (tx.version == AA_AGGREGATED_TX_VERSION){ + // NOTE: we subtract the share of aggregated tx signature valdiation gas used from the validation gas limit + tx.validationGasLimit = tx.validationGasLimit - (gasUsedByAggregator / tx.transactionCount) + validateAccountAbstractionTransaction(tx) + } + } +} + +// note: make sure all transactions are accounted for +assert all_type_x_version_1_transactions_validated() + +// note: 'aggregated signature data' transactions do not pay their own gas +// make sure no such transaction is left 'hanging' in a block without paying 'child' transactions +assert all_type_x_version_1_transactions_gas_paid_for() + +``` + +### Passing cost savings to users via gas cost adjustments + +The RIP-7560 charges the signature validation cost as part of a transaction gas usage. +It also treats transaction `signature` parameter as an arbitrary length byte arrays input. Its cost is calculated in the +same way the transaction `data` cost is calculated for previous transaction types. + +With signature aggregation, however, the individual transactions no longer carry their own signature. They also share +the cost of validating the aggregated signature. + +Therefore, the gas cost of the aggregated validation transaction is evenly divided by the number of transactions it +validates and is added to each aggregated transaction's gas cost. + +This amount of consumed gas counts towards the `validationGasLimit` of the transaction, meaning that each +transaction's validation cost includes `gasUsedByAggregator / transactionCount`. +This value is referred to as `aggregatedValidationGasUsed`. + +### Sender validation frame + +The `AA_TX_TYPE_AGGREGATED_SIG` type transaction includes a parameter `transactionCount`. +This value indicates a number of transactions whose validation has been aggregated. + +For AA transactions marked as "aggregated" by the `AA_TX_TYPE_AGGREGATED_SIG` type transaction, +the validation method `validateTransaction` return value is interpreted as: + +```solidity + +abi.encodePacked(aggregator, MAGIC_VALUE_SENDER, validBefore, validAfter) + +``` + +The block including this transaction is only valid if the `aggregator` address returned by the `validateTransaction` +matches the `aggregator` address specified in the `AA_TX_TYPE_AGGREGATED_SIG` transaction. + +### RPC methods (eth namespace) + +#### `eth_aggregationFeeHistory` + +We propose the RPC method `eth_aggregationFeeHistory` to be created. +This method behaves similarly to `eth_feeHistory` method used to estimate [EIP-1559](./eip-1559.md) gas fees, +but instead provides history of a per-transaction validation costs, +`aggregatedValidationGasUsed` and `builderFee`, for a given aggregator. +The values are calculated as an average across all transactions. + +Value of `null` indicates there was no bundle with the given `aggregator` in the given block. + +Input: `aggregator address`, `block count` + +Returns: + +```json +{ + "oldestBlock": "100000", + "newestBlock": "100003", + "aggregatedValidationGasUsed": [ + "450000", + null, + "400000", + "500000" + ], + "builderFee": [ + "0x2386f26fc10000", + null, + "0x2386f26fc10000", + "0x2386f26fc10000" + ] +} +``` + +#### `eth_estimateGas` + +In case an `aggregator` address is returned by the `validateTransaction` by the `sender`, relies on a +`eth_aggregationFeeHistory` logic in order to calculate sufficient `validationGasLimit` and `builderFee` values. + +Returns `{validationGasLimit, callGasLimit, builderFee}` object. + +#### `eth_getTransactionReceipt` + +Accepts the Transaction Type `AA_TX_TYPE_AGGREGATED_SIG` hash. + +This is a special kind of transaction with `from` field set to the `coinbase` and `to` field set to `aggregator`. + +## Rationale + +### Fixed transaction order in bundle + +The `aggregator` contract maintains control over the number and order of transactions inside the "bundle". +This means that some of the strategies block builders apply in order to extract MEV from a block become +harder to do or even impossible. + +However, allowing the block builder to arbitrarily reorder transactions in the block, mixing aggregated and regular +transactions, would make this RIP impractically complex while the MEV extraction was never an intended feature +in the first place. + +## Backwards Compatibility + +This EIP creates a new distinct version of RIP-7560 transactions and does not break backwards-compatibility with the +original specification. + +Same paymasters and factories contracts can be used with signature aggregation. +Sender contracts need to opt in to signature aggregation explicitly by providing the `aggregator` address +as a returned data from the `validateTransaction` function. + +## Security Considerations + +### Bundle size determination + +The proposed design leaves the freedom to determine the size of the "bundle" of aggregated AA transactions +to the block builder. However, accounts retain some control over the "bundle" size as well by setting the +`validationGasLimit` parameter, which may affect the minimal size of the bundle that works for this transaction. + +This may create opposing forces where bundlers are occasionally incentivized to split one "bundle" into two +which pays more priority fee in total. This is somewhat mitigated by the `eth_estimateGas` relying on historic averages +to calculate the best possible `validationGasLimit` for the transaction. + +### Malicious aggregators + +The `aggregator` contracts are among te most trusted contracts in the entire ecosystem. +They can authorize transactions on behalf of accounts, and they can invalidate large numbers of transactions with +a simple storage change. + +Both account developers and block builders should be extremely careful with the selection of `aggregator` contracts +that they are willing to support. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). diff --git a/assets/rip-9998/block_overview.png b/assets/rip-9998/block_overview.png new file mode 100644 index 0000000..fda28ab Binary files /dev/null and b/assets/rip-9998/block_overview.png differ