From 47777ec152f9fe9a55ad00275389a0d18c3b7154 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Thu, 19 Sep 2024 22:09:17 +0200 Subject: [PATCH 1/5] AA-456: Create 'sendRawTransactionConditional' ERC and add EIP-7702 support --- ERCS/eip-send-tx-conditional.md | 117 ++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 ERCS/eip-send-tx-conditional.md diff --git a/ERCS/eip-send-tx-conditional.md b/ERCS/eip-send-tx-conditional.md new file mode 100644 index 0000000000..880c158f02 --- /dev/null +++ b/ERCS/eip-send-tx-conditional.md @@ -0,0 +1,117 @@ +```--- +eip: send-tx-cond +title: Conditional send transaction RPC +description: Conditional send transaction RPC for better integration with sequencers +author: Dror Tirosh (@drortirosh), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Shahaf Nacson (@shahafn) +discussions-to: +status: Draft +type: Standards Track +category: Interface +created: 2024-04-16 +--- +``` + +## Abstract + +This EIP proposes a new RPC method `eth_sendRawTransactionConditional` for block builders and sequencers, enhancing transaction integration by allowing preconditions for transaction inclusion. This method aims to improve efficiency by reducing the need for transaction simulation, thereby improving transaction ordering cpu cost. + +## Motivation + +Current private APIs, such as the Flashbots API, require block builders to simulate transactions to determine eligibility for inclusion, a process that is CPU-intensive and inefficient. The proposed RPC method addresses this by enabling transactions to specify preconditions, thus reducing computational overhead and potentially lowering transaction costs. + +Moreover, the flashbots API doesn't give any tool to a block-builder to determine the cross-dependencies of different transactions. The only way to guarantee that another transaction doesn't interfere with a given one is by placing it as the first transaction in the block. +This makes this placement very lucrative, and disproportionately expensive. +In addition, since there is no way to give any guarantee on other slots, their pricing has to be low accordingly. + +Since there is no easy way to detect cross-dependencies of different transactions, it is cpu-intensive to find an optimal ordering of transactions. + + +### Out of scope + +This document does not define an algorithm for a block builder to select a transaction in case of conflicting transactions. + +## Specification + +* Method: `eth_sendRawTransactionConditional` + +* Parameters: + +1. transaction: The raw, signed transaction data. Similar to `eth_sendRawTransaction` +2. options: An object containing conditions under which the transaction must be included. +* The "options" param may include any of the following members: + * **knownAccounts**: a map of accounts with expected storage + * The key is account address + * If the value is **hex string**, it is the known storage root hash of that account. + * If the value is an **object**, then each member is in the format of `"slot": "value"`, which are explicit slot values within that account storage. + both `slot` and `value` are hex values + * a special key `balance` define the expected balance of the account + * **blockNumberMin**: [optional] minimal block number for inclusion + * **blockNumberMax**: [optional] maximum block number for inclusion + * **timestampMin**: [optional] minimum block timestamp for inclusion + * **timestampMax**: [optional] maximum block timestamp for inclusion + * **paysConbase**: paysCoinbase[optional] this is not a precondition, but an expected outcome: the caller declares the minmimum amount paid to the coinbase by this transaction (including gas fees and direct payment) + It is only relevant if the API is used to define a "marketplace" for clients to compete on inclusion. + + +* Before accepting the request, the block-builder/sequencer SHOULD: + * If block range was given, check that the block number is within the range. + * If timestamps range was given, check that the block's timestamp is within the range. + * For an address with a storage root hash, validate the current root is unmodified. + * For an address with a list of slots, it should verify that all these slots hold the exact value specified. +* The sequencer should REJECT the request if any address is doesn't pass the above rules. + +### Return value + +In case of successful inclusion, the call should return the same value as `sendRawTransaction` (namely, the transaction-hash) +In case of failure, it SHOULD return an error with indication of failure reason. +The error code SHOULD be -32003 (transaction rejected) with reason string describing the cause: storage error, out of block/time range, +In case of repeated failures or knownAccounts too large, the error code SHOULD be -32005 (Limit exceeded) with a description of the error + +**NOTE:** Even if the transaction was accepted (into the internal mempool), the caller MUST NOT assume block inclusion, and must monitor the blockchain. + + +## Sample request: +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_sendRawTransactionConditional", + "params": [ + "0x2815c17b00...", + { + "blockNumberMax": 12345, + "knownAccounts": { + "0xadd1": "0xfedc....", + "0xadd2": { + "0x1111": "0x1234...", + "0x2222": "0x4567..." + } + } + } + ] +} +``` +### Possible Use-cases: + +- **auction market**: +- **alternative to flashbot api**: + The flashbot api requires the builder to simulate the transactions to determine their cross-dependency. This can be cpu consuming. + For high-MEV, this is acceptable, but not for cheap general-purpose account-abstraction transactions. + +### Limitations + +- Callers should not assume that a successul response means the transaction is included + In particular, it is possible that a block re-order might remove the transaction, or cause it to fail, just like any other transaction. + +### Security Consideration + +The block-builder should protect itself against abuse of the API, namely, submitting a large # of requests which are known to fail. + +Following are suggested mechanisms: + +* **Throttling**: the block builder should allow a maximum rate of rpc calls per sender, and increase + that rate after successful inclusion. repeated rejection of blocks should reduce the allowed rate. +* **Arbitrum**-style protection: Arbitrum implemented this API, but they run the storage validation not only + against the current block, but also into past 2 seconds. + This prevents abusing the API for MEV, while making it viable for ERC-4337 account validation +* **Fastlane on Polygon** uses it explicitly for ERC-4337, by checking the submitted UserOperations exist on the public mempool (and reject the transaction otherwise) From 98e35b0ec87dcfc1b73185ded19e9190b20f416d Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Fri, 20 Sep 2024 01:14:22 +0200 Subject: [PATCH 2/5] Initial readability improvement --- ERCS/eip-send-tx-conditional.md | 111 ++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 42 deletions(-) diff --git a/ERCS/eip-send-tx-conditional.md b/ERCS/eip-send-tx-conditional.md index 880c158f02..4ad15c9af3 100644 --- a/ERCS/eip-send-tx-conditional.md +++ b/ERCS/eip-send-tx-conditional.md @@ -1,7 +1,7 @@ ```--- eip: send-tx-cond title: Conditional send transaction RPC -description: Conditional send transaction RPC for better integration with sequencers +description: JSON-RPC API for block builders allowing users to express preconditions for transaction inclusion author: Dror Tirosh (@drortirosh), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Shahaf Nacson (@shahafn) discussions-to: status: Draft @@ -13,22 +13,32 @@ created: 2024-04-16 ## Abstract -This EIP proposes a new RPC method `eth_sendRawTransactionConditional` for block builders and sequencers, enhancing transaction integration by allowing preconditions for transaction inclusion. This method aims to improve efficiency by reducing the need for transaction simulation, thereby improving transaction ordering cpu cost. +This EIP proposes a new JSON-RPC API method `eth_sendRawTransactionConditional` for block builders and sequencers, +enhancing transaction integration by allowing users to express preconditions for transaction inclusion. + +This method aims to improve efficiency by reducing the need for transaction simulation, +thereby improving the computational efficiency of transaction ordering. ## Motivation -Current private APIs, such as the Flashbots API, require block builders to simulate transactions to determine eligibility for inclusion, a process that is CPU-intensive and inefficient. The proposed RPC method addresses this by enabling transactions to specify preconditions, thus reducing computational overhead and potentially lowering transaction costs. +Current private block builder APIs, such as the Flashbots API, +require block builders to simulate transactions to determine eligibility for inclusion, +a process that is CPU-intensive and inefficient. -Moreover, the flashbots API doesn't give any tool to a block-builder to determine the cross-dependencies of different transactions. The only way to guarantee that another transaction doesn't interfere with a given one is by placing it as the first transaction in the block. -This makes this placement very lucrative, and disproportionately expensive. -In addition, since there is no way to give any guarantee on other slots, their pricing has to be low accordingly. +The proposed RPC method addresses this by enabling transactions to specify preconditions, +thus reducing computational overhead and potentially lowering transaction costs. -Since there is no easy way to detect cross-dependencies of different transactions, it is cpu-intensive to find an optimal ordering of transactions. +Moreover, the flashbots API does not provide the block builder with a mechanism to determine the +cross-dependencies of different transactions. +The only way to guarantee that another transaction does not interfere with a given one is by placing +it as the first transaction in the block. +This makes this placement very lucrative, and disproportionately expensive. -### Out of scope +In addition, since there is no way to give any guarantee on other slots, their pricing has to be low accordingly. -This document does not define an algorithm for a block builder to select a transaction in case of conflicting transactions. +Since there is no easy way to detect cross-dependencies of different transactions, +it is CPU-intensive to find an optimal ordering of transactions. ## Specification @@ -36,39 +46,50 @@ This document does not define an algorithm for a block builder to select a trans * Parameters: -1. transaction: The raw, signed transaction data. Similar to `eth_sendRawTransaction` -2. options: An object containing conditions under which the transaction must be included. -* The "options" param may include any of the following members: - * **knownAccounts**: a map of accounts with expected storage - * The key is account address +1. `transaction`: The raw, signed transaction data. Similar to `eth_sendRawTransaction`. +2. `options`: An object containing conditions under which the transaction must be included. +* The "options" parameter may include any of the following members: + * **knownAccounts**: a mapping of accounts with expected storage + * The key of the mapping is account address + * A special key `balance` defines the expected balance of the account * If the value is **hex string**, it is the known storage root hash of that account. - * If the value is an **object**, then each member is in the format of `"slot": "value"`, which are explicit slot values within that account storage. - both `slot` and `value` are hex values - * a special key `balance` define the expected balance of the account + * If the value is an **object**, then it is a mapping where each member is in the format of `"slot": "value"`. + The `value` fields are explicit slot values of the account's storage. + Both `slot` and `value` are hex-encoded strings. * **blockNumberMin**: [optional] minimal block number for inclusion * **blockNumberMax**: [optional] maximum block number for inclusion * **timestampMin**: [optional] minimum block timestamp for inclusion * **timestampMax**: [optional] maximum block timestamp for inclusion - * **paysConbase**: paysCoinbase[optional] this is not a precondition, but an expected outcome: the caller declares the minmimum amount paid to the coinbase by this transaction (including gas fees and direct payment) - It is only relevant if the API is used to define a "marketplace" for clients to compete on inclusion. + * **paysCoinbase**: [optional] the caller declares the minimum amount paid to the `coinbase` by this transaction, + including gas fees and direct payment. +Before accepting the request, the block-builder or sequencer SHOULD: -* Before accepting the request, the block-builder/sequencer SHOULD: - * If block range was given, check that the block number is within the range. - * If timestamps range was given, check that the block's timestamp is within the range. - * For an address with a storage root hash, validate the current root is unmodified. - * For an address with a list of slots, it should verify that all these slots hold the exact value specified. -* The sequencer should REJECT the request if any address is doesn't pass the above rules. +* Check that the block number is within the block range if the block range value was specified. +* Check that the block's timestamp is within the timestamp range if the timestamp range was specified. +* For all addresses with a specified storage root hash, validate the current root is unmodified. +* For all addresses with a specified slot values mapping, validate that all these slots hold the exact value specified. + +The sequencer should REJECT the request if any address does not pass the above rules. ### Return value -In case of successful inclusion, the call should return the same value as `sendRawTransaction` (namely, the transaction-hash) -In case of failure, it SHOULD return an error with indication of failure reason. -The error code SHOULD be -32003 (transaction rejected) with reason string describing the cause: storage error, out of block/time range, -In case of repeated failures or knownAccounts too large, the error code SHOULD be -32005 (Limit exceeded) with a description of the error +In case of a successful inclusion, the call should return a hash of the newly submitted transaction. +This behaviour is equivalent to the `eth_sendRawTransaction` JSON-RPC API method. + +In case of an immediate failure to validate the transaction's conditions, +the block builder SHOULD return an error with indication of failure reason. -**NOTE:** Even if the transaction was accepted (into the internal mempool), the caller MUST NOT assume block inclusion, and must monitor the blockchain. +The error code SHOULD be "-32003 transaction rejected" with reason string describing the cause: +i.e. storage error, out of block/time range, etc. +In case of repeated failures or `knownAccounts` mapping being too large for the current block builder to handle, +the error code SHOULD be "-32005 limit exceeded" with a description of the error. + +**NOTE:** Same as with the `eth_sendRawTransaction` method, +even if the RPC method call does not resul in an error and the transaction is +initially accepted into the internal block builder's mempool, +the caller MUST NOT assume that a transaction will be included in a block and should monitor the blockchain. ## Sample request: ```json @@ -91,27 +112,33 @@ In case of repeated failures or knownAccounts too large, the error code SHOULD b ] } ``` + ### Possible Use-cases: - **auction market**: -- **alternative to flashbot api**: - The flashbot api requires the builder to simulate the transactions to determine their cross-dependency. This can be cpu consuming. - For high-MEV, this is acceptable, but not for cheap general-purpose account-abstraction transactions. +- **alternative to the Flashbots API**: + The Flashbots API requires the builder to simulate the transactions to determine their cross-dependency. + This can be a CPU-intensive task. + For high-value MEV transactions this high load may be acceptable. + However, it is not acceptable for low-value general-purpose Account Abstraction transactions. ### Limitations -- Callers should not assume that a successul response means the transaction is included - In particular, it is possible that a block re-order might remove the transaction, or cause it to fail, just like any other transaction. +- Callers should not assume that a successful response means the transaction is included. + Specifically, it is possible that a block re-order might remove the transaction or cause it to fail. -### Security Consideration +## Security Consideration -The block-builder should protect itself against abuse of the API, namely, submitting a large # of requests which are known to fail. +The block builder should protect itself against abuse of the API. +Namely, a malicious actor submitting a large number of requests which are known to fail may lead to a denial of service. -Following are suggested mechanisms: +Following is the list of suggested potential mitigation mechanisms: -* **Throttling**: the block builder should allow a maximum rate of rpc calls per sender, and increase - that rate after successful inclusion. repeated rejection of blocks should reduce the allowed rate. +* **Throttling**: the block builder should allow a maximum rate of RPC calls per sender. + The block builder may increase that rate after a successful inclusion. + Repeated rejections of transactions should reduce the allowed rate. * **Arbitrum**-style protection: Arbitrum implemented this API, but they run the storage validation not only against the current block, but also into past 2 seconds. - This prevents abusing the API for MEV, while making it viable for ERC-4337 account validation -* **Fastlane on Polygon** uses it explicitly for ERC-4337, by checking the submitted UserOperations exist on the public mempool (and reject the transaction otherwise) + This prevents abusing the API for MEV, while making it viable for ERC-4337 account validation. +* **Fastlane on Polygon** uses it explicitly for ERC-4337, + by checking the submitted UserOperations exist on the public mempool and rejecting the transaction otherwise. From 4469fa033041e3f41173510fc0d998baf06e6ea9 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Fri, 20 Sep 2024 12:13:15 +0200 Subject: [PATCH 3/5] Add missing sections "Rationale" and "Copyright" --- ERCS/eip-send-tx-conditional.md | 54 +++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/ERCS/eip-send-tx-conditional.md b/ERCS/eip-send-tx-conditional.md index 4ad15c9af3..1cdeb34172 100644 --- a/ERCS/eip-send-tx-conditional.md +++ b/ERCS/eip-send-tx-conditional.md @@ -1,4 +1,4 @@ -```--- +--- eip: send-tx-cond title: Conditional send transaction RPC description: JSON-RPC API for block builders allowing users to express preconditions for transaction inclusion @@ -9,7 +9,6 @@ type: Standards Track category: Interface created: 2024-04-16 --- -``` ## Abstract @@ -48,25 +47,25 @@ it is CPU-intensive to find an optimal ordering of transactions. 1. `transaction`: The raw, signed transaction data. Similar to `eth_sendRawTransaction`. 2. `options`: An object containing conditions under which the transaction must be included. -* The "options" parameter may include any of the following members: - * **knownAccounts**: a mapping of accounts with expected storage - * The key of the mapping is account address - * A special key `balance` defines the expected balance of the account +* The `options` parameter may include any of the following optional members: + * **knownAccounts**: a mapping of accounts with their expected storage slots' values. + * The key of the mapping is account address. + * A special key `balance` defines the expected balance of the account. * If the value is **hex string**, it is the known storage root hash of that account. * If the value is an **object**, then it is a mapping where each member is in the format of `"slot": "value"`. The `value` fields are explicit slot values of the account's storage. Both `slot` and `value` are hex-encoded strings. - * **blockNumberMin**: [optional] minimal block number for inclusion - * **blockNumberMax**: [optional] maximum block number for inclusion - * **timestampMin**: [optional] minimum block timestamp for inclusion - * **timestampMax**: [optional] maximum block timestamp for inclusion - * **paysCoinbase**: [optional] the caller declares the minimum amount paid to the `coinbase` by this transaction, + * **blockNumberMin**: minimal block number for inclusion. + * **blockNumberMax**: maximum block number for inclusion. + * **timestampMin**: minimum block timestamp for inclusion. + * **timestampMax**: maximum block timestamp for inclusion. + * **paysCoinbase**: the caller declares the minimum amount paid to the `coinbase` by this transaction, including gas fees and direct payment. -Before accepting the request, the block-builder or sequencer SHOULD: +Before accepting the request, the block builder or sequencer SHOULD: * Check that the block number is within the block range if the block range value was specified. -* Check that the block's timestamp is within the timestamp range if the timestamp range was specified. +* Check that the block timestamp is within the timestamp range if the timestamp range was specified. * For all addresses with a specified storage root hash, validate the current root is unmodified. * For all addresses with a specified slot values mapping, validate that all these slots hold the exact value specified. @@ -113,20 +112,27 @@ the caller MUST NOT assume that a transaction will be included in a block and sh } ``` -### Possible Use-cases: - -- **auction market**: -- **alternative to the Flashbots API**: - The Flashbots API requires the builder to simulate the transactions to determine their cross-dependency. - This can be a CPU-intensive task. - For high-value MEV transactions this high load may be acceptable. - However, it is not acceptable for low-value general-purpose Account Abstraction transactions. - ### Limitations - Callers should not assume that a successful response means the transaction is included. Specifically, it is possible that a block re-order might remove the transaction or cause it to fail. +## Rationale + +The `knownAccounts` only allows specifying the exact values for storage slots. +While in some cases specifying `minValue` or `maxValue` for a slot could be useful, +it would significantly increase complexity of the proposed API. +Additionally, determining the validity range for a slot value is a non-trivial task for the sender of a transaction. + +One way to provide a more complex rule for a transaction condition is by specifying the `paysCoinbase` parameter, +and issuing a transfer to the `coinbase` address on some condition. + +## Backwards Compatibility + +This is a proposal for a new API method so no backward compatibility issues are expected. +Existing non-standard implementations of `eth_sendRawTransactionConditional` API may need to be modified in order to +become compatible with the standard. + ## Security Consideration The block builder should protect itself against abuse of the API. @@ -142,3 +148,7 @@ Following is the list of suggested potential mitigation mechanisms: This prevents abusing the API for MEV, while making it viable for ERC-4337 account validation. * **Fastlane on Polygon** uses it explicitly for ERC-4337, by checking the submitted UserOperations exist on the public mempool and rejecting the transaction otherwise. + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From 2c9af3eaa4eb71fc0b767fe10f0b7eeeec9de471 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Tue, 22 Oct 2024 15:58:02 +0200 Subject: [PATCH 4/5] Update ERCS/eip-send-tx-conditional.md Co-authored-by: Dror Tirosh --- ERCS/eip-send-tx-conditional.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ERCS/eip-send-tx-conditional.md b/ERCS/eip-send-tx-conditional.md index 1cdeb34172..3b1fbe9d33 100644 --- a/ERCS/eip-send-tx-conditional.md +++ b/ERCS/eip-send-tx-conditional.md @@ -51,6 +51,7 @@ it is CPU-intensive to find an optimal ordering of transactions. * **knownAccounts**: a mapping of accounts with their expected storage slots' values. * The key of the mapping is account address. * A special key `balance` defines the expected balance of the account. + * A special key `code` to expect specific code: `""` to mark "expected not to have code", and `"0xef01…"` for specific eip-7702 delegation. (Other values are irrelevant, since code other code values can't be modified) * If the value is **hex string**, it is the known storage root hash of that account. * If the value is an **object**, then it is a mapping where each member is in the format of `"slot": "value"`. The `value` fields are explicit slot values of the account's storage. From bc8995562f7490e707aa837bebe2cb3d3adb2441 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Tue, 22 Oct 2024 16:03:40 +0200 Subject: [PATCH 5/5] Add 'nonce' and rephrase --- ERCS/eip-send-tx-conditional.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ERCS/eip-send-tx-conditional.md b/ERCS/eip-send-tx-conditional.md index 3b1fbe9d33..61e1e6a22a 100644 --- a/ERCS/eip-send-tx-conditional.md +++ b/ERCS/eip-send-tx-conditional.md @@ -51,7 +51,10 @@ it is CPU-intensive to find an optimal ordering of transactions. * **knownAccounts**: a mapping of accounts with their expected storage slots' values. * The key of the mapping is account address. * A special key `balance` defines the expected balance of the account. - * A special key `code` to expect specific code: `""` to mark "expected not to have code", and `"0xef01…"` for specific eip-7702 delegation. (Other values are irrelevant, since code other code values can't be modified) + * A special key `code` defines the expected code of the account. + Use `""` to indicate that address is expected not to have any code. + Use `"0xef01…"` to indicate a specific EIP-7702 delegation. + * A special key `nonce` defines the expected nonce of the account. * If the value is **hex string**, it is the known storage root hash of that account. * If the value is an **object**, then it is a mapping where each member is in the format of `"slot": "value"`. The `value` fields are explicit slot values of the account's storage.