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 ephemeral block headers to the history network spec #341

Merged

Conversation

pipermerriam
Copy link
Member

@pipermerriam pipermerriam commented Sep 25, 2024

fixes #336

should probably depend on #291

What is wrong

We are going to move towards keeping unproven headers in a separate content type than the proven ones. This is based on the discussion in #336

How was it fixed

We will refer to headers near the front of the chain that are not in a stable HistoricalSummaries as "ephemeral" headers. Their only proving path is through tracing the Header.parent_hash through the chain of headers and anchoring to a trusted header. This trusted header must come from an independent oracle (such as the portal beacon network).

All clients in the network will be assumed to have some quantity of these recent headers. The Ping and Pong custom_data field will also be modified to include a new field that signals how many of these recent headers a client is holding.

Clients will need to perform a data migration on their database to remove the previous unproven headers that are no longer valid after this change. Values in the database that previously used the None proof type should be purged, and the subsequent values should be modifed to correct the Union selector if they have been stored with that as part of the data field.

Clients will need to implement a mechanism to purge ephemeral headers as or after they transition out of the most recent epoch boundary.

Clients will need to implement a syncing mechanism to fetch and fill their database with the appropriate window of recent headers that are still within the current unfinalized epoch.

Clients will need to implement an oracle (such as the portal beacon network) to be continually updated on what the most recent block header is, and to use this as the validation anchor for any headers requested this way.

Our hive and testing infrastructure will need to be updated to reflect these changes.

@@ -157,7 +160,7 @@ each receipt/transaction and re-rlp-encode it, but only if it is a legacy transa

HistoricalHashesAccumulatorProof = Vector[Bytes32, 15]

BlockHeaderProof = Union[None, HistoricalHashesAccumulatorProof]
BlockHeaderProof = Union[HistoricalHashesAccumulatorProof]
Copy link
Collaborator

Choose a reason for hiding this comment

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

We could for now also leave this None in there, allowing this PR to get merged, before clients get ready to migrate data.

And that would allow us to decide on how to deal with it best (future wise).

ephemeral_headers_key = Container(block_hash: Bytes32, ancestor_count: uint8)
selector = 0x04

ephemeral_header_payload = List(ByteList[1024], limit=256)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
ephemeral_header_payload = List(ByteList[1024], limit=256)
ephemeral_header_payload = List(ByteList[1024], limit=MAX_EPHEMERAL_HEADER_PAYLOAD)

Copy link
Member Author

@pipermerriam pipermerriam left a comment

Choose a reason for hiding this comment

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

I'm considering just moving the limit to 16384 (2**16). Very loose rationale is that at the point where we transition across an epoch boundary, it will take some time for the bridge to gossip new headers into the network.

Broader rationale is:

  • Allow time for bridges to gossip proven data as epoch boundaries pass by.
  • Eliminate awkwardness of having to use uint16 for ephemeral_header_count since it allows for a value up to 16384. This way we don't have a weird "dead range" at the top of that value that is invalid and thus would require some kind of special handling.
  • The proving path for headers deep in the ephemeral chain is expensive requiring proving all the way up to head, which adds a natural disincentive for clients to use this old ephemeral data when they don't have to.

Clients can still of course set this value to 8192 or any value they want. This gives us some freedom of movement. Realistically, the real value might be something like 9000 as it gives a little time for bridge gossip but still constrains this value appropriately.

@pipermerriam pipermerriam force-pushed the piper/add-ephemeral-headers branch from ba5ac09 to efd11c8 Compare September 26, 2024 16:03
@pipermerriam pipermerriam marked this pull request as ready for review September 26, 2024 16:22
@pipermerriam pipermerriam changed the title WIP: Add ephemeral block headers to the history network spec Add ephemeral block headers to the history network spec Sep 26, 2024

> Note: The content-id for this data type is not meaningful.

> Note: This message is not valid for Gossip. Clients **SHOULD** not send or accept gossip messages for this content type.
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of "Gossip", should we say "OFFER/ACCEPT"? We can clarify that this includes gossip as well, but that would be implied.

```python
# Content and content key

ephemeral_headers_key = Container(block_hash: Bytes32, ancestor_count: uint8)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Should we explicitly declare that ancestor_count can't be bigger than MAX_EPHEMERAL_HEADER_PAYLOAD? Or is it enough that it's implied by the content type?

Or is it ok to request more than 256, but answer shouldn't have more than that?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll make these things explicitly stated. They are enforced by the encoding types but worth making them stated limits too.

@KolbyML
Copy link
Member

KolbyML commented Oct 21, 2024

This PR changes the custom_payload for history. I propose we deploy this change through #348 which should make upgrading custom_payload easier in the future without the risk of breaking interop and allowing us a window for all implementations to update to the new format before deprecating older versions.

@pipermerriam
Copy link
Member Author

I think this mechanism still has an unsolved issue.

There is no mechanism in place for getting new headers populated into the network. The current PR disallows GOSSIP/ACCEPT for the ephemeral header data type. I wrote it a long time ago and didn't provide a justification for this ban on GOSSIP, but I assume it was because the payload can't easily have a proof attached to it... maybe... we assume that each client has their own "oracle" that tells them the HEAD hash of the chain.

Under this model, I think things at the very HEAD of the chain become awkward to prove because of race conditions where client A hasn't yet progressed to the very latest block and client B is faster and tries to gossip the very latest block.

Anything 2-3 blocks back from the HEAD is probably easy to prove..

@KolbyML
Copy link
Member

KolbyML commented Jan 8, 2025

I think this mechanism still has an unsolved issue.

There is no mechanism in place for getting new headers populated into the network. The current PR disallows GOSSIP/ACCEPT for the ephemeral header data type. I wrote it a long time ago and didn't provide a justification for this ban on GOSSIP, but I assume it was because the payload can't easily have a proof attached to it... maybe... we assume that each client has their own "oracle" that tells them the HEAD hash of the chain.

maybe... we assume that each client has their own "oracle" that tells them the HEAD hash of the chain.

We do assume that they will either have access to Portal Beacon Network node, which would track the head and be constantly receiving the Execution Headers, via its updates

Or running a Full Node in which there also wouldn't be a problem

Under this model, I think things at the very HEAD of the chain become awkward to prove because of race conditions where client A hasn't yet progressed to the very latest block and client B is faster and tries to gossip the very latest block.

We can include an ephemeral header well gossiping the state, this will solve the race condition assuming the node already has latest minus 1 ephemeral headers.

We will need to include headers when gossiping bodies and receipts soon enough to lower latency, I don't see why state content being gossipped at the head of the chain would be any different.

This also avoids tons of nodes doing RFC for headers

Anything 2-3 blocks back from the HEAD is probably easy to prove..

If we include headers well gossiping state or bodies/receipts I think this issue goes away. Assuming that the Portal Client isn't syncing anymore there shouldn't be a problem.

To be clear I think we should ban gossiping ephemeral header data type individually, but if it is bundled with something else I think that is a requirement due to latency concerns going forward.

@KolbyML
Copy link
Member

KolbyML commented Jan 8, 2025

Also I think it is import to note all history,state,etc content from LATEST minus 64 blocks would be non-finalized, not just headers. So we would also need to handle side chains in this window for any history or state network content gossiped in this range. And clear bodies and state from the database, if the side chain is discarded.

@pipermerriam
Copy link
Member Author

Ok, I think I have what I need to get this PR updated. I'll get that done today.

@KolbyML
Copy link
Member

KolbyML commented Jan 8, 2025

Ok, I think I have what I need to get this PR updated. I'll get that done today.

awesome 🚀

@pipermerriam pipermerriam force-pushed the piper/add-ephemeral-headers branch 3 times, most recently from 7bb9e63 to ab54ecf Compare January 8, 2025 19:46
@pipermerriam pipermerriam force-pushed the piper/add-ephemeral-headers branch from ab54ecf to 18f4740 Compare January 8, 2025 19:50
@@ -236,6 +233,47 @@ content = SSZ.serialize(block_header_with_proof)
content_key = selector + SSZ.serialize(block_number_key)
```

##### Ephemeral Block Headers

This content type represents block headers *near* the HEAD of the chain. They are provable by tracing through the chain of `header.parent_hash` values. All nodes in the network are assumed to store some amount of this content. The `Ping.custom_data` and `Pong.custom_data` fields can be used to learn the number of recent headers that a client makes available.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we add a phrase stating that nodes should aim to store at least the latest 8192 ephemeral block headers? (Obviously when syncing they can have less).


> Note: This message is not valid for Gossip. Clients **SHOULD** not send or accept gossip messages for this content type.

> Note: Clients **SHOULD** implement a mechanism to purge headers older than 8192 blocks from their content databases.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is stated before that the amount is configurable per client. So perhaps we shouldn't mention a specific value here.

Copy link
Member Author

Choose a reason for hiding this comment

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

The number needs to be 8192 in this context because this is the point where they transition past the ephemeral boundary and should be replaced by the regular content type that has a stable proof.

history/history-network.md Outdated Show resolved Hide resolved
history/history-network.md Outdated Show resolved Hide resolved
Copy link
Member

@KolbyML KolbyML left a comment

Choose a reason for hiding this comment

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

:shipit:

pipermerriam and others added 3 commits January 13, 2025 09:27
Co-authored-by: kdeme <7857583+kdeme@users.noreply.github.com>
Co-authored-by: kdeme <7857583+kdeme@users.noreply.github.com>
@pipermerriam pipermerriam merged commit 0fa815f into ethereum:master Jan 13, 2025
2 checks passed
@pipermerriam pipermerriam deleted the piper/add-ephemeral-headers branch January 13, 2025 16:39
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.

Dealing with Recent Headers
5 participants