72 lines
2.2 KiB
Go
72 lines
2.2 KiB
Go
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 func(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(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
|
|
}
|