An RPC surface is a promise: a wallet, an indexer or a monitoring tool calls a method and expects the answer geth-XDC gives. This post lists what xOneRS serves on main, how it is exposed, and how we check the answers.

The scope decision

ADR-008 sets the scope. Its status is still Proposed: the owner has not signed the acceptance record. The code follows the text.

  • Served namespaces: eth, net, web3, txpool, admin, debug (a small set), rpc and XDPoS. The xdc namespace is served only when the API list names it.
  • Every other method answers -32601.
  • There are no XDCx namespaces (ADR-009).
  • Each out-of-scope method has a written reason.

The generated list of served methods is docs/rpc/methods.md. A test regenerates it from the method registries.

What is served

  • eth: the standard read methods, eth_call, eth_estimateGas, eth_createAccessList, eth_getLogs, eth_feeHistory, eth_sendRawTransaction, and the polling filters (eth_newFilter, eth_getFilterChanges and the others). eth_subscribe works on WebSocket and IPC only.
  • XDC fields and methods under eth_: eth_getBlockSignersByNumber, eth_getBlockFinalityByNumber, eth_getCandidateStatus, eth_getCandidates, eth_getMasternodes, eth_getAccountInfo, eth_getStakerROI and more. Block headers always carry validators, validator and penalties. Addresses accept the xdc prefix on input. See xdc-eth-extensions.
  • XDPoS: consensus state, such as XDPoS_getSnapshot, XDPoS_getMasternodesByNumber, XDPoS_getEpochNumbersBetween and XDPoS_networkInformation. Names are case-exact: xdpos_getSigners answers -32601. See xdpos-namespace.
  • xdc: the xdc_ twins of the eth_ block-chain methods, as geth-XDC registers them.
  • net, web3, txpool: net_version, net_peerCount, net_listening, web3_clientVersion and four txpool_ methods. web3_sha3 is not served, because the pinned geth-XDC answers -32601 for it.
  • debug: debug_getRaw*, debug_traceTransaction, debug_traceBlock* and debug_traceCall. The native tracers are callTracer, prestateTracer, 4byteTracer, noopTracer and muxTracer. The struct (opcode) logger is the default when tracer is absent. JavaScript tracers answer tracer not found.
  • admin: admin_nodeInfo, admin_peers and peer add and remove.
  • trace: trace_block, trace_get and trace_transaction appear in the generated list. The ADR text still lists trace_* as out, so the ADR lags the code here.

eth_getProof is out by decision. The node stores flat state and has no proof walker for it.

Transports and default exposure

transport-exposure gives one contract for all three transports.

REFERENCE TABLEScroll to explore all columns →
HTTP WebSocket IPC
On by default no (--http) no (--ws) yes (--ipcdisable turns it off)
Default bind localhost:8545 localhost:8546 <datadir>/xone.ipc, mode 0600
Default namespaces eth,net,web3 eth,net,web3 all served namespaces
  • admin and debug are served on HTTP and WebSocket only when the API list names them.
  • An unknown namespace or * refuses the start.
  • --rpc.jwtsecret makes every request carry an HS256 bearer token. It is checked before the body is read.
  • Remote privileged access needs three explicit choices: a non-local bind address, admin or debug in the list, and a JWT secret. No default opens it.
  • Limits come from the quota classes in the scope page: a token bucket per connection and per transport, at most 100 batch items, a 5 MiB body, and a deadline per class.

How parity is measured

The oracle is geth-XDC at a pinned commit. A build script records the oracle's answers for each in-scope method on Apothem and net2040. It samples 50 blocks per network, spread over the fork rows, the V1 to V2 switch and the epoch switches. The files are in conformance/vectors/rpc.

The rpc-parity harness replays each recorded request against the xone-rpc handlers, over a chain backed by the blocks the harness has replayed. Then it diffs the JSON by pointer. The only normalisation is hex case. A missing key counts as a difference (diff.rs).

Each row gets one status:

  • equal: the same JSON.
  • differ: both answered and the JSON differs. The harness exits with 1.
  • not-backed: the data does not exist here, for example state above the replayed tip. The reason goes in the report.
  • allowlisted: the oracle value is node-local, such as the head or the peer set. The reason is required.
cargo run -p xone-rpc-parity -- --network apothem|net2040|all

The reports are committed as conformance/rpc-parity/report/<network>.json. The versions on main read:

REFERENCE TABLEScroll to explore all columns →
Network Replayed tip equal differ not-backed allowlisted
Apothem 1800 820 0 1774 16
net2040 747006 1038 0 1577 4

Zero differ rows is not full coverage. Most rows are not-backed, because the harness holds only part of each chain. A not-backed row proves nothing.

What is not served yet

Open issues on xOneRS:

  • #157: eth_getProof.
  • #159: eth_simulateV1 and call bundles.
  • #181: the rest of the Parity-style trace_* namespace.
  • #220: divergence tracing, such as debug_intermediateRoots and debug_traceBadBlock.
  • #162: debug state inspection.
  • #172: GraphQL.
  • #280: a machine-readable RPC schema.
  • #188: a full reference with parameters and examples for every method.

Three issues are partly done on main but still open. These are #154 (struct logger), #158 (call overrides) and #161 (debug_traceCall). The polling-filter issue, #153, is closed. The scope tracker is #42.

Subscriptions have no replay. A client that is away misses events.

The other clients

The TypeScript, Python and C++ clients serve a smaller subset. The repositories are private.

  • xOneTS: the method table covers eth, net, web3 and xdpos (policy.ts). Its conformance/rpc-parity directory is a placeholder: the README says it will port the Rust harness. A test already compares recorded receipt, log and block-lookup answers on net2040 (rpc-parity.test.ts).
  • xOnePy: namespaces eth, net, web3, xdpos and miner (policy.py). Its XDPoS methods are XDPoS_getEpochNumbersBetween, XDPoS_getLatestPoolStatus and XDPoS_getMasternodesByNumber (methods.py).
  • xOneC: the same three XDPoS methods (methods.cpp). eth_estimateGas is not wired to the executor yet: the handler in that file returns error -32000.

Sources