@@ -3,19 +3,49 @@ package query
33import (
44 "context"
55 "fmt"
6- "strings"
76
87 "github.com/cosmos/gogoproto/proto"
98 "github.com/strangelove-ventures/interchaintest/v8/ibc"
109 "google.golang.org/grpc"
1110 "google.golang.org/grpc/credentials/insecure"
11+ pb "google.golang.org/protobuf/proto"
12+
13+ msgv1 "cosmossdk.io/api/cosmos/msg/v1"
14+ reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1"
1215)
1316
17+ var queryReqToPath = make (map [string ]string )
18+
19+ func PopulateQueryReqToPath (ctx context.Context , chain ibc.Chain ) error {
20+ resp , err := queryFileDescriptors (ctx , chain )
21+ if err != nil {
22+ return err
23+ }
24+
25+ for _ , fileDescriptor := range resp .Files {
26+ for _ , service := range fileDescriptor .GetService () {
27+ // Skip services that are annotated with the "cosmos.msg.v1.service" option.
28+ if ext := pb .GetExtension (service .GetOptions (), msgv1 .E_Service ); ext != nil {
29+ if ok , extBool := ext .(bool ); ok && extBool {
30+ continue
31+ }
32+ }
33+
34+ for _ , method := range service .GetMethod () {
35+ // trim the first character from input which is a dot
36+ queryReqToPath [method .GetInputType ()[1 :]] = fileDescriptor .GetPackage () + "." + service .GetName () + "/" + method .GetName ()
37+ }
38+ }
39+ }
40+
41+ return nil
42+ }
43+
1444// GRPCQuery queries the chain with a query request and deserializes the response to T
1545func GRPCQuery [T any ](ctx context.Context , chain ibc.Chain , req proto.Message , opts ... grpc.CallOption ) (* T , error ) {
16- path , err := getProtoPath (req )
17- if err != nil {
18- return nil , err
46+ path , ok := queryReqToPath [ proto . MessageName (req )]
47+ if ! ok {
48+ return nil , fmt . Errorf ( "no path found for %s" , proto . MessageName ( req ))
1949 }
2050
2151 return grpcQueryWithMethod [T ](ctx , chain , req , path , opts ... )
@@ -43,48 +73,26 @@ func grpcQueryWithMethod[T any](ctx context.Context, chain ibc.Chain, req proto.
4373 return resp , nil
4474}
4575
46- func getProtoPath (req proto.Message ) (string , error ) {
47- typeURL := "/" + proto .MessageName (req )
48-
49- switch {
50- case strings .Contains (typeURL , "Query" ):
51- return getQueryProtoPath (typeURL )
52- case strings .Contains (typeURL , "cosmos.base.tendermint" ):
53- return getCmtProtoPath (typeURL )
54- default :
55- return "" , fmt .Errorf ("unsupported typeURL: %s" , typeURL )
56- }
57- }
58-
59- func getQueryProtoPath (queryTypeURL string ) (string , error ) {
60- queryIndex := strings .Index (queryTypeURL , "Query" )
61- if queryIndex == - 1 {
62- return "" , fmt .Errorf ("invalid typeURL: %s" , queryTypeURL )
63- }
64-
65- // Add to the index to account for the length of "Query"
66- queryIndex += len ("Query" )
67-
68- // Add a slash before the query
69- urlWithSlash := queryTypeURL [:queryIndex ] + "/" + queryTypeURL [queryIndex :]
70- if ! strings .HasSuffix (urlWithSlash , "Request" ) {
71- return "" , fmt .Errorf ("invalid typeURL: %s" , queryTypeURL )
76+ func queryFileDescriptors (ctx context.Context , chain ibc.Chain ) (* reflectionv1.FileDescriptorsResponse , error ) {
77+ // Create a connection to the gRPC server.
78+ grpcConn , err := grpc .Dial (
79+ chain .GetHostGRPCAddress (),
80+ grpc .WithTransportCredentials (insecure .NewCredentials ()),
81+ )
82+ if err != nil {
83+ return nil , err
7284 }
7385
74- return strings .TrimSuffix (urlWithSlash , "Request" ), nil
75- }
76-
77- func getCmtProtoPath (cmtTypeURL string ) (string , error ) {
78- cmtIndex := strings .Index (cmtTypeURL , "Get" )
79- if cmtIndex == - 1 {
80- return "" , fmt .Errorf ("invalid typeURL: %s" , cmtTypeURL )
81- }
86+ defer grpcConn .Close ()
8287
83- // Add a slash before the commitment
84- urlWithSlash := cmtTypeURL [:cmtIndex ] + "Service/" + cmtTypeURL [cmtIndex :]
85- if ! strings .HasSuffix (urlWithSlash , "Request" ) {
86- return "" , fmt .Errorf ("invalid typeURL: %s" , cmtTypeURL )
88+ resp := new (reflectionv1.FileDescriptorsResponse )
89+ err = grpcConn .Invoke (
90+ ctx , reflectionv1 .ReflectionService_FileDescriptors_FullMethodName ,
91+ & reflectionv1.FileDescriptorsRequest {}, resp ,
92+ )
93+ if err != nil {
94+ return nil , err
8795 }
8896
89- return strings . TrimSuffix ( urlWithSlash , "Request" ) , nil
97+ return resp , nil
9098}
0 commit comments