Files
bitcoin/src/test/fuzz
Ava Chow 526673487c Merge bitcoin/bitcoin#34683: rpc: support a formal description of our JSON-RPC interface
ca9ffb8e12 rpc: add OpenRPC discovery alias (willcl-ark)
ef0676f400 rpc: factor getaddressinfo embedded field docs (will)
1fb6b60560 test: add functional test for getopenrpcinfo (will)
672dd42d14 rpc: add getopenrpcinfo command (will)
f5116c587f rpc: add placeholder annotation for deprecated params (will)
26c221a980 rpc: expose RPC metadata for introspection (will)
6a1a66c180 rpc: render Type::ANY in help text instead of aborting (will)
06de34a033 rpc: erase empty map entry in removeCommand (will)
d4d64ae739 rpc: add missing string_view include to server.h (will)

Pull request description:

  Fixes #29912

  This PR adds a machine-readable[ OpenRPC](https://www.open-rpc.org/) 1.4.1 specification of out JSON-RPC interface, auto-generated from existing `RPCHelpMan` metadata.

  There is currently no formal, machine-readable specification of the RPC API. As discussed in #29912, this has knock-on consequences:

  - Client libraries re-implement the API manually, leading to bugs like unit mistakes (sats vs BTC, vB vs kvB) and missing/incorrect argument types. No existing client library fully and correctly implements the API in a type-safe manner.
  - When the API changes, every downstream client must manually discover and adapt, creating downstream maintenance burden. There is no artifact they can diff between releases.
  - Implementing a new client in a new language requires reading C++ source or help text and transcribing it, which is error-prone and tedious, and represents an on-going porting cost.
  - Existing documentation is either stale or not machine-readable. The developer.bitcoin.org docs are wrong/outdated in places, and the bitcoincore.org/en/doc/ pages are rendered from help output but not in a standard schema format.
  - (new/extra) AI/LLM tooling increasingly builds on structured API specifications. A standard spec format enables AI-assisted client generation and integration without the ambiguity of parsing human-readable help text.

  This draft builds on prior art by casey and the observations by laanwj, stickies-v, kilianmh, hodlinator, and cdecker in #29912. Casey's work demonstrated that RPCHelpMan already contains all the structured information needed, which makes this feasible without duplicating any API definitions.

  This differs from Casey's branches in that it uses the OpenRPC standard rather than an ad-hoc format or raw JSON Schema.

  ### Why OpenRPC

  I seletced OpenRPC for a number of reasons:

  - It's purpose-built for JSON-RPC APIs (suggested by stickies-v,nflatrea, and kilianmh).
  - It wraps JSON schema for params/results, so consumers get both the method-level structure and the type-level schemas.
  - Unlike OpenAPI, it is not path-centric, which better fits our single-endpoint JSON-RPC model (concern raised by hodlinator).
    - Although it therefore does not cover our REST interface.
  - It's _kind of_ a standard format with (_some_) existing tooling for type generation (TypeScript, Rust, Python, Go) and client scaffolding, though maturity varies by language. More importantly though, IMO, a ~standardised format is inherently more useful than any ad-hoc one: any JSON Schema validator works, any LLM can consume it directly, and anyone can write a bespoke generator against a known schema rather than parsing help text.

  ### Approach

  `RPCHelpMan` metadata → `getopenrpcinfo` / `rpc.discover` → OpenRPC JSON

  ### Tradeoffs

  vs an ad-hoc format OpenRPC gives us interoperability with the (admittedly surprisingly limited) tooling, documentation generators, code generators, and validators, at the cost of needing x-bitcoin-* extensions for Bitcoin-specific concepts. As Casey noted after trying both approaches, JSON Schema "is probably not a great fit". OpenRPC's method-level framing on top of JSON Schema addresses the ergonomic issues while keeping the schema benefits. After testing both, I think I agree.

  Types: JSON Schema cannot natively express all Bitcoin-specific semantics. Amount result fields are represented as JSON numbers with `x-bitcoin-unit: amount`; other Bitcoin-specific distinctions remain in descriptions or `x-bitcoin-*` extensions. More structured unit metadata and stronger constraints can be added in follow-up work.

  Some RPCs return different types depending on argument values (e.g. verbosity levels). These are represented as `oneOf` in the result schema with free-text condition descriptions. This is accurate but not fully machine-parseable — a code generator cannot automatically determine which result variant corresponds to which argument value without parsing the description. I still we have enough information to satisfy humans an agents alike though.

  ### Regenerating the spec

  The functional test invokes both RPCs, verifies valid JSON, checks public and hidden RPC handling, and covers representative generated schemas. It does not compare a committed generated artifact.

  `getopenrpcinfo` omits hidden RPCs and arguments by default; `getopenrpcinfo(true)` includes them. The standard parameterless `rpc.discover` method returns the public document.

  The RPC output documents which RPCs are available for any given built binary.

  ### Discussion questions

  - Is this valuable/wanted?
  - Do we like openrpc format? (less relevant if we don't want this in this repo, as another repo could generate one or many definitions).
  - Should we cover "hidden" RPCs? They are currently hidden, but don't have to be...

  My personal thoughts are that this is very nice to have.

ACKs for top commit:
  dergoegge:
    ACK ca9ffb8e12
  achow101:
    ACK ca9ffb8e12
  sedited:
    ACK ca9ffb8e12
  w0xlt:
    ACK ca9ffb8e12

Tree-SHA512: 5bf7abdb9f119d591306884f31b9da815908e5cb5812706c5496b39162c22cd949465d7b3ff1fdce7ff5b3c1b6367c14b6d28d58dee86698c0161d4d844d84c9
2026-07-23 10:57:25 -07:00
..
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-17 22:55:22 -07:00
2026-05-12 21:24:19 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-14 13:48:33 +02:00
2026-07-03 18:26:26 +01:00
2026-07-14 13:48:33 +02:00