Repository navigation
feat: add Bogota to the REST + SSZ engine spec - #920
Open
barnabasbusa wants to merge 3 commits into
Open
barnabasbusa wants to merge 3 commits into
barnabasbusa wants to merge 3 commits into
Conversation
This was referenced Oct 6, 2026
jihoonsong
reviewed
Oct 7, 2026
jihoonsong
left a comment
Member
There was a problem hiding this comment.
Looks good to me. I'd defer approving this to whoever has been following SSZ engine APIs closely so far.
nflaig
added a commit
to ChainSafe/lodestar
that referenced
this pull request
Oct 9, 2026
Implements the REST engine API with SSZ encoded bodies from [execution-apis#793](https://github.com/ethereum/execution-apis/blob/main/src/engine/refactor.md) next to the existing JSON-RPC transport. The transport is picked per execution client connection from `GET /engine/v1/capabilities`, so nodes on an execution client without the REST API keep working unchanged, and the REST API is used by default where it is advertised. - add the engine API wire containers, composed from the consensus payload types with `Optional[T]` encoded as `List[T, 1]` - split `ExecutionEngineHttp` into a JSON-RPC and a REST transport behind `IEngineTransport`, the engine keeps the request queue, engine state, payload id cache and result handling - probe the capabilities once per connection and again after a disconnect. In `auto` mode an execution client without the REST API (a 4xx other than 401, 403, 408 or 429) or with a capabilities document that cannot be parsed selects JSON-RPC until it reconnects, the latter with a warning. Timeouts, 408, 429 and 5xx use JSON-RPC and probe again after 12 seconds, 401 and 403 stay errors. Forks and `/blobs/vN` revisions that are not advertised stay on JSON-RPC, and a fork rejected with `unsupported-fork` despite being advertised falls back to JSON-RPC until reconnect - REST is only negotiated with a single execution URL, multiple URLs keep JSON-RPC and its fallback across URLs. `ssz` requires a single URL and never falls back, `json-rpc` never probes - validate the blob versioned hashes of the payload's type-3 transactions against the beacon commitments before submitting over REST, since the envelope has no `expected_blob_versioned_hashes` and the EL can no longer run that check. JSON-RPC keeps delegating it to the EL - honor the advertised request limits, oversized requests fail locally and are not split - add `--execution.engineApi auto|ssz|json-rpc` (default `auto`) and the `lodestar_execution_engine_api_requests_total{transport}` counter, the REST client reports the same per-route client metrics including the request and response bytes from #10195. Transport selection and fallbacks are logged at debug level - decode `/blobs/v2` responses as views into the response body instead of copying, the response is all-or-nothing so every byte is needed, `/blobs/v1` keeps copies since partial responses carry zero-filled entries - send `X-Engine-Client-Version` as the JSON `ClientVersionV1` object since the spec does not pin a format and that is what Nethermind parses - malformed SSZ or JSON on a 2xx response and HTTP errors are classified as engine errors, only transport failures mark the execution client offline The client speaks HTTP/1.1 only, neither reth nor Nethermind negotiates h2c on the cleartext engine port today. Left for follow-ups: HTTP/2, `/blobs/v3` and `/blobs/v4`, `custody_columns` on forkchoice updates, and the `bogota` header value once [execution-apis#920](ethereum/execution-apis#920) lands. Heze stays on JSON-RPC in `auto` mode until then. Verified on kurtosis devnets (minimal preset, blob spam), see the interop reports in the comments for the per-route numbers: - reth `v2.7.0` and `main`: everything over REST including `/blobs/v2`, blobs resolved into data columns on a non-supernode, fulu at genesis and an electra to fulu transition with the blob revision switching at the fork boundary - Nethermind `master` after [NethermindEth/nethermind#14302](NethermindEth/nethermind#14302): same two scenarios, everything over REST. Before the fix every forkchoice update with payload attributes was rejected with `unsupported-fork` on chainspec networks ([NethermindEth/nethermind#14006](NethermindEth/nethermind#14006)) and the per-fork fallback kept the node proposing over JSON-RPC - geth and Nethermind 1.38.0: `404` on capabilities, JSON-RPC for the whole run Supersedes #10155. --------- Co-authored-by: Cayman <caymannava@gmail.com> Co-authored-by: Nazar Hussain <nazarhussain@gmail.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The REST + SSZ engine spec from #793 covers Paris through Amsterdam only, so the Bogota (Heze) FOCIL changes from bogota.md (EIP-7805) have no wire shape there. This adds
bogotaas anEth-Execution-Versionvalue withPayloadAttributesBogotaandExecutionPayloadEnvelopeBogotacarryinginclusion_list_transactions,PayloadStatusBogota/ForkchoiceUpdateResponseBogotacarryinginclusion_list_satisfied, Bogota aliases for the payload, body and built-payload containers, and a fork-scopedGET /inclusion-listendpoint that replacesengine_getInclusionListV1. It follows what is merged in bogota.md today; the open Bogota PRs (#864, #886, #911) don't touch the REST + SSZ files and would need matching updates here if they land.