Skip to content

feat(engine): SSZ-over-REST transport per execution-apis #764#4

Merged
barnabasbusa merged 1 commit into
mainfrom
bbusa/ssz-engine-api
May 15, 2026
Merged

feat(engine): SSZ-over-REST transport per execution-apis #764#4
barnabasbusa merged 1 commit into
mainfrom
bbusa/ssz-engine-api

Conversation

@barnabasbusa
Copy link
Copy Markdown
Collaborator

Summary

  • Adds SSZ-over-REST as an alternative Engine API transport, negotiated via engine_exchangeCapabilities per execution-apis#764. JSON-RPC stays the default and the fallback.
  • New module consensoor/engine/ssz_types.py with the spec's containers (ExecutionPayloadV{1-4}, PayloadStatusV1, ForkchoiceStateV1, PayloadAttributesV{1-4}, ForkchoiceUpdatedResponseV1, BlobsBundleV{1,2}, GetPayloadResponseV{2-6}, NewPayloadV{1-5}Request, ForkchoiceUpdatedV{1-4}Request). Nullable JSON fields encoded as List[T, 1].
  • consensoor/engine/client.py tracks the EL-advertised SSZ endpoints, routes new_payload_v{3,4,5} / forkchoice_updated_v{3,4} / get_payload_v{3,4,5,6} through SSZ when supported, and otherwise falls through to JSON-RPC. exchange_capabilities now advertises the 20 SSZ REST capability strings alongside the JSON-RPC method names.

Test plan

  • Built consensoor:ssz-test and ran against ethpandaops/nethermind:master in a Kurtosis enclave (mainnet preset, Fulu).
  • Capabilities handshake negotiates 17 SSZ endpoints with Nethermind.
  • Snooper confirms binary application/octet-stream requests to /engine/v3/forkchoice (×23 → 200), /engine/v4/payloads (×3 → 200), and /engine/v5/payloads/{id} (×3 → 200).
  • Chain progresses through 14+ slots with consensoor and a lighthouse peer at identical head roots.
  • Add Python tests for the converters and capability negotiation (follow-up).

Negotiates via engine_exchangeCapabilities (JSON-RPC remains the default and
the fallback). When both sides advertise an SSZ REST endpoint, requests use
application/octet-stream with raw SSZ bodies on the same 8551 port with the
same JWT auth.

- consensoor/engine/ssz_types.py: SSZ containers for ExecutionPayloadV{1-4},
  PayloadStatusV1, ForkchoiceStateV1, PayloadAttributesV{1-4},
  ForkchoiceUpdatedResponseV1, BlobsBundleV{1,2}, GetPayloadResponseV{2-6},
  NewPayloadV{1-5}Request, ForkchoiceUpdatedV{1-4}Request. Nullable fields
  encoded as List[T, 1].
- consensoor/engine/client.py: track EL-advertised SSZ endpoints, route
  new_payload_v{3,4,5}/forkchoice_updated_v{3,4}/get_payload_v{3,4,5,6}
  through SSZ when supported, JSON-RPC otherwise. exchange_capabilities now
  advertises the 20 SSZ REST capability strings alongside JSON-RPC names.

Verified against ethpandaops/nethermind:master in a kurtosis enclave: 21 SSZ
forkchoice calls, 3 newPayloadV4 calls, 3 getPayloadV5 calls all returned
200; chain stayed in sync with a Lighthouse peer.
@barnabasbusa barnabasbusa merged commit 53e66a4 into main May 15, 2026
@barnabasbusa barnabasbusa deleted the bbusa/ssz-engine-api branch May 15, 2026 12:40
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.

1 participant