mukan-ibc/e2e/testsuite/query/grpc_query.go
Mukan Erkin Törük 6852832fe8
Some checks failed
CodeQL / Analyze (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (push) Waiting to run
golangci-lint / lint (push) Waiting to run
Tests / Code Coverage / build (amd64) (push) Waiting to run
Tests / Code Coverage / build (arm64) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[additional-args:-tags="test_e2e" name:e2e path:./e2e]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:08-wasm path:./modules/light-clients/08-wasm]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:ibc-go path:.]) (push) Waiting to run
Deploy to GitHub Pages / Deploy to GitHub Pages (push) Has been cancelled
Buf-Push / push (push) Has been cancelled
initial: sovereign Mukan Network fork
2026-05-11 03:18:28 +03:00

161 lines
4.6 KiB
Go

package query
import (
"context"
"fmt"
"strings"
"github.com/cosmos/gogoproto/proto"
"github.com/cosmos/interchaintest/v10/ibc"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
pb "google.golang.org/protobuf/proto"
msgv1 "cosmossdk.io/api/cosmos/msg/v1"
reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
"github.com/cosmos/ibc-go/e2e/testvalues"
)
var queryReqToPath = make(map[string]string)
func PopulateQueryReqToPath(ctx context.Context, chain ibc.Chain) error {
if !testvalues.ReflectionServiceFeatureReleases.IsSupported(chain.Config().Images[0].Version) {
return nil
}
resp, err := queryFileDescriptors(ctx, chain)
if err != nil {
return err
}
for _, fileDescriptor := range resp.Files {
for _, service := range fileDescriptor.GetService() {
// Skip services that are annotated with the "cosmos.msg.v1.service" option.
if ext := pb.GetExtension(service.GetOptions(), msgv1.E_Service); ext != nil {
if ok, extBool := ext.(bool); ok && extBool {
continue
}
}
for _, method := range service.GetMethod() {
// trim the first character from input which is a dot
queryReqToPath[method.GetInputType()[1:]] = fileDescriptor.GetPackage() + "." + service.GetName() + "/" + method.GetName()
}
}
}
return nil
}
// GRPCQuery queries the chain with a query request and deserializes the response to T
func GRPCQuery[T any](ctx context.Context, chain ibc.Chain, req proto.Message, opts ...grpc.CallOption) (*T, error) {
var path string
if testvalues.ReflectionServiceFeatureReleases.IsSupported(chain.Config().Images[0].Version) {
var ok bool
path, ok = queryReqToPath[proto.MessageName(req)]
if !ok {
return nil, fmt.Errorf("no path found for %s", proto.MessageName(req))
}
} else {
var err error
path, err = getProtoPath(req)
if err != nil {
return nil, err
}
}
return grpcQueryWithMethod[T](ctx, chain, req, path, opts...)
}
// grpcQueryWithMethod queries the chain with a query request with a specific method (grpc path) and deserializes the response to T
func grpcQueryWithMethod[T any](ctx context.Context, chain ibc.Chain, req proto.Message, method string, opts ...grpc.CallOption) (*T, error) {
// Create a connection to the gRPC server.
grpcConn, err := grpc.Dial(
chain.GetHostGRPCAddress(),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
return nil, err
}
defer grpcConn.Close()
resp := new(T)
err = grpcConn.Invoke(ctx, method, req, resp, opts...)
if err != nil {
return nil, err
}
return resp, nil
}
func queryFileDescriptors(ctx context.Context, chain ibc.Chain) (*reflectionv1.FileDescriptorsResponse, error) {
// Create a connection to the gRPC server.
grpcConn, err := grpc.Dial(
chain.GetHostGRPCAddress(),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
return nil, err
}
defer grpcConn.Close()
resp := new(reflectionv1.FileDescriptorsResponse)
err = grpcConn.Invoke(
ctx, reflectionv1.ReflectionService_FileDescriptors_FullMethodName,
&reflectionv1.FileDescriptorsRequest{}, resp,
)
if err != nil {
return nil, err
}
return resp, nil
}
// TODO: Remove all of the below when v6 -> v7 upgrade is not supported anymore:
func getProtoPath(req proto.Message) (string, error) {
typeURL := "/" + proto.MessageName(req)
switch {
case strings.Contains(typeURL, "Query"):
return getQueryProtoPath(typeURL)
case strings.Contains(typeURL, "cosmos.base.tendermint"):
return getCmtProtoPath(typeURL)
default:
return "", fmt.Errorf("unsupported typeURL: %s", typeURL)
}
}
func getQueryProtoPath(queryTypeURL string) (string, error) {
queryIndex := strings.Index(queryTypeURL, "Query")
if queryIndex == -1 {
return "", fmt.Errorf("invalid typeURL: %s", queryTypeURL)
}
// Add to the index to account for the length of "Query"
queryIndex += len("Query")
// Add a slash before the query
urlWithSlash := queryTypeURL[:queryIndex] + "/" + queryTypeURL[queryIndex:]
if !strings.HasSuffix(urlWithSlash, "Request") {
return "", fmt.Errorf("invalid typeURL: %s", queryTypeURL)
}
return strings.TrimSuffix(urlWithSlash, "Request"), nil
}
func getCmtProtoPath(cmtTypeURL string) (string, error) {
cmtIndex := strings.Index(cmtTypeURL, "Get")
if cmtIndex == -1 {
return "", fmt.Errorf("invalid typeURL: %s", cmtTypeURL)
}
// Add a slash before the commitment
urlWithSlash := cmtTypeURL[:cmtIndex] + "Service/" + cmtTypeURL[cmtIndex:]
if !strings.HasSuffix(urlWithSlash, "Request") {
return "", fmt.Errorf("invalid typeURL: %s", cmtTypeURL)
}
return strings.TrimSuffix(urlWithSlash, "Request"), nil
}