Skip to content

cardano-rpc: Implement gRPC server reflection (grpc.reflection.v1 and v1alpha) - #1334

Open
carbolymer wants to merge 2 commits into
masterfrom
mgalazyn/feature/grpc-reflection
Open

cardano-rpc: Implement gRPC server reflection (grpc.reflection.v1 and v1alpha)#1334
carbolymer wants to merge 2 commits into
masterfrom
mgalazyn/feature/grpc-reflection

Conversation

@carbolymer

@carbolymer carbolymer commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Description

Implements the gRPC Server Reflection Protocol in cardano-rpc, so clients can discover the available services, methods and message schemas from a running node without local .proto files.

Closes #1295.

What this adds:

  • Both grpc.reflection.v1.ServerReflection and the older grpc.reflection.v1alpha.ServerReflection are served, so current and legacy probes (grpcurl, Postman, buf, evans) both work.
  • The protos are vendored from grpc v1.66.0 and generated through the existing buf generate proto pipeline.
  • One handler core serves both versions: the two proto packages are structurally identical, so v1alpha requests and responses are bridged by transcoding across identical field numbers.
  • A compiled-in descriptor table covers all nine proto files (the five cardano-rpc protos, two google well-known types, and the two reflection protos) and answers file_by_filename and file_containing_symbol with the full transitive dependency closure. A unit test asserts the table stays closed under the descriptors' dependency field, so adding a proto without updating the table fails the test suite.
  • list_services derives its answer from the same service definitions that are registered in the server, so the advertised list cannot drift from what is actually served.
  • The proto2 extension queries (file_containing_extension, all_extension_numbers_of_type) answer NOT_FOUND, since none of our protos use extensions.

Design note for reviewers: lookup failures are answered with an in-stream ErrorResponse and the RPC stays OK, as the protocol specifies. A request with an entirely unset message_request oneof is answered with an in-stream INVALID_ARGUMENT error response; Go's reference implementation terminates the RPC instead, so this is a deliberate, tested divergence.

Testing: the cardano-rpc unit test suite covers the descriptor closure, symbol lookup, error paths, the v1alpha bridge and the terminal stream element (all 123 tests pass under the repo's -Werror nix check). A wire-level integration test against a running node via cardano-testnet follows in a separate cardano-node PR, which will also add grpcurl to the devshell for manual probes.


Context

Additional context for the PR goes here. If the PR fixes a particular issue please provide a link to the issue.

How to trust this PR

Highlight important bits of the PR that will make the review faster. If there are commands the reviewer can run to observe the new behavior, describe them.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. See Running tests for more details
  • Self-reviewed the diff
  • Changelog fragment added in .changes/

@@ -0,0 +1,257 @@
{- This file was auto-generated from grpc/reflection/v1/reflection.proto by the proto-lens-protoc program. -}
{-# LANGUAGE ScopedTypeVariables, DataKinds, TypeFamilies, UndecidableInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, PatternSynonyms, MagicHash, NoImplicitPrelude, DataKinds, BangPatterns, TypeApplications, OverloadedStrings, DerivingStrategies#-}
@@ -0,0 +1,257 @@
{- This file was auto-generated from grpc/reflection/v1/reflection.proto by the proto-lens-protoc program. -}
{-# LANGUAGE ScopedTypeVariables, DataKinds, TypeFamilies, UndecidableInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, PatternSynonyms, MagicHash, NoImplicitPrelude, DataKinds, BangPatterns, TypeApplications, OverloadedStrings, DerivingStrategies#-}
@carbolymer carbolymer changed the title Mgalazyn/feature/grpc reflection cardano-rpc: Implement gRPC server reflection (grpc.reflection.v1 and v1alpha) Sep 9, 2026
@carbolymer
carbolymer force-pushed the mgalazyn/feature/grpc-reflection branch from c15e3df to 8aeebe8 Compare September 9, 2026 14:00
@carbolymer carbolymer self-assigned this Sep 9, 2026
@carbolymer
carbolymer force-pushed the mgalazyn/feature/grpc-reflection branch from 8aeebe8 to 4946bf3 Compare September 10, 2026 16:37
@carbolymer
carbolymer marked this pull request as ready for review September 10, 2026 16:38
Copilot AI lite review requested due to automatic review settings September 10, 2026 16:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The reflection handler’s treatment of all_extension_numbers_of_type as NOT_FOUND (rather than an empty response / UNIMPLEMENTED semantics) and the unexplained cardano-api lower-bound bump should be addressed/justified before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR adds gRPC Server Reflection support to cardano-rpc, serving both grpc.reflection.v1 and legacy grpc.reflection.v1alpha so clients can discover services and schemas from a running node without local .proto files.

Changes:

  • Implemented a reflection handler plus a compiled-in descriptor table with symbol lookup and transitive dependency closure.
  • Registered both reflection services in the server and derived list_services from the same registry used for handler registration.
  • Added unit tests for descriptor closure/symbol lookup and for v1/v1alpha request/response bridging; updated docs, cabal, and changelog fragment.
File summaries
File Description
cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/Reflection/DescriptorTable.hs Unit tests for descriptor table closure, symbol indexing rules, and transitive closure behavior.
cardano-rpc/test/cardano-rpc-test/Test/Cardano/Rpc/Reflection.hs Unit tests for request dispatch, error-path behavior, terminal stream marker, and v1alpha bridging.
cardano-rpc/src/Cardano/Rpc/Server/Internal/Reflection/DescriptorTable.hs Implements descriptor table + symbol index + transitive closure over compiled-in protos.
cardano-rpc/src/Cardano/Rpc/Server/Internal/Reflection.hs Implements v1 reflection bidi handler and v1alpha bridge, plus request dispatch.
cardano-rpc/src/Cardano/Rpc/Server.hs Registers reflection services and centralizes the registered service list used by reflection.
cardano-rpc/src/Cardano/Rpc/Proto/Api/Reflection/V1alpha.hs Exposes v1alpha reflection proto modules and sets grapesy metadata type families.
cardano-rpc/src/Cardano/Rpc/Proto/Api/Reflection/V1.hs Exposes v1 reflection proto modules and sets grapesy metadata type families.
cardano-rpc/README.md Documents reflection support as an additional gRPC service.
cardano-rpc/proto/grpc/reflection/v1alpha/reflection.proto Vendors the upstream v1alpha reflection proto definition.
cardano-rpc/proto/grpc/reflection/v1/reflection.proto Vendors the upstream v1 reflection proto definition.
cardano-rpc/gen/Proto/Grpc/Reflection/V1alpha/Reflection.hs Generated proto-lens bindings for the v1alpha reflection proto.
cardano-rpc/gen/Proto/Grpc/Reflection/V1alpha/Reflection_Fields.hs Generated field lenses for v1alpha reflection messages.
cardano-rpc/gen/Proto/Grpc/Reflection/V1/Reflection_Fields.hs Generated field lenses for v1 reflection messages.
cardano-rpc/cardano-rpc.cabal Adds reflection modules/tests, adds proto-lens-protobuf-types to tests, and bumps cardano-api lower bound.
.changes/20260909_cardano_rpc_grpc_reflection.yml Adds changelog fragment describing the new reflection feature.
Review details
  • Files reviewed: 14/16 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +126 to +128
V1.ServerReflectionRequest'AllExtensionNumbersOfType typeName ->
V1.errorResponse
.~ mkErrorResponse GrpcNotFound ("no extensions are declared of type: " <> typeName)
Comment on lines 100 to +103
base,
base16-bytestring,
bytestring,
cardano-api >=11.5,
cardano-api >=11.7,
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.

[FR] - cardano-rpc: implement gRPC server reflection (grpc.reflection.v1)

3 participants