diff --git a/.gitignore b/.gitignore index 2bf18165980..e821f35d7e7 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,6 @@ dependency-graph.png *.aux *.out *.synctex.gz + +*.history + diff --git a/CHANGELOG.md b/CHANGELOG.md index d0d612dfa1a..4d2f9fd72dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * [\#432](https://github.com/cosmos/ibc-go/pull/432) Introduce `MockIBCApp` struct to the mock module. Allows the mock module to be reused to perform custom logic on each IBC App interface function. This might be useful when testing out IBC applications written as middleware. * [\#380](https://github.com/cosmos/ibc-go/pull/380) Adding the Interchain Accounts module v1 +* [\#679](https://github.com/cosmos/ibc-go/pull/679) New CLI command `query ibc-transfer denom-hash ` to get the denom hash for a denom trace; this might be useful for debug ### Bug Fixes diff --git a/docs/client/swagger-ui/swagger.yaml b/docs/client/swagger-ui/swagger.yaml index 835c894c1a9..5feb43dd2a5 100644 --- a/docs/client/swagger-ui/swagger.yaml +++ b/docs/client/swagger-ui/swagger.yaml @@ -4,6 +4,54 @@ info: description: A REST interface for state queries version: 1.0.0 paths: + '/ibc/apps/transfer/v1/denom_hashes/{trace}': + get: + summary: DenomHash queries a denomination hash information. + operationId: DenomHash + responses: + '200': + description: A successful response. + schema: + type: object + properties: + hash: + type: string + description: hash (in hex format) of the denomination trace information. + description: >- + QueryDenomHashResponse is the response type for the + Query/DenomHash RPC + + method. + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: trace + description: 'The denomination trace ([port_id]/[channel_id])+/[denom]' + in: path + required: true + type: string + tags: + - Query /ibc/apps/transfer/v1/denom_traces: get: summary: DenomTraces queries all denomination traces. @@ -7326,6 +7374,15 @@ paths: required: false type: boolean format: boolean + - name: packet_commitment_sequences + description: list of packet sequences. + in: query + required: false + type: array + items: + type: string + format: uint64 + collectionFormat: multi tags: - Query '/ibc/core/channel/v1/channels/{channel_id}/ports/{port_id}/packet_acks/{sequence}': @@ -9839,6 +9896,15 @@ definitions: SendEnabled parameter for the denomination to false. + ibc.applications.transfer.v1.QueryDenomHashResponse: + type: object + properties: + hash: + type: string + description: hash (in hex format) of the denomination trace information. + description: |- + QueryDenomHashResponse is the response type for the Query/DenomHash RPC + method. ibc.applications.transfer.v1.QueryDenomTraceResponse: type: object properties: diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index 8baaa8eda1a..921a3326522 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -28,6 +28,8 @@ - [GenesisState](#ibc.applications.transfer.v1.GenesisState) - [ibc/applications/transfer/v1/query.proto](#ibc/applications/transfer/v1/query.proto) + - [QueryDenomHashRequest](#ibc.applications.transfer.v1.QueryDenomHashRequest) + - [QueryDenomHashResponse](#ibc.applications.transfer.v1.QueryDenomHashResponse) - [QueryDenomTraceRequest](#ibc.applications.transfer.v1.QueryDenomTraceRequest) - [QueryDenomTraceResponse](#ibc.applications.transfer.v1.QueryDenomTraceResponse) - [QueryDenomTracesRequest](#ibc.applications.transfer.v1.QueryDenomTracesRequest) @@ -549,6 +551,38 @@ GenesisState defines the ibc-transfer genesis state + + +### QueryDenomHashRequest +QueryDenomHashRequest is the request type for the Query/DenomHash RPC +method + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `trace` | [string](#string) | | The denomination trace ([port_id]/[channel_id])+/[denom] | + + + + + + + + +### QueryDenomHashResponse +QueryDenomHashResponse is the response type for the Query/DenomHash RPC +method. + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `hash` | [string](#string) | | hash (in hex format) of the denomination trace information. | + + + + + + ### QueryDenomTraceRequest @@ -655,6 +689,7 @@ Query provides defines the gRPC querier service. | `DenomTrace` | [QueryDenomTraceRequest](#ibc.applications.transfer.v1.QueryDenomTraceRequest) | [QueryDenomTraceResponse](#ibc.applications.transfer.v1.QueryDenomTraceResponse) | DenomTrace queries a denomination trace information. | GET|/ibc/apps/transfer/v1/denom_traces/{hash}| | `DenomTraces` | [QueryDenomTracesRequest](#ibc.applications.transfer.v1.QueryDenomTracesRequest) | [QueryDenomTracesResponse](#ibc.applications.transfer.v1.QueryDenomTracesResponse) | DenomTraces queries all denomination traces. | GET|/ibc/apps/transfer/v1/denom_traces| | `Params` | [QueryParamsRequest](#ibc.applications.transfer.v1.QueryParamsRequest) | [QueryParamsResponse](#ibc.applications.transfer.v1.QueryParamsResponse) | Params queries all parameters of the ibc-transfer module. | GET|/ibc/apps/transfer/v1/params| +| `DenomHash` | [QueryDenomHashRequest](#ibc.applications.transfer.v1.QueryDenomHashRequest) | [QueryDenomHashResponse](#ibc.applications.transfer.v1.QueryDenomHashResponse) | DenomHash queries a denomination hash information. | GET|/ibc/apps/transfer/v1/denom_hashes/{trace}| diff --git a/modules/apps/transfer/client/cli/cli.go b/modules/apps/transfer/client/cli/cli.go index 643af504178..de83f4d4736 100644 --- a/modules/apps/transfer/client/cli/cli.go +++ b/modules/apps/transfer/client/cli/cli.go @@ -20,6 +20,7 @@ func GetQueryCmd() *cobra.Command { GetCmdQueryDenomTraces(), GetCmdParams(), GetCmdQueryEscrowAddress(), + GetCmdQueryDenomHash(), ) return queryCmd diff --git a/modules/apps/transfer/client/cli/query.go b/modules/apps/transfer/client/cli/query.go index 78d7bfd1b99..de585061ccf 100644 --- a/modules/apps/transfer/client/cli/query.go +++ b/modules/apps/transfer/client/cli/query.go @@ -135,3 +135,35 @@ func GetCmdQueryEscrowAddress() *cobra.Command { return cmd } + +// GetCmdQueryDenomHash defines the command to query a denomination hash from a given trace. +func GetCmdQueryDenomHash() *cobra.Command { + cmd := &cobra.Command{ + Use: "denom-hash [trace]", + Short: "Query the denom hash info from a given denom trace", + Long: "Query the denom hash info from a given denom trace", + Example: fmt.Sprintf("%s query ibc-transfer denom-hash [denom_trace]", version.AppName), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + req := &types.QueryDenomHashRequest{ + Trace: args[0], + } + + res, err := queryClient.DenomHash(cmd.Context(), req) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} diff --git a/modules/apps/transfer/keeper/grpc_query.go b/modules/apps/transfer/keeper/grpc_query.go index 8e8e4a807f4..e3310094c2d 100644 --- a/modules/apps/transfer/keeper/grpc_query.go +++ b/modules/apps/transfer/keeper/grpc_query.go @@ -81,3 +81,30 @@ func (q Keeper) Params(c context.Context, _ *types.QueryParamsRequest) (*types.Q Params: ¶ms, }, nil } + +// DenomHash implements the Query/DenomHash gRPC method +func (q Keeper) DenomHash(c context.Context, req *types.QueryDenomHashRequest) (*types.QueryDenomHashResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + // Convert given request trace path to DenomTrace struct to confirm the path in a valid denom trace format + denomTrace := types.ParseDenomTrace(req.Trace) + if err := denomTrace.Validate(); err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + + ctx := sdk.UnwrapSDKContext(c) + denomHash := denomTrace.Hash() + found := q.HasDenomTrace(ctx, denomHash) + if !found { + return nil, status.Error( + codes.NotFound, + sdkerrors.Wrap(types.ErrTraceNotFound, req.Trace).Error(), + ) + } + + return &types.QueryDenomHashResponse{ + Hash: denomHash.String(), + }, nil +} diff --git a/modules/apps/transfer/keeper/grpc_query_test.go b/modules/apps/transfer/keeper/grpc_query_test.go index 61469ebf593..5d65ed3d839 100644 --- a/modules/apps/transfer/keeper/grpc_query_test.go +++ b/modules/apps/transfer/keeper/grpc_query_test.go @@ -140,3 +140,70 @@ func (suite *KeeperTestSuite) TestQueryParams() { res, _ := suite.queryClient.Params(ctx, &types.QueryParamsRequest{}) suite.Require().Equal(&expParams, res.Params) } + +func (suite *KeeperTestSuite) TestQueryDenomHash() { + + reqTrace := types.DenomTrace{ + Path: "transfer/channelToA/transfer/channelToB", + BaseDenom: "uatom", + } + + var ( + req *types.QueryDenomHashRequest + expHash = reqTrace.Hash().String() + ) + + testCases := []struct { + msg string + malleate func() + expPass bool + }{ + { + "invalid trace", + func() { + req = &types.QueryDenomHashRequest{ + Trace: "transfer/channelToA/transfer/", + } + }, + false, + }, + { + "not found denom trace", + func() { + req = &types.QueryDenomHashRequest{ + Trace: "transfer/channelToC/uatom", + } + }, + false, + }, + { + "success", + func() {}, + true, + }, + } + + for _, tc := range testCases { + suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { + suite.SetupTest() // reset + + req = &types.QueryDenomHashRequest{ + Trace: reqTrace.GetFullDenomPath(), + } + suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), reqTrace) + + tc.malleate() + ctx := sdk.WrapSDKContext(suite.chainA.GetContext()) + + res, err := suite.queryClient.DenomHash(ctx, req) + + if tc.expPass { + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().Equal(expHash, res.Hash) + } else { + suite.Require().Error(err) + } + }) + } +} diff --git a/modules/apps/transfer/types/query.pb.go b/modules/apps/transfer/types/query.pb.go index ee8a05e63cc..024da758162 100644 --- a/modules/apps/transfer/types/query.pb.go +++ b/modules/apps/transfer/types/query.pb.go @@ -310,6 +310,100 @@ func (m *QueryParamsResponse) GetParams() *Params { return nil } +// QueryDenomHashRequest is the request type for the Query/DenomHash RPC +// method +type QueryDenomHashRequest struct { + // The denomination trace ([port_id]/[channel_id])+/[denom] + Trace string `protobuf:"bytes,1,opt,name=trace,proto3" json:"trace,omitempty"` +} + +func (m *QueryDenomHashRequest) Reset() { *m = QueryDenomHashRequest{} } +func (m *QueryDenomHashRequest) String() string { return proto.CompactTextString(m) } +func (*QueryDenomHashRequest) ProtoMessage() {} +func (*QueryDenomHashRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a638e2800a01538c, []int{6} +} +func (m *QueryDenomHashRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomHashRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomHashRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryDenomHashRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomHashRequest.Merge(m, src) +} +func (m *QueryDenomHashRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomHashRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomHashRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomHashRequest proto.InternalMessageInfo + +func (m *QueryDenomHashRequest) GetTrace() string { + if m != nil { + return m.Trace + } + return "" +} + +// QueryDenomHashResponse is the response type for the Query/DenomHash RPC +// method. +type QueryDenomHashResponse struct { + // hash (in hex format) of the denomination trace information. + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` +} + +func (m *QueryDenomHashResponse) Reset() { *m = QueryDenomHashResponse{} } +func (m *QueryDenomHashResponse) String() string { return proto.CompactTextString(m) } +func (*QueryDenomHashResponse) ProtoMessage() {} +func (*QueryDenomHashResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a638e2800a01538c, []int{7} +} +func (m *QueryDenomHashResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomHashResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomHashResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryDenomHashResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomHashResponse.Merge(m, src) +} +func (m *QueryDenomHashResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomHashResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomHashResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomHashResponse proto.InternalMessageInfo + +func (m *QueryDenomHashResponse) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + func init() { proto.RegisterType((*QueryDenomTraceRequest)(nil), "ibc.applications.transfer.v1.QueryDenomTraceRequest") proto.RegisterType((*QueryDenomTraceResponse)(nil), "ibc.applications.transfer.v1.QueryDenomTraceResponse") @@ -317,6 +411,8 @@ func init() { proto.RegisterType((*QueryDenomTracesResponse)(nil), "ibc.applications.transfer.v1.QueryDenomTracesResponse") proto.RegisterType((*QueryParamsRequest)(nil), "ibc.applications.transfer.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "ibc.applications.transfer.v1.QueryParamsResponse") + proto.RegisterType((*QueryDenomHashRequest)(nil), "ibc.applications.transfer.v1.QueryDenomHashRequest") + proto.RegisterType((*QueryDenomHashResponse)(nil), "ibc.applications.transfer.v1.QueryDenomHashResponse") } func init() { @@ -324,41 +420,45 @@ func init() { } var fileDescriptor_a638e2800a01538c = []byte{ - // 532 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0xce, 0xb6, 0x10, 0x89, 0x09, 0xe2, 0xb0, 0x54, 0x10, 0x59, 0x91, 0x5b, 0x59, 0x11, 0x84, - 0x16, 0x76, 0x71, 0xcb, 0xcf, 0x85, 0x53, 0x85, 0x40, 0xdc, 0xda, 0xc0, 0x09, 0x0e, 0x68, 0xed, - 0x2c, 0x8e, 0xa5, 0xd8, 0xeb, 0x7a, 0x9d, 0x48, 0x15, 0xe2, 0xc2, 0x13, 0x20, 0xf5, 0x25, 0x10, - 0xe2, 0x21, 0x38, 0xf6, 0x58, 0x89, 0x0b, 0x27, 0x40, 0x09, 0xef, 0xc0, 0x15, 0x79, 0x77, 0xdd, - 0xd8, 0xa4, 0x4a, 0xeb, 0xdb, 0x6a, 0x3c, 0xdf, 0x7c, 0x3f, 0x33, 0x32, 0xf4, 0x42, 0xcf, 0xa7, - 0x2c, 0x49, 0x46, 0xa1, 0xcf, 0xb2, 0x50, 0xc4, 0x92, 0x66, 0x29, 0x8b, 0xe5, 0x3b, 0x9e, 0xd2, - 0x89, 0x4b, 0x0f, 0xc6, 0x3c, 0x3d, 0x24, 0x49, 0x2a, 0x32, 0x81, 0x3b, 0xa1, 0xe7, 0x93, 0x72, - 0x27, 0x29, 0x3a, 0xc9, 0xc4, 0xb5, 0xd6, 0x02, 0x11, 0x08, 0xd5, 0x48, 0xf3, 0x97, 0xc6, 0x58, - 0x9b, 0xbe, 0x90, 0x91, 0x90, 0xd4, 0x63, 0x92, 0xeb, 0x61, 0x74, 0xe2, 0x7a, 0x3c, 0x63, 0x2e, - 0x4d, 0x58, 0x10, 0xc6, 0x6a, 0x90, 0xe9, 0xdd, 0x5a, 0xaa, 0xe4, 0x94, 0x4b, 0x37, 0x77, 0x02, - 0x21, 0x82, 0x11, 0xa7, 0x2c, 0x09, 0x29, 0x8b, 0x63, 0x91, 0x19, 0x49, 0xea, 0xab, 0x73, 0x17, - 0x6e, 0xec, 0xe7, 0x64, 0x4f, 0x79, 0x2c, 0xa2, 0x57, 0x29, 0xf3, 0x79, 0x9f, 0x1f, 0x8c, 0xb9, - 0xcc, 0x30, 0x86, 0x4b, 0x43, 0x26, 0x87, 0x6d, 0xb4, 0x81, 0x7a, 0x57, 0xfa, 0xea, 0xed, 0x0c, - 0xe0, 0xe6, 0x42, 0xb7, 0x4c, 0x44, 0x2c, 0x39, 0x7e, 0x01, 0xad, 0x41, 0x5e, 0x7d, 0x9b, 0xe5, - 0x65, 0x85, 0x6a, 0x6d, 0xf7, 0xc8, 0xb2, 0x24, 0x48, 0x69, 0x0c, 0x0c, 0x4e, 0xdf, 0x0e, 0x5b, - 0x60, 0x91, 0x85, 0xa8, 0x67, 0x00, 0xf3, 0x34, 0x0c, 0xc9, 0x2d, 0xa2, 0xa3, 0x23, 0x79, 0x74, - 0x44, 0xef, 0xc1, 0x44, 0x47, 0xf6, 0x58, 0x50, 0x18, 0xea, 0x97, 0x90, 0xce, 0x37, 0x04, 0xed, - 0x45, 0x0e, 0x63, 0xe5, 0x0d, 0x5c, 0x2d, 0x59, 0x91, 0x6d, 0xb4, 0xb1, 0x5a, 0xc7, 0xcb, 0xee, - 0xb5, 0xe3, 0x9f, 0xeb, 0x8d, 0x2f, 0xbf, 0xd6, 0x9b, 0x66, 0x6e, 0x6b, 0xee, 0x4d, 0xe2, 0xe7, - 0x15, 0x07, 0x2b, 0xca, 0xc1, 0xed, 0x73, 0x1d, 0x68, 0x65, 0x15, 0x0b, 0x6b, 0x80, 0x95, 0x83, - 0x3d, 0x96, 0xb2, 0xa8, 0x08, 0xc8, 0x79, 0x09, 0xd7, 0x2b, 0x55, 0x63, 0xe9, 0x09, 0x34, 0x13, - 0x55, 0x31, 0x99, 0x75, 0x97, 0x9b, 0x31, 0x68, 0x83, 0xd9, 0xfe, 0xbb, 0x0a, 0x97, 0xd5, 0x54, - 0xfc, 0x15, 0x01, 0xcc, 0x9d, 0xe2, 0x07, 0xcb, 0xc7, 0x9c, 0x7d, 0x59, 0xd6, 0xc3, 0x9a, 0x28, - 0xed, 0xc1, 0x71, 0x3f, 0x7e, 0xff, 0x73, 0xb4, 0xb2, 0x85, 0xef, 0x50, 0x73, 0xfe, 0xd5, 0xb3, - 0x2f, 0xaf, 0x8c, 0xbe, 0xcf, 0xcf, 0xf5, 0x03, 0xfe, 0x8c, 0xa0, 0x55, 0xda, 0x30, 0xae, 0xc7, - 0x5c, 0x84, 0x6a, 0x3d, 0xaa, 0x0b, 0x33, 0x8a, 0x37, 0x95, 0xe2, 0x2e, 0x76, 0xce, 0x57, 0x8c, - 0x8f, 0x10, 0x34, 0x75, 0xec, 0xf8, 0xfe, 0x05, 0xe8, 0x2a, 0x5b, 0xb7, 0xdc, 0x1a, 0x08, 0xa3, - 0xad, 0xab, 0xb4, 0xd9, 0xb8, 0x73, 0xb6, 0x36, 0xbd, 0xf9, 0xdd, 0xfd, 0xe3, 0xa9, 0x8d, 0x4e, - 0xa6, 0x36, 0xfa, 0x3d, 0xb5, 0xd1, 0xa7, 0x99, 0xdd, 0x38, 0x99, 0xd9, 0x8d, 0x1f, 0x33, 0xbb, - 0xf1, 0xfa, 0x71, 0x10, 0x66, 0xc3, 0xb1, 0x47, 0x7c, 0x11, 0x51, 0xf3, 0xeb, 0x0a, 0x3d, 0xff, - 0x5e, 0x20, 0xe8, 0x64, 0x87, 0x46, 0x62, 0x30, 0x1e, 0x71, 0xf9, 0xdf, 0xd8, 0xec, 0x30, 0xe1, - 0xd2, 0x6b, 0xaa, 0x1f, 0xcf, 0xce, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x64, 0xab, 0xc6, 0xb0, - 0x4f, 0x05, 0x00, 0x00, + // 595 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4f, 0x6f, 0xd3, 0x30, + 0x1c, 0xad, 0x07, 0xab, 0x34, 0x17, 0x71, 0x30, 0x05, 0xaa, 0xa8, 0xca, 0xa6, 0xa8, 0x82, 0xd2, + 0x6d, 0x36, 0x69, 0x07, 0x5c, 0x38, 0x4d, 0x88, 0x3f, 0xb7, 0xad, 0x70, 0x82, 0x03, 0x72, 0x52, + 0x93, 0x46, 0x6a, 0xe3, 0x2c, 0x4e, 0x2b, 0x4d, 0x68, 0x17, 0x3e, 0x01, 0xd2, 0xbe, 0x02, 0x07, + 0x34, 0xf1, 0x21, 0x38, 0xee, 0x38, 0x89, 0x0b, 0x27, 0x40, 0x2d, 0x1f, 0x04, 0xc5, 0x76, 0xda, + 0x84, 0x56, 0xdd, 0x72, 0x73, 0xdd, 0xdf, 0xfb, 0xfd, 0xde, 0x7b, 0xbf, 0x17, 0xc3, 0xa6, 0xef, + 0xb8, 0x84, 0x86, 0xe1, 0xc0, 0x77, 0x69, 0xec, 0xf3, 0x40, 0x90, 0x38, 0xa2, 0x81, 0xf8, 0xc0, + 0x22, 0x32, 0xb6, 0xc9, 0xd1, 0x88, 0x45, 0xc7, 0x38, 0x8c, 0x78, 0xcc, 0x51, 0xdd, 0x77, 0x5c, + 0x9c, 0xad, 0xc4, 0x69, 0x25, 0x1e, 0xdb, 0x46, 0xd5, 0xe3, 0x1e, 0x97, 0x85, 0x24, 0x39, 0x29, + 0x8c, 0xd1, 0x72, 0xb9, 0x18, 0x72, 0x41, 0x1c, 0x2a, 0x98, 0x6a, 0x46, 0xc6, 0xb6, 0xc3, 0x62, + 0x6a, 0x93, 0x90, 0x7a, 0x7e, 0x20, 0x1b, 0xe9, 0xda, 0xed, 0x95, 0x4c, 0x66, 0xb3, 0x54, 0x71, + 0xdd, 0xe3, 0xdc, 0x1b, 0x30, 0x42, 0x43, 0x9f, 0xd0, 0x20, 0xe0, 0xb1, 0xa6, 0x24, 0xff, 0xb5, + 0x76, 0xe0, 0x9d, 0xc3, 0x64, 0xd8, 0x33, 0x16, 0xf0, 0xe1, 0x9b, 0x88, 0xba, 0xac, 0xcb, 0x8e, + 0x46, 0x4c, 0xc4, 0x08, 0xc1, 0xeb, 0x7d, 0x2a, 0xfa, 0x35, 0xb0, 0x05, 0x9a, 0x1b, 0x5d, 0x79, + 0xb6, 0x7a, 0xf0, 0xee, 0x42, 0xb5, 0x08, 0x79, 0x20, 0x18, 0x7a, 0x05, 0x2b, 0xbd, 0xe4, 0xf6, + 0x7d, 0x9c, 0x5c, 0x4b, 0x54, 0xa5, 0xdd, 0xc4, 0xab, 0x9c, 0xc0, 0x99, 0x36, 0xb0, 0x37, 0x3b, + 0x5b, 0x74, 0x61, 0x8a, 0x48, 0x49, 0x3d, 0x87, 0x70, 0xee, 0x86, 0x1e, 0x72, 0x0f, 0x2b, 0xeb, + 0x70, 0x62, 0x1d, 0x56, 0x7b, 0xd0, 0xd6, 0xe1, 0x03, 0xea, 0xa5, 0x82, 0xba, 0x19, 0xa4, 0xf5, + 0x1d, 0xc0, 0xda, 0xe2, 0x0c, 0x2d, 0xe5, 0x1d, 0xbc, 0x91, 0x91, 0x22, 0x6a, 0x60, 0xeb, 0x5a, + 0x11, 0x2d, 0xfb, 0x37, 0xcf, 0x7f, 0x6d, 0x96, 0xce, 0x7e, 0x6f, 0x96, 0x75, 0xdf, 0xca, 0x5c, + 0x9b, 0x40, 0x2f, 0x72, 0x0a, 0xd6, 0xa4, 0x82, 0xfb, 0x97, 0x2a, 0x50, 0xcc, 0x72, 0x12, 0xaa, + 0x10, 0x49, 0x05, 0x07, 0x34, 0xa2, 0xc3, 0xd4, 0x20, 0xeb, 0x35, 0xbc, 0x95, 0xbb, 0xd5, 0x92, + 0x9e, 0xc2, 0x72, 0x28, 0x6f, 0xb4, 0x67, 0x8d, 0xd5, 0x62, 0x34, 0x5a, 0x63, 0xac, 0x5d, 0x78, + 0x7b, 0x6e, 0xd6, 0x4b, 0x2a, 0xfa, 0xe9, 0x3a, 0xaa, 0x70, 0x7d, 0xbe, 0xee, 0x8d, 0xae, 0xfa, + 0x91, 0xcf, 0x94, 0x2a, 0xd7, 0x34, 0x96, 0x64, 0xaa, 0xfd, 0x65, 0x1d, 0xae, 0xcb, 0x72, 0xf4, + 0x0d, 0x40, 0x38, 0xb7, 0x11, 0xed, 0xad, 0xe6, 0xb8, 0x3c, 0xb6, 0xc6, 0xa3, 0x82, 0x28, 0xc5, + 0xcc, 0xb2, 0x3f, 0xfd, 0xf8, 0x7b, 0xba, 0xb6, 0x8d, 0x1e, 0x10, 0xfd, 0x6d, 0xe5, 0xbf, 0xa9, + 0x6c, 0x1e, 0xc8, 0xc7, 0x84, 0xf7, 0x09, 0xfa, 0x0a, 0x60, 0x25, 0x13, 0x1f, 0x54, 0x6c, 0x72, + 0xba, 0x31, 0xe3, 0x71, 0x51, 0x98, 0x66, 0xdc, 0x92, 0x8c, 0x1b, 0xc8, 0xba, 0x9c, 0x31, 0x3a, + 0x05, 0xb0, 0xac, 0x76, 0x8a, 0x1e, 0x5e, 0x61, 0x5c, 0x2e, 0x52, 0x86, 0x5d, 0x00, 0xa1, 0xb9, + 0x35, 0x24, 0x37, 0x13, 0xd5, 0x97, 0x73, 0x53, 0xb1, 0x42, 0x67, 0x00, 0x6e, 0xcc, 0x32, 0x82, + 0x3a, 0x57, 0xf5, 0x21, 0x13, 0x40, 0x63, 0xaf, 0x18, 0x48, 0xd3, 0x6b, 0x4b, 0x7a, 0x3b, 0xa8, + 0xb5, 0xca, 0xba, 0x64, 0xc9, 0xc9, 0xb2, 0xa5, 0x85, 0x27, 0xfb, 0x87, 0xe7, 0x13, 0x13, 0x5c, + 0x4c, 0x4c, 0xf0, 0x67, 0x62, 0x82, 0xcf, 0x53, 0xb3, 0x74, 0x31, 0x35, 0x4b, 0x3f, 0xa7, 0x66, + 0xe9, 0xed, 0x13, 0xcf, 0x8f, 0xfb, 0x23, 0x07, 0xbb, 0x7c, 0x48, 0xf4, 0x23, 0xee, 0x3b, 0xee, + 0xae, 0xc7, 0xc9, 0xb8, 0x43, 0x86, 0xbc, 0x37, 0x1a, 0x30, 0xf1, 0xdf, 0x90, 0xf8, 0x38, 0x64, + 0xc2, 0x29, 0xcb, 0x27, 0xb8, 0xf3, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x16, 0x01, 0x88, 0xe2, 0x59, + 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -379,6 +479,8 @@ type QueryClient interface { DenomTraces(ctx context.Context, in *QueryDenomTracesRequest, opts ...grpc.CallOption) (*QueryDenomTracesResponse, error) // Params queries all parameters of the ibc-transfer module. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // DenomHash queries a denomination hash information. + DenomHash(ctx context.Context, in *QueryDenomHashRequest, opts ...grpc.CallOption) (*QueryDenomHashResponse, error) } type queryClient struct { @@ -416,6 +518,15 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . return out, nil } +func (c *queryClient) DenomHash(ctx context.Context, in *QueryDenomHashRequest, opts ...grpc.CallOption) (*QueryDenomHashResponse, error) { + out := new(QueryDenomHashResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.transfer.v1.Query/DenomHash", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // DenomTrace queries a denomination trace information. @@ -424,6 +535,8 @@ type QueryServer interface { DenomTraces(context.Context, *QueryDenomTracesRequest) (*QueryDenomTracesResponse, error) // Params queries all parameters of the ibc-transfer module. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // DenomHash queries a denomination hash information. + DenomHash(context.Context, *QueryDenomHashRequest) (*QueryDenomHashResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -439,6 +552,9 @@ func (*UnimplementedQueryServer) DenomTraces(ctx context.Context, req *QueryDeno func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } +func (*UnimplementedQueryServer) DenomHash(ctx context.Context, req *QueryDenomHashRequest) (*QueryDenomHashResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DenomHash not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -498,6 +614,24 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _Query_DenomHash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryDenomHashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).DenomHash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.transfer.v1.Query/DenomHash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).DenomHash(ctx, req.(*QueryDenomHashRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "ibc.applications.transfer.v1.Query", HandlerType: (*QueryServer)(nil), @@ -514,6 +648,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Params", Handler: _Query_Params_Handler, }, + { + MethodName: "DenomHash", + Handler: _Query_DenomHash_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "ibc/applications/transfer/v1/query.proto", @@ -726,6 +864,66 @@ func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QueryDenomHashRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryDenomHashRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomHashRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Trace) > 0 { + i -= len(m.Trace) + copy(dAtA[i:], m.Trace) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Trace))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryDenomHashResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryDenomHashResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomHashResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -817,6 +1015,32 @@ func (m *QueryParamsResponse) Size() (n int) { return n } +func (m *QueryDenomHashRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Trace) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryDenomHashResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1333,6 +1557,170 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryDenomHashRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryDenomHashRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomHashRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Trace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Trace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryDenomHashResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryDenomHashResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomHashResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/modules/apps/transfer/types/query.pb.gw.go b/modules/apps/transfer/types/query.pb.gw.go index 0cd48139ccc..6f17d4dc055 100644 --- a/modules/apps/transfer/types/query.pb.gw.go +++ b/modules/apps/transfer/types/query.pb.gw.go @@ -139,6 +139,60 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal } +func request_Query_DenomHash_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomHashRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["trace"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "trace") + } + + protoReq.Trace, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "trace", err) + } + + msg, err := client.DenomHash(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_DenomHash_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomHashRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["trace"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "trace") + } + + protoReq.Trace, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "trace", err) + } + + msg, err := server.DenomHash(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -205,6 +259,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_DenomHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_DenomHash_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_DenomHash_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -306,6 +380,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_DenomHash_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_DenomHash_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_DenomHash_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -315,6 +409,8 @@ var ( pattern_Query_DenomTraces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "transfer", "v1", "denom_traces"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "transfer", "v1", "params"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_DenomHash_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"ibc", "apps", "transfer", "v1", "denom_hashes", "trace"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( @@ -323,4 +419,6 @@ var ( forward_Query_DenomTraces_0 = runtime.ForwardResponseMessage forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_DenomHash_0 = runtime.ForwardResponseMessage ) diff --git a/proto/ibc/applications/transfer/v1/query.proto b/proto/ibc/applications/transfer/v1/query.proto index 12876608db8..2ed28049fd7 100644 --- a/proto/ibc/applications/transfer/v1/query.proto +++ b/proto/ibc/applications/transfer/v1/query.proto @@ -25,6 +25,11 @@ service Query { rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/ibc/apps/transfer/v1/params"; } + + // DenomHash queries a denomination hash information. + rpc DenomHash(QueryDenomHashRequest) returns (QueryDenomHashResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denom_hashes/{trace}"; + } } // QueryDenomTraceRequest is the request type for the Query/DenomTrace RPC @@ -65,3 +70,17 @@ message QueryParamsResponse { // params defines the parameters of the module. Params params = 1; } + +// QueryDenomHashRequest is the request type for the Query/DenomHash RPC +// method +message QueryDenomHashRequest { + // The denomination trace ([port_id]/[channel_id])+/[denom] + string trace = 1; +} + +// QueryDenomHashResponse is the response type for the Query/DenomHash RPC +// method. +message QueryDenomHashResponse { + // hash (in hex format) of the denomination trace information. + string hash = 1; +}