From 55a7226535df02accc549f2c9c6a67a7e142d331 Mon Sep 17 00:00:00 2001 From: Federico Kunze <31522760+fedekunze@users.noreply.github.com> Date: Fri, 12 Jun 2020 14:06:24 +0200 Subject: [PATCH] x/ibc: channel from client state query (#6401) * x/ibc: channel from client state query * 04-channel/client: add CLI and REST queries * querier test --- x/ibc/04-channel/client/cli/cli.go | 6 +- x/ibc/04-channel/client/cli/query.go | 25 ++++ x/ibc/04-channel/client/rest/query.go | 29 ++++- x/ibc/04-channel/client/rest/rest.go | 4 +- x/ibc/04-channel/client/utils/utils.go | 26 ++++ x/ibc/04-channel/keeper/querier.go | 34 ++++++ x/ibc/04-channel/keeper/querier_test.go | 152 +++++++++++++++++++----- x/ibc/04-channel/module.go | 2 +- x/ibc/04-channel/types/keys.go | 2 +- x/ibc/04-channel/types/querier.go | 16 +++ x/ibc/keeper/querier.go | 29 +++-- x/ibc/keeper/querier_test.go | 49 ++++---- 12 files changed, 301 insertions(+), 73 deletions(-) diff --git a/x/ibc/04-channel/client/cli/cli.go b/x/ibc/04-channel/client/cli/cli.go index 7c24dff1e9..ba85611ec9 100644 --- a/x/ibc/04-channel/client/cli/cli.go +++ b/x/ibc/04-channel/client/cli/cli.go @@ -5,18 +5,20 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // GetQueryCmd returns the query commands for IBC channels func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ics04ChannelQueryCmd := &cobra.Command{ - Use: "channel", + Use: types.SubModuleName, Short: "IBC channel query subcommands", DisableFlagParsing: true, } ics04ChannelQueryCmd.AddCommand(flags.GetCommands( GetCmdQueryChannel(storeKey, cdc), + GetCmdQueryChannelClientState(cdc), )...) return ics04ChannelQueryCmd @@ -25,7 +27,7 @@ func GetQueryCmd(storeKey string, cdc *codec.Codec) *cobra.Command { // GetTxCmd returns the transaction commands for IBC channels func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command { ics04ChannelTxCmd := &cobra.Command{ - Use: "channel", + Use: types.SubModuleName, Short: "IBC channel transaction subcommands", } diff --git a/x/ibc/04-channel/client/cli/query.go b/x/ibc/04-channel/client/cli/query.go index e789b92628..b2e94330eb 100644 --- a/x/ibc/04-channel/client/cli/query.go +++ b/x/ibc/04-channel/client/cli/query.go @@ -46,3 +46,28 @@ $ %s query ibc channel end [port-id] [channel-id] return cmd } + +// GetCmdQueryChannelClientState defines the command to query a client state from a channel +func GetCmdQueryChannelClientState(cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "client-state [port-id] [channel-id]", + Short: "Query the client state associated with a channel", + Long: "Query the client state associated with a channel, by providing its port and channel identifiers.", + Example: fmt.Sprintf("%s query ibc channel client-state [port-id] [channel-id]", version.ClientName), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.NewContext().WithCodec(cdc) + portID := args[0] + channelID := args[1] + + clientStateRes, height, err := utils.QueryChannelClientState(clientCtx, portID, channelID) + if err != nil { + return err + } + + clientCtx = clientCtx.WithHeight(height) + return clientCtx.PrintOutput(clientStateRes) + }, + } + return cmd +} diff --git a/x/ibc/04-channel/client/rest/query.go b/x/ibc/04-channel/client/rest/query.go index fa22d7c7f4..cc296c66e7 100644 --- a/x/ibc/04-channel/client/rest/query.go +++ b/x/ibc/04-channel/client/rest/query.go @@ -12,8 +12,9 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/client/utils" ) -func registerQueryRoutes(clientCtx client.Context, r *mux.Router, queryRoute string) { - r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}", RestPortID, RestChannelID), queryChannelHandlerFn(clientCtx, queryRoute)).Methods("GET") +func registerQueryRoutes(clientCtx client.Context, r *mux.Router) { + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}", RestPortID, RestChannelID), queryChannelHandlerFn(clientCtx)).Methods("GET") + r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/client_state", RestPortID, RestChannelID), queryChannelClientStateHandlerFn(clientCtx)).Methods("GET") } // queryChannelHandlerFn implements a channel querying route @@ -28,7 +29,7 @@ func registerQueryRoutes(clientCtx client.Context, r *mux.Router, queryRoute str // @Failure 400 {object} rest.ErrorResponse "Invalid port id or channel id" // @Failure 500 {object} rest.ErrorResponse "Internal Server Error" // @Router /ibc/ports/{port-id}/channels/{channel-id} [get] -func queryChannelHandlerFn(clientCtx client.Context, _ string) http.HandlerFunc { +func queryChannelHandlerFn(clientCtx client.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) portID := vars[RestPortID] @@ -50,3 +51,25 @@ func queryChannelHandlerFn(clientCtx client.Context, _ string) http.HandlerFunc rest.PostProcessResponse(w, clientCtx, channelRes) } } + +func queryChannelClientStateHandlerFn(clientCtx client.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + portID := vars[RestPortID] + channelID := vars[RestChannelID] + + clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r) + if !ok { + return + } + + clientState, height, err := utils.QueryChannelClientState(clientCtx, portID, channelID) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + clientCtx = clientCtx.WithHeight(height) + rest.PostProcessResponse(w, clientCtx, clientState) + } +} diff --git a/x/ibc/04-channel/client/rest/rest.go b/x/ibc/04-channel/client/rest/rest.go index fc7c62cf28..94924add1f 100644 --- a/x/ibc/04-channel/client/rest/rest.go +++ b/x/ibc/04-channel/client/rest/rest.go @@ -14,8 +14,8 @@ const ( ) // RegisterRoutes - Central function to define routes that get registered by the main application -func RegisterRoutes(clientCtx client.Context, r *mux.Router, queryRoute string) { - registerQueryRoutes(clientCtx, r, queryRoute) +func RegisterRoutes(clientCtx client.Context, r *mux.Router) { + registerQueryRoutes(clientCtx, r) registerTxRoutes(clientCtx, r) } diff --git a/x/ibc/04-channel/client/utils/utils.go b/x/ibc/04-channel/client/utils/utils.go index e670b3b490..58aa32d1eb 100644 --- a/x/ibc/04-channel/client/utils/utils.go +++ b/x/ibc/04-channel/client/utils/utils.go @@ -1,9 +1,12 @@ package utils import ( + "fmt" + abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client" + clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" ) @@ -68,3 +71,26 @@ func QueryChannel( } return types.NewChannelResponse(portID, channelID, channel, res.Proof, res.Height), nil } + +// QueryChannelClientState uses the channel Querier to return the ClientState of +// a Channel. +func QueryChannelClientState(clientCtx client.Context, portID, channelID string) (clientexported.ClientState, int64, error) { + params := types.NewQueryChannelClientStateParams(portID, channelID) + bz, err := clientCtx.Codec.MarshalJSON(params) + if err != nil { + return nil, 0, fmt.Errorf("failed to marshal query params: %w", err) + } + + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryChannelClientState) + res, height, err := clientCtx.QueryWithData(route, bz) + if err != nil { + return nil, 0, err + } + + var clientState clientexported.ClientState + err = clientCtx.Codec.UnmarshalJSON(res, &clientState) + if err != nil { + return nil, 0, fmt.Errorf("failed to unmarshal connections: %w", err) + } + return clientState, height, nil +} diff --git a/x/ibc/04-channel/keeper/querier.go b/x/ibc/04-channel/keeper/querier.go index b11ad08b4f..8c1e344488 100644 --- a/x/ibc/04-channel/keeper/querier.go +++ b/x/ibc/04-channel/keeper/querier.go @@ -7,6 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) @@ -67,6 +69,38 @@ func QuerierConnectionChannels(ctx sdk.Context, req abci.RequestQuery, k Keeper) return res, nil } +// QuerierChannelClientState defines the sdk.Querier to query all the ClientState +// associated with a given Channel. +func QuerierChannelClientState(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { + var params types.QueryChannelClientStateParams + + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) + } + + channel, found := k.GetChannel(ctx, params.PortID, params.ChannelID) + if !found { + return nil, sdkerrors.Wrapf(types.ErrChannelNotFound, params.PortID, params.ChannelID) + } + + connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) + if !found { + return nil, sdkerrors.Wrapf(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) + } + + clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientID) + if !found { + return nil, sdkerrors.Wrapf(clienttypes.ErrClientNotFound, connection.ClientID) + } + + res, err := codec.MarshalJSONIndent(k.cdc, clientState) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} + // QuerierPacketCommitments defines the sdk.Querier to query all packet commitments on a // specified channel. func QuerierPacketCommitments(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) { diff --git a/x/ibc/04-channel/keeper/querier_test.go b/x/ibc/04-channel/keeper/querier_test.go index d5f92c2531..d58823e69d 100644 --- a/x/ibc/04-channel/keeper/querier_test.go +++ b/x/ibc/04-channel/keeper/querier_test.go @@ -19,7 +19,7 @@ func (suite *KeeperTestSuite) TestQueryChannels() { params := types.NewQueryAllChannelsParams(1, 100) data, err := suite.cdc.MarshalJSON(params) - suite.NoError(err) + suite.Require().NoError(err) query := abci.RequestQuery{ Path: "", @@ -65,7 +65,7 @@ func (suite *KeeperTestSuite) TestQueryChannels() { // set expected result expRes, err = codec.MarshalJSONIndent(suite.cdc, channels) - suite.NoError(err) + suite.Require().NoError(err) }, }, { @@ -98,7 +98,7 @@ func (suite *KeeperTestSuite) TestQueryChannels() { // set expected result expRes, err = codec.MarshalJSONIndent(suite.cdc, channels) - suite.NoError(err) + suite.Require().NoError(err) }, }, { @@ -106,7 +106,7 @@ func (suite *KeeperTestSuite) TestQueryChannels() { func() { suite.SetupTest() expRes, err = codec.MarshalJSONIndent(suite.cdc, []types.IdentifiedChannel{}) - suite.NoError(err) + suite.Require().NoError(err) }, }, } @@ -116,8 +116,8 @@ func (suite *KeeperTestSuite) TestQueryChannels() { bz, err := suite.querier(suite.chainA.GetContext(), path, query) - suite.NoError(err, "test case %d failed: %s", i, tc.name) - suite.Equal(expRes, bz, "test case %d failed: %s", i, tc.name) + suite.Require().NoError(err, "test case %d failed: %s", i, tc.name) + suite.Require().Equal(expRes, bz, "test case %d failed: %s", i, tc.name) } } @@ -132,7 +132,7 @@ func (suite *KeeperTestSuite) TestQueryConnectionChannels() { params := types.NewQueryConnectionChannelsParams(testConnectionIDA, 1, 100) data, err := suite.cdc.MarshalJSON(params) - suite.NoError(err) + suite.Require().NoError(err) query := abci.RequestQuery{ Path: "", @@ -173,7 +173,7 @@ func (suite *KeeperTestSuite) TestQueryConnectionChannels() { // set expected result expRes, err = codec.MarshalJSONIndent(suite.cdc, channels) - suite.NoError(err) + suite.Require().NoError(err) }, }, { @@ -208,7 +208,7 @@ func (suite *KeeperTestSuite) TestQueryConnectionChannels() { // set expected result expRes, err = codec.MarshalJSONIndent(suite.cdc, channels) - suite.NoError(err) + suite.Require().NoError(err) }, }, { @@ -216,7 +216,7 @@ func (suite *KeeperTestSuite) TestQueryConnectionChannels() { func() { suite.SetupTest() expRes, err = codec.MarshalJSONIndent(suite.cdc, []types.IdentifiedChannel{}) - suite.NoError(err) + suite.Require().NoError(err) }, }, } @@ -226,10 +226,104 @@ func (suite *KeeperTestSuite) TestQueryConnectionChannels() { bz, err := suite.querier(suite.chainA.GetContext(), path, query) - suite.NoError(err, "test case %d failed: %s", i, tc.name) - suite.Equal(expRes, bz, "test case %d failed: %s", i, tc.name) + suite.Require().NoError(err, "test case %d failed: %s", i, tc.name) + suite.Require().Equal(expRes, bz, "test case %d failed: %s", i, tc.name) + } +} + +func (suite *KeeperTestSuite) TestQuerierChannelClientState() { + path := []string{types.SubModuleName, types.QueryChannelClientState} + params := types.NewQueryChannelClientStateParams(testPort1, testChannel1) + data, err := suite.cdc.MarshalJSON(params) + suite.Require().NoError(err) + + query := abci.RequestQuery{ + Path: "", + Data: data, } + testCases := []struct { + name string + setup func() + expPass bool + }{ + { + "channel not found", + func() {}, + false, + }, + { + "connection for channel not found", + func() { + _ = suite.chainA.createChannel( + testPort1, testChannel1, testPort2, testChannel2, + types.OPEN, types.ORDERED, testConnectionIDA, + ) + }, + false, + }, + { + "client state for channel's connection not found", + func() { + _ = suite.chainA.createConnection( + testConnectionIDA, testConnectionIDB, + testClientIDA, testClientIDB, + connection.OPEN, + ) + _ = suite.chainA.createChannel( + testPort1, testChannel1, testPort2, testChannel2, + types.OPEN, types.ORDERED, testConnectionIDA, + ) + }, + false, + }, + { + "success", + func() { + err = suite.chainA.CreateClient(suite.chainB) + suite.Require().NoError(err) + err = suite.chainB.CreateClient(suite.chainA) + suite.Require().NoError(err) + suite.chainA.createConnection( + testConnectionIDB, testConnectionIDA, testClientIDB, testClientIDA, + connection.OPEN, + ) + suite.chainB.createConnection( + testConnectionIDA, testConnectionIDB, testClientIDA, testClientIDB, + connection.OPEN, + ) + suite.chainA.createChannel( + testPort1, testChannel1, testPort2, testChannel2, types.INIT, + types.ORDERED, testConnectionIDB, + ) + suite.chainB.createChannel( + testPort2, testChannel2, testPort1, testChannel1, types.TRYOPEN, + types.ORDERED, testConnectionIDA, + ) + }, + true, + }, + } + + for i, tc := range testCases { + tc.setup() + + clientState, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), testClientIDB) + bz, err := suite.querier(suite.chainA.GetContext(), path, query) + + if tc.expPass { + // set expected result + expRes, merr := codec.MarshalJSONIndent(suite.cdc, clientState) + suite.Require().NoError(merr) + suite.Require().True(found) + suite.Require().NoError(err, "test case %d failed: %s", i, tc.name) + suite.Require().Equal(string(expRes), string(bz), "test case %d failed: %s", i, tc.name) + } else { + suite.Require().False(found) + suite.Require().Error(err, "test case %d passed: %s", i, tc.name) + suite.Require().Nil(bz, "test case %d passed: %s", i, tc.name) + } + } } // TestQueryPacketCommitments tests querying packet commitments on a specified channel end. @@ -242,7 +336,7 @@ func (suite *KeeperTestSuite) TestQueryPacketCommitments() { params := types.NewQueryPacketCommitmentsParams(testPort1, testChannel1, 1, 100) data, err := suite.cdc.MarshalJSON(params) - suite.NoError(err) + suite.Require().NoError(err) query := abci.RequestQuery{ Path: "", @@ -268,7 +362,7 @@ func (suite *KeeperTestSuite) TestQueryPacketCommitments() { } expRes, err = codec.MarshalJSONIndent(suite.cdc, commitments) - suite.NoError(err) + suite.Require().NoError(err) }, }, { @@ -291,7 +385,7 @@ func (suite *KeeperTestSuite) TestQueryPacketCommitments() { } expRes, err = codec.MarshalJSONIndent(suite.cdc, commitments) - suite.NoError(err) + suite.Require().NoError(err) }, }, { @@ -299,7 +393,7 @@ func (suite *KeeperTestSuite) TestQueryPacketCommitments() { func() { suite.SetupTest() expRes, err = codec.MarshalJSONIndent(suite.cdc, []uint64{}) - suite.NoError(err) + suite.Require().NoError(err) }, }, } @@ -309,8 +403,8 @@ func (suite *KeeperTestSuite) TestQueryPacketCommitments() { bz, err := suite.querier(suite.chainA.GetContext(), path, query) - suite.NoError(err, "test case %d failed: %s", i, tc.name) - suite.Equal(expRes, bz, "test case %d failed: %s", i, tc.name) + suite.Require().NoError(err, "test case %d failed: %s", i, tc.name) + suite.Require().Equal(expRes, bz, "test case %d failed: %s", i, tc.name) } } @@ -329,7 +423,7 @@ func (suite *KeeperTestSuite) TestQueryUnrelayedAcks() { params := types.NewQueryUnrelayedPacketsParams(testPort1, testChannel1, sequences, 1, 100) data, err := suite.cdc.MarshalJSON(params) - suite.NoError(err) + suite.Require().NoError(err) query := abci.RequestQuery{ Path: "", @@ -359,10 +453,10 @@ func (suite *KeeperTestSuite) TestQueryUnrelayedAcks() { } expResAck, err = codec.MarshalJSONIndent(suite.cdc, unrelayedAcks) - suite.NoError(err) + suite.Require().NoError(err) expResSend, err = codec.MarshalJSONIndent(suite.cdc, unrelayedSends) - suite.NoError(err) + suite.Require().NoError(err) }, }, @@ -392,10 +486,10 @@ func (suite *KeeperTestSuite) TestQueryUnrelayedAcks() { } expResAck, err = codec.MarshalJSONIndent(suite.cdc, unrelayedAcks) - suite.NoError(err) + suite.Require().NoError(err) expResSend, err = codec.MarshalJSONIndent(suite.cdc, unrelayedSends) - suite.NoError(err) + suite.Require().NoError(err) }, }, { @@ -410,10 +504,10 @@ func (suite *KeeperTestSuite) TestQueryUnrelayedAcks() { } expResSend, err = codec.MarshalJSONIndent(suite.cdc, []uint64{}) - suite.NoError(err) + suite.Require().NoError(err) expResAck, err = codec.MarshalJSONIndent(suite.cdc, sequences) - suite.NoError(err) + suite.Require().NoError(err) }, }, } @@ -423,13 +517,13 @@ func (suite *KeeperTestSuite) TestQueryUnrelayedAcks() { bz, err := suite.querier(suite.chainA.GetContext(), pathAck, query) - suite.NoError(err, "test case %d failed: %s", i, tc.name) - suite.Equal(expResAck, bz, "test case %d failed: %s", i, tc.name) + suite.Require().NoError(err, "test case %d failed: %s", i, tc.name) + suite.Require().Equal(expResAck, bz, "test case %d failed: %s", i, tc.name) bz, err = suite.querier(suite.chainA.GetContext(), pathSend, query) - suite.NoError(err, "test case %d failed: %s", i, tc.name) - suite.Equal(expResSend, bz, "test case %d failed: %s", i, tc.name) + suite.Require().NoError(err, "test case %d failed: %s", i, tc.name) + suite.Require().Equal(expResSend, bz, "test case %d failed: %s", i, tc.name) } diff --git a/x/ibc/04-channel/module.go b/x/ibc/04-channel/module.go index c88df5c2a5..3943f48e20 100644 --- a/x/ibc/04-channel/module.go +++ b/x/ibc/04-channel/module.go @@ -19,7 +19,7 @@ func Name() string { // RegisterRESTRoutes registers the REST routes for the IBC channel func RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router, queryRoute string) { - rest.RegisterRoutes(clientCtx, rtr, fmt.Sprintf("%s/%s", queryRoute, SubModuleName)) + rest.RegisterRoutes(clientCtx, rtr) } // GetTxCmd returns the root tx command for the IBC connections. diff --git a/x/ibc/04-channel/types/keys.go b/x/ibc/04-channel/types/keys.go index 21372dc48d..60f24d5e74 100644 --- a/x/ibc/04-channel/types/keys.go +++ b/x/ibc/04-channel/types/keys.go @@ -2,7 +2,7 @@ package types const ( // SubModuleName defines the IBC channels name - SubModuleName = "channels" + SubModuleName = "channel" // StoreKey is the store key string for IBC channels StoreKey = SubModuleName diff --git a/x/ibc/04-channel/types/querier.go b/x/ibc/04-channel/types/querier.go index 0f0db02b7c..d42f06b8c1 100644 --- a/x/ibc/04-channel/types/querier.go +++ b/x/ibc/04-channel/types/querier.go @@ -14,6 +14,7 @@ const ( QueryAllChannels = "channels" QueryChannel = "channel" QueryConnectionChannels = "connection-channels" + QueryChannelClientState = "channel-client-state" QueryPacketCommitments = "packet-commitments" QueryUnrelayedAcknowledgements = "unrelayed-acknowledgements" QueryUnrelayedPacketSends = "unrelayed-packet-sends" @@ -155,3 +156,18 @@ func NewRecvResponse( ProofHeight: uint64(height), } } + +// QueryChannelClientStateParams defines the parameters necessary for querying +// ClientState at an associated port ID and channel ID. +type QueryChannelClientStateParams struct { + PortID string `json:"port_id" yaml:"port_id"` + ChannelID string `json:"channel_id" yaml:"channel_id"` +} + +// NewQueryChannelClientStateParams creates a new QueryChannelClientStateParams instance. +func NewQueryChannelClientStateParams(portID, channelID string) QueryChannelClientStateParams { + return QueryChannelClientStateParams{ + PortID: portID, + ChannelID: channelID, + } +} diff --git a/x/ibc/keeper/querier.go b/x/ibc/keeper/querier.go index 40104a8feb..bb4d4e18d5 100644 --- a/x/ibc/keeper/querier.go +++ b/x/ibc/keeper/querier.go @@ -7,7 +7,8 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + channelkeeper "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" ) // NewQuerier creates a querier for the IBC module @@ -37,20 +38,22 @@ func NewQuerier(k Keeper) sdk.Querier { default: err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", connection.SubModuleName) } - case channel.SubModuleName: + case channeltypes.SubModuleName: switch path[1] { - case channel.QueryAllChannels: - res, err = channel.QuerierChannels(ctx, req, k.ChannelKeeper) - case channel.QueryConnectionChannels: - res, err = channel.QuerierConnectionChannels(ctx, req, k.ChannelKeeper) - case channel.QueryPacketCommitments: - res, err = channel.QuerierPacketCommitments(ctx, req, k.ChannelKeeper) - case channel.QueryUnrelayedAcknowledgements: - res, err = channel.QuerierUnrelayedAcknowledgements(ctx, req, k.ChannelKeeper) - case channel.QueryUnrelayedPacketSends: - res, err = channel.QuerierUnrelayedPacketSends(ctx, req, k.ChannelKeeper) + case channeltypes.QueryAllChannels: + res, err = channelkeeper.QuerierChannels(ctx, req, k.ChannelKeeper) + case channeltypes.QueryConnectionChannels: + res, err = channelkeeper.QuerierConnectionChannels(ctx, req, k.ChannelKeeper) + case channeltypes.QueryChannelClientState: + res, err = channelkeeper.QuerierChannelClientState(ctx, req, k.ChannelKeeper) + case channeltypes.QueryPacketCommitments: + res, err = channelkeeper.QuerierPacketCommitments(ctx, req, k.ChannelKeeper) + case channeltypes.QueryUnrelayedAcknowledgements: + res, err = channelkeeper.QuerierUnrelayedAcknowledgements(ctx, req, k.ChannelKeeper) + case channeltypes.QueryUnrelayedPacketSends: + res, err = channelkeeper.QuerierUnrelayedPacketSends(ctx, req, k.ChannelKeeper) default: - err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", channel.SubModuleName) + err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", channeltypes.SubModuleName) } default: err = sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown IBC query endpoint") diff --git a/x/ibc/keeper/querier_test.go b/x/ibc/keeper/querier_test.go index 54bd4bf126..7912a7d820 100644 --- a/x/ibc/keeper/querier_test.go +++ b/x/ibc/keeper/querier_test.go @@ -5,9 +5,9 @@ import ( "github.com/stretchr/testify/require" - client "github.com/cosmos/cosmos-sdk/x/ibc/02-client" - connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection" - channel "github.com/cosmos/cosmos-sdk/x/ibc/04-channel" + clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types" + connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" abci "github.com/tendermint/tendermint/abci/types" ) @@ -15,7 +15,6 @@ import ( // TestNewQuerier tests that the querier paths are correct. // NOTE: the actuall testing functionality are located on each ICS querier test. func (suite *KeeperTestSuite) TestNewQuerier() { - query := abci.RequestQuery{ Path: "", Data: []byte{}, @@ -28,92 +27,98 @@ func (suite *KeeperTestSuite) TestNewQuerier() { errMsg string }{ {"client - QuerierClientState", - []string{client.SubModuleName, client.QueryClientState}, + []string{clienttypes.SubModuleName, clienttypes.QueryClientState}, false, "", }, {"client - QuerierClients", - []string{client.SubModuleName, client.QueryAllClients}, + []string{clienttypes.SubModuleName, clienttypes.QueryAllClients}, false, "", }, { "client - QuerierConsensusState", - []string{client.SubModuleName, client.QueryConsensusState}, + []string{clienttypes.SubModuleName, clienttypes.QueryConsensusState}, false, "", }, { "client - invalid query", - []string{client.SubModuleName, "foo"}, + []string{clienttypes.SubModuleName, "foo"}, true, - fmt.Sprintf("unknown IBC %s query endpoint", client.SubModuleName), + fmt.Sprintf("unknown IBC %s query endpoint", clienttypes.SubModuleName), }, { "connection - QuerierConnections", - []string{connection.SubModuleName, connection.QueryAllConnections}, + []string{connectiontypes.SubModuleName, connectiontypes.QueryAllConnections}, false, "", }, { "connection - QuerierAllClientConnections", - []string{connection.SubModuleName, connection.QueryAllClientConnections}, + []string{connectiontypes.SubModuleName, connectiontypes.QueryAllClientConnections}, false, "", }, { "connection - QuerierClientConnections", - []string{connection.SubModuleName, connection.QueryClientConnections}, + []string{connectiontypes.SubModuleName, connectiontypes.QueryClientConnections}, false, "", }, { "connection - invalid query", - []string{connection.SubModuleName, "foo"}, + []string{connectiontypes.SubModuleName, "foo"}, true, - fmt.Sprintf("unknown IBC %s query endpoint", connection.SubModuleName), + fmt.Sprintf("unknown IBC %s query endpoint", connectiontypes.SubModuleName), }, { "channel - QuerierChannel", - []string{channel.SubModuleName, channel.QueryChannel}, + []string{channeltypes.SubModuleName, channeltypes.QueryChannel}, false, "", }, { "channel - QuerierChannels", - []string{channel.SubModuleName, channel.QueryAllChannels}, + []string{channeltypes.SubModuleName, channeltypes.QueryAllChannels}, false, "", }, { "channel - QuerierConnectionChannels", - []string{channel.SubModuleName, channel.QueryConnectionChannels}, + []string{channeltypes.SubModuleName, channeltypes.QueryConnectionChannels}, + false, + "", + }, + { + "channel - QuerierChannelClientState", + []string{channeltypes.SubModuleName, channeltypes.QueryChannelClientState}, false, "", }, { "channel - QuerierPacketCommitments", - []string{channel.SubModuleName, channel.QueryPacketCommitments}, + []string{channeltypes.SubModuleName, channeltypes.QueryPacketCommitments}, false, "", }, { "channel - QuerierUnrelayedAcknowledgements", - []string{channel.SubModuleName, channel.QueryUnrelayedAcknowledgements}, + []string{channeltypes.SubModuleName, channeltypes.QueryUnrelayedAcknowledgements}, false, "", }, { "channel - QuerierUnrelayedPacketSends", - []string{channel.SubModuleName, channel.QueryUnrelayedPacketSends}, + []string{channeltypes.SubModuleName, channeltypes.QueryUnrelayedPacketSends}, false, "", }, { "channel - invalid query", - []string{channel.SubModuleName, "foo"}, + []string{channeltypes.SubModuleName, "foo"}, true, - fmt.Sprintf("unknown IBC %s query endpoint", channel.SubModuleName), + fmt.Sprintf("unknown IBC %s query endpoint", channeltypes.SubModuleName), }, { "invalid query",