-
Notifications
You must be signed in to change notification settings - Fork 6k
Update EIP-7069: Rename and update semantics #8287
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
Changes from 7 commits
520ebb6
2cbfc32
5786b32
260828e
39c6e05
c3de483
a26d3a4
c3b528a
743a3fb
de40636
92a768f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| --- | ||
| eip: 7069 | ||
| title: Revamped CALL instructions | ||
| description: Introduce CALL2, DELEGATECALL2 and STATICCALL2 with simplified semantics | ||
| description: Introduce EXTCALL, EXTDELEGATECALL and EXTSTATICCALL with simplified semantics | ||
| author: Alex Beregszaszi (@axic), Paweł Bylica (@chfast), Danno Ferrin (@shemnon), Andrei Maiboroda (@gumb0), Charles Cooper (@charles-cooper) | ||
| discussions-to: https://ethereum-magicians.org/t/eip-revamped-call-instructions/14432 | ||
| status: Draft | ||
|
|
@@ -13,7 +13,7 @@ requires: 150, 211, 214, 2929 | |
|
|
||
| ## Abstract | ||
|
|
||
| Introduce three new call instructions, `CALL2`, `DELEGATECALL2` and `STATICCALL2`, with simplified semantics. Introduce another instruction, `RETURNDATALOAD` for loading a word from return data into stack. The existing call instructions remain unchanged. | ||
| Introduce three new call instructions, `EXTCALL`, `EXTDELEGATECALL` and `EXTSTATICCALL`, with simplified semantics. Introduce another instruction, `RETURNDATALOAD` for loading a word from return data into stack. The existing call instructions remain unchanged. | ||
|
|
||
| The new instructions do not allow specifying a gas limit, but rather rely on the "63/64th rule" ([EIP-150](./eip-150.md)) to limit gas. An important improvement is the rules around the "stipend" are simplified, and callers do not need to perform special calculation whether the value is sent or not. | ||
|
|
||
|
|
@@ -50,31 +50,32 @@ Lastly, the introduction of the `RETURNDATA*` instructions ([EIP-211](./eip-211. | |
|
|
||
| We introduce four new instructions: | ||
|
|
||
| - `CALL2` (`0xf8`) with arguments `(target_address, input_offset, input_size, value)` | ||
| - `DELEGATECALL2` (`0xf9`) with arguments `(target_address, input_offset, input_size)` | ||
| - `STATICCALL2` (`0xfb`) with arguments `(target_address, input_offset, input_size)` | ||
| - `EXTCALL` (`0xf8`) with arguments `(target_address, input_offset, input_size, value)` | ||
| - `EXTDELEGATECALL` (`0xf9`) with arguments `(target_address, input_offset, input_size)` | ||
| - `EXTSTATICCALL` (`0xfb`) with arguments `(target_address, input_offset, input_size)` | ||
| - `RETURNDATALOAD` (`0xf7`) with argument `offset` | ||
|
|
||
| Execution semantics of `*CALL2`: | ||
| Execution semantics of `EXT*CALL`: | ||
|
|
||
| 1. Charge `WARM_STORAGE_READ_COST` (100) gas. | ||
| 2. Pop required arguments from stack, fail with error on stack underflow. | ||
| 4. If `value` is non-zero: | ||
| 3a. Fail with error if the current frame is in `static-mode`. | ||
| 3b. Fail with error if the balance of the current account is less than `value`. | ||
| 3c. Charge `CALL_VALUE_COST` gas. | ||
| 2. Pop required arguments from stack, halt with exceptional failure on stack underflow. | ||
| 3. If `value` is non-zero: | ||
| - Halt with exceptional failure if the current frame is in `static-mode`. | ||
| - Charge `CALL_VALUE_COST` gas. | ||
| 4. Peform (and charge for) memory expansion using `[input_offset, input_size]`. | ||
| 5. If `target_address` is not in the `warm_account_list`, charge `COLD_ACCOUNT_ACCESS - WARM_STORAGE_READ_COST` (2500) gas. | ||
| 6. If `target_address` is not in the state and the call configuration would result in account creation, charge `ACCOUNT_CREATION_COST` (25000) gas. | ||
| - The only such case in this EIP is if `value` is non-zero. | ||
| 7. Calculate the gas available to callee as caller's remaining gas reduced by `max(ceil(gas/64), MIN_RETAINED_GAS)` (`MIN_RETAINED_GAS` is 5000). | ||
| 8. Fail with error if the gas available to callee at this point is less than `MIN_CALLEE_GAS` (2300). | ||
| 9. Perform the call with the available gas and configuration. | ||
| 10. Push a status code on the stack: | ||
| 11a. `0` if the call was successful. | ||
| 11b. `1` if the call has reverted. | ||
| 11c. `2` if the call has failed. | ||
| 11. Gas not used by the callee is returned to the caller. | ||
| 7. Calculate the gas available to callee as caller's remaining gas reduced by `max(floor(gas/64), MIN_RETAINED_GAS)`. | ||
| 8. Halt with exceptional failure if the gas available to callee at this point is less than `MIN_CALLEE_GAS`. | ||
|
||
| 9. If `value` is non-zero, fail lightly if the balance of the current account is less than `value` (push `1` on the stack, only consume gas charged until this point). | ||
pdobacz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 10. Fail lightly if call stack depth equals `1024` (push `1` on the stack, only consume gas charged until this point). | ||
pdobacz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 11. Perform the call with the available gas and configuration. | ||
| 12. Push a status code on the stack: | ||
| - `0` if the call was successful. | ||
| - `1` if the call has reverted (also can be pushed earlier in a light failure scenario). | ||
| - `2` if the call has failed. | ||
| 13. Gas not used by the callee is returned to the caller. | ||
|
|
||
| Execution semantics of `RETURNDATALOAD`: | ||
|
|
||
|
|
@@ -114,10 +115,13 @@ Before the 63/64th rule was introduced, it was required to calculate available g | |
|
|
||
| We have changed the ruleset: | ||
|
|
||
| 1. Removed the call depth check. | ||
| 2. Use the 63/64th rule, but | ||
| 2a. ensure that at least 5000 gas is retained prior to executing the callee, | ||
| 2b. ensure that at least 2300 gas is available to the callee. | ||
| 1. Use the 63/64th rule, but | ||
| - Ensure that at least `MIN_RETAINED_GAS` gas is retained prior to executing the callee, | ||
| - Ensure that at least `MIN_CALLEE_GAS` gas is available to the callee. | ||
pdobacz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Removing the call stack depth check was initially considered, but this would be incompatible with the original `*CALL` instructions, as well as `CREATE*` instructions, which can be intertwined with the new `EXT*CALL` instructions in the call stack. As such, keepeing the call stack depth involves the least change for legacy code. | ||
pdobacz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Also, we find the simple (as opposed to the complex 63/64th rule) hard cap reassuring, that the call stack depth is limited, in case the gas rules can be bypassed. Lastly, the amount of gas to reach depth of 1024 is huge, but not absurdly huge and we want to avoid constrain ourselves by relying this check on current gas limits. | ||
pdobacz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### Output buffers | ||
|
|
||
|
|
@@ -129,18 +133,20 @@ Current call instructions return a boolean value to signal success: 0 means fail | |
|
|
||
| We change the value from boolean to a status code, where `0` signals success and thus it will be possible to introduce more non-success codes in the future, if desired. | ||
|
|
||
| Status code `1` is used for both reverts coming from the callee frame and light failures encountered in the execution of the instructions. The reason for combining them is keeping the semantics similar to the original CALLs - both scenario preserve unused gas and continue being indistinguishable to the caller. | ||
pdobacz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ### Parameter order | ||
|
|
||
| The order of parameters has been changed to move the `value` field to be the last. This allows the instructions to have identical encoding with the exception of the last parameter, and simplifies EVM and compiler implementations slightly. | ||
|
|
||
| ### Opcode encoding | ||
|
|
||
| Instead of introducing three new `*CALL2` opcodes we have discussed a version with an immediate configuration byte (flags). There are two main disadvantages to this: | ||
| Instead of introducing three new `EXT*CALL` opcodes we have discussed a version with an immediate configuration byte (flags). There are two main disadvantages to this: | ||
|
|
||
| 1. Some combination of flags may not be useful/be invalid, and this increases the testing/implementation surface. | ||
| 2. The instruction could take variable number of stack items (i.e. `value` for `CALL2`) would be a brand new concept no other instruction has. | ||
| 2. The instruction could take variable number of stack items (i.e. `value` for `EXTCALL`) would be a brand new concept no other instruction has. | ||
|
|
||
| It is also useful to have these as new opcodes instead of modifying the exiting CALL series inside of EOF. This creates an "escape hatch" in case gas observability needs to be restored to EOF contracts. This is done by adding the GAS and original CALL series opcodes to the valid EOF opcode list. | ||
| It is also useful to have these as new opcodes instead of modifying the existing CALL series inside of EOF. This creates an "escape hatch" in case gas observability needs to be restored to EOF contracts. This is done by adding the GAS and original CALL series opcodes to the valid EOF opcode list. | ||
|
|
||
| ### `CALLCODE` | ||
|
|
||
|
|
||
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.
It seems at this point EIP tries to maintain compatibility with both legacy and EOF, so maybe
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.
The idea is for this EIP to be fully legacy-complete and EOF-independent. EOF (Megaspec) lists the differences required it to be EOF-complete (which is lack of runtime stack underflow check and banning new opcodes in legacy).
Is there any other piece which is EOF-only in this EIP?
(this is just a question to your comment, I have no objections towards adding this note for completeness, and I'll add it)