-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Update EIP-2935: Move to Draft #8166
Merged
Merged
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
dcc901f
verkle-friendly eip2935
gballet a2fc8bf
fix some linter issues
gballet bdc951c
modify the behavior to persist entire history window on fork block (#2)
g11tech 177bba3
fix some of the formatting issues
gballet 007aa7e
2935 cleanup
g11tech 8ee0458
address linter issues
g11tech 5dfe9b9
cleanup eip98 ref
g11tech d022729
apply update
g11tech 1bf7b83
Apply suggestions from code review
g11tech 052181f
improve the specification using the pseudocode
g11tech 23333d7
further clarification
g11tech 74ed493
use constant
g11tech 8e4a928
eip 158 handling
g11tech f37a2b3
apply feedback
g11tech a06c418
fix typo
g11tech 1aa15f2
linter
g11tech a4c79a5
fix condition
g11tech 941d3be
update
g11tech 8e3730f
Update the eip to store in ring buffer instead of serial storage and …
g11tech 2b73ecb
extend history retention to 8192 and modify blockhash to charge addit…
g11tech File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -1,15 +1,16 @@ | ||||||||
--- | ||||||||
eip: 2935 | ||||||||
title: Save historical block hashes in state | ||||||||
author: Vitalik Buterin (@vbuterin), Tomasz Stanczak (@tkstanczak) | ||||||||
description: store previous block hashes as storage slots of a system contract to allow for stateless execution | ||||||||
author: Vitalik Buterin (@vbuterin), Tomasz Stanczak (@tkstanczak), Guillaume Ballet (@gballet), Gajinder Singh (@g11tech), Tanishq Jasoria (@tanishqjasoria) | ||||||||
discussions-to: https://ethereum-magicians.org/t/eip-2935-save-historical-block-hashes-in-state/4565 | ||||||||
status: Stagnant | ||||||||
status: Draft | ||||||||
type: Standards Track | ||||||||
category: Core | ||||||||
created: 2020-09-03 | ||||||||
--- | ||||||||
|
||||||||
## Simple Summary | ||||||||
## Abstract | ||||||||
|
||||||||
Store historical block hashes in a contract, and modify the `BLOCKHASH (0x40)` opcode to read this contract. | ||||||||
|
||||||||
|
@@ -26,22 +27,65 @@ | |||||||
|
||||||||
| Parameter | Value | | ||||||||
| - | - | | ||||||||
| `FORK_BLKNUM` | TBD | | ||||||||
| `FORK_TIMESTAMP` | TBD | | ||||||||
| `HISTORY_STORAGE_ADDRESS` | `0xfffffffffffffffffffffffffffffffffffffffe`| | ||||||||
| `HISTORY_SERVE_WINDOW` | `256` | | ||||||||
|
||||||||
At the start of processing any block where `block.number > FORK_BLKNUM` (ie. before processing any transactions), run `sstore(HISTORY_STORAGE_ADDRESS, block.number - 1, block.prevhash)`. | ||||||||
At the start of processing any block where `block.timestamp > FORK_TIMESTAMP` (ie. before processing any transactions), update the history in the following way: | ||||||||
g11tech marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
||||||||
When `block.number > FORK_BLKNUM + 256`, change the logic of the `BLOCKHASH` opcode as follows: if `FORK_BLKNUM <= arg < block.number`, return `sload(HISTORY_STORAGE_ADDRESS, arg)`. Otherwise return 0. | ||||||||
```python | ||||||||
def process_block_hash_history(block :Block, state: State): | ||||||||
if block.timestamp >= FORK_TIMESTAMP: | ||||||||
state.insert_slot(HISTORY_STORAGE_ADDRESS, block.number-1, block.parent.hash) | ||||||||
|
||||||||
# If this is the first fork block, add the parent's direct 255 ancestors as well | ||||||||
if block.parent.timestamp < FORK_TIMESTAMP: | ||||||||
ancestor = block.parent | ||||||||
for i in range(HISTORY_SERVE_WINDOW - 1): | ||||||||
# stop at genesis block | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The wording here is confusing, I suggest the following:
Suggested change
|
||||||||
if ancestor.number == 0: | ||||||||
break | ||||||||
g11tech marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
||||||||
ancestor = ancestor.parent | ||||||||
state.insert_slot(HISTORY_STORAGE_ADDRESS, ancestor.number, ancestor.hash) | ||||||||
``` | ||||||||
|
||||||||
Note that if this is the fork block, then it persists the additional requisite history that could be needed while resolving `BLOCKHASH` opcode for all of the `HISTORY_SERVE_WINDOW` ancestors (up untill genesis). | ||||||||
g11tech marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
||||||||
For resolving the `BLOCKHASH` opcode this fork onwards (`block.timestamp > FORK_TIMESTAMP`), switch the logic to: | ||||||||
g11tech marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
||||||||
```python | ||||||||
def resolve_blockhash(block: Block, state: State, arg: uint64): | ||||||||
assert(arg < block.number) | ||||||||
g11tech marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
return state.load_slot(HISTORY_STORAGE_ADDRESS, arg) | ||||||||
``` | ||||||||
|
||||||||
Edge cases: | ||||||||
|
||||||||
* For the fork to be activated at genesis, no history is written to the genesis state, and at the start of block `1`, genesis hash will be written as a normal operation to slot `0`. | ||||||||
* for activation at block `1`, only genesis hash will be written at slot `0` as there is no additional history that needs to be persisted. | ||||||||
* for activation at block `32`, block `31`'s hash will be written to slot `31` and additonal history for `0..30`'s hashes will be persisted, so all in all `0..31`'s hashes. | ||||||||
|
||||||||
### EIP-158 exception | ||||||||
Check failure on line 69 in EIPS/eip-2935.md GitHub Actions / EIP Walidatorthe first match of the given pattern must be a link
|
||||||||
|
||||||||
This address is currently exempt from [EIP-158](./eip-158.md) cleanup in Kaustinen Verkle Testnet but there are two ways this could be addressed before this EIP is adopted by ACD: | ||||||||
|
||||||||
* Update the nonce to 1 in the fork block, or | ||||||||
* Deploy a contract à la [EIP-4788](./eip-4788.md) with `BLOCKHASH` opcode delegating call to this contract with appropriate args. | ||||||||
|
||||||||
While the second option looks more elegant, but it has higher complexity as well as gas consumption considerations. | ||||||||
g11tech marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
|
||||||||
## Rationale | ||||||||
|
||||||||
Very similar ideas were proposed before in EIP-98 and EIP-210. This EIP is a simplification, removing two sources of needless complexity: | ||||||||
Very similar ideas were proposed before in [EIP-210](./eip-210.md) et al. This EIP is a simplification, removing two sources of needless complexity: | ||||||||
|
||||||||
1. Having a tree-like structure with multiple layers as opposed to a single list | ||||||||
2. Writing the EIP in EVM code | ||||||||
|
||||||||
The former was intended to save space. Since then, however, storage usage has increased massively, to the point where even eg. 5 million new storage slots are fairly negligible compared to existing usage. The latter was intended as a first step toward "writing the Ethereum protocol in EVM" as much as possible, but this goal has since been de-facto abandoned. | ||||||||
|
||||||||
Storing of all last `HISTORY_SERVE_WINDOW` block hashes alleviates the need to detect fork activation height to transition to the new logic as the entire required history will be available from the first block of the fork itself. The cost of doing so is marginal considering the `HISTORY_SERVE_WINDOW` being small. | ||||||||
|
||||||||
## Backwards Compatibility | ||||||||
|
||||||||
The range of `BLOCKHASH` is increased by this opcode, but behavior within the previous 256-block range remains unchanged. | ||||||||
|
@@ -50,13 +94,14 @@ | |||||||
|
||||||||
TBD | ||||||||
|
||||||||
## Implementation | ||||||||
## Reference Implementation | ||||||||
|
||||||||
TBD | ||||||||
* PR 28878 of go-ethereum | ||||||||
* Active on verkle-gen-devet-3 for its verkle implementation | ||||||||
|
||||||||
## Security Considerations | ||||||||
|
||||||||
Adding ~2.5 million storage slots per year bloats the state somewhat (but not much relative to the hundreds of millions of existing state objects). However, this EIP is not intended to be permanent; when eth1 is merged into eth2, the BLOCKHASH opcode would likely be repurposed to use eth2's built-in history accumulator structure (see [phase 0 spec](https://github.com/ethereum/annotated-spec/blob/master/phase0/beacon-chain.md#slots_per_historical_root)). | ||||||||
Adding ~2.5 million storage slots per year bloats the state somewhat but not much relative to the hundreds of millions of existing state objects. | ||||||||
|
||||||||
## Copyright | ||||||||
|
||||||||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This conflicts with the system address from EIP-4788.