x/ibc: migrate rest of 04-channel to gRPC (#6964)
* migrate channel querier to grpc * fix various issues in channel grpc migration * remove querier and add tests * fix lint * update utils based on self review * Update x/ibc/24-host/keys.go Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * apply @fedekunze review suggestions * fix build * fix build * run make proto gen again Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
61a97ef347
commit
1744194e71
@ -1,41 +1,68 @@
|
||||
syntax = "proto3";
|
||||
package ibc.channel;
|
||||
|
||||
import "ibc/client/client.proto";
|
||||
import "gogoproto/gogo.proto";
|
||||
import "cosmos/base/query/v1beta1/pagination.proto";
|
||||
import "ibc/channel/channel.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types";
|
||||
|
||||
// Query provides defines the gRPC querier service
|
||||
service Query {
|
||||
// Channel queries an IBC Channel.
|
||||
rpc Channel(QueryChannelRequest) returns (QueryChannelResponse) {}
|
||||
rpc Channel(QueryChannelRequest) returns (QueryChannelResponse) {
|
||||
}
|
||||
|
||||
// Channels queries all the IBC channels of a chain.
|
||||
rpc Channels(QueryChannelsRequest) returns (QueryChannelsResponse) {}
|
||||
rpc Channels(QueryChannelsRequest) returns (QueryChannelsResponse) {
|
||||
}
|
||||
|
||||
// ConnectionChannels queries all the channels associated with a connection end.
|
||||
rpc ConnectionChannels(QueryConnectionChannelsRequest) returns (QueryConnectionChannelsResponse) {}
|
||||
// ConnectionChannels queries all the channels associated with a connection
|
||||
// end.
|
||||
rpc ConnectionChannels(QueryConnectionChannelsRequest)
|
||||
returns (QueryConnectionChannelsResponse) {
|
||||
}
|
||||
|
||||
// ChannelClientState queries for the client state for the channel associated
|
||||
// with the provided channel identifiers.
|
||||
rpc ChannelClientState(QueryChannelClientStateRequest)
|
||||
returns (QueryChannelClientStateResponse) {
|
||||
}
|
||||
|
||||
// ChannelConsensusState queries for the consensus state for the channel
|
||||
// associated with the provided channel identifiers.
|
||||
rpc ChannelConsensusState(QueryChannelConsensusStateRequest)
|
||||
returns (QueryChannelConsensusStateResponse) {
|
||||
}
|
||||
|
||||
// PacketCommitment queries a stored packet commitment hash.
|
||||
rpc PacketCommitment(QueryPacketCommitmentRequest) returns (QueryPacketCommitmentResponse) {}
|
||||
rpc PacketCommitment(QueryPacketCommitmentRequest)
|
||||
returns (QueryPacketCommitmentResponse) {
|
||||
}
|
||||
|
||||
// PacketCommitments returns the all the packet commitments hashes associated with a channel.
|
||||
rpc PacketCommitments(QueryPacketCommitmentsRequest) returns (QueryPacketCommitmentsResponse) {}
|
||||
// PacketCommitments returns the all the packet commitments hashes associated
|
||||
// with a channel.
|
||||
rpc PacketCommitments(QueryPacketCommitmentsRequest)
|
||||
returns (QueryPacketCommitmentsResponse) {
|
||||
}
|
||||
|
||||
// PacketAcknowledgement queries a stored packet acknowledgement hash.
|
||||
rpc PacketAcknowledgement(QueryPacketAcknowledgementRequest) returns (QueryPacketAcknowledgementResponse) {}
|
||||
rpc PacketAcknowledgement(QueryPacketAcknowledgementRequest)
|
||||
returns (QueryPacketAcknowledgementResponse) {
|
||||
}
|
||||
|
||||
// UnrelayedPackets returns all the unrelayed IBC packets associated with a channel and sequences.
|
||||
rpc UnrelayedPackets(QueryUnrelayedPacketsRequest) returns (QueryUnrelayedPacketsResponse) {}
|
||||
// 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) {}
|
||||
// rpc ChannelConsensusState(QueryChannelConsensusStateRequest) returns (QueryChannelConsensusStateRequest) {}
|
||||
rpc NextSequenceReceive(QueryNextSequenceReceiveRequest)
|
||||
returns (QueryNextSequenceReceiveResponse) {
|
||||
}
|
||||
}
|
||||
|
||||
// QueryChannelRequest is the request type for the Query/Channel RPC method
|
||||
@ -76,7 +103,8 @@ message QueryChannelsResponse {
|
||||
int64 height = 3;
|
||||
}
|
||||
|
||||
// QueryConnectionChannelsRequest is the request type for the Query/QueryConnectionChannels RPC method
|
||||
// QueryConnectionChannelsRequest is the request type for the
|
||||
// Query/QueryConnectionChannels RPC method
|
||||
message QueryConnectionChannelsRequest {
|
||||
// connection unique identifier
|
||||
string connection = 1;
|
||||
@ -84,7 +112,8 @@ message QueryConnectionChannelsRequest {
|
||||
cosmos.base.query.v1beta1.PageRequest pagination = 2;
|
||||
}
|
||||
|
||||
// QueryConnectionChannelsResponse is the Response type for the Query/QueryConnectionChannels RPC method
|
||||
// QueryConnectionChannelsResponse is the Response type for the
|
||||
// Query/QueryConnectionChannels RPC method
|
||||
message QueryConnectionChannelsResponse {
|
||||
// list of channels associated with a connection.
|
||||
repeated ibc.channel.IdentifiedChannel channels = 1;
|
||||
@ -94,7 +123,56 @@ message QueryConnectionChannelsResponse {
|
||||
int64 height = 3;
|
||||
}
|
||||
|
||||
// QueryPacketCommitmentRequest is the request type for the Query/PacketCommitment RPC method
|
||||
// QueryChannelClientStateRequest is the request type for the Query/ClientState
|
||||
// RPC method
|
||||
message QueryChannelClientStateRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
// channel unique identifier
|
||||
string channel_id = 2 [(gogoproto.customname) = "ChannelID"];
|
||||
}
|
||||
|
||||
// QueryChannelClientStateResponse is the Response type for the
|
||||
// Query/QueryChannelClientState RPC method
|
||||
message QueryChannelClientStateResponse {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// QueryChannelConsensusStateRequest is the request type for the
|
||||
// Query/ConsensusState RPC method
|
||||
message QueryChannelConsensusStateRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
// channel unique identifier
|
||||
string channel_id = 2 [(gogoproto.customname) = "ChannelID"];
|
||||
// height of the consensus state
|
||||
uint64 height = 3;
|
||||
}
|
||||
|
||||
// QueryChannelClientStateResponse is the Response type for the
|
||||
// Query/QueryChannelClientState RPC method
|
||||
message QueryChannelConsensusStateResponse {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// QueryPacketCommitmentRequest is the request type for the
|
||||
// Query/PacketCommitment RPC method
|
||||
message QueryPacketCommitmentRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
@ -104,8 +182,9 @@ message QueryPacketCommitmentRequest {
|
||||
uint64 sequence = 3;
|
||||
}
|
||||
|
||||
// QueryPacketCommitmentResponse defines the client query response for a packet which also
|
||||
// includes a proof, its path and the height form which the proof was retrieved
|
||||
// QueryPacketCommitmentResponse defines the client query response for a packet
|
||||
// which also includes a proof, its path and the height form which the proof was
|
||||
// retrieved
|
||||
message QueryPacketCommitmentResponse {
|
||||
// packet associated with the request fields
|
||||
bytes commitment = 1;
|
||||
@ -117,7 +196,8 @@ message QueryPacketCommitmentResponse {
|
||||
uint64 proof_height = 4;
|
||||
}
|
||||
|
||||
// QueryPacketCommitmentsRequest is the request type for the Query/QueryPacketCommitments RPC method
|
||||
// QueryPacketCommitmentsRequest is the request type for the
|
||||
// Query/QueryPacketCommitments RPC method
|
||||
message QueryPacketCommitmentsRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
@ -127,7 +207,8 @@ message QueryPacketCommitmentsRequest {
|
||||
cosmos.base.query.v1beta1.PageRequest pagination = 3;
|
||||
}
|
||||
|
||||
// QueryPacketCommitmentsResponse is the request type for the Query/QueryPacketCommitments RPC method
|
||||
// QueryPacketCommitmentsResponse is the request type for the
|
||||
// Query/QueryPacketCommitments RPC method
|
||||
message QueryPacketCommitmentsResponse {
|
||||
repeated ibc.channel.PacketAckCommitment commitments = 1;
|
||||
// pagination response
|
||||
@ -136,7 +217,8 @@ message QueryPacketCommitmentsResponse {
|
||||
int64 height = 3;
|
||||
}
|
||||
|
||||
// QueryPacketAcknowledgementRequest is the request type for the Query/PacketAcknowledgement RPC method
|
||||
// QueryPacketAcknowledgementRequest is the request type for the
|
||||
// Query/PacketAcknowledgement RPC method
|
||||
message QueryPacketAcknowledgementRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
@ -146,8 +228,9 @@ message QueryPacketAcknowledgementRequest {
|
||||
uint64 sequence = 3;
|
||||
}
|
||||
|
||||
// QueryPacketAcknowledgementResponse defines the client query response for a packet which also
|
||||
// includes a proof, its path and the height form which the proof was retrieved
|
||||
// QueryPacketAcknowledgementResponse defines the client query response for a
|
||||
// packet which also includes a proof, its path and the height form which the
|
||||
// proof was retrieved
|
||||
message QueryPacketAcknowledgementResponse {
|
||||
// packet associated with the request fields
|
||||
bytes acknowledgement = 1;
|
||||
@ -159,19 +242,23 @@ message QueryPacketAcknowledgementResponse {
|
||||
uint64 proof_height = 4;
|
||||
}
|
||||
|
||||
// QueryUnrelayedPacketsRequest is the request type for the Query/UnrelayedPackets RPC method
|
||||
// QueryUnrelayedPacketsRequest is the request type for the
|
||||
// Query/UnrelayedPackets RPC method
|
||||
message QueryUnrelayedPacketsRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
// channel unique identifier
|
||||
string channel_id = 2 [(gogoproto.customname) = "ChannelID"];
|
||||
// list of packet sequences
|
||||
repeated uint64 packet_commitment_sequences = 3 [(gogoproto.customname) = "PacketCommitmentSequences"];
|
||||
// flag indicating if the return value is packet commitments or acknowledgements
|
||||
repeated uint64 packet_commitment_sequences = 3
|
||||
[(gogoproto.customname) = "PacketCommitmentSequences"];
|
||||
// flag indicating if the return value is packet commitments or
|
||||
// acknowledgements
|
||||
bool acknowledgements = 4;
|
||||
}
|
||||
|
||||
// QueryUnrelayedPacketsResponse is the request type for the Query/UnrelayedPacketCommitments RPC method
|
||||
// QueryUnrelayedPacketsResponse is the request type for the
|
||||
// Query/UnrelayedPacketCommitments RPC method
|
||||
message QueryUnrelayedPacketsResponse {
|
||||
// list of unrelayed packet sequences
|
||||
repeated uint64 sequences = 1;
|
||||
@ -179,7 +266,8 @@ message QueryUnrelayedPacketsResponse {
|
||||
int64 height = 2;
|
||||
}
|
||||
|
||||
// QueryNextSequenceReceiveRequest is the request type for the Query/QueryNextSequenceReceiveRequest RPC method
|
||||
// QueryNextSequenceReceiveRequest is the request type for the
|
||||
// Query/QueryNextSequenceReceiveRequest RPC method
|
||||
message QueryNextSequenceReceiveRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
@ -187,7 +275,8 @@ message QueryNextSequenceReceiveRequest {
|
||||
string channel_id = 2 [(gogoproto.customname) = "ChannelID"];
|
||||
}
|
||||
|
||||
// QuerySequenceResponse is the request type for the Query/QueryNextSequenceReceiveResponse RPC method
|
||||
// QuerySequenceResponse is the request type for the
|
||||
// Query/QueryNextSequenceReceiveResponse RPC method
|
||||
message QueryNextSequenceReceiveResponse {
|
||||
// next sequence receive number
|
||||
uint64 next_sequence_receive = 1;
|
||||
@ -199,18 +288,3 @@ message QueryNextSequenceReceiveResponse {
|
||||
uint64 proof_height = 4;
|
||||
}
|
||||
|
||||
// QueryChannelClientStateRequest is the request type for the Query/ClientState RPC method
|
||||
message QueryChannelClientStateRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
// channel unique identifier
|
||||
string channel_id = 2 [(gogoproto.customname) = "ChannelID"];
|
||||
}
|
||||
|
||||
// QueryChannelConsensusStateRequest is the request type for the Query/ConsensusState RPC method
|
||||
message QueryChannelConsensusStateRequest {
|
||||
// port unique identifier
|
||||
string port_id = 1 [(gogoproto.customname) = "PortID"];
|
||||
// channel unique identifier
|
||||
string channel_id = 2 [(gogoproto.customname) = "ChannelID"];
|
||||
}
|
||||
|
||||
15
proto/ibc/client/client.proto
Normal file
15
proto/ibc/client/client.proto
Normal file
@ -0,0 +1,15 @@
|
||||
syntax = "proto3";
|
||||
package ibc.client;
|
||||
|
||||
option go_package = "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types";
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
// IdentifiedClientState defines a client state with additional client identifier field.
|
||||
message IdentifiedClientState {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
// client identifier
|
||||
string id = 1 [(gogoproto.customname) = "ID", (gogoproto.moretags) = "yaml:\"id\""];
|
||||
google.protobuf.Any client_state = 2;
|
||||
}
|
||||
@ -39,6 +39,7 @@ func QueryAllClientStates(clientCtx client.Context, page, limit int) ([]exported
|
||||
|
||||
// QueryClientState queries the store to get the light client state and a merkle
|
||||
// proof.
|
||||
// TODO: delete
|
||||
func QueryClientState(
|
||||
clientCtx client.Context, clientID string, prove bool,
|
||||
) (types.StateResponse, error) {
|
||||
@ -63,8 +64,40 @@ func QueryClientState(
|
||||
return clientStateRes, nil
|
||||
}
|
||||
|
||||
// QueryClientState queries the store to get the light client state and a merkle
|
||||
// proof.
|
||||
func QueryClientStateABCI(
|
||||
clientCtx client.Context, clientID string,
|
||||
) (exported.ClientState, []byte, uint64, error) {
|
||||
req := abci.RequestQuery{
|
||||
Path: "store/ibc/key",
|
||||
Data: host.FullKeyClientPath(clientID, host.KeyClientState()),
|
||||
Prove: true,
|
||||
}
|
||||
|
||||
res, err := clientCtx.QueryABCI(req)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
|
||||
proofBz, err := clientCtx.LegacyAmino.MarshalBinaryBare(res.Proof)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
|
||||
var clientState exported.ClientState
|
||||
if err := clientCtx.LegacyAmino.UnmarshalBinaryBare(res.Value, &clientState); err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
|
||||
// FIXME: height + 1 is returned as the proof height
|
||||
// Issue: https://github.com/cosmos/cosmos-sdk/issues/6567
|
||||
return clientState, proofBz, uint64(res.Height + 1), nil
|
||||
}
|
||||
|
||||
// QueryConsensusState queries the store to get the consensus state and a merkle
|
||||
// proof.
|
||||
// TODO: delete
|
||||
func QueryConsensusState(
|
||||
clientCtx client.Context, clientID string, height uint64, prove bool,
|
||||
) (types.ConsensusStateResponse, error) {
|
||||
@ -89,6 +122,38 @@ func QueryConsensusState(
|
||||
return types.NewConsensusStateResponse(clientID, cs, res.Proof, res.Height), nil
|
||||
}
|
||||
|
||||
// QueryConsensusState queries the store to get the consensus state of a light
|
||||
// client and a merkle proof of its existence or non-existence.
|
||||
func QueryConsensusStateABCI(
|
||||
clientCtx client.Context, clientID string, height uint64,
|
||||
) (exported.ConsensusState, []byte, uint64, error) {
|
||||
|
||||
req := abci.RequestQuery{
|
||||
Path: "store/ibc/key",
|
||||
Data: host.FullKeyClientPath(clientID, host.KeyConsensusState(height)),
|
||||
Prove: true,
|
||||
}
|
||||
|
||||
res, err := clientCtx.QueryABCI(req)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
|
||||
proofBz, err := clientCtx.LegacyAmino.MarshalBinaryBare(res.Proof)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
|
||||
var cs exported.ConsensusState
|
||||
if err := clientCtx.LegacyAmino.UnmarshalBinaryBare(res.Value, &cs); err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
|
||||
// FIXME: height + 1 is returned as the proof height
|
||||
// Issue: https://github.com/cosmos/cosmos-sdk/issues/6567
|
||||
return cs, proofBz, uint64(res.Height + 1), nil
|
||||
}
|
||||
|
||||
// QueryTendermintHeader takes a client context and returns the appropriate
|
||||
// tendermint header
|
||||
func QueryTendermintHeader(clientCtx client.Context) (ibctmtypes.Header, int64, error) {
|
||||
|
||||
40
x/ibc/02-client/types/client.go
Normal file
40
x/ibc/02-client/types/client.go
Normal file
@ -0,0 +1,40 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
|
||||
)
|
||||
|
||||
var _ codectypes.UnpackInterfacesMessage = IdentifiedClientState{}
|
||||
|
||||
// NewIdentifiedClientState creates a new IdentifiedClientState instance
|
||||
func NewIdentifiedClientState(clientID string, clientState exported.ClientState) IdentifiedClientState {
|
||||
msg, ok := clientState.(proto.Message)
|
||||
if !ok {
|
||||
panic(fmt.Errorf("cannot proto marshal %T", clientState))
|
||||
}
|
||||
|
||||
anyClientState, err := codectypes.NewAnyWithValue(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return IdentifiedClientState{
|
||||
ID: clientID,
|
||||
ClientState: anyClientState,
|
||||
}
|
||||
}
|
||||
|
||||
// UnpackInterfaces implements UnpackInterfacesMesssage.UnpackInterfaces
|
||||
func (ics IdentifiedClientState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
|
||||
var clientState exported.ClientState
|
||||
err := unpacker.UnpackAny(ics.ClientState, &clientState)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
373
x/ibc/02-client/types/client.pb.go
Normal file
373
x/ibc/02-client/types/client.pb.go
Normal file
@ -0,0 +1,373 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: ibc/client/client.proto
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
types "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// IdentifiedClientState defines a client state with additional client identifier field.
|
||||
type IdentifiedClientState struct {
|
||||
// client identifier
|
||||
ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"`
|
||||
ClientState *types.Any `protobuf:"bytes,2,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty"`
|
||||
}
|
||||
|
||||
func (m *IdentifiedClientState) Reset() { *m = IdentifiedClientState{} }
|
||||
func (m *IdentifiedClientState) String() string { return proto.CompactTextString(m) }
|
||||
func (*IdentifiedClientState) ProtoMessage() {}
|
||||
func (*IdentifiedClientState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_226f80e576f20abd, []int{0}
|
||||
}
|
||||
func (m *IdentifiedClientState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *IdentifiedClientState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_IdentifiedClientState.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 *IdentifiedClientState) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_IdentifiedClientState.Merge(m, src)
|
||||
}
|
||||
func (m *IdentifiedClientState) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *IdentifiedClientState) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_IdentifiedClientState.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_IdentifiedClientState proto.InternalMessageInfo
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*IdentifiedClientState)(nil), "ibc.client.IdentifiedClientState")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("ibc/client/client.proto", fileDescriptor_226f80e576f20abd) }
|
||||
|
||||
var fileDescriptor_226f80e576f20abd = []byte{
|
||||
// 256 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcf, 0x4c, 0x4a, 0xd6,
|
||||
0x4f, 0xce, 0xc9, 0x4c, 0xcd, 0x2b, 0x81, 0x52, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x5c,
|
||||
0x99, 0x49, 0xc9, 0x7a, 0x10, 0x11, 0x29, 0x91, 0xf4, 0xfc, 0xf4, 0x7c, 0xb0, 0xb0, 0x3e, 0x88,
|
||||
0x05, 0x51, 0x21, 0x25, 0x99, 0x9e, 0x9f, 0x9f, 0x9e, 0x93, 0xaa, 0x0f, 0xe6, 0x25, 0x95, 0xa6,
|
||||
0xe9, 0x27, 0xe6, 0x55, 0x42, 0xa4, 0x94, 0xaa, 0xb9, 0x44, 0x3d, 0x53, 0x52, 0xf3, 0x4a, 0x32,
|
||||
0xd3, 0x32, 0x53, 0x53, 0x9c, 0xc1, 0x86, 0x04, 0x97, 0x24, 0x96, 0xa4, 0x0a, 0x29, 0x73, 0x31,
|
||||
0x65, 0xa6, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x3a, 0x09, 0x3f, 0xba, 0x27, 0xcf, 0xe4, 0xe9,
|
||||
0xf2, 0xe9, 0x9e, 0x3c, 0x67, 0x65, 0x62, 0x6e, 0x8e, 0x95, 0x52, 0x66, 0x8a, 0x52, 0x10, 0x53,
|
||||
0x66, 0x8a, 0x90, 0x39, 0x17, 0x0f, 0xc4, 0xe2, 0xf8, 0x62, 0x90, 0x26, 0x09, 0x26, 0x05, 0x46,
|
||||
0x0d, 0x6e, 0x23, 0x11, 0x3d, 0x88, 0x7d, 0x7a, 0x30, 0xfb, 0xf4, 0x1c, 0xf3, 0x2a, 0x83, 0xb8,
|
||||
0x93, 0x11, 0xa6, 0x5b, 0xb1, 0x74, 0x2c, 0x90, 0x67, 0x70, 0xf2, 0x39, 0xf1, 0x48, 0x8e, 0xf1,
|
||||
0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e,
|
||||
0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xa3, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc,
|
||||
0x5c, 0xfd, 0xe4, 0xfc, 0xe2, 0xdc, 0xfc, 0x62, 0x28, 0xa5, 0x5b, 0x9c, 0x92, 0xad, 0x5f, 0xa1,
|
||||
0x0f, 0x0a, 0x0b, 0x03, 0x23, 0x5d, 0x68, 0x70, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81,
|
||||
0xad, 0x33, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x0c, 0x55, 0xf9, 0x29, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *IdentifiedClientState) 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 *IdentifiedClientState) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *IdentifiedClientState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.ClientState != nil {
|
||||
{
|
||||
size, err := m.ClientState.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintClient(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if len(m.ID) > 0 {
|
||||
i -= len(m.ID)
|
||||
copy(dAtA[i:], m.ID)
|
||||
i = encodeVarintClient(dAtA, i, uint64(len(m.ID)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintClient(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovClient(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *IdentifiedClientState) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.ID)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovClient(uint64(l))
|
||||
}
|
||||
if m.ClientState != nil {
|
||||
l = m.ClientState.Size()
|
||||
n += 1 + l + sovClient(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovClient(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozClient(x uint64) (n int) {
|
||||
return sovClient(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *IdentifiedClientState) 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 ErrIntOverflowClient
|
||||
}
|
||||
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: IdentifiedClientState: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: IdentifiedClientState: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowClient
|
||||
}
|
||||
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 ErrInvalidLengthClient
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthClient
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ID = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ClientState", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowClient
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthClient
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthClient
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.ClientState == nil {
|
||||
m.ClientState = &types.Any{}
|
||||
}
|
||||
if err := m.ClientState.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipClient(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthClient
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
return ErrInvalidLengthClient
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipClient(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowClient
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowClient
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowClient
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthClient
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupClient
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthClient
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthClient = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowClient = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupClient = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
||||
@ -79,3 +79,14 @@ func MustPackConsensusState(consensusState exported.ConsensusState) *codectypes.
|
||||
|
||||
return anyConsensusState
|
||||
}
|
||||
|
||||
// UnpackConsensusState unpacks an Any into a ConsensusState. It returns an error if the
|
||||
// consensus state can't be unpacked into a ConsensusState.
|
||||
func UnpackConsensusState(any *codectypes.Any) (exported.ConsensusState, error) {
|
||||
consensusState, ok := any.GetCachedValue().(exported.ConsensusState)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot unpack Any into ConsensusState %T", any)
|
||||
}
|
||||
|
||||
return consensusState, nil
|
||||
}
|
||||
|
||||
@ -51,7 +51,6 @@ func GetCmdQueryChannels() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithHeight(res.Height)
|
||||
return clientCtx.PrintOutput(res)
|
||||
},
|
||||
}
|
||||
@ -88,7 +87,6 @@ func GetCmdQueryChannel() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithHeight(int64(channelRes.ProofHeight))
|
||||
return clientCtx.PrintOutput(channelRes)
|
||||
},
|
||||
}
|
||||
@ -130,7 +128,6 @@ func GetCmdQueryConnectionChannels() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithHeight(res.Height)
|
||||
return clientCtx.PrintOutput(res)
|
||||
},
|
||||
}
|
||||
@ -159,14 +156,12 @@ func GetCmdQueryChannelClientState() *cobra.Command {
|
||||
portID := args[0]
|
||||
channelID := args[1]
|
||||
|
||||
clientStateRes, height, err := utils.QueryChannelClientState(clientCtx, portID, channelID)
|
||||
res, err := utils.QueryChannelClientState(clientCtx, portID, channelID, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithHeight(height)
|
||||
|
||||
return clientCtx.PrintOutputLegacy(clientStateRes)
|
||||
return clientCtx.PrintOutputLegacy(res.IdentifiedClientState)
|
||||
},
|
||||
}
|
||||
|
||||
@ -207,7 +202,6 @@ func GetCmdQueryPacketCommitments() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithHeight(res.Height)
|
||||
return clientCtx.PrintOutput(res)
|
||||
},
|
||||
}
|
||||
@ -249,7 +243,6 @@ func GetCmdQueryPacketCommitment() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithHeight(int64(res.ProofHeight))
|
||||
return clientCtx.PrintOutput(res)
|
||||
},
|
||||
}
|
||||
|
||||
@ -52,14 +52,14 @@ func queryChannelClientStateHandlerFn(clientCtx client.Context) http.HandlerFunc
|
||||
return
|
||||
}
|
||||
|
||||
clientState, height, err := utils.QueryChannelClientState(clientCtx, portID, channelID)
|
||||
res, err := utils.QueryChannelClientState(clientCtx, portID, channelID, false)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
clientCtx = clientCtx.WithHeight(height)
|
||||
rest.PostProcessResponse(w, clientCtx, clientState)
|
||||
clientCtx = clientCtx.WithHeight(int64(res.ProofHeight))
|
||||
rest.PostProcessResponse(w, clientCtx, res.IdentifiedClientState)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,12 +3,13 @@ package utils
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
clientutils "github.com/cosmos/cosmos-sdk/x/ibc/02-client/client/utils"
|
||||
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/04-channel/types"
|
||||
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
|
||||
)
|
||||
@ -53,7 +54,8 @@ func queryPacketCommitmentABCI(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// FIXME: res.Height+1 is hack, fix later
|
||||
// FIXME: height + 1 is returned as the proof height
|
||||
// Issue: https://github.com/cosmos/cosmos-sdk/issues/6567
|
||||
return types.NewQueryPacketCommitmentResponse(portID, channelID, sequence, res.Value, proofBz, res.Height+1), nil
|
||||
}
|
||||
|
||||
@ -101,67 +103,101 @@ func queryChannelABCI(clientCtx client.Context, portID, channelID string) (*type
|
||||
return types.NewQueryChannelResponse(portID, channelID, channel, proofBz, 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.NewQueryChannelClientStateRequest(portID, channelID)
|
||||
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to marshal query params: %w", err)
|
||||
// QueryChannelClientState returns the ClientState of a channel 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 QueryChannelClientState(
|
||||
clientCtx client.Context, portID, channelID string, prove bool,
|
||||
) (*types.QueryChannelClientStateResponse, error) {
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
req := &types.QueryChannelClientStateRequest{
|
||||
PortID: portID,
|
||||
ChannelID: channelID,
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryChannelClientState)
|
||||
res, height, err := clientCtx.QueryWithData(route, bz)
|
||||
res, err := queryClient.ChannelClientState(context.Background(), req)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var clientState clientexported.ClientState
|
||||
err = clientCtx.JSONMarshaler.UnmarshalJSON(res, &clientState)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to unmarshal client state: %w", 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.NewQueryChannelClientStateResponse(identifiedClientState, proof, int64(proofHeight))
|
||||
}
|
||||
return clientState, height, nil
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// QueryChannelConsensusState uses the channel Querier to return the ConsensusState
|
||||
// of a Channel.
|
||||
func QueryChannelConsensusState(clientCtx client.Context, portID, channelID string) (clientexported.ConsensusState, int64, error) {
|
||||
params := types.NewQueryChannelConsensusStateRequest(portID, channelID)
|
||||
bz, err := clientCtx.JSONMarshaler.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to marshal query params: %w", err)
|
||||
// QueryChannelConsensusState returns the ConsensusState of a channel 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 QueryChannelConsensusState(
|
||||
clientCtx client.Context, portID, channelID string, prove bool,
|
||||
) (*types.QueryChannelConsensusStateResponse, error) {
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
req := &types.QueryChannelConsensusStateRequest{
|
||||
PortID: portID,
|
||||
ChannelID: channelID,
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryChannelConsensusState)
|
||||
res, height, err := clientCtx.QueryWithData(route, bz)
|
||||
res, err := queryClient.ChannelConsensusState(context.Background(), req)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var consensusState clientexported.ConsensusState
|
||||
err = clientCtx.JSONMarshaler.UnmarshalJSON(res, &consensusState)
|
||||
consensusState, err := clienttypes.UnpackConsensusState(res.ConsensusState)
|
||||
if err != nil {
|
||||
return nil, 0, fmt.Errorf("failed to unmarshal consensus state: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
return consensusState, height, nil
|
||||
|
||||
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.NewQueryChannelConsensusStateResponse(res.ClientID, anyConsensusState, consensusState.GetHeight(), proof, int64(proofHeight))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// 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) (clientexported.ConsensusState, int64, error) {
|
||||
func QueryCounterpartyConsensusState(
|
||||
clientCtx client.Context, portID, channelID string,
|
||||
) (clientexported.ConsensusState, uint64, error) {
|
||||
channelRes, err := QueryChannel(clientCtx, portID, channelID, false)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
counterparty := channelRes.Channel.Counterparty
|
||||
clientState, height, err := QueryChannelConsensusState(clientCtx, counterparty.PortID, counterparty.ChannelID)
|
||||
res, err := QueryChannelConsensusState(clientCtx, counterparty.PortID, counterparty.ChannelID, false)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return clientState, height, nil
|
||||
consensusState, err := clienttypes.UnpackConsensusState(res.ConsensusState)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return consensusState, res.ProofHeight, nil
|
||||
}
|
||||
|
||||
// QueryNextSequenceReceive returns the next sequence receive.
|
||||
|
||||
@ -12,6 +12,8 @@ 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"
|
||||
connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
|
||||
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
|
||||
)
|
||||
@ -126,6 +128,92 @@ func (q Keeper) ConnectionChannels(c context.Context, req *types.QueryConnection
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ChannelClientState implements the Query/ChannelClientState gRPC method
|
||||
func (q Keeper) ChannelClientState(c context.Context, req *types.QueryChannelClientStateRequest) (*types.QueryChannelClientStateResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
if err := validategRPCRequest(req.PortID, req.ChannelID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
channel, found := q.GetChannel(ctx, req.PortID, req.ChannelID)
|
||||
if !found {
|
||||
return nil, status.Error(
|
||||
codes.NotFound,
|
||||
sdkerrors.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id %s", req.PortID, req.ChannelID).Error(),
|
||||
)
|
||||
}
|
||||
|
||||
connection, found := q.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0])
|
||||
if !found {
|
||||
return nil, status.Error(
|
||||
codes.NotFound,
|
||||
sdkerrors.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", channel.ConnectionHops[0]).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.NewQueryChannelClientStateResponse(identifiedClientState, nil, ctx.BlockHeight()), nil
|
||||
|
||||
}
|
||||
|
||||
// ChannelConsensusState implements the Query/ChannelConsensusState gRPC method
|
||||
func (q Keeper) ChannelConsensusState(c context.Context, req *types.QueryChannelConsensusStateRequest) (*types.QueryChannelConsensusStateResponse, error) {
|
||||
if req == nil {
|
||||
return nil, status.Error(codes.InvalidArgument, "empty request")
|
||||
}
|
||||
|
||||
if err := validategRPCRequest(req.PortID, req.ChannelID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
channel, found := q.GetChannel(ctx, req.PortID, req.ChannelID)
|
||||
if !found {
|
||||
return nil, status.Error(
|
||||
codes.NotFound,
|
||||
sdkerrors.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id %s", req.PortID, req.ChannelID).Error(),
|
||||
)
|
||||
}
|
||||
|
||||
connection, found := q.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0])
|
||||
if !found {
|
||||
return nil, status.Error(
|
||||
codes.NotFound,
|
||||
sdkerrors.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", channel.ConnectionHops[0]).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.NewQueryChannelConsensusStateResponse(connection.ClientID, anyConsensusState, consensusState.GetHeight(), nil, ctx.BlockHeight()), nil
|
||||
}
|
||||
|
||||
// PacketCommitment implements the Query/PacketCommitment gRPC method
|
||||
func (q Keeper) PacketCommitment(c context.Context, req *types.QueryPacketCommitmentRequest) (*types.QueryPacketCommitmentResponse, error) {
|
||||
if req == nil {
|
||||
|
||||
@ -6,6 +6,8 @@ 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"
|
||||
connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
|
||||
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
|
||||
)
|
||||
@ -292,6 +294,253 @@ func (suite *KeeperTestSuite) TestQueryConnectionChannels() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestQueryChannelClientState() {
|
||||
var (
|
||||
req *types.QueryChannelClientStateRequest
|
||||
expIdentifiedClientState clienttypes.IdentifiedClientState
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
req = nil
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid port ID",
|
||||
func() {
|
||||
req = &types.QueryChannelClientStateRequest{
|
||||
PortID: "",
|
||||
ChannelID: "test-channel-id",
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid channel ID",
|
||||
func() {
|
||||
req = &types.QueryChannelClientStateRequest{
|
||||
PortID: "test-port-id",
|
||||
ChannelID: "",
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{"channel not found",
|
||||
func() {
|
||||
req = &types.QueryChannelClientStateRequest{
|
||||
PortID: "test-port-id",
|
||||
ChannelID: "test-channel-id",
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"connection not found",
|
||||
func() {
|
||||
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
||||
|
||||
channel := suite.chainA.GetChannel(channelA)
|
||||
// update channel to reference a connection that does not exist
|
||||
channel.ConnectionHops[0] = "doesnotexist"
|
||||
|
||||
// set connection hops to wrong connection ID
|
||||
suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel)
|
||||
|
||||
req = &types.QueryChannelClientStateRequest{
|
||||
PortID: channelA.PortID,
|
||||
ChannelID: channelA.ID,
|
||||
}
|
||||
}, false,
|
||||
},
|
||||
{
|
||||
"client state for channel's connection not found",
|
||||
func() {
|
||||
_, _, connA, _, channelA, _ := 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, connectiontypes.ConnectionEnd{})
|
||||
|
||||
req = &types.QueryChannelClientStateRequest{
|
||||
PortID: channelA.PortID,
|
||||
ChannelID: channelA.ID,
|
||||
}
|
||||
}, false,
|
||||
},
|
||||
{
|
||||
"success",
|
||||
func() {
|
||||
clientA, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint)
|
||||
// init channel
|
||||
channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, types.ORDERED)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
expClientState := suite.chainA.GetClientState(clientA)
|
||||
expIdentifiedClientState = clienttypes.NewIdentifiedClientState(clientA, expClientState)
|
||||
|
||||
req = &types.QueryChannelClientStateRequest{
|
||||
PortID: channelA.PortID,
|
||||
ChannelID: channelA.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.ChannelClientState(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) TestQueryChannelConsensusState() {
|
||||
var (
|
||||
req *types.QueryChannelConsensusStateRequest
|
||||
expConsensusState clientexported.ConsensusState
|
||||
expClientID string
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
malleate func()
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
func() {
|
||||
req = nil
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid port ID",
|
||||
func() {
|
||||
req = &types.QueryChannelConsensusStateRequest{
|
||||
PortID: "",
|
||||
ChannelID: "test-channel-id",
|
||||
Height: 1,
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid channel ID",
|
||||
func() {
|
||||
req = &types.QueryChannelConsensusStateRequest{
|
||||
PortID: "test-port-id",
|
||||
ChannelID: "",
|
||||
Height: 1,
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{"channel not found",
|
||||
func() {
|
||||
req = &types.QueryChannelConsensusStateRequest{
|
||||
PortID: "test-port-id",
|
||||
ChannelID: "test-channel-id",
|
||||
Height: 1,
|
||||
}
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"connection not found",
|
||||
func() {
|
||||
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
||||
|
||||
channel := suite.chainA.GetChannel(channelA)
|
||||
// update channel to reference a connection that does not exist
|
||||
channel.ConnectionHops[0] = "doesnotexist"
|
||||
|
||||
// set connection hops to wrong connection ID
|
||||
suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel)
|
||||
|
||||
req = &types.QueryChannelConsensusStateRequest{
|
||||
PortID: channelA.PortID,
|
||||
ChannelID: channelA.ID,
|
||||
Height: 1,
|
||||
}
|
||||
}, false,
|
||||
},
|
||||
{
|
||||
"consensus state for channel's connection not found",
|
||||
func() {
|
||||
_, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
||||
|
||||
req = &types.QueryChannelConsensusStateRequest{
|
||||
PortID: channelA.PortID,
|
||||
ChannelID: channelA.ID,
|
||||
Height: uint64(suite.chainA.GetContext().BlockHeight()), // use current height
|
||||
}
|
||||
}, false,
|
||||
},
|
||||
{
|
||||
"success",
|
||||
func() {
|
||||
clientA, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint)
|
||||
// init channel
|
||||
channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, types.ORDERED)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
clientState := suite.chainA.GetClientState(clientA)
|
||||
expConsensusState, _ = suite.chainA.GetConsensusState(clientA, clientState.GetLatestHeight())
|
||||
suite.Require().NotNil(expConsensusState)
|
||||
expClientID = clientA
|
||||
|
||||
req = &types.QueryChannelConsensusStateRequest{
|
||||
PortID: channelA.PortID,
|
||||
ChannelID: channelA.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.ChannelConsensusState(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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestQueryPacketCommitment() {
|
||||
var (
|
||||
req *types.QueryPacketCommitmentRequest
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// QuerierChannelClientState defines the sdk.Querier to query all the ClientState
|
||||
// associated with a given Channel.
|
||||
func QuerierChannelClientState(ctx sdk.Context, abciReq abci.RequestQuery, k Keeper, legacyQuerierCdc codec.JSONMarshaler) ([]byte, error) {
|
||||
var req types.QueryChannelClientStateRequest
|
||||
|
||||
if err := legacyQuerierCdc.UnmarshalJSON(abciReq.Data, &req); err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
|
||||
channel, found := k.GetChannel(ctx, req.PortID, req.ChannelID)
|
||||
if !found {
|
||||
return nil, sdkerrors.Wrapf(types.ErrChannelNotFound, req.PortID, req.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(legacyQuerierCdc, clientState)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
@ -1,108 +0,0 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
|
||||
connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
|
||||
)
|
||||
|
||||
// TestQuerierChannelClientState verifies correct querying of client state associated
|
||||
// with a channel end.
|
||||
func (suite *KeeperTestSuite) TestQuerierChannelClientState() {
|
||||
path := []string{types.SubModuleName, types.QueryChannelClientState}
|
||||
|
||||
var (
|
||||
clientID string
|
||||
req *types.QueryChannelClientStateRequest
|
||||
)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
setup func()
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"channel not found",
|
||||
func() {
|
||||
clientA, err := suite.coordinator.CreateClient(suite.chainA, suite.chainB, clientexported.Tendermint)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
clientID = clientA
|
||||
req = types.NewQueryChannelClientStateRequest("doesnotexist", "doesnotexist")
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"connection for channel not found",
|
||||
func() {
|
||||
// connection for channel is deleted from state
|
||||
clientA, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
||||
|
||||
channel := suite.chainA.GetChannel(channelA)
|
||||
channel.ConnectionHops[0] = "doesnotexist"
|
||||
|
||||
// set connection hops to wrong connection ID
|
||||
suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel)
|
||||
|
||||
clientID = clientA
|
||||
req = types.NewQueryChannelClientStateRequest(channelA.PortID, channelA.ID)
|
||||
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"client state for channel's connection not found",
|
||||
func() {
|
||||
clientA, _, connA, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
||||
|
||||
// setting connection to empty results in wrong clientID used
|
||||
suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connectiontypes.ConnectionEnd{})
|
||||
|
||||
clientID = clientA
|
||||
req = types.NewQueryChannelClientStateRequest(channelA.PortID, channelA.ID)
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"success",
|
||||
func() {
|
||||
clientA, _, _, _, channelA, _ := suite.coordinator.Setup(suite.chainA, suite.chainB)
|
||||
|
||||
clientID = clientA
|
||||
req = types.NewQueryChannelClientStateRequest(channelA.PortID, channelA.ID)
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
suite.SetupTest() // reset
|
||||
tc.setup()
|
||||
|
||||
data, err := suite.chainA.App.AppCodec().MarshalJSON(req)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
query := abci.RequestQuery{
|
||||
Path: "",
|
||||
Data: data,
|
||||
}
|
||||
|
||||
clientState, found := suite.chainA.App.IBCKeeper.ClientKeeper.GetClientState(suite.chainA.GetContext(), clientID)
|
||||
bz, err := suite.chainA.Querier(suite.chainA.GetContext(), path, query)
|
||||
|
||||
if tc.expPass {
|
||||
// set expected result
|
||||
expRes, merr := codec.MarshalJSONIndent(suite.chainA.App.AppCodec(), clientState)
|
||||
suite.Require().NoError(merr)
|
||||
suite.Require().True(found, "test case %d failed: %s", i, tc.name)
|
||||
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().Error(err, "test case %d passed: %s", i, tc.name)
|
||||
suite.Require().Nil(bz, "test case %d passed: %s", i, tc.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ import (
|
||||
// ClientKeeper expected account IBC client keeper
|
||||
type ClientKeeper interface {
|
||||
GetClientState(ctx sdk.Context, clientID string) (clientexported.ClientState, bool)
|
||||
GetClientConsensusState(ctx sdk.Context, clientID string, height uint64) (clientexported.ConsensusState, bool)
|
||||
}
|
||||
|
||||
// ConnectionKeeper expected account IBC connection keeper
|
||||
|
||||
@ -3,16 +3,12 @@ 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"
|
||||
)
|
||||
|
||||
// query routes supported by the IBC channel Querier
|
||||
const (
|
||||
QueryChannelClientState = "channel-client-state"
|
||||
QueryChannelConsensusState = "channel-consensus-state"
|
||||
)
|
||||
|
||||
// NewQueryChannelResponse creates a new QueryChannelResponse instance
|
||||
func NewQueryChannelResponse(portID, channelID string, channel Channel, proof []byte, height int64) *QueryChannelResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.ChannelPath(portID, channelID), "/"))
|
||||
@ -24,6 +20,29 @@ func NewQueryChannelResponse(portID, channelID string, channel Channel, proof []
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryChannelClientStateResponse creates a newQueryChannelClientStateResponse instance
|
||||
func NewQueryChannelClientStateResponse(identifiedClientState clienttypes.IdentifiedClientState, proof []byte, height int64) *QueryChannelClientStateResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.FullClientPath(identifiedClientState.ID, host.ClientStatePath()), "/"))
|
||||
return &QueryChannelClientStateResponse{
|
||||
IdentifiedClientState: &identifiedClientState,
|
||||
Proof: proof,
|
||||
ProofPath: path.Pretty(),
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryChannelConsensusStateResponse creates a newQueryChannelConsensusStateResponse instance
|
||||
func NewQueryChannelConsensusStateResponse(clientID string, anyConsensusState *codectypes.Any, consensusStateHeight uint64, proof []byte, height int64) *QueryChannelConsensusStateResponse {
|
||||
path := commitmenttypes.NewMerklePath(strings.Split(host.FullClientPath(clientID, host.ConsensusStatePath(consensusStateHeight)), "/"))
|
||||
return &QueryChannelConsensusStateResponse{
|
||||
ConsensusState: anyConsensusState,
|
||||
ClientID: clientID,
|
||||
Proof: proof,
|
||||
ProofPath: path.Pretty(),
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryPacketCommitmentResponse creates a new QueryPacketCommitmentResponse instance
|
||||
func NewQueryPacketCommitmentResponse(
|
||||
portID, channelID string, sequence uint64, commitment []byte, proof []byte, height int64,
|
||||
@ -62,19 +81,3 @@ func NewQueryNextSequenceReceiveResponse(
|
||||
ProofHeight: uint64(height),
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryChannelClientStateRequest creates a new QueryChannelClientStateRequest instance.
|
||||
func NewQueryChannelClientStateRequest(portID, channelID string) *QueryChannelClientStateRequest {
|
||||
return &QueryChannelClientStateRequest{
|
||||
PortID: portID,
|
||||
ChannelID: channelID,
|
||||
}
|
||||
}
|
||||
|
||||
// NewQueryChannelConsensusStateRequest creates a new QueryChannelConsensusStateRequest instance.
|
||||
func NewQueryChannelConsensusStateRequest(portID, channelID string) *QueryChannelConsensusStateRequest {
|
||||
return &QueryChannelConsensusStateRequest{
|
||||
PortID: portID,
|
||||
ChannelID: channelID,
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -40,8 +40,14 @@ func KeyPrefixBytes(prefix int) []byte {
|
||||
return []byte(fmt.Sprintf("%d/", prefix))
|
||||
}
|
||||
|
||||
// FullClientPath returns the full path of a specific client path in the format:
|
||||
// "clients/{clientID}/{path}" as a string.
|
||||
func FullClientPath(clientID string, path string) string {
|
||||
return string(FullKeyClientPath(clientID, []byte(path)))
|
||||
}
|
||||
|
||||
// FullKeyClientPath returns the full path of specific client path in the format:
|
||||
// "clients/{clientID}/{path}".
|
||||
// "clients/{clientID}/{path}" as a byte array.
|
||||
func FullKeyClientPath(clientID string, path []byte) []byte {
|
||||
return append(KeyClientStorePrefix, append([]byte("/"+clientID+"/"), path...)...)
|
||||
}
|
||||
|
||||
@ -37,6 +37,16 @@ func (q Keeper) ConnectionChannels(c context.Context, req *channeltypes.QueryCon
|
||||
return q.ChannelKeeper.ConnectionChannels(c, req)
|
||||
}
|
||||
|
||||
// ChannelClientState implements the IBC QueryServer interface
|
||||
func (q Keeper) ChannelClientState(c context.Context, req *channeltypes.QueryChannelClientStateRequest) (*channeltypes.QueryChannelClientStateResponse, error) {
|
||||
return q.ChannelKeeper.ChannelClientState(c, req)
|
||||
}
|
||||
|
||||
// ChannelConsensusState implements the IBC QueryServer interface
|
||||
func (q Keeper) ChannelConsensusState(c context.Context, req *channeltypes.QueryChannelConsensusStateRequest) (*channeltypes.QueryChannelConsensusStateResponse, error) {
|
||||
return q.ChannelKeeper.ChannelConsensusState(c, req)
|
||||
}
|
||||
|
||||
// PacketCommitment implements the IBC QueryServer interface
|
||||
func (q Keeper) PacketCommitment(c context.Context, req *channeltypes.QueryPacketCommitmentRequest) (*channeltypes.QueryPacketCommitmentResponse, error) {
|
||||
return q.ChannelKeeper.PacketCommitment(c, req)
|
||||
|
||||
@ -10,7 +10,6 @@ import (
|
||||
clientkeeper "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper"
|
||||
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
|
||||
connectiontypes "github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
|
||||
channelkeeper "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper"
|
||||
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
|
||||
)
|
||||
|
||||
@ -33,12 +32,7 @@ func NewQuerier(k Keeper, legacyQuerierCdc codec.JSONMarshaler) sdk.Querier {
|
||||
case connectiontypes.SubModuleName:
|
||||
err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", connectiontypes.SubModuleName)
|
||||
case channeltypes.SubModuleName:
|
||||
switch path[1] {
|
||||
case channeltypes.QueryChannelClientState:
|
||||
res, err = channelkeeper.QuerierChannelClientState(ctx, req, k.ChannelKeeper, legacyQuerierCdc)
|
||||
default:
|
||||
err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", channeltypes.SubModuleName)
|
||||
}
|
||||
err = sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown IBC %s query endpoint", channeltypes.SubModuleName)
|
||||
default:
|
||||
err = sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown IBC query endpoint")
|
||||
}
|
||||
|
||||
@ -43,12 +43,6 @@ func (suite *KeeperTestSuite) TestNewQuerier() {
|
||||
true,
|
||||
fmt.Sprintf("unknown IBC %s query endpoint", connectiontypes.SubModuleName),
|
||||
},
|
||||
{
|
||||
"channel - QuerierChannelClientState",
|
||||
[]string{channeltypes.SubModuleName, channeltypes.QueryChannelClientState},
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"channel - invalid query",
|
||||
[]string{channeltypes.SubModuleName, "foo"},
|
||||
|
||||
@ -6,8 +6,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
@ -31,7 +29,6 @@ import (
|
||||
ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/07-tendermint/types"
|
||||
commitmenttypes "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment/types"
|
||||
host "github.com/cosmos/cosmos-sdk/x/ibc/24-host"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
@ -71,7 +68,6 @@ type TestChain struct {
|
||||
ChainID string
|
||||
LastHeader ibctmtypes.Header // header for last block height committed
|
||||
CurrentHeader abci.Header // header for current block height
|
||||
Querier sdk.Querier // TODO: deprecate once clients are migrated to gRPC
|
||||
QueryServer types.QueryServer
|
||||
TxConfig client.TxConfig
|
||||
|
||||
@ -114,7 +110,6 @@ func NewTestChain(t *testing.T, chainID string) *TestChain {
|
||||
}
|
||||
|
||||
app := simapp.SetupWithGenesisValSet(t, valSet, []authtypes.GenesisAccount{acc}, balance)
|
||||
legacyQuerierCdc := codec.NewAminoCodec(app.LegacyAmino())
|
||||
|
||||
// create current header and call begin block
|
||||
header := abci.Header{
|
||||
@ -130,7 +125,6 @@ func NewTestChain(t *testing.T, chainID string) *TestChain {
|
||||
ChainID: chainID,
|
||||
App: app,
|
||||
CurrentHeader: header,
|
||||
Querier: keeper.NewQuerier(*app.IBCKeeper, legacyQuerierCdc),
|
||||
QueryServer: app.IBCKeeper,
|
||||
TxConfig: txConfig,
|
||||
Vals: valSet,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user