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

Remove restriction that payloads cannot be built on ancestors of the head #313

Open
michaelsproul opened this issue Oct 14, 2022 · 2 comments

Comments

@michaelsproul
Copy link
Contributor

In the current spec for forkchoiceUpdatedV1 it is stated that a node must not allow a payload to be built atop any ancestor of the head:

Client software MAY skip an update of the forkchoice state and MUST NOT begin a payload build process if forkchoiceState.headBlockHash references an ancestor of the head of canonical chain. In the case of such an event, client software MUST return {payloadStatus: {status: VALID, latestValidHash: forkchoiceState.headBlockHash, validationError: null}, payloadId: null}.

(from: https://github.com/ethereum/execution-apis/blob/main/src/engine/specification.md#engine_forkchoiceupdatedv1)

However, there are cases where it is better for the health of the chain if payloads can be built upon ancestors. If a block arrives late across the entire network and has not been attested to, then it is beneficial to re-org it out to disincentivise that behaviour. Validators may be incentivised to publish blocks as late as possible to maximise MEV, and re-orging them out when they do this is IMO the most viable way to establish a healthy equilibrium.

I have a proposal for the consensus-specs that allows honest validators to perform re-orgs of late blocks, but it currently requires a hack to suppress the forkchoiceUpdated message for the block-to-be-reorged (see: ethereum/consensus-specs#3034). If execution clients were capable of building payloads on ancestors of the head then this hack wouldn't be necessary and the consensus client could just send payload attributes for whichever block it wants to build on.

Whether or not my proposal is adopted, I suspect that we will eventually move to (block, slot) fork choice which will allow attesters to vote for the emptiness of a slot. This would lead to a similar situation, where the canonical head can revert to an ancestor of the previous head, and a new block should be built atop that ancestor.

@mkalinin
Copy link
Collaborator

This requirement in the Engine API spec has been introduced to handle the situation when CL client is syncing from scratch while EL was is already fully synced. In this situation CL sends forkchoiceUpdated with pretty old blocks as long as it's catching up with the chain. Reorgs to early blocks are either impossible or very costly for EL clients because of state pruning. Note that building a payload must always happen on top of the head as some EL clients (e.g. Erigon) can't do the other way because they maintain only one state copy. So, the change to Engine API spec must permit reorgs to ancestors up to a certain extent, probably up to the most recent finalized block.

@michaelsproul
Copy link
Contributor Author

@marioevz Also suggests that we could differentiate "legitimate" reversions from re-syncing by looking for payload attributes. So the rule would become: if the fcU includes payload attributes and elects a head newer than finalization, then the EL must revert to that head and start building a payload

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants