Skip to content

Allow zero safeBlockHash and finalizedBlockHash after finalization#760

Open
dapplion wants to merge 1 commit intoethereum:mainfrom
dapplion:allow-zero-forkchoice-hashes
Open

Allow zero safeBlockHash and finalizedBlockHash after finalization#760
dapplion wants to merge 1 commit intoethereum:mainfrom
dapplion:allow-zero-forkchoice-hashes

Conversation

@dapplion
Copy link
Copy Markdown
Member

@dapplion dapplion commented Feb 26, 2026

Summary

  • Remove the restriction that safeBlockHash and finalizedBlockHash must be non-zero once the transition block is finalized
  • When set to zero, the EL defaults to the latest known value (or genesis)
  • The -38002 invalid forkchoice state check now only applies to non-zero hashes

Motivation

During extended non-finality periods, a CL client checkpoint-syncing from a non-finalized state may not yet know the network's finalized or safe block hash. The current spec forces the CL to provide non-zero values post-merge, which is not always possible. This change lets the CL signal "unknown" by sending zeroes, with the EL falling back to its last known state.

The other options are:

  • The CL tells the EL "fake" safe and finalized hashes (the checkpoint root), breaking the meaning of those block tags in the first place
  • The CL tries to fetch the execution hashes of the finalized and justified checkpoints from its p2p or checkpointz server. Possible, (and we want to implement it) but this PR is still helpful. If checkpointz faults and can't provide the blocks for finalized and justified checkpoint the network can't sync, potentially killing liveness on a catastrophic event.

See also: sigp/lighthouse#8382

@dapplion dapplion force-pushed the allow-zero-forkchoice-hashes branch from c943ecb to 7736063 Compare February 26, 2026 21:32
Comment thread src/engine/paris.md
- `finalizedBlockHash`: `DATA`, 32 Bytes - block hash of the most recent finalized block

*Note:* `safeBlockHash` and `finalizedBlockHash` fields are allowed to have `0x0000000000000000000000000000000000000000000000000000000000000000` value unless transition block is finalized.
*Note:* `safeBlockHash` and `finalizedBlockHash` fields are allowed to have `0x0000000000000000000000000000000000000000000000000000000000000000` value. When set to zero, the client **MUST** default to the latest known value for the corresponding field, or the genesis block hash if no value is known.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The safeBlockHash with FCR implementation may point to an already unsafe block on the EL side. In this case EL should rather revert it to finalizedBlockHash

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

How would you phrase that?

Copy link
Copy Markdown
Contributor

@mkalinin mkalinin Mar 9, 2026

Choose a reason for hiding this comment

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

Suggested change
*Note:* `safeBlockHash` and `finalizedBlockHash` fields are allowed to have `0x0000000000000000000000000000000000000000000000000000000000000000` value. When set to zero, the client **MUST** default to the latest known value for the corresponding field, or the genesis block hash if no value is known.
*Note:* `safeBlockHash` and `finalizedBlockHash` fields are allowed to have `0x0000000000000000000000000000000000000000000000000000000000000000` value. When set to zero, the client **MUST** default both values to the latest known `finalizedBlockHash` value, or the genesis block hash if no `finalizedBlockHash` value is known.

Will the above work?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we should make this an explicit statement in the fcU spec below to aid visibility.

Comment thread src/engine/paris.md
Comment thread src/engine/paris.md
- `finalizedBlockHash`: `DATA`, 32 Bytes - block hash of the most recent finalized block

*Note:* `safeBlockHash` and `finalizedBlockHash` fields are allowed to have `0x0000000000000000000000000000000000000000000000000000000000000000` value unless transition block is finalized.
*Note:* `safeBlockHash` and `finalizedBlockHash` fields are allowed to have `0x0000000000000000000000000000000000000000000000000000000000000000` value. When set to zero, the client **MUST** default to the latest known value for the corresponding field, or the genesis block hash if no value is known.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think the zero case is especially important for the transition period, changing this now is possible since we have transitioned, but it does not feel very "clean" to "change" the behavior at the transition. I also realize that not being backwards compatible should not be a big problem (assume chains have already transitioned or new chains start in PoS mode) so not a super strong opinion here, but one suggestion:

How about adding this rule to forkchoiceUpdatedV2 and all FcUs after, instead of forkchoiceUpdatedV1? This would keep the "old" behavior and ship new behavior to a fork after the transition.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think that zero hash would work for both situations:

  • When transition block isn’t yet finalized, there is yet no known finalized block on EL side and it’s fine to mark genesis block as final
  • When there is already a finalized block, EL will stick with it unless a non-zero hash comes from the CL side

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

Successfully merging this pull request may close these issues.

3 participants