Internal/External
Internal
Area
Other (cardano-rpc / gRPC server)
Describe the feature you'd like
Implement the gRPC Server Reflection Protocol in cardano-rpc, so that clients can discover the available services, methods and message schemas from a running node.
Today the server registers four services (cardano.rpc.Node, utxorpc.v1beta.query.QueryService, utxorpc.v1beta.submit.SubmitService, utxorpc.v1beta.sync.SyncService) and nothing else.
A reflection probe (grpcurl ... list, Postman, evans, buf) falls into grapesy's automatic unknown-method path and is answered with a bare UNIMPLEMENTED status.
Clients therefore have to obtain and compile the .proto files (or a protoset) out of band before they can talk to the node at all.
This matters for ecosystem parity: Dolos, the other UTxO RPC node implementation, already serves reflection, and the utxorpc.org grpcurl guide assumes grpcurl -plaintext <node> list simply works against a UTxO RPC endpoint.
Anyone following that guide against cardano-rpc currently gets server does not support the reflection API.
Note that grapesy (1.1.1, our gRPC library) does not ship reflection support and has an open, unstarted feature request for it (well-typed/grapesy#43, open since November 2023).
So this needs to be implemented on our side (and could later be offered upstream).
Implementation sketch:
- Vendor the reflection protos (
grpc/reflection/v1/reflection.proto and the v1alpha variant, which older grpcurl/buf clients fall back to) under proto/ and regenerate with buf generate proto.
- Implement the bidi-streaming
ServerReflectionInfo handler in a new module (e.g. Cardano.Rpc.Server.Reflection), answering list_services, file_containing_symbol and file_by_filename; the proto2 extension requests can return NOT_FOUND since our protos use none.
- The descriptor data is already embedded in our generated code: every proto-lens module in
gen/ exposes the serialised FileDescriptorProto as packedFileDescriptor, so no protoc step is needed at runtime. Well-known types (google.protobuf.*) descriptors come from proto-lens-protobuf-types. Responses must include the full transitive dependency closure of each file, which is the one fiddly part.
- Register the handler as an additional
fromMethods entry in Cardano.Rpc.Server, for both the v1 and v1alpha service names.
- Advertise via
list_services only the services actually registered (the four above plus reflection itself).
Scope note: reflection is file-level, so describe output will also show proto-declared methods that cardano-rpc does not implement yet (e.g. DumpHistory); calling those keeps returning UNIMPLEMENTED, which is the standard behaviour and matches the coverage table in the README.
Acceptance criteria:
grpcurl -unix -plaintext <rpc socket> list lists the registered services without any local proto files (the server listens on a Unix socket).
grpcurl -unix -plaintext <rpc socket> describe utxorpc.v1beta.query.QueryService returns the full service schema.
- Both
grpc.reflection.v1.ServerReflection and grpc.reflection.v1alpha.ServerReflection probes are answered.
- A cardano-testnet integration test exercises reflection against a running node.
Describe alternatives you've considered
- Contribute reflection support to grapesy itself (well-typed/grapesy#43) and consume it here. Cleaner for the wider Haskell ecosystem, but gated on upstream review and a CHaP release; implementing in cardano-rpc first and upstreaming later keeps both options open.
- Status quo plus a documented workaround: publish a pre-compiled protoset and document
grpcurl -protoset. Poor developer experience, and it diverges from the expectation the rest of the UTxO RPC ecosystem already sets.
Additional context / screenshots
Internal/External
Internal
Area
Other (cardano-rpc / gRPC server)
Describe the feature you'd like
Implement the gRPC Server Reflection Protocol in cardano-rpc, so that clients can discover the available services, methods and message schemas from a running node.
Today the server registers four services (
cardano.rpc.Node,utxorpc.v1beta.query.QueryService,utxorpc.v1beta.submit.SubmitService,utxorpc.v1beta.sync.SyncService) and nothing else.A reflection probe (
grpcurl ... list, Postman, evans, buf) falls into grapesy's automatic unknown-method path and is answered with a bareUNIMPLEMENTEDstatus.Clients therefore have to obtain and compile the
.protofiles (or a protoset) out of band before they can talk to the node at all.This matters for ecosystem parity: Dolos, the other UTxO RPC node implementation, already serves reflection, and the utxorpc.org grpcurl guide assumes
grpcurl -plaintext <node> listsimply works against a UTxO RPC endpoint.Anyone following that guide against cardano-rpc currently gets
server does not support the reflection API.Note that grapesy (1.1.1, our gRPC library) does not ship reflection support and has an open, unstarted feature request for it (well-typed/grapesy#43, open since November 2023).
So this needs to be implemented on our side (and could later be offered upstream).
Implementation sketch:
grpc/reflection/v1/reflection.protoand thev1alphavariant, which older grpcurl/buf clients fall back to) underproto/and regenerate withbuf generate proto.ServerReflectionInfohandler in a new module (e.g.Cardano.Rpc.Server.Reflection), answeringlist_services,file_containing_symbolandfile_by_filename; the proto2 extension requests can returnNOT_FOUNDsince our protos use none.gen/exposes the serialisedFileDescriptorProtoaspackedFileDescriptor, so no protoc step is needed at runtime. Well-known types (google.protobuf.*) descriptors come fromproto-lens-protobuf-types. Responses must include the full transitive dependency closure of each file, which is the one fiddly part.fromMethodsentry inCardano.Rpc.Server, for both the v1 and v1alpha service names.list_servicesonly the services actually registered (the four above plus reflection itself).Scope note: reflection is file-level, so
describeoutput will also show proto-declared methods that cardano-rpc does not implement yet (e.g.DumpHistory); calling those keeps returningUNIMPLEMENTED, which is the standard behaviour and matches the coverage table in the README.Acceptance criteria:
grpcurl -unix -plaintext <rpc socket> listlists the registered services without any local proto files (the server listens on a Unix socket).grpcurl -unix -plaintext <rpc socket> describe utxorpc.v1beta.query.QueryServicereturns the full service schema.grpc.reflection.v1.ServerReflectionandgrpc.reflection.v1alpha.ServerReflectionprobes are answered.Describe alternatives you've considered
grpcurl -protoset. Poor developer experience, and it diverges from the expectation the rest of the UTxO RPC ecosystem already sets.Additional context / screenshots