Automatically merged updates to draft EIP(s) 2733 (#2954)

Hi, I'm a bot! This change was automatically merged because:

 - It only modifies existing Draft or Last Call EIP(s)
 - The PR was approved or written by at least one author of each modified EIP
 - The build is passing
This commit is contained in:
lightclient 2020-09-07 23:38:25 -06:00 committed by GitHub
parent 75314be8ac
commit 48d4fe8e94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -12,7 +12,7 @@ requires: 2718
## Simple Summary
Creates a new transaction type which executes a package of one or more
transactions.
transactions, while passing status information to subsequent transactions.
## Abstract
After `FORK_BLOCK`, a new [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)
@ -25,18 +25,23 @@ the next transaction.
Meta-transaction relay contracts have historically been designed to catch
reversions in their inner transactions by only passing a portion of the
available gas to the subcall. This has been considered bad practice for a long
time, but in the case of untrust subcalls -- it is the only available solution.
Transaction packages are an alternative solution which allow multiple
transactions to be bundled into one package and executed atomically.
time, but in the case of untrusted subcalls, like the ones relay contracts
make, it is the only available solution. Transaction packages are an
alternative that allow multiple transactions to be bundled into one package and
executed atomically, similarly to how relay contracts operate. Transactions are
able to pass their result to subsequent transactions. This allows for
conditional workflows based on the outcome of previous transactions. Although
this functionality is already possible as described above, workflows using
transaction packages are more robust, because they are protected from future
changes to the gas schedule.
## Specification
### Definitions
```
N = TBD transaction type number
INTRINSIC_COST = TBD
TOTAL_COST = INTRINSIC_COST + inner_txs.reduce(|itx, acc| acc += itx.value + itx.gas_price * itx.gas_limit)
TOTAL_COST = INTRINSIC_COST + inner_txs.reduce(|itx, acc| acc += itx.value + tx.gas_price * itx.gas_limit)
TOTAL_GAS_LIMIT = inner_txs.reduce(|itx, acc| acc += itx.gas_limit)
TX_HASH = hash of transaction as defined below
SENDER = ecrecover(hash, v, r, s)
@ -47,21 +52,22 @@ RESULT = result as defined below for the previous transaction, empty if its the
After `FORK_BLOCK`, a new [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)
transaction type `N` will be interpreted as follows:
`rlp([N, rlp([nonce, v, r, s, [inner_tx_0, ..., inner_tx_n]])`
`rlp([N, [v, r, s, chain_id, nonce, gas_price, [inner_tx_0, ..., inner_tx_n]])`
where `inner_tx_n` is defined as:
`[chain_id, to, value, data, gas_limit, gas_price]`
`[to, value, data, gas_limit]`
### Hashing
The hash of transaction type `N` is defined to be the Keccak-256 hash of the
rlp encoding of the entire transaction with `v`, `r`, and `s` values omitted.
rlp encoding of the entire transaction with `v`, `r`, and `s` values set to
zero.
### Results
Subsequent transactions will be able to receive the result of the previous
transaction via `RETURNDATACOPY (0x3E)` in first frame of exeuction, before
making any subcalls. Each element except the last will be `0`-padded left to 32
bytes.
making any subcalls. Each element, except the last, will be `0`-padded left to
32 bytes.
| Name | Type | Description |
|---|---|---|
@ -72,27 +78,25 @@ bytes.
| `return_value` | bytes | The return value of the previous transaction
### Validation
* (v, r, s) are a valid signature of the hash of the transaction
* The nonce is one greater than recovered address' current nonce
* The recovered address has a balance of at least `TOTAL_COST`
* The `TOTAL_GAS_LIMIT` is less than the current block's `gas_limit`
### Execution
Transaction packages should be executed as follows:
1. Deduct `TOTAL_COST` from `SENDER`'s balance
2. Execute the first inner transaction in the list
3. Refund any unused `gas`
4. If there are no more transaction, stop
5. Compute `RESULT` for the previously executed transaction
6. Prepare `RESULT` to be available via return opcodes in the next
4. Record all state changes, logs, and the receipt
5. If there are no more transaction, stop
6. Compute `RESULT` for the previously executed transaction
7. Prepare `RESULT` to be available via return opcodes in the next
transaction's first frame
7. Execute the transaction
8. Execute the next transaction
9. Goto `3`
## Rationale
#### Non-recursive inner transactions
@ -102,16 +106,12 @@ suppose there is a transaction type which can become invalid after a certain
block number. It would be beneficial to support those types of transactions
within a package, but the complexity of this EIP would dramatically increase.
#### Appending result data to transaction input data
An alternative to using return opcodes to propagate `RESULT` would be to append
the `RESULT` to the subsequent transaction's `data` field. Unfortunately, in
many cases contracts generated using Solidity [will
fail](https://solidity.readthedocs.io/en/v0.6.0/contracts.html#overload-resolution-and-argument-matching)
to resolve the intended function if additional data is present. Another
alternative is introducing new opcodes to expose the result data were not
proposed.
to resolve the intended function if additional data is present.
## Backwards Compatibility
Contracts which rely on `ORIGIN (0x32) == CALLER (0x33) && RETURNDATASIZE