[docs-agent] Add debug_executePayload and debug_proofsSyncStatus method definitions for Base#1453
[docs-agent] Add debug_executePayload and debug_proofsSyncStatus method definitions for Base#1453alchemy-bot wants to merge 2 commits into
Conversation
…od definitions for Base
Adds OpenRPC method definitions for two Base debug endpoints served by Base's historical proofs execution extension (ExEx):
* debug_executePayload: re-execute a payload on top of a parent block and return the execution witness (state / codes / keys / headers preimages). Used by fault-proof provers and stateless clients.
* debug_proofsSyncStatus: return the currently indexed block range of the historical proofs store as { earliest, latest }.
Definitions land in src/openrpc/chains/_components/custom/methods.yaml (matching the location of the existing debug_executionWitness / debug_executionWitnessByHash entries). Supporting schemas (ExecutionWitness, OpPayloadAttributes) live in a new src/openrpc/chains/_components/custom/debug.yaml.
Does NOT modify base.yaml $ref list or base-api-overview.mdx: those additions are handled by Daikon in PR #1447, which was blocked on these two definitions being missing. Once this PR merges, #1447 can rebase and its $refs will resolve cleanly.
Sources for the schema:
* base/base crates/execution/rpc/src/{debug,witness}.rs: canonical trait definitions for DebugExecutionWitnessApi::execute_payload and DebugApiOverride::proofs_sync_status, plus the ProofsSyncStatus struct.
* ethereum-optimism/optimism rust/op-reth/crates/rpc/src/debug.rs and docs/public-docs/node-operators/{reference/op-reth-historical-proof-config,tutorials/reth-historical-proofs}.mdx: identical signatures and "{ earliest, latest }" result envelope.
* alloy-rs/alloy crates/rpc-types-debug/src/execution_witness.rs: authoritative ExecutionWitness struct (state, codes, keys, headers).
* alloy-rs/op-alloy crates/rpc-types-engine/src/attributes.rs: authoritative OpPayloadAttributes struct (payload_attributes flattened via serde flatten, plus transactions/no_tx_pool/gas_limit/eip_1559_params/min_base_fee, camelCase serialization).
* Base's official docs at docs.base.org/base-chain/node-operators/run-a-base-node reference both methods.
* Live smoke test against https://base-mainnet.g.alchemy.com/v2/docs-demo:
- debug_proofsSyncStatus with params [] returned {earliest: 47338810, latest: 48634815}, matching the two-field envelope.
- debug_executePayload with a real parent hash and full OpPayloadAttributes (including eip1559Params and minBaseFee, since Jovian is active on Base mainnet) returned an ExecutionWitness with fields state (50 entries), codes (2), keys (6), headers (0), matching the schema field-for-field.
- debug_executePayload with an all-zero parent hash returned -32603 "no header found for Hash(...)", matching the documented error path.
Validation: pnpm run generate:rpc + pnpm run validate:rpc both pass; prettier clean on both files.
Refs DOCS-137
Requested-by: @dslovinsky
🔗 Preview Mode
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c623c73c8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| oneOf: | ||
| - $ref: "../evm/base-types.yaml#/components/schemas/uint64" | ||
| - type: "null" |
There was a problem hiding this comment.
Use numeric schema for proofs sync blocks
When debug_proofsSyncStatus has indexed blocks, the Base API returns earliest and latest as JSON numbers (the example immediately below also uses numbers), but this schema only allows the EVM uint64 hex string or null. Generated docs, clients, or response validators will reject real non-null responses from this method; model these fields as non-negative integers plus null instead of uint64.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 44196d3. You're right — ../evm/base-types.yaml#/components/schemas/uint64 is a hex-encoded string schema (type: string, pattern: ^0x([1-9a-f]+[0-9a-f]{0,15})|0$), but Base's debug_proofsSyncStatus returns raw JSON numbers.
Just re-verified against base-mainnet.g.alchemy.com/v2/docs-demo: earliest: 47345687, latest: 48641705, both type: "number" in the live response. Swapped the $ref for an inline { type: integer, minimum: 0 } in the oneOf and added a description note calling out the JSON-number serialization so this doesn't get re-introduced later.
pnpm run generate:rpc + pnpm run validate:rpc both pass on the updated commit.
…mbers, not hex uint64 Addresses Codex P2 review comment on PR #1453: my previous schema declared `earliest` and `latest` as `oneOf: [uint64, null]`, but Base's `uint64` schema is a hex-encoded string (`^0x([1-9a-f]+[0-9a-f]{0,15})|0$`). The server actually returns raw JSON numbers, so generated clients and response validators would reject valid non-null responses. Verified with a fresh live call to `base-mainnet.g.alchemy.com/v2/docs-demo`: `result.earliest` = 47345687 (jq `type` -> "number") `result.latest` = 48641705 (jq `type` -> "number") Fix: replace the `uint64` $ref with an inline `{ type: integer, minimum: 0 }` in the `oneOf`, and add a description note that the serialization is a JSON number (not hex) so future readers do not re-introduce the mistake. Validation: `pnpm run generate:rpc` + `pnpm run validate:rpc` both pass; prettier clean. Refs DOCS-137 Requested-by: @dslovinsky
Summary
Adds OpenRPC method definitions for two Base debug endpoints that Daikon PR #1447 tried to $ref but that had no matching definition anywhere in
_components/:debug_executePayload— re-executes a payload on top of a parent block and returns the resulting execution witness (state/codes/keys/headerspreimages). Used by fault-proof provers and stateless clients.debug_proofsSyncStatus— returns the currently indexed block range of the node's historical proofs execution extension (ExEx) as{ earliest, latest }.debug_executionWitness(the third method Daikon #1447 references) already has a definition in_components/custom/methods.yaml, so it is left alone.Changes
src/openrpc/chains/_components/custom/methods.yaml— two new method entries added right after the existingdebug_executionWitnessByHashentry, before the Stellar section. Both$refinto a new sibling schemas file.src/openrpc/chains/_components/custom/debug.yaml— new file with supporting schemas:ExecutionWitness(state,codes,keys,headers— allVec<Bytes>) andOpPayloadAttributes(Engine-APIPayloadAttributesfields flattened, plus rollup-specifictransactions/noTxPool/gasLimit/eip1559Params/minBaseFee).Does NOT modify
src/openrpc/chains/base/base.yamlorcontent/api-reference/base/base-api-overview.mdx: those additions are handled by Daikon in PR #1447, which was blocked on these two definitions being missing. Once this PR merges, #1447 can rebase and its$refs will resolve cleanly.Sources for the schema
base/base—crates/execution/rpc/src/witness.rsdefines theDebugExecutionWitnessApitrait withexecute_payload(parent_block_hash: B256, attributes: Attributes) -> RpcResult<ExecutionWitness>.crates/execution/rpc/src/debug.rsdefines theDebugApiOverridetrait withexecute_payload,execution_witness, andproofs_sync_status, plus the concreteProofsSyncStatus { earliest: Option<u64>, latest: Option<u64> }struct.crates/execution/exex/README.mddocuments the intended behavior verbatim:debug_proofsSyncStatus → { "earliest": <block>, "latest": <block> }.ethereum-optimism/optimism—rust/op-reth/crates/rpc/src/debug.rshas an identicalDebugApiOverride<Attributes>trait andProofsSyncStatusstruct (Base and op-reth share the same schema). The op-reth historical proof config reference and tutorial document the RPC surface publicly.alloy-rs/alloy—crates/rpc-types-debug/src/execution_witness.rsis the authoritativeExecutionWitnessstruct:state,codes,keys,headers, eachVec<Bytes>. Field docstrings feed the descriptions indebug.yaml.alloy-rs/op-alloy—crates/rpc-types-engine/src/attributes.rsis the authoritativeOpPayloadAttributesstruct with#[serde(rename_all = "camelCase")]and#[serde(flatten)] payload_attributes, plustransactions/no_tx_pool/gas_limit/eip_1559_params/min_base_fee. The camelCase field names in the OpenRPC schema mirror this exactly.debug_executePayloadanddebug_executionWitnessby name in the context of the historical proofs ExEx.https://base-mainnet.g.alchemy.com/v2/docs-demo:debug_proofsSyncStatuswithparams: []→200 OKwith{ "earliest": 47338810, "latest": 48634815 }(matches the two-field envelope).debug_executePayloadwith a real parent hash + fullOpPayloadAttributes(includingeip1559Params: "0x000000fa00000006"andminBaseFee: 0, since Jovian is active on Base mainnet) →200 OKwith{"codes": [...], "headers": [], "keys": [...], "state": [...]}— fields match the schema key-for-key.debug_executePayloadwith an all-zero parent hash →-32603 "no header found for Hash(0x0000...)", matching the documented internal error path.debug_executePayloadwithparams: []→-32602 "Invalid params", matching the documented invalid-params error.debug_executePayloadwithminBaseFeeomitted →-32603 "Minimum base fee cannot be None after Jovian", confirming thatminBaseFeeis required for Base mainnet payloads today (documented in the method description).Validation
pnpm run generate:rpc— succeeded.pnpm run validate:rpc— passed both json-rpc and chains OpenRPC specs.$refs are applied locally tobase.yaml,generate:rpcproducescontent/api-specs/chains/base.jsoncontaining all threedebug_*methods andvalidate:rpcstill passes (that scratch change was reverted; docs(specs): update OpenRPC specifications from Daikon [Bot] #1447 owns the ref additions).npx prettier --check— clean on both changed files.Linear
DOCS-137 (originally scoped to the Solana
getTokenAccountsByOwnerAtSlotmethod, extended by follow-up from @dslovinsky in the Daikon PR #1447 notification thread; the Solana half landed in PR #1444).Requested by
@dslovinsky (via Slack thread)