Skip to content

feat: proxy REST+SSZ Engine API over h2c (execution-apis #793)#48

Open
barnabasbusa wants to merge 3 commits into
masterfrom
bbusa/ssz-engine-rest-h2c
Open

feat: proxy REST+SSZ Engine API over h2c (execution-apis #793)#48
barnabasbusa wants to merge 3 commits into
masterfrom
bbusa/ssz-engine-rest-h2c

Conversation

@barnabasbusa

Copy link
Copy Markdown
Contributor

Summary

Makes the snooper proxy the REST+SSZ Engine API (execution-apis #793) instead of dropping it.

That transport uses HTTP/2 cleartext (h2c) prior-knowledge. The snooper's server was HTTP/1.1-only, so when a consensus client opened an h2c connection (e.g. GET /engine/v2/capabilities) the connection was reset — the client then silently fell back to JSON-RPC, and none of the #793 traffic was ever observable through the snooper.

Changes

  • h2c downstream server — wrap the handler in h2c.NewHandler so the proxy accepts both HTTP/1.1 (JSON-RPC) and HTTP/2 cleartext (REST+SSZ) on the same port.

  • Protocol-matched upstream — forward each call to the EL using the same HTTP version it arrived on (autodetected per request from the inbound connection): HTTP/2 for REST+SSZ, HTTP/1.1 for JSON-RPC. No client is forced onto a transport it didn't choose.

  • #793 route matching — extend ssz/route.go to the fork-scoped endpoints (/engine/v2/{fork}/payloads|forkchoice|bodies), independently-versioned blobs (/engine/v2/blobs/vN), and the unscoped identity endpoint, with tests.

  • Readable logs — show the autodetected protocol and resolved Engine API method inline on REQUEST/RESPONSE lines, e.g.

    REQUEST  #28: [h2c]      POST /engine/v2/amsterdam/forkchoice → engine_forkchoiceUpdated[amsterdam]
    REQUEST  #3:  [http/1.1] POST /                               → engine_forkchoiceUpdatedV3
    

Supersedes

Includes and replaces the closed #36 (which only added method-name detection for log readability); this PR adds the actual h2c proxying needed to carry the traffic.

Testing

Verified live in a Kurtosis devnet (geth ssz-engine-api branch + consensoor): GET /engine/v2/capabilities, /engine/v2/identity, and the fork-scoped POST /engine/v2/amsterdam/{forkchoice,payloads} / GET .../payloads/{id} SSZ calls all proxy with 200 and are logged with the correct method. JSON-RPC clients (lighthouse, teku) are unaffected and continue over HTTP/1.1. go test ./... passes.

🤖 Generated with Claude Code

barnabasbusa and others added 2 commits June 15, 2026 16:21
Maps Engine API REST URL paths to method names (e.g.
/engine/v3/payloads → engine_newPayloadV3) for improved
log readability when proxying SSZ-encoded traffic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The HTTP/1.1-only server dropped consensus clients that speak the
REST+SSZ Engine API (execution-apis #793), which uses HTTP/2 cleartext
prior-knowledge — the connection was reset and clients fell back to
JSON-RPC, so #793 traffic was never observable through the snooper.

- Wrap the downstream server in h2c so it accepts both HTTP/1.1
  (JSON-RPC) and HTTP/2 cleartext (REST+SSZ) on the same port.
- Forward each call to the EL using the same HTTP version it arrived
  on: HTTP/2 for REST+SSZ, HTTP/1.1 for JSON-RPC.
- Extend SSZ route matching to the #793 fork-scoped endpoints
  (/engine/v2/{fork}/payloads|forkchoice|bodies), independently
  versioned blobs (/blobs/vN), and the unscoped identity endpoint.
- Show the resolved Engine API method inline on REQUEST/RESPONSE lines
  (' -> engine_forkchoiceUpdatedV3') instead of a trailing field, and
  echo it on responses so request/response pairs are easy to read.
@barnabasbusa barnabasbusa requested a review from pk910 as a code owner June 15, 2026 14:24
SSZ bodies were logged as an opaque '<N bytes>' placeholder. SSZ isn't
self-describing so we can't pretty-print it like JSON, but emitting the
raw body as hex (honouring truncation) keeps the on-wire content visible
and decodable offline. The byte count remains on the line via 'length'.
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