Skip to content

feat(jsonrpc): eth-compatible JSON-RPC server bootstrap - #1654

Open
libotony wants to merge 3 commits into
eth-equivalencefrom
tony/bootstrap-json-rpc
Open

feat(jsonrpc): eth-compatible JSON-RPC server bootstrap#1654
libotony wants to merge 3 commits into
eth-equivalencefrom
tony/bootstrap-json-rpc

Conversation

@libotony

@libotony libotony commented Aug 4, 2026

Copy link
Copy Markdown
Member

Description

Bootstrap of an Ethereum-compatible JSON-RPC 2.0 server for Thor.

This PR lands the server engine and wiring only — a minimal, self-contained JSON-RPC core plus two example namespaces to prove the full request path end to end. It is intentionally small; the complete Ethereum method set, websocket subscriptions, filters and write paths are out of scope and tracked as follow-ups.

What's in it

Reflection-based registry (api/jsonrpc/server) — a from-scratch JSON-RPC 2.0 core, no dependency on go-ethereum/rpc. It reflects over a service struct's exported methods and exposes each as <namespace>_<method>, following go-ethereum's rpc/service.go contract:

  • Legal signatures: Method() error, Method(args...) Result, Method(args...) (Result, error), Method(ctx, args...) (Result, error).
  • A leading context.Context is injected by the server and is not part of the JSON params.
  • Positional params: a pointer arg is optional (nil when omitted), a non-pointer arg is required (-32602 if missing); omission is tail-only.
  • Duplicate method registration returns an error rather than silently overwriting.

HTTP transport (server/http.go) — POST /rpc, single request and batch array, notification handling (no id → no reply, per spec), batch-size cap.

Error model (server/json.go) — standard codes (-32700/-32600/-32601/-32602/-32603/-32000) plus a DataError interface so business errors can attach structured error.data. A panic inside a method is recovered at the call layer and returned as -32603 instead of tearing down the connection.

Package layout — three packages with a clear dependency direction:

  • api/jsonrpc/server — the transport-agnostic engine (stdlib only).
  • api/jsonrpc/service — thor business namespaces (eth, net).
  • api/jsonrpc — top-level composition + Mount.

Example methodseth_chainId, eth_blockNumber, net_version. Enough to exercise reflection, dispatch, batching and error codes; not a complete namespace.

Wiring — a new --enable-rpc flag mounts the server under /rpc on the existing REST router, reusing thor's middleware chain. Off by default.

Dependencies

Stacked on top of eth-equivalence (the PR base). Should be reviewed/merged after it.

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

Unit tests cover the reflection contract (signature acceptance/rejection, ctx injection, required vs optional args), dispatch and every error code, batch and notification handling, and the two example namespaces against a genesis-only testchain.

  • go test ./api/jsonrpc/...
  • go build ./...
  • golangci-lint run + modernize clean

Test Configuration:

  • Go Version: 1.26.5

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my feature works
  • New and existing unit tests pass locally with my changes
  • I have not added any vulnerable dependencies to my code

@libotony
libotony requested a review from a team as a code owner August 4, 2026 09:17
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