Add clientState and consensusState gRPC support to connection (#7017)
* add proto querys for connection * add client state and consensus state grpc for connection * update client utils
This commit is contained in:
parent
d752a7b21f
commit
3a4e608930
@ -3,31 +3,51 @@ package ibc.connection;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "cosmos/base/query/v1beta1/pagination.proto";
|
||||
import "ibc/client/client.proto";
|
||||
import "ibc/connection/connection.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types";
|
||||
|
||||
// Query provides defines the gRPC querier service
|
||||
service Query {
|
||||
// Connection queries an IBC connection end.
|
||||
rpc Connection(QueryConnectionRequest) returns (QueryConnectionResponse) {}
|
||||
rpc Connection(QueryConnectionRequest) returns (QueryConnectionResponse) {
|
||||
}
|
||||
|
||||
// Connections queries all the IBC connections of a chain.
|
||||
rpc Connections(QueryConnectionsRequest) returns (QueryConnectionsResponse) {}
|
||||
rpc Connections(QueryConnectionsRequest) returns (QueryConnectionsResponse) {
|
||||
}
|
||||
|
||||
// ClientConnections queries the connection paths associated with a client state.
|
||||
rpc ClientConnections(QueryClientConnectionsRequest) returns (QueryClientConnectionsResponse) {}
|
||||
// ClientConnections queries the connection paths associated with a client
|
||||
// state.
|
||||
rpc ClientConnections(QueryClientConnectionsRequest)
|
||||
returns (QueryClientConnectionsResponse) {
|
||||
}
|
||||
|
||||
// ConnectionClientState queries the client state associated with the
|
||||
// connection
|
||||
rpc ConnectionClientState(QueryConnectionClientStateRequest)
|
||||
returns (QueryConnectionClientStateResponse) {
|
||||
}
|
||||
|
||||
// ConnectionConsensusState queries the consensus state associated with the
|
||||
// connection
|
||||
rpc ConnectionConsensusState(QueryConnectionConsensusStateRequest)
|
||||
returns (QueryConnectionConsensusStateResponse) {
|
||||
}
|
||||
}
|
||||
|
||||
// QueryConnectionRequest is the request type for the Query/Connection RPC method
|
||||
// QueryConnectionRequest is the request type for the Query/Connection RPC
|
||||
// method
|
||||
message QueryConnectionRequest {
|
||||
// connection unique identifier
|
||||
string connection_id = 1 [(gogoproto.customname) = "ConnectionID"];
|
||||
}
|
||||
|
||||
// QueryConnectionResponse is the response type for the Query/Connection RPC method.
|
||||
// Besides the connection end, it includes a proof and the height from which the
|
||||
// proof was retrieved.
|
||||
// QueryConnectionResponse is the response type for the Query/Connection RPC
|
||||
// method. Besides the connection end, it includes a proof and the height from
|
||||
// which the proof was retrieved.
|
||||
message QueryConnectionResponse {
|
||||
// connection associated with the request identifier
|
||||
ibc.connection.ConnectionEnd connection = 1;
|
||||
@ -39,12 +59,14 @@ message QueryConnectionResponse {
|
||||
uint64 proof_height = 4;
|
||||
}
|
||||
|
||||
// QueryConnectionsRequest is the request type for the Query/Connections RPC method
|
||||
// QueryConnectionsRequest is the request type for the Query/Connections RPC
|
||||
// method
|
||||
message QueryConnectionsRequest {
|
||||
cosmos.base.query.v1beta1.PageRequest pagination = 1;
|
||||
}
|
||||
|
||||
// QueryConnectionsResponse is the response type for the Query/Connections RPC method.
|
||||
// QueryConnectionsResponse is the response type for the Query/Connections RPC
|
||||
// method.
|
||||
message QueryConnectionsResponse {
|
||||
// list of stored connections of the chain.
|
||||
repeated ibc.connection.IdentifiedConnection connections = 1;
|
||||
@ -54,15 +76,15 @@ message QueryConnectionsResponse {
|
||||
int64 height = 3;
|
||||
}
|
||||
|
||||
// QueryClientConnectionsRequest is the request type for the Query/ClientConnections
|
||||
// RPC method
|
||||
// QueryClientConnectionsRequest is the request type for the
|
||||
// Query/ClientConnections RPC method
|
||||
message QueryClientConnectionsRequest {
|
||||
// client identifier associated with a connection
|
||||
string client_id = 1 [(gogoproto.customname) = "ClientID"];
|
||||
}
|
||||
|
||||
// QueryClientConnectionsResponse is the response type for the Query/ClientConnections
|
||||
// RPC method
|
||||
// QueryClientConnectionsResponse is the response type for the
|
||||
// Query/ClientConnections RPC method
|
||||
message QueryClientConnectionsResponse {
|
||||
// slice of all the connection paths associated with a client.
|
||||
repeated string connection_paths = 1;
|
||||
@ -73,3 +95,52 @@ message QueryClientConnectionsResponse {
|
||||
// height at which the proof was generated
|
||||
uint64 proof_height = 4;
|
||||
}
|
||||
|
||||
// QueryConnectionClientStateRequest is the request type for the
|
||||
// Query/ConnectionClientState RPC method
|
||||
message QueryConnectionClientStateRequest {
|
||||
// connection identifier
|
||||
string id = 1 [
|
||||
(gogoproto.customname) = "ConnectionID",
|
||||
(gogoproto.moretags) = "yaml:\"connection_id\""
|
||||
];
|
||||
}
|
||||
|
||||
// QueryConnectionClientStateResponse is the response type for the
|
||||
// Query/ConnectionClientState RPC method
|
||||
message QueryConnectionClientStateResponse {
|
||||
// client state associated with the channel
|
||||
ibc.client.IdentifiedClientState identified_client_state = 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;
|
||||
}
|
||||
|
||||
// QueryConnectionConsensusStateRequest is the request type for the
|
||||
// Query/ConnectionConsensusState RPC method
|
||||
message QueryConnectionConsensusStateRequest {
|
||||
// connection identifier
|
||||
string connection_id = 1 [
|
||||
(gogoproto.customname) = "ConnectionID",
|
||||
(gogoproto.moretags) = "yaml:\"connection_id\""
|
||||
];
|
||||
uint64 height = 2;
|
||||
}
|
||||
|
||||
// QueryConnectionConsensusStateResponse is the response type for the
|
||||
// Query/ConnectionConsensusState RPC method
|
||||
message QueryConnectionConsensusStateResponse {
|
||||
// consensus state associated with the channel
|
||||
google.protobuf.Any consensus_state = 1;
|
||||
// client ID associated with the consensus state
|
||||
string client_id = 2 [(gogoproto.customname) = "ClientID"];
|
||||
// merkle proof of existence
|
||||
bytes proof = 3;
|
||||
// merkle proof path
|
||||
string proof_path = 4;
|
||||
// height at which the proof was retrieved
|
||||
uint64 proof_height = 5;
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ to the counterparty channel. Any timeout set to 0 is disabled.`),
|
||||
// if the timeouts are not absolute, retrieve latest block height and block timestamp
|
||||
// for the consensus state connected to the destination port/channel
|
||||
if !absoluteTimeouts {
|
||||
consensusState, _, err := channelutils.QueryCounterpartyConsensusState(clientCtx, srcPort, srcChannel)
|
||||
consensusState, _, err := channelutils.QueryCounterpartyConsensusState(clientCtx, srcPort, srcChannel, uint64(clientCtx.Height))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils"
|
||||
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
|
||||
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
|
||||
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
|
||||
@ -102,6 +104,78 @@ func queryClientConnectionsABCI(clientCtx client.Context, clientID string) (*typ
|
||||
return types.NewQueryClientConnectionsResponse(clientID, paths, proofBz, res.Height), nil
|
||||
}
|
||||
|
||||
// QueryConnectionClientState returns the ClientState of a connection end. If
|
||||
// prove is true, it performs an ABCI store query in order to retrieve the
|
||||
// merkle proof. Otherwise, it uses the gRPC query client.
|
||||
func QueryConnectionClientState(
|
||||
clientCtx client.Context, connectionID string, prove bool,
|
||||
) (*types.QueryConnectionClientStateResponse, error) {
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
req := &types.QueryConnectionClientStateRequest{
|
||||
ConnectionID: connectionID,
|
||||
}
|
||||
|
||||
res, err := queryClient.ConnectionClientState(context.Background(), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if prove {
|
||||
clientState, proof, proofHeight, err := clientutils.QueryClientStateABCI(clientCtx, res.IdentifiedClientState.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// use client state returned from ABCI query in case query height differs
|
||||
identifiedClientState := clienttypes.NewIdentifiedClientState(res.IdentifiedClientState.ID, clientState)
|
||||
res = types.NewQueryConnectionClientStateResponse(identifiedClientState, proof, int64(proofHeight))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// QueryConnectionConsensusState returns the ConsensusState of a connection end. If
|
||||
// prove is true, it performs an ABCI store query in order to retrieve the
|
||||
// merkle proof. Otherwise, it uses the gRPC query client.
|
||||
func QueryConnectionConsensusState(
|
||||
clientCtx client.Context, connectionID string, height uint64, prove bool,
|
||||
) (*types.QueryConnectionConsensusStateResponse, error) {
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
req := &types.QueryConnectionConsensusStateRequest{
|
||||
ConnectionID: connectionID,
|
||||
Height: height,
|
||||
}
|
||||
|
||||
res, err := queryClient.ConnectionConsensusState(context.Background(), req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
consensusState, err := clienttypes.UnpackConsensusState(res.ConsensusState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if prove {
|
||||
consensusState, proof, proofHeight, err := clientutils.QueryConsensusStateABCI(clientCtx, res.ClientID, consensusState.GetHeight())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// use consensus state returned from ABCI query in case query height differs
|
||||
anyConsensusState, err := clienttypes.PackConsensusState(consensusState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = types.NewQueryConnectionConsensusStateResponse(res.ClientID, anyConsensusState, consensusState.GetHeight(), proof, int64(proofHeight))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ParsePrefix unmarshals an cmd input argument from a JSON string to a commitment
|
||||
// Prefix. If the input is not a JSON, it looks for a path to the JSON file.
|
||||
func ParsePrefix(cdc *codec.LegacyAmino, arg string) (commitmenttypes.MerklePrefix, error) {
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
|
||||
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
|
||||
)
|
||||
@ -103,3 +104,73 @@ func (q Keeper) ClientConnections(c context.Context, req *types.QueryClientConne
|
||||
ProofHeight: uint64(ctx.BlockHeight()),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ConnectionClientState implements the Query/ConnectionClientState gRPC method
|
||||
func (q Keeper) ConnectionClientState(c context.Context, req *types.QueryConnectionClientStateRequest) (*types.QueryConnectionClientStateResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
if err := host.ConnectionIdentifierValidator(req.ConnectionID); err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
connection, found := q.GetConnection(ctx, req.ConnectionID)
|
||||
if !found {
|
||||
return nil, status.Error(
|
||||
codes.NotFound,
|
||||
sdkerrors.Wrapf(types.ErrConnectionNotFound, "connection-id: %s", req.ConnectionID).Error(),
|
||||
)
|
||||
}
|
||||
|
||||
clientState, found := q.clientKeeper.GetClientState(ctx, connection.ClientID)
|
||||
if !found {
|
||||
return nil, status.Error(
|
||||
codes.NotFound,
|
||||
sdkerrors.Wrapf(clienttypes.ErrClientNotFound, "client-id: %s", connection.ClientID).Error(),
|
||||
)
|
||||
}
|
||||
|
||||
identifiedClientState := clienttypes.NewIdentifiedClientState(connection.ClientID, clientState)
|
||||
|
||||
return types.NewQueryConnectionClientStateResponse(identifiedClientState, nil, ctx.BlockHeight()), nil
|
||||
|
||||
}
|
||||
|
||||
// ConnectionConsensusState implements the Query/ConnectionConsensusState gRPC method
|
||||
func (q Keeper) ConnectionConsensusState(c context.Context, req *types.QueryConnectionConsensusStateRequest) (*types.QueryConnectionConsensusStateResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
if err := host.ConnectionIdentifierValidator(req.ConnectionID); err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
connection, found := q.GetConnection(ctx, req.ConnectionID)
|
||||
if !found {
|
||||
return nil, status.Error(
|
||||
codes.NotFound,
|
||||
sdkerrors.Wrapf(types.ErrConnectionNotFound, "connection-id: %s", req.ConnectionID).Error(),
|
||||
)
|
||||
}
|
||||
|
||||
consensusState, found := q.clientKeeper.GetClientConsensusState(ctx, connection.ClientID, req.Height)
|
||||
if !found {
|
||||
return nil, status.Error(
|
||||
codes.NotFound,
|
||||
sdkerrors.Wrapf(clienttypes.ErrConsensusStateNotFound, "client-id: %s", connection.ClientID).Error(),
|
||||
)
|
||||
}
|
||||
|
||||
anyConsensusState, err := clienttypes.PackConsensusState(consensusState)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return types.NewQueryConnectionConsensusStateResponse(connection.ClientID, anyConsensusState, consensusState.GetHeight(), nil, ctx.BlockHeight()), nil
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/query"
|
||||
clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
|
||||
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
|
||||
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
|
||||
)
|
||||
@ -227,3 +228,180 @@ func (suite *KeeperTestSuite) TestQueryClientConnections() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestQueryConnectionClientState() {
|
||||
var (
|
||||
req *types.QueryConnectionClientStateRequest
|
||||
expIdentifiedClientState clienttypes.IdentifiedClientState
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
req = nil
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid connection ID",
|
||||
func() {
|
||||
req = &types.QueryConnectionClientStateRequest{
|
||||
ConnectionID: "",
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"connection not found",
|
||||
func() {
|
||||
req = &types.QueryConnectionClientStateRequest{
|
||||
ConnectionID: "test-connection-id",
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"client state not found",
|
||||
func() {
|
||||
_, _, connA, _, _, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
||||
|
||||
// set connection to empty so clientID is empty
|
||||
suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, types.ConnectionEnd{})
|
||||
|
||||
req = &types.QueryConnectionClientStateRequest{
|
||||
ConnectionID: connA.ID,
|
||||
}
|
||||
}, false,
|
||||
},
|
||||
{
|
||||
"success",
|
||||
func() {
|
||||
clientA, _, connA, _ := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint)
|
||||
|
||||
expClientState := suite.chainA.GetClientState(clientA)
|
||||
expIdentifiedClientState = clienttypes.NewIdentifiedClientState(clientA, expClientState)
|
||||
|
||||
req = &types.QueryConnectionClientStateRequest{
|
||||
ConnectionID: connA.ID,
|
||||
}
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
suite.SetupTest() // reset
|
||||
|
||||
tc.malleate()
|
||||
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
|
||||
|
||||
res, err := suite.chainA.QueryServer.ConnectionClientState(ctx, req)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(res)
|
||||
suite.Require().Equal(&expIdentifiedClientState, res.IdentifiedClientState)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestQueryConnectionConsensusState() {
|
||||
var (
|
||||
req *types.QueryConnectionConsensusStateRequest
|
||||
expConsensusState clientexported.ConsensusState
|
||||
expClientID string
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
req = nil
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid connection ID",
|
||||
func() {
|
||||
req = &types.QueryConnectionConsensusStateRequest{
|
||||
ConnectionID: "",
|
||||
Height: 1,
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"connection not found",
|
||||
func() {
|
||||
req = &types.QueryConnectionConsensusStateRequest{
|
||||
ConnectionID: "test-connection-id",
|
||||
Height: 1,
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"consensus state not found",
|
||||
func() {
|
||||
_, _, connA, _, _, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
||||
|
||||
req = &types.QueryConnectionConsensusStateRequest{
|
||||
ConnectionID: connA.ID,
|
||||
Height: uint64(suite.chainA.GetContext().BlockHeight()), // use current height
|
||||
}
|
||||
}, false,
|
||||
},
|
||||
{
|
||||
"success",
|
||||
func() {
|
||||
clientA, _, connA, _ := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint)
|
||||
|
||||
clientState := suite.chainA.GetClientState(clientA)
|
||||
expConsensusState, _ = suite.chainA.GetConsensusState(clientA, clientState.GetLatestHeight())
|
||||
suite.Require().NotNil(expConsensusState)
|
||||
expClientID = clientA
|
||||
|
||||
req = &types.QueryConnectionConsensusStateRequest{
|
||||
ConnectionID: connA.ID,
|
||||
Height: expConsensusState.GetHeight(),
|
||||
}
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
||||
suite.SetupTest() // reset
|
||||
|
||||
tc.malleate()
|
||||
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
|
||||
|
||||
res, err := suite.chainA.QueryServer.ConnectionConsensusState(ctx, req)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(res)
|
||||
consensusState, err := clienttypes.UnpackConsensusState(res.ConsensusState)
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(expConsensusState, consensusState)
|
||||
suite.Require().Equal(expClientID, res.ClientID)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
|
||||
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
|
||||
)
|
||||
|
||||
// NewQueryConnectionResponse creates a new QueryConnectionResponse instance
|
||||
func NewQueryConnectionResponse(
|
||||
connectionID string, connection ConnectionEnd, proof []byte, height int64,
|
||||
) *QueryConnectionResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.ConnectionPath(connectionID), "/"))
|
||||
return &QueryConnectionResponse{
|
||||
Connection: &connection,
|
||||
Proof: proof,
|
||||
ProofPath: path.Pretty(),
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryClientConnectionsResponse creates a new ConnectionPaths instance
|
||||
func NewQueryClientConnectionsResponse(
|
||||
clientID string, connectionPaths []string, proof []byte, height int64,
|
||||
) *QueryClientConnectionsResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.ClientConnectionsPath(clientID), "/"))
|
||||
return &QueryClientConnectionsResponse{
|
||||
ConnectionPaths: connectionPaths,
|
||||
Proof: proof,
|
||||
ProofPath: path.Pretty(),
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryClientConnectionsRequest creates a new QueryClientConnectionsRequest instance
|
||||
func NewQueryClientConnectionsRequest(clientID string) *QueryClientConnectionsRequest {
|
||||
return &QueryClientConnectionsRequest{
|
||||
ClientID: clientID,
|
||||
}
|
||||
}
|
||||
66
x/ibc/03-connection/types/query.go
Normal file
66
x/ibc/03-connection/types/query.go
Normal file
@ -0,0 +1,66 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
|
||||
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
|
||||
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
|
||||
)
|
||||
|
||||
// NewQueryConnectionResponse creates a new QueryConnectionResponse instance
|
||||
func NewQueryConnectionResponse(
|
||||
connectionID string, connection ConnectionEnd, proof []byte, height int64,
|
||||
) *QueryConnectionResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.ConnectionPath(connectionID), "/"))
|
||||
return &QueryConnectionResponse{
|
||||
Connection: &connection,
|
||||
Proof: proof,
|
||||
ProofPath: path.Pretty(),
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryClientConnectionsResponse creates a new ConnectionPaths instance
|
||||
func NewQueryClientConnectionsResponse(
|
||||
clientID string, connectionPaths []string, proof []byte, height int64,
|
||||
) *QueryClientConnectionsResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.ClientConnectionsPath(clientID), "/"))
|
||||
return &QueryClientConnectionsResponse{
|
||||
ConnectionPaths: connectionPaths,
|
||||
Proof: proof,
|
||||
ProofPath: path.Pretty(),
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryClientConnectionsRequest creates a new QueryClientConnectionsRequest instance
|
||||
func NewQueryClientConnectionsRequest(clientID string) *QueryClientConnectionsRequest {
|
||||
return &QueryClientConnectionsRequest{
|
||||
ClientID: clientID,
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryConnectionClientStateResponse creates a newQueryConnectionClientStateResponse instance
|
||||
func NewQueryConnectionClientStateResponse(identifiedClientState clienttypes.IdentifiedClientState, proof []byte, height int64) *QueryConnectionClientStateResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.FullClientPath(identifiedClientState.ID, host.ClientStatePath()), "/"))
|
||||
return &QueryConnectionClientStateResponse{
|
||||
IdentifiedClientState: &identifiedClientState,
|
||||
Proof: proof,
|
||||
ProofPath: path.Pretty(),
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryConnectionConsensusStateResponse creates a newQueryConnectionConsensusStateResponse instance
|
||||
func NewQueryConnectionConsensusStateResponse(clientID string, anyConsensusState *codectypes.Any, consensusStateHeight uint64, proof []byte, height int64) *QueryConnectionConsensusStateResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.FullClientPath(clientID, host.ConsensusStatePath(consensusStateHeight)), "/"))
|
||||
return &QueryConnectionConsensusStateResponse{
|
||||
ConsensusState: anyConsensusState,
|
||||
ClientID: clientID,
|
||||
Proof: proof,
|
||||
ProofPath: path.Pretty(),
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -139,13 +139,14 @@ func QueryChannelClientState(
|
||||
// prove is true, it performs an ABCI store query in order to retrieve the
|
||||
// merkle proof. Otherwise, it uses the gRPC query client.
|
||||
func QueryChannelConsensusState(
|
||||
clientCtx client.Context, portID, channelID string, prove bool,
|
||||
clientCtx client.Context, portID, channelID string, height uint64, prove bool,
|
||||
) (*types.QueryChannelConsensusStateResponse, error) {
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
req := &types.QueryChannelConsensusStateRequest{
|
||||
PortID: portID,
|
||||
ChannelID: channelID,
|
||||
Height: height,
|
||||
}
|
||||
|
||||
res, err := queryClient.ChannelConsensusState(context.Background(), req)
|
||||
@ -179,7 +180,7 @@ func QueryChannelConsensusState(
|
||||
// QueryCounterpartyConsensusState uses the channel Querier to return the
|
||||
// counterparty ConsensusState given the source port ID and source channel ID.
|
||||
func QueryCounterpartyConsensusState(
|
||||
clientCtx client.Context, portID, channelID string,
|
||||
clientCtx client.Context, portID, channelID string, height uint64,
|
||||
) (clientexported.ConsensusState, uint64, error) {
|
||||
channelRes, err := QueryChannel(clientCtx, portID, channelID, false)
|
||||
if err != nil {
|
||||
@ -187,7 +188,7 @@ func QueryCounterpartyConsensusState(
|
||||
}
|
||||
|
||||
counterparty := channelRes.Channel.Counterparty
|
||||
res, err := QueryChannelConsensusState(clientCtx, counterparty.PortID, counterparty.ChannelID, false)
|
||||
res, err := QueryChannelConsensusState(clientCtx, counterparty.PortID, counterparty.ChannelID, height, false)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
@ -332,7 +332,8 @@ func (suite *KeeperTestSuite) TestQueryChannelClientState() {
|
||||
},
|
||||
false,
|
||||
},
|
||||
{"channel not found",
|
||||
{
|
||||
"channel not found",
|
||||
func() {
|
||||
req = &types.QueryChannelClientStateRequest{
|
||||
PortID: "test-port-id",
|
||||
@ -454,7 +455,8 @@ func (suite *KeeperTestSuite) TestQueryChannelConsensusState() {
|
||||
},
|
||||
false,
|
||||
},
|
||||
{"channel not found",
|
||||
{
|
||||
"channel not found",
|
||||
func() {
|
||||
req = &types.QueryChannelConsensusStateRequest{
|
||||
PortID: "test-port-id",
|
||||
|
||||
@ -22,6 +22,16 @@ func (q Keeper) ClientConnections(c context.Context, req *connectiontypes.QueryC
|
||||
return q.ConnectionKeeper.ClientConnections(c, req)
|
||||
}
|
||||
|
||||
// ConnectionClientState implements the IBC QueryServer interface
|
||||
func (q Keeper) ConnectionClientState(c context.Context, req *connectiontypes.QueryConnectionClientStateRequest) (*connectiontypes.QueryConnectionClientStateResponse, error) {
|
||||
return q.ConnectionKeeper.ConnectionClientState(c, req)
|
||||
}
|
||||
|
||||
// ConnectionConsensusState implements the IBC QueryServer interface
|
||||
func (q Keeper) ConnectionConsensusState(c context.Context, req *connectiontypes.QueryConnectionConsensusStateRequest) (*connectiontypes.QueryConnectionConsensusStateResponse, error) {
|
||||
return q.ConnectionKeeper.ConnectionConsensusState(c, req)
|
||||
}
|
||||
|
||||
// Channel implements the IBC QueryServer interface
|
||||
func (q Keeper) Channel(c context.Context, req *channeltypes.QueryChannelRequest) (*channeltypes.QueryChannelResponse, error) {
|
||||
return q.ChannelKeeper.Channel(c, req)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user