Skip to content

Commit

Permalink
move next sequence recv query to channel client
Browse files Browse the repository at this point in the history
  • Loading branch information
fedekunze committed Jun 24, 2020
1 parent 327e440 commit 759ae9c
Show file tree
Hide file tree
Showing 13 changed files with 733 additions and 220 deletions.
23 changes: 23 additions & 0 deletions proto/ibc/channel/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ service Query {
// UnrelayedPackets returns all the unrelayed IBC packets associated with a channel and sequences.
rpc UnrelayedPackets(QueryUnrelayedPacketsRequest) returns (QueryUnrelayedPacketsResponse) {}

// NextSequenceReceive returns the next receive sequence for a given channel
rpc NextSequenceReceive(QueryNextSequenceReceiveRequest) returns (QueryNextSequenceReceiveResponse) {}

// TODO: blocked by client proto migration
// rpc ChannelClientState(QueryChannelClientStateRequest) returns (QueryChannelClientStateRequest) {}
}
Expand Down Expand Up @@ -151,6 +154,26 @@ message QueryUnrelayedPacketsResponse {
int64 height = 3;
}

// QueryNextSequenceReceiveRequest is the request type for the Query/QueryNextSequenceReceiveRequest RPC method
message QueryNextSequenceReceiveRequest {
// port unique identifier
string port_id = 1 [(gogoproto.customname) = "PortID"];
// channel unique identifier
string channel_id = 2 [(gogoproto.customname) = "ChannelID"];
}

// QuerySequenceResponse is the request type for the Query/QueryNextSequenceReceiveResponse RPC method
message QueryNextSequenceReceiveResponse {
// next sequence receive number
uint64 next_sequence_receive = 1;
// merkle proof of existence
bytes proof = 2;
// merkle proof path
string proof_path = 3;
// height at which the proof was retrieved
uint64 proof_height = 4;
}

// QueryChannelClientStateRequest is the request type for the Query/ClientState RPC method
message QueryChannelClientStateRequest {
// port unique identifier
Expand Down
17 changes: 0 additions & 17 deletions x/ibc-transfer/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,6 @@ import (
"github.com/cosmos/cosmos-sdk/client/flags"
)

// GetQueryCmd returns the query commands for IBC fungible token transfer
func GetQueryCmd(clientCtx client.Context) *cobra.Command {
ics20TransferQueryCmd := &cobra.Command{
Use: "ibc-transfer",
Short: "IBC fungible token transfer query subcommands",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

ics20TransferQueryCmd.AddCommand(flags.GetCommands(
GetCmdQueryNextSequence(clientCtx),
)...)

return ics20TransferQueryCmd
}

// NewTxCmd returns the transaction commands for IBC fungible token transfer
func NewTxCmd(clientCtx client.Context) *cobra.Command {
ics20TransferTxCmd := &cobra.Command{
Expand Down
49 changes: 0 additions & 49 deletions x/ibc-transfer/client/cli/query.go

This file was deleted.

51 changes: 0 additions & 51 deletions x/ibc-transfer/client/rest/query.go

This file was deleted.

6 changes: 0 additions & 6 deletions x/ibc-transfer/client/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,8 @@ import (
"github.com/cosmos/cosmos-sdk/types/rest"
)

const (
RestChannelID = "channel-id"
RestPortID = "port-id"
)

// RegisterRoutes - Central function to define routes that get registered by the main application
func RegisterRoutes(clientCtx client.Context, r *mux.Router) {
registerQueryRoutes(clientCtx, r)
registerTxRoutes(clientCtx, r)
}

Expand Down
33 changes: 0 additions & 33 deletions x/ibc-transfer/client/utils/utils.go

This file was deleted.

2 changes: 1 addition & 1 deletion x/ibc/03-connection/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func GetCmdQueryConnections(clientCtx client.Context) *cobra.Command {
clientCtx = clientCtx.Init()
queryClient := types.NewQueryClient(clientCtx)

req := types.QueryConnectionsRequest{
req := &types.QueryConnectionsRequest{
Req: &query.PageRequest{},
}

Expand Down
1 change: 1 addition & 0 deletions x/ibc/04-channel/client/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func GetQueryCmd(clientCtx client.Context) *cobra.Command {
// TODO: Query all packet commitments
// TODO: Query unrelayed packet ACKS
// TODO: Query unrelayed packet sends
GetCmdQueryNextSequence(clientCtx),
)...)

return ics04ChannelQueryCmd
Expand Down
31 changes: 30 additions & 1 deletion x/ibc/04-channel/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ func GetCmdQueryChannel(clientCtx client.Context) *cobra.Command {
},
}
cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results")

return cmd
}

Expand Down Expand Up @@ -70,3 +69,33 @@ func GetCmdQueryChannelClientState(clientCtx client.Context) *cobra.Command {
}
return cmd
}

// GetCmdQueryNextSequence defines the command to query a next receive sequence for a given channel
func GetCmdQueryNextSequence(clientCtx client.Context) *cobra.Command {
cmd := &cobra.Command{
Use: "next-sequence-receive [port-id] [channel-id]",
Short: "Query a next receive sequence",
Long: "Query the next receive sequence for a given channel"
Example: fmt.Sprintf(
"%s query %s %s next-sequence-receive [port-id] [channel-id]", version.ClientName, host.ModuleName, types.SubModuleName,
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx = clientCtx.Init()

portID := args[0]
channelID := args[1]
prove := viper.GetBool(flags.FlagProve)

sequenceRes, err := utils.QueryNextSequenceReceive(clientCtx, portID, channelID, prove)
if err != nil {
return err
}

clientCtx = clientCtx.WithHeight(int64(sequenceRes.ProofHeight))
return clientCtx.PrintOutput(sequenceRes)
},
}
cmd.Flags().Bool(flags.FlagProve, true, "show proofs for the query results")
return cmd
}
36 changes: 24 additions & 12 deletions x/ibc/04-channel/client/rest/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,9 @@ import (
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")
r.HandleFunc(fmt.Sprintf("/ibc/ports/{%s}/channels/{%s}/next_sequence_receive", RestPortID, RestChannelID), queryNextSequenceRecvHandlerFn(clientCtx)).Methods("GET")
}

// queryChannelHandlerFn implements a channel querying route
//
// @Summary Query channel
// @Tags IBC
// @Produce json
// @Param port-id path string true "Port ID"
// @Param channel-id path string true "Channel ID"
// @Param prove query boolean false "Proof of result"
// @Success 200 {object} QueryChannel "OK"
// @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) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
Expand Down Expand Up @@ -73,3 +62,26 @@ func queryChannelClientStateHandlerFn(clientCtx client.Context) http.HandlerFunc
rest.PostProcessResponse(w, clientCtx, clientState)
}
}

func queryNextSequenceRecvHandlerFn(clientCtx client.Context) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
portID := vars[RestPortID]
channelID := vars[RestChannelID]
prove := rest.ParseQueryParamBool(r, flags.FlagProve)

clientCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, clientCtx, r)
if !ok {
return
}

sequenceRes, err := utils.QueryNextSequenceReceive(clientCtx, portID, channelID, prove)
if err != nil {
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
return
}

clientCtx = clientCtx.WithHeight(int64(sequenceRes.ProofHeight))
rest.PostProcessResponse(w, clientCtx, sequenceRes)
}
}
21 changes: 21 additions & 0 deletions x/ibc/04-channel/client/utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package utils

import (
"encoding/binary"
"fmt"

abci "github.com/tendermint/tendermint/abci/types"
Expand Down Expand Up @@ -86,3 +87,23 @@ func QueryChannelClientState(clientCtx client.Context, portID, channelID string)
}
return clientState, height, nil
}

// QueryNextSequenceReceive queries the store to get the next receive sequence and
// a merkle proof.
func QueryNextSequenceReceive(
clientCtx client.Context, portID, channelID string, prove bool,
) (*types.QueryNextSequenceReceiveResponse, error) {
req := abci.RequestQuery{
Path: "store/ibc/key",
Data: host.KeyNextSequenceRecv(portID, channelID),
Prove: prove,
}

res, err := clientCtx.QueryABCI(req)
if err != nil {
return nil, err
}

sequence := binary.BigEndian.Uint64(res.Value)
return types.NewQueryNextSequenceReceiveResponse(portID, channelID, sequence, res.Proof, res.Height), nil
}
13 changes: 13 additions & 0 deletions x/ibc/04-channel/types/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,19 @@ func NewQueryPacketCommitmentResponse(
}
}

// NewQueryNextSequenceReceiveResponse creates a new QueryNextSequenceReceiveResponse instance
func NewQueryNextSequenceReceiveResponse(
portID, channelID string, sequence uint64, proof []byte, height int64,
) *QueryNextSequenceReceiveResponse {
path := commitmenttypes.NewMerklePath(strings.Split(host.NextSequenceRecvPath(portID, channelID), "/"))
return &QueryNextSequenceReceiveResponse{
NextSequenceReceive: sequence,
Proof: proof,
ProofPath: path.Pretty(),
ProofHeight: uint64(height),
}
}

// NewQueryChannelClientStateRequest creates a new QueryChannelClientStateRequest instance.
func NewQueryChannelClientStateRequest(portID, channelID string) *QueryChannelClientStateRequest {
return &QueryChannelClientStateRequest{
Expand Down
Loading

0 comments on commit 759ae9c

Please sign in to comment.