Skip to content

Add head_v2 event and deprecate head event#590

Open
chong-he wants to merge 11 commits intoethereum:masterfrom
chong-he:event-head
Open

Add head_v2 event and deprecate head event#590
chong-he wants to merge 11 commits intoethereum:masterfrom
chong-he:event-head

Conversation

@chong-he
Copy link
Copy Markdown

This PR adds a new_head event to the event stream as per discussion in #589

Comment on lines +177 to +178
event: new_head
data: {"slot":"10", "block":"0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "state":"0x600e852a08c1200654ddf11025f1ceacb3c2e74bdd5c630cde0838b2591b69f9", "epoch_transition":false, "previous_epoch_dependent_root":"0x5e0043f107cb57913498fbf2f99ff55e730bf1e151f02f221e977c91a90a0e91", "current_epoch_dependent_root":"0x5e0043f107cb57913498fbf2f99ff55e730bf1e151f02f221e977c91a90a0e91", "next_epoch_dependent_root":"0x5e0043f107cb57913498fbf2f99ff55e730bf1e151f02f221e977c91a90a0e91", "execution_optimistic": false}
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.

we should probably add version tag in this event @nflaig thoughts?

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 Nico was pushing back on the version idea here:

I am not convinced to use {"version": "fork_name", "data": { ... }} everywhere, that is, if they don't emit data based on spec containers, or not fork specific, it feels a bit unnecessary. Although since we change the head event now, we never know. It's just not consistent with format of existing events. When we go with v2 at some point, then yes, maybe it makes sense to wrap all events in the version container.

Although I agree with you, we may as well version it for future proofing.

Copy link
Copy Markdown
Member

@nflaig nflaig Mar 19, 2026

Choose a reason for hiding this comment

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

not against adding a version here but in this case it's not trivial for a consumer to interpret it, while in the spec container case it's simple, you just pick the fork container based on version and use it to deserialize the data

while here, if we have to change the event in the future I'd expect we likely change the semantics of the event, not just the data format in which case a new event likely makes sense anyways

and clients should not break if new fields are added to the event, ie. #585 should be totally fine, if a client can't handle that, it needs to be fixed on that end imo

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added the version in response

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.

the more I think about the version here, the more I dislike it, it's not really clear what it is "versioning" in that case because the data isn't really fork specific

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I am ok to remove the version. The response in data is not fork-dependent as the fields x_epoch_dependent_root is fixed since Fulu now. What do others think?

@rolfyone rolfyone added the Gloas api's needed in Gloas fork. label Mar 19, 2026
event: payload_attestation_message
data: {"version":"gloas", "data":{"validator_index": "123", "data": {"beacon_block_root": "0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "slot": "10", "payload_present": true, "blob_data_available": true}, "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}
new_head:
description: The node has finished processing, resulting in a new head. previous_epoch_dependent_root is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 2) - 1)`, current_epoch_dependent_root is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch - 1) - 1)` and next_epoch_dependent_root is `get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch) - 1)`. All dependent roots use the genesis block root in the case of underflow. This `new_head` event is for post-Fulu slots. For pre-Fulu slots, use the `head` event.
Copy link
Copy Markdown
Member

@nflaig nflaig Mar 19, 2026

Choose a reason for hiding this comment

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

do we wanna update the duty apis as part of this PR? currently their description still refers to the old head event

- event.previous_duty_dependent_root when `compute_epoch_at_slot(event.slot) == epoch`
- event.current_duty_dependent_root when `compute_epoch_at_slot(event.slot) + 1 == epoch`

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks, I have made the changes similar to proposer.v2.yaml. But I am not sure if I am doing it right?

@chong-he chong-he changed the title Add new_head event Add head_v2 event and deprecate head event Mar 20, 2026
Copy link
Copy Markdown
Author

@chong-he chong-he left a comment

Choose a reason for hiding this comment

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

Added some questions that I have


After Fulu:

- event.previous_epoch_dependent_root when `compute_epoch_at_slot(event.slot) == epoch`
Copy link
Copy Markdown
Author

@chong-he chong-he Mar 20, 2026

Choose a reason for hiding this comment

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

I use the term previous_epoch_dependent_root here (instead of previous_duty_dependent_root) as I thought after Fulu it is "epoch", not "duty". Is this right? If so, maybe I can also update this part in proposer.v2.yaml:

- event.previous_duty_dependent_root when `compute_epoch_at_slot(event.slot) == epoch`

Edit: Should it actually be current_epoch_dependent_root instead of previous_epoch_dependent_root for post-Fulu case?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

After discussed with @michaelsproul , we revise this part to make it clearer:

  • Remove before Fulu / after Fulu as now the chain is at Fulu
  • rename to use current_epoch... instead of current_duty...
  • remove event.block otherwise bullet point as it serves no purpose (and could be confusing)
  • changes made to: attester.yaml, proposer.v2.yaml and ptc.yaml

chong-he and others added 2 commits March 20, 2026 19:21
Co-authored-by: Nico Flaig <nflaig@protonmail.com>
value: |
event: payload_attestation_message
data: {"version":"gloas", "data":{"validator_index": "123", "data": {"beacon_block_root": "0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "slot": "10", "payload_present": true, "blob_data_available": true}, "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}
data: {"version":"gloas", "data":{"validator_index": "123", "data": {"beacon_block_root": "0x9a2fefd2fdb57f74993c7780ea5b9030d2897b615b89f808011ca5aebed54eaf", "slot": "10", "payload_present": true, "blob_data_available": true}, "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}
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.

Should we also take the opportunity to disambiguate the slot field? As far as I know, clients do different things with this field because it was never precisely specified whether it should be:

  1. The slot of the head block matching beacon_block_root, or
  2. The current wall-clock slot, or fork choice store slot

This makes it somewhat less useful for validator clients like Vouch/Vero, which might want to keep track of head block slots.

In head_v2 we could fix this with two fields:

  • head_block_slot: Slot
  • wall_clock_slot: Slot

What do we think?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

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 was personally not aware of this ambiguity and assumed every CL client returned option 1 - "The slot of the head block matching beacon_block_root".

I don't see a reason to ever return a different slot there but I very well may be missing something. Quite the opposite, it seems like a bad idea to me to return dozens of head events with the same slot while syncing / catching up.

As far as I know, clients do different things

Can we have CL client teams confirm what they do? This may not even be an issue if every client already does option 1 right now, and we just need to clarify that in the spec.

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 would read that as head.slot so slot should definitely not be the wall clock slot, as for lodestar, we emit the slot of the head block

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Gloas api's needed in Gloas fork.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants