Skip to content

feat: add ssz to engine api#764

Draft
barnabasbusa wants to merge 11 commits intoethereum:mainfrom
barnabasbusa:bbusa/ssz
Draft

feat: add ssz to engine api#764
barnabasbusa wants to merge 11 commits intoethereum:mainfrom
barnabasbusa:bbusa/ssz

Conversation

@barnabasbusa
Copy link
Copy Markdown
Member

@barnabasbusa barnabasbusa commented Mar 4, 2026

Core change: Full binary SSZ over REST. No JSON, no hex encoding - raw SSZ bytes over HTTP.

Rationale:

  1. Performance: Eliminates JSON parsing + hex encoding/decoding on the critical path. The CL already has execution payloads in SSZ (from beacon blocks) — with binary transport it can forward raw bytes to the EL without any conversion.
  2. Blob scaling: As blob count increases, JSON becomes the bottleneck. Each blob is 131,072 bytes — hex encoding doubles that. Binary SSZ sends blobs at their actual size. This directly unblocks increasing MAX_BLOB_COMMITMENTS_PER_BLOCK without degrading CL-EL communication.
  3. Zero breakage: JSON-RPC stays as default. SSZ is opt-in via capabilities exchange. Existing clients work unchanged.

…eflect optionality removal

Removes `Optional[T]` mapping as it is replaced by specific zero/empty value encoding in container definitions.
Updates `PayloadStatusV1`, `ForkchoiceUpdatedResponseV1`, `ExecutionPayloadBodyV1`, and `ExecutionPayloadBodyV2` to use non-optional types where JSON mapping implies a zero/empty value instead of true optionality.
Updates SSZ mappings for `engine_getPayloadBodiesByHashV1/V2` and `engine_getBlobsV1/V2/V3` to use nested lists (`List[List[T, 1]]`) instead of `Optional[T]` to represent the presence or absence of data, consistent with non-null SSZ encoding for absent data.
Adds notes explaining the zero/empty encoding for absent fields.
@barnabasbusa barnabasbusa marked this pull request as draft March 4, 2026 19:38
…update examples

The documentation for how `T or null` maps to SSZ encoding is being clarified.

Replaced the generic statement about `Optional[T]` being encoded as `List[T, 1]` with a more direct explanation that it is represented as `List[T, 1]`.

Also updated the description for `payload_attributes` in `ForkchoiceUpdated` requests to explicitly state that presence is indicated by a list with 1 element, matching the SSZ type definition.

Additionally, added missing vocabulary words to `wordlist.txt` to improve future documentation generation tools.
…ation to reflect capability exchange

The transport negotiation mechanism has been updated to exclusively use `engine_exchangeCapabilities` over JSON-RPC for determining support of SSZ REST endpoints. This change clarifies the required steps for clients to discover and utilize the binary SSZ transport.
Update documentation to better explain how JSON-RPC remains the default for negotiation and fallback, explicitly stating when binary SSZ is used. This clarifies the steps involved for CL and EL during initialization.
Comment on lines +73 to +75
- The CL uses SSZ natively, forcing a round-trip conversion (SSZ to JSON, then JSON to internal types) at the Engine API boundary.

Binary SSZ eliminates all of this. The CL sends raw SSZ bytes over HTTP; the EL deserializes directly. No hex encoding, no JSON parsing, no intermediate representations. Payload sizes are reduced by 50% or more compared to JSON-RPC, and serialization is no longer a bottleneck in the critical path between CL and EL.
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 EL uses RLP, why not RLP? The EL does not currently support SSZ while the CL does support RLP for various reasons. This would reduce the number of libraries in the EL but be net zero for the CL.

What unique utility does SSZ provide?

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.

2 participants