#36175 rpc: Stamp `getblock` OpenRPC result discriminator
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #36175 rpc: Stamp `getblock` OpenRPC result discriminator | Ready | 1 | Strong | 43 + 11 tests | |||
|
|
|
|
| |||
Reviewability: ReadyStalePaused Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs. Size: lines added or modified outside tests, then in tests; greener = smaller. | |||||||
Goal
This pull request adds an `RPCResultDiscriminator` metadata structure to RPC result definitions and emits it in OpenRPC specifications as `x-bitcoin-discriminated-result`. It applies this discriminator to the `getblock` RPC method to explicitly map `verbosity` integer values (0, 1, 2, 3) to its four `oneOf` result schema branches. It also updates the schema and `getblock` help text to clarify that responses for verbosity 2 and 3 cannot be reliably distinguished by response validation alone.
Problem: OpenRPC documents `getblock` result variants as a `oneOf` union across `verbosity` levels, but the schema provides no machine-readable metadata mapping specific parameter values to their respective result branches. Consequently, client libraries and code generators (such as corepc or btcd) that expose typed return values per verbosity level must hardcode the mapping. Furthermore, verbosity 2 and 3 responses can be structurally identical (e.g., for blocks with no spent inputs), preventing clients from reliably distinguishing the schema branch by validating response payloads alone.
Evidence of importance:
- PR description: "OpenRPC documents `getblock` as a four-way `oneOf` on `verbosity`, but the dump does not say which integer selects which arm. Therefore, clients that expose a type or method per verbosity (e.g. corepc, btcd) have to hardcode that map."
- Commit 7571e8dd4c diff in `src/rpc/blockchain.cpp`: "The verbosity = 2 and verbosity = 3 result schemas cannot be distinguished by validating a response alone because a block with no spent inputs returns byte-identical JSON at both levels (a coinbase input has no prevout to add), and the verbosity = 3 schema lists prevout as optional, so both object arms accept both responses."
Reviewability
Ready
Nothing known that would invalidate a review now.
Waiting on (from the thread read):
- reviewer: maflcko to review author's reply regarding discriminating one RPC at a time 2026-10-25
Agreement
Strong
substantive support, no open objection (willcl-ark)
Thread notes: Author replied to maflcko's question explaining the approach of discriminating one RPC at a time starting with getblock.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| jeanpablojp (contributor) | suggestion, correctness | Pin the relations behind discriminator literals by comparing parameter names and checking prevout differences in tests | fixed · fix pushed · author updated functional tests to assert the relations | answered | yes | 2026-09-06: 'The test asserts the discriminator's literals rather than the two relations behind them... Worth pinning them?' Status from: 2026-09-07: nervana21: 'Good catch, thanks! I've updated the tests according to your suggestion' |
| jeanpablojp (contributor) | question, approach | Ask if the integer form for RPCResultDiscriminator was deliberate for a first pass rather than UniValue | answered · author confirmed it was deliberate and preferred adding overloads when used | answered | yes | 2026-09-06: 'Is the integer form deliberate for a first pass?' Status from: 2026-09-07: nervana21: 'Yes, the integer form was done deliberately on this first pass. Would prefer to add overloads in specific commits that u' |
| jeanpablojp (contributor) | suggestion, interface | Document x-bitcoin-discriminated-result and x-bitcoin-default-hint in the schema description fields | fixed · fix pushed · author added documentation to schema fields | answered | yes | 2026-09-06: 'Worth a line for `x-bitcoin-discriminatedResult` too? The parameter-side `schema` field next to it has the same gap for `x-bitcoin-default-hint`' Status from: 2026-09-07: nervana21: 'Done.' |
| jeanpablojp (contributor) | suggestion, interface | Explain in getblock description that validating cannot distinguish verbosity 2 and 3 when blocks have no spends | fixed · fix pushed · author updated description in help text | answered | yes | 2026-09-06: 'Worth putting in the description? Validating cannot pick the arm either, because a block with no spends comes back byte identical at verbosity 2 and 3' Status from: 2026-09-07: nervana21: 'Done.' |
| maflcko (member) | question, correctness | Ask what the static_cast<int> in server.cpp is for | fixed · fix pushed · author removed the cast in an update | answered | yes | 2026-09-17: 'What is this cast for?' Status from: 2026-09-17: nervana21: 'I've removed the cast. I had initially used it to get around an error that I can no longer reproduce' |
| maflcko (member) | suggestion, approach | Question why only getblock is discriminated rather than all results or introducing an Undiscriminated wrapper | answered · author explained they planned to go one by one starting with getblock | answered | yes | 2026-10-20: 'I am asking because clients would either care to have all of them discriminated, or none? What is so special about `getblock`?' Status from: 2026-10-25: nervana21: 'I had planned to go one by one for the RPCs that are selected by a request parameter. `getblock` seems to be a more commonly used and complex RPC' |
Support:
- jeanpablojp (contributor) (Concept ACK, 2026-09-06): no reason given: Concept ACK [not substantive]
- willcl-ark (member) (ACK, 2026-09-21) [read]: RPCResultDiscriminator seems like a fair concept to use here, and alternatives like attaching verbosity directly to RPCResult arms would be overkill for one current use
Participants:
- jeanpablojp (contributor, support, 4 statements 2026-09-06 to 2026-09-06): Concept ACK; suggested test assertions and schema documentation updates
- maflcko (member, question, 2 statements 2026-09-17 to 2026-10-20): asked why static_cast<int> was needed, and asked why only getblock is discriminated rather than all results
- willcl-ark (member, support, 1 statements 2026-09-21 to 2026-09-21): ACK; considers RPCResultDiscriminator a fair approach and simpler than alternatives
Files
11 lines under test/bench/ci.
- src/rpc/util.h +23/-0
- src/rpc/server.cpp +15/-2
- test/functional/rpc_openrpc.py +11/-0
- src/rpc/blockchain.cpp +5/-3
Card
The short text the ranking pass compares across PRs.
This pull request introduces an OpenRPC result discriminator extension and stamps it onto `getblock`. OpenRPC documents `getblock` as a four-way `oneOf` union across verbosity levels, but currently provides no machine-readable link between parameter values and schema arms, forcing client libraries and code generators to hardcode the mapping. The PR adds `RPCResultDiscriminator` emitted as `x-bitcoin-discriminated-result` mapping `verbosity` values {0, 1, 2, 3} to their respective result schemas, and notes in the documentation that verbosity 2 and 3 cannot be told apart by payload validation alone. Strongest evidence comes from the PR description noting typed client generators like corepc and btcd currently have to hardcode these mappings.
Data
thread read through 2026-10-25 (15 statements), head 85f2993079
labels: RPC/REST/ZMQ
Categories
RPC / REST / ZMQ
P3 · new feature (ranking pass: Moved down 9: metadata for one method, benefiting code generators only.)
Adds machine-readable discriminator metadata to OpenRPC schemas to eliminate hardcoded mappings in typed client libraries. The PR description notes that client libraries like corepc and btcd currently have to hardcode the mapping between verbosity levels and getblock result branches.
Membership: Matches the RPC/REST/ZMQ label and modifies RPC metadata and schema generation in src/rpc/util.h, src/rpc/server.cpp, and src/rpc/blockchain.cpp.
Factors: security/stability 0, bug 0, performance 0, user value 1, leverage 0