-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: wire new handlers to grpc (#22333)
Co-authored-by: Randy Grok <@faulttolerance.net> Co-authored-by: Julien Robert <[email protected]>
- Loading branch information
1 parent
8c24b6b
commit 62ddd3e
Showing
9 changed files
with
4,276 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
syntax = "proto3"; | ||
package cosmos.base.grpc.v2; | ||
|
||
import "google/protobuf/any.proto"; | ||
|
||
option go_package = "cosmossdk.io/server/v2/api/grpc"; | ||
|
||
// Service defines the gRPC service for query server for v2 | ||
service Service { | ||
// Query queries the server with a request, the request can be any sdk Msg. | ||
rpc Query(QueryRequest) returns (QueryResponse) {} | ||
|
||
// ListQueryHandlers lists all the available query handlers. | ||
rpc ListQueryHandlers(ListQueryHandlersRequest) returns (ListQueryHandlersResponse) {} | ||
} | ||
|
||
// QueryRequest is the request for the Query method | ||
message QueryRequest { | ||
google.protobuf.Any request = 1; | ||
} | ||
|
||
// QueryResponse is the response for the Query method | ||
message QueryResponse { | ||
google.protobuf.Any response = 1; | ||
} | ||
|
||
// ListQueryHandlersRequest is the request for the ListQueryHandlers method | ||
message ListQueryHandlersRequest {} | ||
|
||
// ListQueryHandlersResponse is the response for the ListQueryHandlers method | ||
message ListQueryHandlersResponse { | ||
repeated Handler handlers = 1; | ||
} | ||
|
||
// Handler defines a query handler | ||
message Handler { | ||
string request_name = 1; | ||
string response_name = 2; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package grpc | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/cosmos/gogoproto/proto" | ||
gogoproto "github.com/cosmos/gogoproto/types/any" | ||
"google.golang.org/grpc/codes" | ||
"google.golang.org/grpc/status" | ||
|
||
appmodulev2 "cosmossdk.io/core/appmodule/v2" | ||
"cosmossdk.io/core/transaction" | ||
) | ||
|
||
// v2Service implements the gRPC service interface for handling queries and listing handlers. | ||
type v2Service struct { | ||
queryHandlers map[string]appmodulev2.Handler | ||
queryable interface { | ||
Query(ctx context.Context, version uint64, msg transaction.Msg) (transaction.Msg, error) | ||
} | ||
} | ||
|
||
// Query handles incoming query requests by unmarshaling the request, processing it, | ||
// and returning the response in an Any protobuf message. | ||
func (s v2Service) Query(ctx context.Context, request *QueryRequest) (*QueryResponse, error) { | ||
if request == nil || request.Request == nil { | ||
return nil, status.Error(codes.InvalidArgument, "empty request") | ||
} | ||
|
||
msgName := request.Request.TypeUrl | ||
|
||
handler, exists := s.queryHandlers[msgName] | ||
if !exists { | ||
return nil, status.Errorf(codes.NotFound, "handler not found for %s", msgName) | ||
} | ||
|
||
protoMsg := handler.MakeMsg() | ||
if err := proto.Unmarshal(request.Request.Value, protoMsg); err != nil { | ||
return nil, status.Errorf(codes.InvalidArgument, "failed to unmarshal request: %v", err) | ||
} | ||
|
||
queryResp, err := s.queryable.Query(ctx, 0, protoMsg) | ||
if err != nil { | ||
return nil, status.Errorf(codes.Internal, "query failed: %v", err) | ||
} | ||
|
||
respBytes, err := proto.Marshal(queryResp) | ||
if err != nil { | ||
return nil, status.Errorf(codes.Internal, "failed to marshal response: %v", err) | ||
} | ||
|
||
anyResp := &gogoproto.Any{ | ||
TypeUrl: "/" + proto.MessageName(queryResp), | ||
Value: respBytes, | ||
} | ||
|
||
return &QueryResponse{Response: anyResp}, nil | ||
} | ||
|
||
func (s v2Service) ListQueryHandlers(_ context.Context, _ *ListQueryHandlersRequest) (*ListQueryHandlersResponse, error) { | ||
var handlerDescriptors []*Handler | ||
for handlerName := range s.queryHandlers { | ||
msg := s.queryHandlers[handlerName].MakeMsg() | ||
resp := s.queryHandlers[handlerName].MakeMsgResp() | ||
|
||
handlerDescriptors = append(handlerDescriptors, &Handler{ | ||
RequestName: proto.MessageName(msg), | ||
ResponseName: proto.MessageName(resp), | ||
}) | ||
} | ||
|
||
return &ListQueryHandlersResponse{Handlers: handlerDescriptors}, nil | ||
} |
Oops, something went wrong.