Skip to content

Commit

Permalink
Update EIP-7069: Rename and update semantics
Browse files Browse the repository at this point in the history
Merged by EIP-Bot.
  • Loading branch information
pdobacz authored Mar 22, 2024
1 parent 8135bcc commit 30a52d0
Showing 1 changed file with 34 additions and 26 deletions.
60 changes: 34 additions & 26 deletions EIPS/eip-7069.md
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
Expand All @@ -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.

Expand Down Expand Up @@ -50,31 +50,34 @@ 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.
- **NOTE**: When implemented in EOF, stack underflow check is done during stack validation and runtime check is omitted.
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. Fail with status code `1` returned on stack if any of the following is true (only gas charged until this point is consumed):
- Gas available to callee at this point is less than `MIN_CALLEE_GAS`.
- Balance of the current account is less than `value`.
- Current call stack depth equals `1024`.
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`:

Expand Down Expand Up @@ -114,10 +117,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.
The 63/64th rule is still applied, but
- At least `MIN_RETAINED_GAS` gas is retained prior to executing the callee,
- At least `MIN_CALLEE_GAS` gas is available to the callee.

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, keeping the call stack depth check involves no change affecting legacy code.

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 constraining ourselves by dependency of this check on current gas limits.

### Output buffers

Expand All @@ -129,18 +135,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 scenarios preserve unused gas and continue being indistinguishable to the caller.

### 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.

This comment has been minimized.

Copy link
@Ooonryy

Ooonryy Mar 23, 2024

Алекс Берегзаси ( @axic ), Пол Дворзански ( @poemm ), Джаред Васингер ( @jwasinger ), Кейси Детрио ( @cdetrio ), Павел Былица ( @chfast ), Чарльз Купер ( @charles-cooper ), «EIP-5656: MCOPY — Инструкция по копированию памяти [ПРОЕКТ], « Предложения по улучшению Ethereum» , вып. 5656, февраль 2021 г. [Онлайн-сериал]. Доступно:


### `CALLCODE`

Expand Down

0 comments on commit 30a52d0

Please sign in to comment.