x/ibc: query all client connection paths (#6155)

* x/ibc: query all client connections

* add queries to CLI and REST

* add missing height

* update swagger
This commit is contained in:
Federico Kunze 2020-05-06 11:56:49 -04:00 committed by GitHub
parent d7ebee74e7
commit ff24a24ae6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 249 additions and 8 deletions

File diff suppressed because one or more lines are too long

View File

@ -2151,6 +2151,35 @@ paths:
description: Invalid client id
500:
description: Internal Server Error
/ibc/connections:
get:
summary: Query all connections
tags:
- IBC
produces:
- application/json
parameters:
- in: query
name: page
description: Page number
type: integer
x-example: 1
- in: query
name: limit
description: Maximum number of items per page
type: integer
x-example: 1
responses:
200:
description: OK
schema:
type: array
items:
$ref: "#/definitions/Connection"
400:
description: Bad Request
500:
description: Internal Server Error
/ibc/connections/{connection-id}:
get:
summary: Query connection
@ -2179,6 +2208,35 @@ paths:
description: Invalid connection id
500:
description: Internal Server Error
/ibc/clients/connections:
get:
summary: Query all client connection paths
tags:
- IBC
produces:
- application/json
parameters:
- in: query
name: page
description: Page number
type: integer
x-example: 1
- in: query
name: limit
description: Maximum number of items per page
type: integer
x-example: 1
responses:
200:
description: OK
schema:
type: array
items:
$ref: "#/definitions/ConnectionPaths"
400:
description: Bad Request
500:
description: Internal Server Error
/ibc/clients/{client-id}/connections:
get:
summary: Query connections of a client
@ -2204,7 +2262,7 @@ paths:
schema:
$ref: "#/definitions/ClientConnectionsResponse"
400:
description: Invalid client id
description: Invalid Client Id
500:
description: Internal Server Error
/ibc/connections/open-init:
@ -3616,16 +3674,22 @@ definitions:
Connection:
type: object
properties:
id:
type: string
example: "connectionidone"
state:
type: string
example: "OPEN"
client_id:
type: string
example: "clientidone"
counterparty:
$ref: "#/definitions/ConnectionCounterparty"
versions:
type: array
items:
type: string
example: "1.0.0"
ConnectionCounterparty:
type: object
properties:
@ -3650,6 +3714,17 @@ definitions:
type: string
enc:
type: integer
ConnectionPaths:
type: object
properties:
client-id:
type: string
example: "clientidone"
paths:
type: array
items:
type: string
example: "connectionidone"
ClientConnectionsResponse:
type: object
properties:

View File

@ -29,6 +29,7 @@ func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router) {
// @Param page query int false "The page number to query" default(1)
// @Param limit query int false "The number of results per page" default(100)
// @Success 200 {object} QueryClientState "OK"
// @Failure 400 {object} rest.ErrorResponse "Bad Request"
// @Failure 500 {object} rest.ErrorResponse "Internal Server Error"
// @Router /ibc/clients [get]
func queryAllClientStatesFn(cliCtx context.CLIContext) http.HandlerFunc {

View File

@ -19,6 +19,7 @@ const (
RouterKey = types.RouterKey
QuerierRoute = types.QuerierRoute
QueryAllConnections = types.QueryAllConnections
QueryAllClientConnections = types.QueryAllClientConnections
QueryClientConnections = types.QueryClientConnections
)
@ -27,6 +28,7 @@ var (
NewKeeper = keeper.NewKeeper
QuerierConnections = keeper.QuerierConnections
QuerierClientConnections = keeper.QuerierClientConnections
QuerierAllClientConnections = keeper.QuerierAllClientConnections
RegisterCodec = types.RegisterCodec
RegisterInterfaces = types.RegisterInterfaces
NewConnectionEnd = types.NewConnectionEnd

View File

@ -34,11 +34,12 @@ $ %s query ibc connection connections
page := viper.GetInt(flags.FlagPage)
limit := viper.GetInt(flags.FlagLimit)
connections, _, err := utils.QueryAllConnections(cliCtx, page, limit)
connections, height, err := utils.QueryAllConnections(cliCtx, page, limit)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
return cliCtx.PrintOutput(connections)
},
}
@ -71,6 +72,7 @@ $ %s query ibc connection end [connection-id]
return err
}
cliCtx = cliCtx.WithHeight(int64(connRes.ProofHeight))
return cliCtx.PrintOutput(connRes)
},
}
@ -79,18 +81,51 @@ $ %s query ibc connection end [connection-id]
return cmd
}
// GetCmdQueryAllClientConnections defines the command to query a all the client connection paths.
func GetCmdQueryAllClientConnections(queryRoute string, cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "paths",
Short: "Query all stored client connection paths",
Long: strings.TrimSpace(fmt.Sprintf(`Query all stored client connection paths
Example:
$ %s query ibc connection paths
`, version.ClientName),
),
Example: fmt.Sprintf("%s query ibc connection paths", version.ClientName),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
page := viper.GetInt(flags.FlagPage)
limit := viper.GetInt(flags.FlagLimit)
connectionPaths, height, err := utils.QueryAllClientConnectionPaths(cliCtx, page, limit)
if err != nil {
return err
}
cliCtx = cliCtx.WithHeight(height)
return cliCtx.PrintOutput(connectionPaths)
},
}
cmd.Flags().Int(flags.FlagPage, 1, "pagination page of light clients to to query for")
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of light clients to query for")
return cmd
}
// GetCmdQueryClientConnections defines the command to query a client connections
func GetCmdQueryClientConnections(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "client [client-id]",
Use: "path [client-id]",
Short: "Query stored client connection paths",
Long: strings.TrimSpace(fmt.Sprintf(`Query stored client connection paths
Example:
$ %s query ibc connection client [client-id]
$ %s query ibc connection path [client-id]
`, version.ClientName),
),
Example: fmt.Sprintf("%s query ibc connection client [client-id]", version.ClientName),
Example: fmt.Sprintf("%s query ibc connection path [client-id]", version.ClientName),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
@ -102,6 +137,7 @@ $ %s query ibc connection client [client-id]
return err
}
cliCtx = cliCtx.WithHeight(int64(connPathsRes.ProofHeight))
return cliCtx.PrintOutput(connPathsRes)
},
}

View File

@ -13,10 +13,46 @@ import (
)
func registerQueryRoutes(cliCtx context.CLIContext, r *mux.Router, queryRoute string) {
r.HandleFunc("/ibc/connections", queryConnectionsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/ibc/connections/{%s}", RestConnectionID), queryConnectionHandlerFn(cliCtx, queryRoute)).Methods("GET")
r.HandleFunc("/ibc/clients/connections", queryClientsConnectionsHandlerFn(cliCtx)).Methods("GET")
r.HandleFunc(fmt.Sprintf("/ibc/clients/{%s}/connections", RestClientID), queryClientConnectionsHandlerFn(cliCtx, queryRoute)).Methods("GET")
}
// queryConnectionsHandlerFn implements connections querying route
//
// @Summary Query a client connection paths
// @Tags IBC
// @Produce json
// @Param page query int false "The page number to query" default(1)
// @Param limit query int false "The number of results per page" default(100)
// @Success 200 {object} QueryConnection "OK"
// @Failure 400 {object} rest.ErrorResponse "Bad Request"
// @Failure 500 {object} rest.ErrorResponse "Internal Server Error"
// @Router /ibc/connections [get]
func queryClientsConnectionsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
if rest.CheckBadRequestError(w, err) {
return
}
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
connections, height, err := utils.QueryAllConnections(cliCtx, page, limit)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, connections)
}
}
// queryConnectionHandlerFn implements a connection querying route
//
// @Summary Query connection
@ -50,6 +86,40 @@ func queryConnectionHandlerFn(cliCtx context.CLIContext, _ string) http.HandlerF
}
}
// queryConnectionsHandlerFn implements a client connections paths querying route
//
// @Summary Query all client connection paths
// @Tags IBC
// @Produce json
// @Param page query int false "The page number to query" default(1)
// @Param limit query int false "The number of results per page" default(100)
// @Success 200 {object} QueryClientsConnections "OK"
// @Failure 400 {object} rest.ErrorResponse "Bad Request"
// @Failure 500 {object} rest.ErrorResponse "Internal Server Error"
// @Router /ibc/clients/connections [get]
func queryConnectionsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
_, page, limit, err := rest.ParseHTTPArgsWithLimit(r, 0)
if rest.CheckBadRequestError(w, err) {
return
}
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
connectionsPaths, height, err := utils.QueryAllClientConnectionPaths(cliCtx, page, limit)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}
cliCtx = cliCtx.WithHeight(height)
rest.PostProcessResponse(w, cliCtx, connectionsPaths)
}
}
// queryClientConnectionsHandlerFn implements a client connections querying route
//
// @Summary Query connections of a client

View File

@ -64,6 +64,29 @@ func QueryConnection(
return connRes, nil
}
// QueryAllClientConnectionPaths returns all the client connections paths. It
// _does not_ return any merkle proof.
func QueryAllClientConnectionPaths(cliCtx context.CLIContext, page, limit int) ([]types.ConnectionPaths, int64, error) {
params := types.NewQueryAllConnectionsParams(page, limit)
bz, err := cliCtx.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.QueryAllClientConnections)
res, height, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return nil, 0, err
}
var connectionPaths []types.ConnectionPaths
err = cliCtx.Codec.UnmarshalJSON(res, &connectionPaths)
if err != nil {
return nil, 0, fmt.Errorf("failed to unmarshal client connection paths: %w", err)
}
return connectionPaths, height, nil
}
// QueryClientConnections queries the store to get the registered connection paths
// registered for a particular client and a merkle proof.
func QueryClientConnections(

View File

@ -55,3 +55,28 @@ func QuerierClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper)
return bz, nil
}
// QuerierAllClientConnections defines the sdk.Querier to query the connections paths for clients.
func QuerierAllClientConnections(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
var params types.QueryAllConnectionsParams
if err := k.cdc.UnmarshalJSON(req.Data, &params); err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}
clientsConnectionPaths := k.GetAllClientConnectionPaths(ctx)
start, end := client.Paginate(len(clientsConnectionPaths), params.Page, params.Limit, 100)
if start < 0 || end < 0 {
clientsConnectionPaths = []types.ConnectionPaths{}
} else {
clientsConnectionPaths = clientsConnectionPaths[start:end]
}
res, err := codec.MarshalJSONIndent(k.cdc, clientsConnectionPaths)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}
return res, nil
}

View File

@ -11,8 +11,9 @@ import (
// query routes supported by the IBC connection Querier
const (
QueryAllConnections = "connections"
QueryClientConnections = "client_connections"
QueryAllConnections = "connections"
QueryClientConnections = "client_connections"
QueryAllClientConnections = "all_client_connections"
)
// ConnectionResponse defines the client query response for a connection which

View File

@ -30,6 +30,8 @@ func NewQuerier(k Keeper) sdk.Querier {
switch path[1] {
case connection.QueryAllConnections:
res, err = connection.QuerierConnections(ctx, req, k.ConnectionKeeper)
case connection.QueryAllClientConnections:
res, err = connection.QuerierAllClientConnections(ctx, req, k.ConnectionKeeper)
case connection.QueryClientConnections:
res, err = connection.QuerierClientConnections(ctx, req, k.ConnectionKeeper)
default:

View File

@ -55,6 +55,12 @@ func (suite *KeeperTestSuite) TestNewQuerier() {
false,
"",
},
{
"connection - QuerierAllClientConnections",
[]string{connection.SubModuleName, connection.QueryAllClientConnections},
false,
"",
},
{
"connection - QuerierClientConnections",
[]string{connection.SubModuleName, connection.QueryClientConnections},