Skip to content
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

Add EIP: Read BLOCKHASH from storage and update cost #8578

Merged
merged 36 commits into from
May 29, 2024
Merged
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
36a6af7
eip/initial-draft
gabrocheleau May 18, 2024
df5dbc3
adjust title
gabrocheleau May 18, 2024
026d264
adjust number
gabrocheleau May 18, 2024
38d94e2
adjust EIP number
gabrocheleau May 20, 2024
1a45332
chore: update link to eth magicians
gabrocheleau May 20, 2024
5879ff8
chore: add require and minor adjustments
gabrocheleau May 20, 2024
14a872c
chore: adjust should/must for retrieving from storage and execution w…
gabrocheleau May 20, 2024
c3168f0
chore: adjust formatting
gabrocheleau May 20, 2024
e800e87
chore: add history serve window constant and adjust verkle fork block…
gabrocheleau May 20, 2024
72ff886
eip 7709: add warm storage slot for newly inserted blockhash
gabrocheleau May 21, 2024
9a4c141
make history storage address tbd
gabrocheleau May 22, 2024
f3fb509
update as per comments
gabrocheleau May 22, 2024
9ee85fe
Update EIPS/eip-7709.md
gabrocheleau May 26, 2024
e925fba
eip-7709: address review
gabrocheleau May 26, 2024
755fb77
Merge branch 'eip/verkle-blockhash-ring-buffer' of https://github.com…
gabrocheleau May 26, 2024
a7e97d4
eip-7709: linting error
gabrocheleau May 26, 2024
100a05e
refactor the eip
g11tech May 27, 2024
2fb7c0e
lint
g11tech May 27, 2024
c730a3a
some more clarity in test cases
g11tech May 27, 2024
e29aae4
some more testcase clarity
g11tech May 27, 2024
6c56f5f
typo
g11tech May 27, 2024
17af009
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
ffb76d1
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
571f149
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
8cd03d7
Update EIPS/eip-7709.md
g11tech May 27, 2024
066be67
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
dfc2b69
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
1bafa49
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
dc246c4
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
21e0c29
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
9ae6d5c
clarify activation
g11tech May 27, 2024
37a83cb
Update EIPS/eip-7709.md
gabrocheleau May 27, 2024
87f3ba0
Update EIPS/eip-7709.md
g11tech May 28, 2024
5420e02
Update EIPS/eip-7709.md
g11tech May 28, 2024
e4f8c11
Update EIPS/eip-7709.md
g11tech May 28, 2024
8110463
feedback
g11tech May 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions EIPS/eip-7709.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
eip: 7709
title: Read BLOCKHASH from storage and update cost
description: Read the `BLOCKHASH (0x40)` opcode from the EIP-2935 system contract storage and adjust its gas cost to reflect storage access.
author: Vitalik Buterin (@vbuterin), Tomasz Stanczak (@tkstanczak), Guillaume Ballet (@gballet), Gajinder Singh (@g11tech), Tanishq Jasoria (@tanishqjasoria), Ignacio Hagopian (@jsign), Jochem Brouwer (@jochem-brouwer), Gabriel Rocheleau (@gabrocheleau)
discussions-to: https://ethereum-magicians.org/t/eip-7709-read-blockhash-opcode-from-storage-and-adjust-gas-cost/20052
status: Draft
type: Standards Track
category: Core
created: 2024-05-18
requires: 2935
---

## Abstract

Update the `BLOCKHASH (0x40)` opcode to read and serve from the system contract storage and charge the **additional** (cold or warm) storage costs.

## Motivation

The `BLOCKHASH (0x40)` opcode currently assumes that the client has knowledge of the previous blocks, which in Verkle [EIP-6800](./eip-6800.md) would prevent stateless execution. However with [EIP-2935](./eip-2935.md) blockhashes can be retrieved and served from its system contract storage which allows Verkle blocks to include a storage access witness for stateless execution.

## Specification

| Parameter | Value |
| ------------------------- | ------ |
| `FORK_TIMESTAMP` | TBD |
| `HISTORY_STORAGE_ADDRESS` | TBD |
| `BLOCKHASH_SERVE_WINDOW` | `256` |

The `BLOCKHASH` opcode semantics remains the same as before. From the `fork_block` (defined as `fork_block.timestamp >= FORK_TIMESTAMP and fork_block.parent.timestamp < FORK_TIMESTAMP`), the `BLOCKHASH` instruction should be updated to resolve block hash in the following manner:

```python
def resolve_blockhash(block: Block, state: State, arg: uint64):
# note that outside the BLOCKHASH_SERVE_WINDOW we continue to return 0
# despite the 2935 history contract being able to serve more hashes
if arg >= block.number or (arg + BLOCKHASH_SERVE_WINDOW) < block.number
return 0

# performs an sload on arg % HISTORY_SERVE_WINDOW including gas charges,
# warming effects as well as execution accesses
#
# note that the `BLOCKHASH_SERVE_WINDOW` and the 2935 ring buffer window
# `HISTORY_SERVE_WINDOW` for slot calculation are different
return state.load_slot(HISTORY_STORAGE_ADDRESS, arg % HISTORY_SERVE_WINDOW)
```

ONLY if the `arg` is within the correct `BLOCKHASH` window, clients can choose to either

* do a direct `SLOAD` from state, or
* do a system call to [EIP-2935](./eip-2935.md) contract via its `get` mechanism (caller other than `SYSTEM_ADDRESS`) or
* serve from memory or as per current designs if maintaining requisite history (full clients for e.g.)

However the entire semantics and after effects of the `SLOAD` operation needs to be applied as per the current fork if the `arg` is within the correct `BLOCKHASH` window:

* `SLOAD` gas costs (cold or warm) for the `arg % HISTORY_SERVE_WINDOW` slot.
* `SLOAD` after effects on the slot (warming the slot)
* `SLOAD` accesses added to execution witnesses if Verkle ([EIP-6800](./eip-6800.md) and [EIP-4762](./eip-4762.md)) is activated

### Activation

This EIP specifies the transition to the new logic assuming that [EIP-2935](./eip-2935.md) has been activated:

* sufficiently ahead of this EIP's activation (>= `BLOCKHASH_SERVE_WINDOW`) or
* at genesis for testnets/devnets where this EIP could also be activated at genesis

The current proposal is to activate this EIP with Verkle to allow for stateless execution of the block.

### Gas costs

As described above, if the `arg` to be resolved is within the correct window, the corresponding `SLOAD` charges and accesses are to be applied for the slot `arg % HISTORY_SERVE_WINDOW`. Note that the `HISTORY_SERVE_WINDOW` and `BLOCKHASH_SERVE_WINDOW` are different.

### Reading from the System contract

Even if the clients choose to resolve `BLOCKHASH` through system call to [EIP-2935](./eip-2935.md) contract, the gas cost for the system code execution (and also the code witnesses if Verkle activated) is not applied. Only the effect of `SLOAD` is applied as described above.
g11tech marked this conversation as resolved.
Show resolved Hide resolved

## Rationale

* The reason behind the updated gas cost is to match the real operation, which is equivalent to an `SLOAD`.
g11tech marked this conversation as resolved.
Show resolved Hide resolved
* The [EIP-2935](./eip-2935.md) system contract execution charges (and accesses) are not applied to keep the gas low and to keep things simple for clients which choose to resolve `BLOCKHASH` in other ways (directly or though memory/maintained history)
g11tech marked this conversation as resolved.
Show resolved Hide resolved

Note that `BLOCKHASH` opcode only serves a limited `BLOCKHASH_SERVE_WINDOW` to be backward compatible (and to not extend the above exemptions). For deeper accesses one will need to directly call [EIP-2935](./eip-2935.md) system contract which will lead to a normal contract execution (as well as charges and accesses)

## Backwards Compatibility

This EIP introduces a significant increase in the cost of `BLOCKHASH`, which could break use-cases that rely on the previous gas cost. Also, this EIP introduces a breaking change in the case where less than `BLOCKHASH_SERVE_WINDOW` elapse between the [EIP-2935](./eip-2935.md) fork and this EIP's fork (unless [EIP-2935](./eip-2935.md) is activated in genesis for e.g. in testnets/devnets) as the [EIP-2935](./eip-2935.md) system contract would not have saved the required history.

## Test Cases

* If `BLOCKHASH` is not called or there is no [EIP-2935](./eip-2935.md) contract call by any transaction, only the [EIP-2935](./eip-2935.md) system update of the parent hash shows up in witnesses if Verkle is activated.
* If `BLOCKHASH` is called, there MUST be a storage access gas charge (and corresponding access witness if Verkle is activated) for the storage slot but ONLY if the `BLOCKHASH` query is for the last `BLOCKHASH_SERVE_WINDOW` ancestors. This is irrespective of how the client chooses to resolve the `BLOCKHASH` (directly, via system contract or via memory)
* The gas cost for each `BLOCKHASH` operation should still be charged, in addition to the `SLOAD` cost of each lookup (if performed)
* If the [EIP-2935](./eip-2935.md) contract is called directly (i.e. not through `BLOCKHASH`), then the witness and gas costs (including those related to contract code) are applied as per normal contract execution of the current fork.
* `BLOCKHASH` should be consistently resolved if this EIP is activated correctly `>= BLOCKHASH_SERVE_WINDOW` after [EIP-2935](./eip-2935.md)

## Security Considerations

No security considerations other than the ones contained in [EIP-2935](./eip-2935.md) are determined as of now.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
Loading