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: Delayed Execution Layer State Root #9241

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

charlie-paradigm
Copy link

This EIP implements a delayed state root. It is ready for draft status and discussion.

@github-actions github-actions bot added c-new Creates a brand new proposal s-draft This EIP is a Draft t-core labels Jan 14, 2025
@eth-bot
Copy link
Collaborator

eth-bot commented Jan 14, 2025

File EIPS/eip-7862.md

Requires 1 more reviewers from @g11tech, @lightclient, @SamWilsn

@github-actions github-actions bot added the w-ci Waiting on CI to pass label Jan 14, 2025
@eth-bot eth-bot added e-consensus Waiting on editor consensus e-review Waiting on editor to review labels Jan 14, 2025
@eth-bot eth-bot changed the title Add EIP: State Root Delay Add EIP: Delayed Execution Layer State Root Jan 14, 2025
EIPS/eip-xxxx.md Outdated

The EL `state_root` must be computed by block builders (and verified by relays, validators, and light clients) in near-real-time. This computation accounts for a large fraction of block production and verification time, especially in an MEV-Boost environment. This overhead is also a challenge for efforts to enable real-time ZK proving of the chain.

By delaying the EL `state_root` reference by one block, we can remove EL `state_root` calculation overhead from the critical path of block production. Instead, clients can pipeline calculation of block `n-1`'s EL `state_root` during the idle slot time of block `n`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idle slot time of block n.

I think this is n-1. At n-1, the block arrives around the 4th second of the slot, you verify everything except the state root, and then you have 8 more seconds in n-1 to verify the state root

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in this design the EL clients are calculating the state root of block n-1 while building block n at the same time, and this process occurs during the last 8 seconds of block n-1. Is this correct?

Copy link
Contributor

@g11tech g11tech Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea either change it to n-1 or it should read:

Instead, clients can pipeline calculation of block n's EL state_root during the idle slot time of block n.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be clearer to specify post-state root, rather than the parameter.

"Instead, clients can pipeline calculation of block n-1's EL post-state root during the idle slot time of block n."

Would you guys be happy with this?

To clarify what happens is that:

When n-1 arrives, it contains the EL pre-state root of n-1.

While waiting for block n to arrive, the client can calculate the post-state root of n-1 (equivalently, pre-state of n).

When block n arrives, it can verify that it contains the correct post-state of n-1 (equivalently, pre-state of n).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so all we are delaying for the attesting/verifying validator is the stateroot calc? how significant is that as percentate of block building time?

we could infact delay the entire execution for the attesting/verifying validator (which means they can execute/verify bigger blocks on the commodity hardware while the specialized builders can build a gas chugging block

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can delay attesting unless we do eip7732

EIPS/eip-xxxx.md Outdated
- The actual new state root resulting from block `n` will only appear in block `n+1`.
3. **Proactive Computation of Post-state Root**:
- To fully realize latency benefits, clients should compute the post-state root of block `n-1` during the idle time of slot `n`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

during the idle time of slot n.

Same. I think this would be n-1, not n

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that I agree.

You could say "compute the pre-state root of n during the idle slot time of n"

and that might be clearer?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at this again and think what you have is fine. If we want to be clearer, we could rephrase it as the following:

"As a proposer/builder for n, assuming it receives a block for n-1 during slot n-1, to fill in the state_root field, they should compute the post-state root at n-1 during the idle time of n-1"

I agree with what you said here: #9241 (comment)

EIPS/eip-xxxx.md Outdated Show resolved Hide resolved
EIPS/eip-xxxx.md Outdated Show resolved Hide resolved
EIPS/eip-xxxx.md Outdated Show resolved Hide resolved
EIPS/eip-xxxx.md Outdated
bytes32 parentHash;
address feeRecipient;
...
bytes32 stateRoot; // now references the post-state root of block (n-1)
Copy link
Contributor

@g11tech g11tech Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have another Q:

since the block builders will have the stateroot because they can't include a tx before executing a previous one because of previous txs affecting any prestate of the tx, so why should we not include the stateroot in it

since the logs/requests etc are all dependent on the correct execution. Ofcourse the attesters can still do delayed verification.

may we we just add a block pre-stateroot field and use that for running verifications because proofs of correct execution results against this block might require this block's post stateroot and will be easy and fast check for whenever the block gets executed before next block arrives

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the block builders will have the stateroot because they can't include a tx before executing a previous one because of previous txs affecting any prestate of the tx, so why should we not include the stateroot in it

They only need the state, not the state root.

Currently they'd need to compute the state root before completing the block building process. Now they don't need to compute it eagerly (they can do it async).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I get that, but having post stateroot in block is a good thing for creating proofs merkle and ZK against the current block header itself.

yes it would matter how hard it is to create a stateroot, my supposition is : its not really that expensive and doesn't add any real latency but then depends on how big the block is, but if its vialble we should include it

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I'm not sure I understand. Do you suggest to include both pre state root and post state root of the current block in its header?

having post stateroot in block is a good thing for creating proofs merkle and ZK against the current block header itself

Do you mean verifying blocks with a zk proof instead of re-executing them? That's not necessarily in conflict with this EIP, nodes can still receive the state root together with the proof (not as part of the header but on some other channel).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I mean to specify both because the block builder will have the final execution results anyway when its done adding txs to the block.

for the proof, it needs to be anchored in post state root. Although receipts should have the entire execution traced but thats not true of system updates which are purely reflected in stateroot.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok now I understand that this EIP is trying to save post state root compute time even for builder. is that correct?

if so then as I asked in a previous comment how significant this time would be (so benchmarks against some typical blocks with 30m 60m... 100m 1g gas i guess) on a latest commondity hardware (which one would expect least of block builders)

I guess that would bring forward the proper justification of the EIP

EIPS/eip-xxxx.md Outdated
# assert compute_state_root(transactions_of_block_n) == payload_n.stateRoot
#
# Now:
assert payload_n.stateRoot == post_state_of_block_n_minus_1

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean that if a future protocol upgrade changes EVM behavior, then nodes that did not upgrade would fork off the network with 1 block delay? (Though I don't think this is an issue.)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that is true only if the protocol change results in a mismatched state but doesn't change the execution flow of the transactions.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, so for instance adding a new tx type could result in a fork exactly at the upgrade block.

But adding a new opcode or precompile, or changing the gas schedule, could result in a fork one block later.

# assert compute_state_root(transactions_of_block_n) == payload_n.stateRoot
#
# Now:
assert payload_n.stateRoot == post_state_of_block_n_minus_1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the current block execution validations also validates receipts, execution requests root, header has logbloom etc so many other fields which are the result of block execution and get validated so I am assuming that those validations stay in?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not realize this until this comment, because I first assumed that this could mean that tx execution could happen after publishing the block. But this is not possible, since we still need receipt roots.

Are there any numbers how much the time is of calculating the state root? This is a simplification, but I would assume that most clients would execute txs and write state changes to a cache. Only at the end of running the txs this cache is flushed to disk in order to calculate the new state root. I would honestly have no idea what the ratio is between executing the transactions and flushing the new cache to disk / calculating the root and would love to see some numbers on this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea agree with @jochem-brouwer we should see what is the benchmark delay for batched state root calculation

@github-actions github-actions bot removed the w-ci Waiting on CI to pass label Jan 16, 2025
Copy link

The commit adc3c35 (as a parent of 8e28b3e) contains errors.
Please inspect the Run Summary for details.

@github-actions github-actions bot added the w-ci Waiting on CI to pass label Jan 16, 2025
@github-actions github-actions bot removed the w-ci Waiting on CI to pass label Jan 16, 2025

## Motivation

Currently, every Ethereum block includes two `state_root`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the wording of this statement incorrect, EL blocks have only one state root, and this is the state root of Ethereum's "world state" (MPT of accounts)


The execution layer (EL) `state_root` contained within the `ExecutionPayload` tracks the effect of transaction execution (e.g., account balances, code, etc.).

The EL `state_root` must be computed by block builders (and verified by relays, validators, and light clients) in near-real-time. This computation accounts for a large fraction of block production and verification time, especially in an MEV-Boost environment. This overhead is also a challenge for efforts to enable real-time ZK proving of the chain.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love to see some numbers here, what is this large fraction? If splitting the time between receiving a block, executing the txs, and calculating the root, what would these numbers be?


3. **Reliant Contracts**

- We are not aware of any common contract types that assume the availability of same-block state roots.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contracts cannot read a block state root, so I'm not sure if this is relevant?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c-new Creates a brand new proposal e-consensus Waiting on editor consensus e-review Waiting on editor to review s-draft This EIP is a Draft t-core
Projects
None yet
Development

Successfully merging this pull request may close these issues.