SSZ-REST Engine API Transport for Prysm#16447
SSZ-REST Engine API Transport for Prysm#16447Giulio2002 wants to merge 11 commits intoOffchainLabs:developfrom
Conversation
Implements the CL side of EIP-8161, enabling Prysm to communicate with the EL via SSZ-REST instead of JSON-RPC when the EL advertises the ssz_rest channel via EIP-8160. - SSZ-REST client with automatic discovery via engine_getClientCommunicationChannelsV1 - SSZ encode/decode for all Engine API request/response types - Transparent fallback to JSON-RPC on network errors - Periodic channel refresh (every 5 minutes) - --disable-ssz-rest flag to force JSON-RPC only - Container-aware URL resolution (handles 0.0.0.0 advertised addresses) - BlobsBundleV2 support for Fulu epoch and later - Unit tests for SSZ encoding round-trips Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Call engine_exchangeCapabilitiesV2 first to get both capabilities and supportedProtocols in a single request. Falls back to V1 + separate GetClientCommunicationChannelsV1 if V2 is not supported. This follows the updated EIP-8160 spec where protocol discovery is integrated into the capability exchange handshake. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
potuz
left a comment
There was a problem hiding this comment.
Nice! is this something EL clients will be moving to? We'd be happy to move the engine calls to SSZ!
| type sszRestClient struct { | ||
| baseURL string | ||
| httpClient *http.Client | ||
| mu sync.RWMutex |
There was a problem hiding this comment.
Is this mutex even used? I couldn't find a guard and there seem to be plenty of races that could be preventing by using this very mutex. Looks like this was probably coded by an AI?
| } | ||
|
|
||
| // Reconstruct the proto types from the SSZ data. | ||
| payload := &pb.ExecutionPayloadDeneb{} |
There was a problem hiding this comment.
This should probably not be hardcoded to a Deneb Payload.
| } | ||
| // Check for common network error patterns. | ||
| errStr := err.Error() | ||
| for _, pattern := range []string{ |
There was a problem hiding this comment.
Could we do this with errors.Is or similar? string matching smells like an easy regret to me.
Remove getClientCommunicationChannels, exchangeCapabilitiesV2, and protocol discovery. Replace --disable-ssz-rest with --ssz-rest-url flag that directly specifies the EL's SSZ-REST endpoint. Add Dockerfile and Dockerfile.validator for kurtosis devnet support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ding Replace hand-written binary.LittleEndian offset encoding with ssz.WriteOffset()/ssz.ReadOffset() from fastssz library for proper SSZ container/list encoding in EIP-8161 ExchangeCapabilities. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…SSZ-REST
- new_payload → POST /engine/v{N}/payloads
- forkchoice_updated → POST /engine/v3/forkchoice
- get_payload → GET /engine/v{N}/payloads/{payload_id}
- get_blobs → POST /engine/v1/blobs
- exchange_capabilities → POST /engine/v1/capabilities
- get_client_version → POST /engine/v1/client/version
- Error responses now text/plain instead of JSON
- Added doGetRequest/doHTTP for GET support
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Per execution-apis PR OffchainLabs#764 spec: - PayloadStatus.latest_valid_hash: List[Hash32, 1] - ForkchoiceUpdatedResponse.payload_id: List[Bytes8, 1] - ForkchoiceUpdatedRequest.payload_attributes: List[PayloadAttributes, 1] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SSZ-REST URL is now derived from the engine endpoint (same host:port). The EL serves SSZ-REST on the engine port under /engine/* paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, only network-level errors (connection refused, timeout) triggered JSON-RPC fallback. Protocol-level errors (400 bad request, encoding mismatches) were returned directly, which could block slot processing entirely. Now all SSZ-REST errors fall back to JSON-RPC, ensuring the chain progresses even if SSZ encoding is wrong. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
Implements the SSZ-REST Engine API transport spec: ethereum/execution-apis#764 |
Implements SSZ-REST transport for the CL↔EL Engine API in Prysm, as specified in ethereum/execution-apis#764.
When connected to an EL that serves SSZ-REST endpoints on the Engine API port (
/engine/v{N}/...), Prysm uses binary SSZ encoding instead of JSON-RPC for all Engine API calls —newPayload,forkchoiceUpdated,getPayload,getBlobs, andexchangeCapabilities.What this PR does
sszrest_client.go): HTTP client that encodes requests as SSZ (application/octet-stream) and sends them to REST endpoints on the engine portsszrest_encoding.go,sszrest_types.go): SSZ container definitions for all Engine API request/response types, usingList[T, 1]for nullable fields per spec/engine/*paths, no additional configuration neededBlobsBundleV2encoding for Fulu epoch and laterEndpoints
new_payloadPOST /engine/v{N}/payloadsforkchoice_updatedPOST /engine/v3/forkchoiceget_payloadGET /engine/v{N}/payloads/{payload_id}get_blobsPOST /engine/v1/blobsexchange_capabilitiesPOST /engine/v1/capabilitiesSpec
Co-Authored-By: Claude noreply@anthropic.com