From e13b08c579b9df4901f4563cb77f3a70bb41c8f3 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Fri, 7 Jan 2022 12:13:26 +0100 Subject: [PATCH 01/17] define and generate new metadata proto type --- docs/ibc/proto-docs.md | 38 ++ .../types/metadata.pb.go | 482 ++++++++++++++++++ .../interchain_accounts/v1/metadata.proto | 16 + 3 files changed, 536 insertions(+) create mode 100644 modules/apps/27-interchain-accounts/types/metadata.pb.go create mode 100644 proto/ibc/applications/interchain_accounts/v1/metadata.proto diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index 8baaa8eda1a..b06a4e974ca 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -14,6 +14,9 @@ - [HostGenesisState](#ibc.applications.interchain_accounts.v1.HostGenesisState) - [RegisteredInterchainAccount](#ibc.applications.interchain_accounts.v1.RegisteredInterchainAccount) +- [ibc/applications/interchain_accounts/v1/metadata.proto](#ibc/applications/interchain_accounts/v1/metadata.proto) + - [Metadata](#ibc.applications.interchain_accounts.v1.Metadata) + - [ibc/applications/interchain_accounts/v1/packet.proto](#ibc/applications/interchain_accounts/v1/packet.proto) - [CosmosTx](#ibc.applications.interchain_accounts.v1.CosmosTx) - [InterchainAccountPacketData](#ibc.applications.interchain_accounts.v1.InterchainAccountPacketData) @@ -386,6 +389,41 @@ RegisteredInterchainAccount contains a pairing of controller port ID and associa + + + + + + + + + + + +

Top

+ +## ibc/applications/interchain_accounts/v1/metadata.proto + + + + + +### Metadata +Metadata defines a set of protocol specific data encoded into the channel version bytestring +See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| `version` | [string](#string) | | | +| `controller_connection_id` | [string](#string) | | | +| `host_connection_id` | [string](#string) | | | +| `address` | [string](#string) | | | + + + + + diff --git a/modules/apps/27-interchain-accounts/types/metadata.pb.go b/modules/apps/27-interchain-accounts/types/metadata.pb.go new file mode 100644 index 00000000000..6d89668ff1a --- /dev/null +++ b/modules/apps/27-interchain-accounts/types/metadata.pb.go @@ -0,0 +1,482 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/interchain_accounts/v1/metadata.proto + +package types + +import ( + fmt "fmt" + _ "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 + +// Metadata defines a set of protocol specific data encoded into the channel version bytestring +// See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning +type Metadata struct { + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + ControllerConnectionId string `protobuf:"bytes,2,opt,name=controller_connection_id,json=controllerConnectionId,proto3" json:"controller_connection_id,omitempty" yaml:"controller_connection_id"` + HostConnectionId string `protobuf:"bytes,3,opt,name=host_connection_id,json=hostConnectionId,proto3" json:"host_connection_id,omitempty" yaml:"host_connection_id"` + Address string `protobuf:"bytes,4,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *Metadata) Reset() { *m = Metadata{} } +func (m *Metadata) String() string { return proto.CompactTextString(m) } +func (*Metadata) ProtoMessage() {} +func (*Metadata) Descriptor() ([]byte, []int) { + return fileDescriptor_c29c32e397d1f21e, []int{0} +} +func (m *Metadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Metadata.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 *Metadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metadata.Merge(m, src) +} +func (m *Metadata) XXX_Size() int { + return m.Size() +} +func (m *Metadata) XXX_DiscardUnknown() { + xxx_messageInfo_Metadata.DiscardUnknown(m) +} + +var xxx_messageInfo_Metadata proto.InternalMessageInfo + +func (m *Metadata) GetVersion() string { + if m != nil { + return m.Version + } + return "" +} + +func (m *Metadata) GetControllerConnectionId() string { + if m != nil { + return m.ControllerConnectionId + } + return "" +} + +func (m *Metadata) GetHostConnectionId() string { + if m != nil { + return m.HostConnectionId + } + return "" +} + +func (m *Metadata) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func init() { + proto.RegisterType((*Metadata)(nil), "ibc.applications.interchain_accounts.v1.Metadata") +} + +func init() { + proto.RegisterFile("ibc/applications/interchain_accounts/v1/metadata.proto", fileDescriptor_c29c32e397d1f21e) +} + +var fileDescriptor_c29c32e397d1f21e = []byte{ + // 316 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xcf, 0x4b, 0xc3, 0x30, + 0x14, 0xc7, 0x57, 0x15, 0xa7, 0x3d, 0x49, 0x11, 0x89, 0x82, 0x99, 0xd4, 0x83, 0x5e, 0xd6, 0x30, + 0x07, 0x0a, 0x1e, 0x27, 0x1e, 0x44, 0xbc, 0xec, 0x28, 0x48, 0x49, 0x5f, 0x42, 0x17, 0x68, 0xf3, + 0x4a, 0x92, 0x15, 0xf6, 0x5f, 0xf8, 0x67, 0x79, 0xdc, 0xd1, 0xd3, 0x90, 0xed, 0xe6, 0x71, 0x7f, + 0x81, 0x74, 0x9d, 0x9b, 0x3f, 0x6f, 0x79, 0x79, 0xdf, 0xcf, 0x27, 0xe4, 0x3d, 0xff, 0x52, 0x25, + 0xc0, 0x78, 0x51, 0x64, 0x0a, 0xb8, 0x53, 0xa8, 0x2d, 0x53, 0xda, 0x49, 0x03, 0x03, 0xae, 0x74, + 0xcc, 0x01, 0x70, 0xa8, 0x9d, 0x65, 0x65, 0x87, 0xe5, 0xd2, 0x71, 0xc1, 0x1d, 0x8f, 0x0a, 0x83, + 0x0e, 0x83, 0x33, 0x95, 0x40, 0xf4, 0x95, 0x8b, 0xfe, 0xe0, 0xa2, 0xb2, 0x73, 0xb4, 0x9f, 0x62, + 0x8a, 0x0b, 0x86, 0x55, 0xa7, 0x1a, 0x0f, 0xdf, 0x3d, 0x7f, 0xe7, 0x61, 0x69, 0x0c, 0x88, 0xdf, + 0x2c, 0xa5, 0xb1, 0x0a, 0x35, 0xf1, 0x4e, 0xbc, 0xf3, 0xdd, 0xfe, 0x67, 0x19, 0x3c, 0xf9, 0x04, + 0x50, 0x3b, 0x83, 0x59, 0x26, 0x4d, 0x0c, 0xa8, 0xb5, 0x84, 0xea, 0xb5, 0x58, 0x09, 0xb2, 0x51, + 0x45, 0x7b, 0xa7, 0xf3, 0x49, 0xab, 0x35, 0xe2, 0x79, 0x76, 0x1d, 0xfe, 0x97, 0x0c, 0xfb, 0x07, + 0xeb, 0xd6, 0xcd, 0xaa, 0x73, 0x27, 0x82, 0x7b, 0x3f, 0x18, 0xa0, 0x75, 0x3f, 0xc4, 0x9b, 0x0b, + 0xf1, 0xf1, 0x7c, 0xd2, 0x3a, 0xac, 0xc5, 0xbf, 0x33, 0x61, 0x7f, 0xaf, 0xba, 0xfc, 0x26, 0x23, + 0x7e, 0x93, 0x0b, 0x61, 0xa4, 0xb5, 0x64, 0xab, 0xfe, 0xc5, 0xb2, 0xec, 0xc5, 0x2f, 0x53, 0xea, + 0x8d, 0xa7, 0xd4, 0x7b, 0x9b, 0x52, 0xef, 0x79, 0x46, 0x1b, 0xe3, 0x19, 0x6d, 0xbc, 0xce, 0x68, + 0xe3, 0xf1, 0x36, 0x55, 0x6e, 0x30, 0x4c, 0x22, 0xc0, 0x9c, 0x01, 0xda, 0x1c, 0x2d, 0x53, 0x09, + 0xb4, 0x53, 0x64, 0x65, 0x97, 0xe5, 0x28, 0x86, 0x99, 0xb4, 0xd5, 0x76, 0x2c, 0xbb, 0xb8, 0x6a, + 0xaf, 0x07, 0xdc, 0x5e, 0x2d, 0xc6, 0x8d, 0x0a, 0x69, 0x93, 0xed, 0xc5, 0x50, 0xbb, 0x1f, 0x01, + 0x00, 0x00, 0xff, 0xff, 0xb0, 0xff, 0x53, 0x4e, 0xcd, 0x01, 0x00, 0x00, +} + +func (m *Metadata) 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 *Metadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintMetadata(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0x22 + } + if len(m.HostConnectionId) > 0 { + i -= len(m.HostConnectionId) + copy(dAtA[i:], m.HostConnectionId) + i = encodeVarintMetadata(dAtA, i, uint64(len(m.HostConnectionId))) + i-- + dAtA[i] = 0x1a + } + if len(m.ControllerConnectionId) > 0 { + i -= len(m.ControllerConnectionId) + copy(dAtA[i:], m.ControllerConnectionId) + i = encodeVarintMetadata(dAtA, i, uint64(len(m.ControllerConnectionId))) + i-- + dAtA[i] = 0x12 + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = encodeVarintMetadata(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintMetadata(dAtA []byte, offset int, v uint64) int { + offset -= sovMetadata(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Metadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Version) + if l > 0 { + n += 1 + l + sovMetadata(uint64(l)) + } + l = len(m.ControllerConnectionId) + if l > 0 { + n += 1 + l + sovMetadata(uint64(l)) + } + l = len(m.HostConnectionId) + if l > 0 { + n += 1 + l + sovMetadata(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovMetadata(uint64(l)) + } + return n +} + +func sovMetadata(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozMetadata(x uint64) (n int) { + return sovMetadata(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Metadata) 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 ErrIntOverflowMetadata + } + 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: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetadata + } + 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 ErrInvalidLengthMetadata + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetadata + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ControllerConnectionId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetadata + } + 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 ErrInvalidLengthMetadata + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetadata + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ControllerConnectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HostConnectionId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetadata + } + 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 ErrInvalidLengthMetadata + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetadata + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HostConnectionId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetadata + } + 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 ErrInvalidLengthMetadata + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetadata + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMetadata(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetadata + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipMetadata(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, ErrIntOverflowMetadata + } + 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, ErrIntOverflowMetadata + } + 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, ErrIntOverflowMetadata + } + 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, ErrInvalidLengthMetadata + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupMetadata + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthMetadata + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthMetadata = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowMetadata = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupMetadata = fmt.Errorf("proto: unexpected end of group") +) diff --git a/proto/ibc/applications/interchain_accounts/v1/metadata.proto b/proto/ibc/applications/interchain_accounts/v1/metadata.proto new file mode 100644 index 00000000000..07a2a5c5d65 --- /dev/null +++ b/proto/ibc/applications/interchain_accounts/v1/metadata.proto @@ -0,0 +1,16 @@ +syntax = "proto3"; + +package ibc.applications.interchain_accounts.v1; + +option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types"; + +import "gogoproto/gogo.proto"; + +// Metadata defines a set of protocol specific data encoded into the channel version bytestring +// See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning +message Metadata { + string version = 1; + string controller_connection_id = 2 [(gogoproto.moretags) = "yaml:\"controller_connection_id\""]; + string host_connection_id = 3 [(gogoproto.moretags) = "yaml:\"host_connection_id\""]; + string address = 4; +} From a5e9947b13bfe4516be628cce4c8c11e13252874 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Fri, 7 Jan 2022 12:15:02 +0100 Subject: [PATCH 02/17] refactor types pkg, remove version string parsers, add PortPrefix --- .../27-interchain-accounts/types/account.go | 22 ++++ .../types/account_test.go | 3 +- .../apps/27-interchain-accounts/types/keys.go | 15 ++- .../apps/27-interchain-accounts/types/port.go | 61 +-------- .../27-interchain-accounts/types/port_test.go | 116 +----------------- .../27-interchain-accounts/types/version.go | 67 ---------- .../types/version_test.go | 106 ---------------- 7 files changed, 39 insertions(+), 351 deletions(-) delete mode 100644 modules/apps/27-interchain-accounts/types/version.go delete mode 100644 modules/apps/27-interchain-accounts/types/version_test.go diff --git a/modules/apps/27-interchain-accounts/types/account.go b/modules/apps/27-interchain-accounts/types/account.go index e55c57f3b35..5ad990dd34d 100644 --- a/modules/apps/27-interchain-accounts/types/account.go +++ b/modules/apps/27-interchain-accounts/types/account.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "regexp" "strings" crypto "github.com/cosmos/cosmos-sdk/crypto/types" @@ -17,6 +18,13 @@ var ( _ InterchainAccountI = (*InterchainAccount)(nil) ) +// DefaultMaxAddrLength defines the default maximum character length used in validation of addresses +var DefaultMaxAddrLength = 128 + +// IsValidAddr defines a regular expression to check if the provided string consists of +// strictly alphanumeric characters +var IsValidAddr = regexp.MustCompile("^[a-zA-Z0-9]*$").MatchString + // InterchainAccountI wraps the authtypes.AccountI interface type InterchainAccountI interface { authtypes.AccountI @@ -37,6 +45,20 @@ func GenerateAddress(moduleAccAddr sdk.AccAddress, portID string) sdk.AccAddress return sdk.AccAddress(sdkaddress.Derive(moduleAccAddr, []byte(portID))) } +// ValidateAccountAddress performs basic validation of interchain account addresses, enforcing constraints +// on address length and character set +func ValidateAccountAddress(addr string) error { + if !IsValidAddr(addr) || len(addr) == 0 || len(addr) > DefaultMaxAddrLength { + return sdkerrors.Wrapf( + ErrInvalidAccountAddress, + "address must contain strictly alphanumeric characters, not exceeding %d characters in length", + DefaultMaxAddrLength, + ) + } + + return nil +} + // NewInterchainAccount creates and returns a new InterchainAccount type func NewInterchainAccount(ba *authtypes.BaseAccount, accountOwner string) *InterchainAccount { return &InterchainAccount{ diff --git a/modules/apps/27-interchain-accounts/types/account_test.go b/modules/apps/27-interchain-accounts/types/account_test.go index 265a74d09af..d2098a3bdbb 100644 --- a/modules/apps/27-interchain-accounts/types/account_test.go +++ b/modules/apps/27-interchain-accounts/types/account_test.go @@ -17,8 +17,9 @@ import ( var ( // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + // TestPortID defines a resuable port identifier for testing purposes - TestPortID, _ = types.GeneratePortID(TestOwnerAddress, "connection-0", "connection-0") + TestPortID, _ = types.NewControllerPortID(TestOwnerAddress) ) type TypesTestSuite struct { diff --git a/modules/apps/27-interchain-accounts/types/keys.go b/modules/apps/27-interchain-accounts/types/keys.go index 3f535a01489..7a9f96bf97f 100644 --- a/modules/apps/27-interchain-accounts/types/keys.go +++ b/modules/apps/27-interchain-accounts/types/keys.go @@ -8,12 +8,15 @@ const ( // ModuleName defines the interchain accounts module name ModuleName = "interchainaccounts" - // VersionPrefix defines the current version for interchain accounts - VersionPrefix = "ics27-1" - - // PortID is the default port id that the interchain accounts module binds to + // PortID is the default port id that the interchain accounts host submodule binds to PortID = "interchain-account" + // PortPrefix is the default port prefix that the interchain accounts controller submodule binds to + PortPrefix = "ics27" + + // Version defines the current version for interchain accounts + Version = "ics27-1" + // StoreKey is the store key string for interchain accounts StoreKey = ModuleName @@ -23,8 +26,8 @@ const ( // QuerierRoute is the querier route for interchain accounts QuerierRoute = ModuleName - // Delimiter is the delimiter used for the interchain accounts version string - Delimiter = "." + // Delimiter is the delimiter used for the interchain accounts controller port + Delimiter = "-" ) var ( diff --git a/modules/apps/27-interchain-accounts/types/port.go b/modules/apps/27-interchain-accounts/types/port.go index 32c7de66af3..ea6f9448e36 100644 --- a/modules/apps/27-interchain-accounts/types/port.go +++ b/modules/apps/27-interchain-accounts/types/port.go @@ -2,12 +2,9 @@ package types import ( "fmt" - "strconv" "strings" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - connectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" - porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" ) const ( @@ -16,63 +13,11 @@ const ( ControllerPortFormat = "..." ) -// GeneratePortID generates an interchain accounts controller port identifier for the provided owner -// in the following format: -// -// 'ics-27---' -// https://github.com/seantking/ibc/tree/sean/ics-27-updates/spec/app/ics-027-interchain-accounts#registering--controlling-flows -// TODO: update link to spec -func GeneratePortID(owner, connectionID, counterpartyConnectionID string) (string, error) { +// NewControllerPortID creates and returns a new controller port identifier in the expected format +func NewControllerPortID(owner string) (string, error) { if strings.TrimSpace(owner) == "" { return "", sdkerrors.Wrap(ErrInvalidAccountAddress, "owner address cannot be empty") } - connectionSeq, err := connectiontypes.ParseConnectionSequence(connectionID) - if err != nil { - return "", sdkerrors.Wrap(err, "invalid connection identifier") - } - - counterpartyConnectionSeq, err := connectiontypes.ParseConnectionSequence(counterpartyConnectionID) - if err != nil { - return "", sdkerrors.Wrap(err, "invalid counterparty connection identifier") - } - - return fmt.Sprint( - VersionPrefix, Delimiter, - connectionSeq, Delimiter, - counterpartyConnectionSeq, Delimiter, - owner, - ), nil -} - -// ParseControllerConnSequence attempts to parse the controller connection sequence from the provided port identifier -// The port identifier must match the controller chain format outlined in (TODO: link spec), otherwise an empty string is returned -func ParseControllerConnSequence(portID string) (uint64, error) { - s := strings.Split(portID, Delimiter) - if len(s) != 4 { - return 0, sdkerrors.Wrap(porttypes.ErrInvalidPort, "failed to parse port identifier") - } - - seq, err := strconv.ParseUint(s[1], 10, 64) - if err != nil { - return 0, sdkerrors.Wrapf(err, "failed to parse connection sequence (%s)", s[1]) - } - - return seq, nil -} - -// ParseHostConnSequence attempts to parse the host connection sequence from the provided port identifier -// The port identifier must match the controller chain format outlined in (TODO: link spec), otherwise an empty string is returned -func ParseHostConnSequence(portID string) (uint64, error) { - s := strings.Split(portID, Delimiter) - if len(s) != 4 { - return 0, sdkerrors.Wrap(porttypes.ErrInvalidPort, "failed to parse port identifier") - } - - seq, err := strconv.ParseUint(s[2], 10, 64) - if err != nil { - return 0, sdkerrors.Wrapf(err, "failed to parse connection sequence (%s)", s[2]) - } - - return seq, nil + return fmt.Sprint(PortPrefix, Delimiter, owner), nil } diff --git a/modules/apps/27-interchain-accounts/types/port_test.go b/modules/apps/27-interchain-accounts/types/port_test.go index 3a01b79391a..5fc86be4991 100644 --- a/modules/apps/27-interchain-accounts/types/port_test.go +++ b/modules/apps/27-interchain-accounts/types/port_test.go @@ -7,7 +7,7 @@ import ( ibctesting "github.com/cosmos/ibc-go/v3/testing" ) -func (suite *TypesTestSuite) TestGeneratePortID() { +func (suite *TypesTestSuite) TestNewControllerPortID() { var ( path *ibctesting.Path owner = TestOwnerAddress @@ -22,33 +22,9 @@ func (suite *TypesTestSuite) TestGeneratePortID() { { "success", func() {}, - fmt.Sprint(types.VersionPrefix, types.Delimiter, "0", types.Delimiter, "0", types.Delimiter, TestOwnerAddress), + fmt.Sprint(types.PortPrefix, types.Delimiter, TestOwnerAddress), true, }, - { - "success with non matching connection sequences", - func() { - path.EndpointA.ConnectionID = "connection-1" - }, - fmt.Sprint(types.VersionPrefix, types.Delimiter, "1", types.Delimiter, "0", types.Delimiter, TestOwnerAddress), - true, - }, - { - "invalid connectionID", - func() { - path.EndpointA.ConnectionID = "connection" - }, - "", - false, - }, - { - "invalid counterparty connectionID", - func() { - path.EndpointB.ConnectionID = "connection" - }, - "", - false, - }, { "invalid owner address", func() { @@ -69,7 +45,7 @@ func (suite *TypesTestSuite) TestGeneratePortID() { tc.malleate() // malleate mutates test data - portID, err := types.GeneratePortID(owner, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + portID, err := types.NewControllerPortID(owner) if tc.expPass { suite.Require().NoError(err, tc.name) @@ -81,89 +57,3 @@ func (suite *TypesTestSuite) TestGeneratePortID() { }) } } - -func (suite *TypesTestSuite) TestParseControllerConnSequence() { - - testCases := []struct { - name string - portID string - expValue uint64 - expPass bool - }{ - { - "success", - TestPortID, - 0, - true, - }, - { - "failed to parse port identifier", - "invalid-port-id", - 0, - false, - }, - { - "failed to parse connection sequence", - "ics27-1.x.y.cosmos1", - 0, - false, - }, - } - - for _, tc := range testCases { - suite.Run(tc.name, func() { - connSeq, err := types.ParseControllerConnSequence(tc.portID) - - if tc.expPass { - suite.Require().Equal(tc.expValue, connSeq) - suite.Require().NoError(err, tc.name) - } else { - suite.Require().Zero(connSeq) - suite.Require().Error(err, tc.name) - } - }) - } -} - -func (suite *TypesTestSuite) TestParseHostConnSequence() { - - testCases := []struct { - name string - portID string - expValue uint64 - expPass bool - }{ - { - "success", - TestPortID, - 0, - true, - }, - { - "failed to parse port identifier", - "invalid-port-id", - 0, - false, - }, - { - "failed to parse connection sequence", - "ics27-1.x.y.cosmos1", - 0, - false, - }, - } - - for _, tc := range testCases { - suite.Run(tc.name, func() { - connSeq, err := types.ParseHostConnSequence(tc.portID) - - if tc.expPass { - suite.Require().Equal(tc.expValue, connSeq) - suite.Require().NoError(err, tc.name) - } else { - suite.Require().Zero(connSeq) - suite.Require().Error(err, tc.name) - } - }) - } -} diff --git a/modules/apps/27-interchain-accounts/types/version.go b/modules/apps/27-interchain-accounts/types/version.go deleted file mode 100644 index ffa33aa0017..00000000000 --- a/modules/apps/27-interchain-accounts/types/version.go +++ /dev/null @@ -1,67 +0,0 @@ -package types - -import ( - "fmt" - "regexp" - "strings" - - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" -) - -// DefaultMaxAddrLength defines the default maximum character length used in validation of addresses -var DefaultMaxAddrLength = 128 - -// IsValidAddr defines a regular expression to check if the provided string consists of -// strictly alphanumeric characters -var IsValidAddr = regexp.MustCompile("^[a-zA-Z0-9]*$").MatchString - -// NewVersion returns a complete version string in the format: VersionPrefix + Delimter + AccAddress -func NewAppVersion(versionPrefix, accAddr string) string { - return fmt.Sprint(versionPrefix, Delimiter, accAddr) -} - -// ParseAddressFromVersion attempts to extract the associated account address from the provided version string -func ParseAddressFromVersion(version string) (string, error) { - s := strings.Split(version, Delimiter) - if len(s) != 2 { - return "", sdkerrors.Wrap(ErrInvalidVersion, "failed to parse version") - } - - return s[1], nil -} - -// ValidateVersion performs basic validation of the provided ics27 version string. -// An ics27 version string may include an optional account address as per [TODO: Add spec when available] -// ValidateVersion first attempts to split the version string using the standard delimiter, then asserts a supported -// version prefix is included, followed by additional checks which enforce constraints on the account address. -func ValidateVersion(version string) error { - s := strings.Split(version, Delimiter) - - if len(s) != 2 { - return sdkerrors.Wrapf(ErrInvalidVersion, "expected format , got %s", Delimiter, version) - } - - if s[0] != VersionPrefix { - return sdkerrors.Wrapf(ErrInvalidVersion, "expected %s, got %s", VersionPrefix, s[0]) - } - - if err := ValidateAccountAddress(s[1]); err != nil { - return err - } - - return nil -} - -// ValidateAccountAddress performs basic validation of interchain account addresses, enforcing constraints -// on address length and character set -func ValidateAccountAddress(addr string) error { - if !IsValidAddr(addr) || len(addr) == 0 || len(addr) > DefaultMaxAddrLength { - return sdkerrors.Wrapf( - ErrInvalidAccountAddress, - "address must contain strictly alphanumeric characters, not exceeding %d characters in length", - DefaultMaxAddrLength, - ) - } - - return nil -} diff --git a/modules/apps/27-interchain-accounts/types/version_test.go b/modules/apps/27-interchain-accounts/types/version_test.go deleted file mode 100644 index 6da0c780c3e..00000000000 --- a/modules/apps/27-interchain-accounts/types/version_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package types_test - -import ( - "fmt" - - "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" -) - -func (suite *TypesTestSuite) TestParseAddressFromVersion() { - - testCases := []struct { - name string - version string - expValue string - expPass bool - }{ - { - "success", - types.NewAppVersion(types.VersionPrefix, TestOwnerAddress), - TestOwnerAddress, - true, - }, - { - "failed to parse address from version", - "invalid-version-string", - "", - false, - }, - { - "failure with multiple delimiters", - fmt.Sprint(types.NewAppVersion(types.VersionPrefix, TestOwnerAddress), types.Delimiter, types.NewAppVersion(types.VersionPrefix, TestOwnerAddress)), - "", - false, - }, - } - - for _, tc := range testCases { - suite.Run(tc.name, func() { - addr, err := types.ParseAddressFromVersion(tc.version) - - if tc.expPass { - suite.Require().Equal(tc.expValue, addr) - suite.Require().NoError(err, tc.name) - } else { - suite.Require().Empty(addr) - suite.Require().Error(err, tc.name) - } - }) - } -} - -func (suite *TypesTestSuite) TestValidateVersion() { - testCases := []struct { - name string - version string - expPass bool - }{ - { - "success", - types.NewAppVersion(types.VersionPrefix, TestOwnerAddress), - true, - }, - { - "unexpected version string format", - "invalid-version-string-format", - false, - }, - { - "unexpected version string format, additional delimiter", - types.NewAppVersion(types.VersionPrefix, "cosmos17dtl0mjt3t77kpu.hg2edqzjpszulwhgzuj9ljs"), - false, - }, - { - "invalid version", - types.NewAppVersion("ics27-5", TestOwnerAddress), - false, - }, - { - "invalid account address - empty", - types.NewAppVersion(types.VersionPrefix, ""), - false, - }, - { - "invalid account address - exceeded character length", - types.NewAppVersion(types.VersionPrefix, "ofwafxhdmqcdbpzvrccxkidbunrwyyoboyctignpvthxbwxtmnzyfwhhywobaatltfwafxhdmqcdbpzvrccxkidbunrwyyoboyctignpvthxbwxtmnzyfwhhywobaatlt"), - false, - }, - { - "invalid account address - non alphanumeric characters", - types.NewAppVersion(types.VersionPrefix, "-_-"), - false, - }, - } - - for _, tc := range testCases { - suite.Run(tc.name, func() { - err := types.ValidateVersion(tc.version) - - if tc.expPass { - suite.Require().NoError(err, tc.name) - } else { - suite.Require().Error(err, tc.name) - } - }) - } -} From a79ab75113a3a1b08dc84c5491a26ff580ef7531 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Fri, 7 Jan 2022 12:22:52 +0100 Subject: [PATCH 03/17] refactor ica entrypoint and handshake to handle connection ids in metadata --- .../controller/keeper/account.go | 22 ++++++- .../controller/keeper/handshake.go | 63 ++++++++----------- .../host/keeper/handshake.go | 57 ++++++++--------- 3 files changed, 72 insertions(+), 70 deletions(-) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/account.go b/modules/apps/27-interchain-accounts/controller/keeper/account.go index 4e4527a8af6..9b279daefc0 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account.go @@ -15,8 +15,8 @@ import ( // call 04-channel 'ChanOpenInit'. An error is returned if the port identifier is // already in use. Gaining access to interchain accounts whose channels have closed // cannot be done with this function. A regular MsgChanOpenInit must be used. -func (k Keeper) InitInterchainAccount(ctx sdk.Context, connectionID, counterpartyConnectionID, owner string) error { - portID, err := icatypes.GeneratePortID(owner, connectionID, counterpartyConnectionID) +func (k Keeper) InitInterchainAccount(ctx sdk.Context, connectionID, owner string) error { + portID, err := icatypes.NewControllerPortID(owner) if err != nil { return err } @@ -30,7 +30,23 @@ func (k Keeper) InitInterchainAccount(ctx sdk.Context, connectionID, counterpart return sdkerrors.Wrap(err, "unable to bind to newly generated portID") } - msg := channeltypes.NewMsgChannelOpenInit(portID, icatypes.VersionPrefix, channeltypes.ORDERED, []string{connectionID}, icatypes.PortID, icatypes.ModuleName) + connectionEnd, err := k.channelKeeper.GetConnection(ctx, connectionID) + if err != nil { + return err + } + + metadata := icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: connectionID, + HostConnectionId: connectionEnd.GetCounterparty().GetConnectionID(), + } + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + if err != nil { + return err + } + + msg := channeltypes.NewMsgChannelOpenInit(portID, string(bz), channeltypes.ORDERED, []string{connectionID}, icatypes.PortID, icatypes.ModuleName) handler := k.msgRouter.Handler(msg) res, err := handler(ctx, msg) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index ea0b907569a..24ebbfab5b5 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -32,26 +32,23 @@ func (k Keeper) OnChanOpenInit( return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s", channeltypes.ORDERED, order) } - connSequence, err := icatypes.ParseControllerConnSequence(portID) - if err != nil { - return sdkerrors.Wrapf(err, "expected format %s, got %s", icatypes.ControllerPortFormat, portID) - } + // TODO: Validate first party port ID (controller) - counterpartyConnSequence, err := icatypes.ParseHostConnSequence(portID) - if err != nil { - return sdkerrors.Wrapf(err, "expected format %s, got %s", icatypes.ControllerPortFormat, portID) + if counterparty.PortId != icatypes.PortID { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "expected %s, got %s", icatypes.PortID, counterparty.PortId) } - if err := k.validateControllerPortParams(ctx, connectionHops, connSequence, counterpartyConnSequence); err != nil { - return sdkerrors.Wrapf(err, "failed to validate controller port %s", portID) + var metadata icatypes.Metadata + if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(version), &metadata); err != nil { + return sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account metadata") } - if counterparty.PortId != icatypes.PortID { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "expected %s, got %s", icatypes.PortID, counterparty.PortId) + if err := k.validateConnectionParams(ctx, connectionHops, metadata.ControllerConnectionId, metadata.HostConnectionId); err != nil { + return err } - if version != icatypes.VersionPrefix { - return sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.VersionPrefix, version) + if metadata.Version != icatypes.Version { + return sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.Version, metadata.Version) } activeChannelID, found := k.GetActiveChannelID(ctx, portID) @@ -74,18 +71,21 @@ func (k Keeper) OnChanOpenAck( return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "portID cannot be host chain port ID: %s", icatypes.PortID) } - if err := icatypes.ValidateVersion(counterpartyVersion); err != nil { - return sdkerrors.Wrap(err, "counterparty version validation failed") + var metadata icatypes.Metadata + if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &metadata); err != nil { + return sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account metadata") } - k.SetActiveChannelID(ctx, portID, channelID) + if err := icatypes.ValidateAccountAddress(metadata.Address); err != nil { + return err + } - accAddr, err := icatypes.ParseAddressFromVersion(counterpartyVersion) - if err != nil { - return sdkerrors.Wrapf(err, "expected format , got %s", icatypes.Delimiter, counterpartyVersion) + if metadata.Version != icatypes.Version { + return sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.Version, metadata.Version) } - k.SetInterchainAccountAddress(ctx, portID, accAddr) + k.SetActiveChannelID(ctx, portID, channelID) + k.SetInterchainAccountAddress(ctx, portID, metadata.Address) return nil } @@ -102,31 +102,20 @@ func (k Keeper) OnChanCloseConfirm( return nil } -// validateControllerPortParams asserts the provided connection sequence and counterparty connection sequence -// match that of the associated connection stored in state -func (k Keeper) validateControllerPortParams(ctx sdk.Context, connectionHops []string, connectionSeq, counterpartyConnectionSeq uint64) error { +// validateConnectionParams asserts the provided controller and host connection identifiers match that of the associated connection stored in state +func (k Keeper) validateConnectionParams(ctx sdk.Context, connectionHops []string, controllerConnectionID, hostConnectionID string) error { connectionID := connectionHops[0] connection, err := k.channelKeeper.GetConnection(ctx, connectionID) if err != nil { return err } - connSeq, err := connectiontypes.ParseConnectionSequence(connectionID) - if err != nil { - return sdkerrors.Wrapf(err, "failed to parse connection sequence %s", connectionID) - } - - counterpartyConnSeq, err := connectiontypes.ParseConnectionSequence(connection.GetCounterparty().GetConnectionID()) - if err != nil { - return sdkerrors.Wrapf(err, "failed to parse counterparty connection sequence %s", connection.GetCounterparty().GetConnectionID()) - } - - if connSeq != connectionSeq { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "sequence mismatch, expected %d, got %d", connSeq, connectionSeq) + if controllerConnectionID != connectionID { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionID, controllerConnectionID) } - if counterpartyConnSeq != counterpartyConnectionSeq { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "counterparty sequence mismatch, expected %d, got %d", counterpartyConnSeq, counterpartyConnectionSeq) + if hostConnectionID != connection.GetCounterparty().GetConnectionID() { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), hostConnectionID) } return nil diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake.go b/modules/apps/27-interchain-accounts/host/keeper/handshake.go index bb65da4a33b..289ba85334c 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake.go @@ -34,22 +34,19 @@ func (k Keeper) OnChanOpenTry( return "", sdkerrors.Wrapf(porttypes.ErrInvalidPort, "expected %s, got %s", icatypes.PortID, portID) } - connSequence, err := icatypes.ParseHostConnSequence(counterparty.PortId) - if err != nil { - return "", sdkerrors.Wrapf(err, "expected format %s, got %s", icatypes.ControllerPortFormat, counterparty.PortId) - } + // TODO: Validate counterparty port ID (controller) - counterpartyConnSequence, err := icatypes.ParseControllerConnSequence(counterparty.PortId) - if err != nil { - return "", sdkerrors.Wrapf(err, "expected format %s, got %s", icatypes.ControllerPortFormat, counterparty.PortId) + var metadata icatypes.Metadata + if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &metadata); err != nil { + return "", sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account metadata") } - if err := k.validateControllerPortParams(ctx, connectionHops, connSequence, counterpartyConnSequence); err != nil { - return "", sdkerrors.Wrapf(err, "failed to validate controller port %s", counterparty.PortId) + if err := k.validateConnectionParams(ctx, connectionHops, metadata.ControllerConnectionId, metadata.HostConnectionId); err != nil { + return "", err } - if counterpartyVersion != icatypes.VersionPrefix { - return "", sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.VersionPrefix, counterpartyVersion) + if metadata.Version != icatypes.Version { + return "", sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.Version, counterpartyVersion) } // On the host chain the capability may only be claimed during the OnChanOpenTry @@ -62,9 +59,20 @@ func (k Keeper) OnChanOpenTry( // Register interchain account if it does not already exist k.RegisterInterchainAccount(ctx, accAddr, counterparty.PortId) - version := icatypes.NewAppVersion(icatypes.VersionPrefix, accAddr.String()) - return version, nil + metadata = icatypes.Metadata{ + Version: metadata.Version, + ControllerConnectionId: metadata.ControllerConnectionId, + HostConnectionId: metadata.HostConnectionId, + Address: accAddr.String(), + } + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + if err != nil { + return "", err + } + + return string(bz), nil } // OnChanOpenConfirm completes the handshake process by setting the active channel in state on the host chain @@ -91,31 +99,20 @@ func (k Keeper) OnChanCloseConfirm( return nil } -// validateControllerPortParams asserts the provided connection sequence and counterparty connection sequence -// match that of the associated connection stored in state -func (k Keeper) validateControllerPortParams(ctx sdk.Context, connectionHops []string, connectionSeq, counterpartyConnectionSeq uint64) error { +// validateConnectionParams asserts the provided controller and host connection identifiers match that of the associated connection stored in state +func (k Keeper) validateConnectionParams(ctx sdk.Context, connectionHops []string, controllerConnectionID, hostConnectionID string) error { connectionID := connectionHops[0] connection, err := k.channelKeeper.GetConnection(ctx, connectionID) if err != nil { return err } - connSeq, err := connectiontypes.ParseConnectionSequence(connectionID) - if err != nil { - return sdkerrors.Wrapf(err, "failed to parse connection sequence %s", connectionID) - } - - counterpartyConnSeq, err := connectiontypes.ParseConnectionSequence(connection.GetCounterparty().GetConnectionID()) - if err != nil { - return sdkerrors.Wrapf(err, "failed to parse counterparty connection sequence %s", connection.GetCounterparty().GetConnectionID()) - } - - if connSeq != connectionSeq { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "sequence mismatch, expected %d, got %d", connSeq, connectionSeq) + if hostConnectionID != connectionID { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionID, controllerConnectionID) } - if counterpartyConnSeq != counterpartyConnectionSeq { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "counterparty sequence mismatch, expected %d, got %d", counterpartyConnSeq, counterpartyConnectionSeq) + if controllerConnectionID != connection.GetCounterparty().GetConnectionID() { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), hostConnectionID) } return nil From f14d4dd1db511776b72eae5153945200f6aa4655 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Fri, 7 Jan 2022 12:23:33 +0100 Subject: [PATCH 04/17] fixing broken test cases --- .../controller/ibc_module_test.go | 23 ++-- .../controller/keeper/account_test.go | 4 +- .../controller/keeper/handshake_test.go | 115 +++++++++++------- .../controller/keeper/keeper_test.go | 17 ++- .../host/ibc_module_test.go | 23 ++-- .../host/keeper/account_test.go | 3 +- .../host/keeper/handshake_test.go | 95 ++++++++------- .../host/keeper/keeper_test.go | 19 ++- .../host/keeper/relay_test.go | 2 +- 9 files changed, 179 insertions(+), 122 deletions(-) diff --git a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go index 5137606e764..8f4b1c42882 100644 --- a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go @@ -21,12 +21,19 @@ var ( // TestAccAddress defines a resuable bech32 address for testing purposes // TODO: update crypto.AddressHash() when sdk uses address.Module() TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), TestPortID) + // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + // TestPortID defines a resuable port identifier for testing purposes - TestPortID, _ = icatypes.GeneratePortID(TestOwnerAddress, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) + TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) + // TestVersion defines a resuable interchainaccounts version string for testing purposes - TestVersion = icatypes.NewAppVersion(icatypes.VersionPrefix, TestAccAddress.String()) + TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + })) ) type InterchainAccountsTestSuite struct { @@ -55,21 +62,21 @@ func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path.EndpointB.ChannelConfig.PortID = icatypes.PortID path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointA.ChannelConfig.Version = icatypes.VersionPrefix + path.EndpointA.ChannelConfig.Version = TestVersion path.EndpointB.ChannelConfig.Version = TestVersion return path } func InitInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { - portID, err := icatypes.GeneratePortID(owner, endpoint.ConnectionID, endpoint.Counterparty.ConnectionID) + portID, err := icatypes.NewControllerPortID(owner) if err != nil { return err } channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) - if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.InitInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, endpoint.Counterparty.ConnectionID, owner); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.InitInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner); err != nil { return err } @@ -150,7 +157,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { suite.coordinator.SetupConnections(path) // mock init interchain account - portID, err := icatypes.GeneratePortID(TestOwnerAddress, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) suite.Require().NoError(err) portCap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) @@ -166,7 +173,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() { Ordering: channeltypes.ORDERED, Counterparty: counterparty, ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: icatypes.VersionPrefix, + Version: path.EndpointA.ChannelConfig.Version, } tc.malleate() // malleate mutates test data @@ -219,7 +226,7 @@ func (suite *InterchainAccountsTestSuite) TestChanOpenTry() { proofInit, proofHeight := path.EndpointB.Chain.QueryProof(channelKey) // use chainA (controller) for ChanOpenTry - msg := channeltypes.NewMsgChannelOpenTry(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, TestVersion, channeltypes.ORDERED, []string{path.EndpointA.ConnectionID}, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, icatypes.VersionPrefix, proofInit, proofHeight, icatypes.ModuleName) + msg := channeltypes.NewMsgChannelOpenTry(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, TestVersion, channeltypes.ORDERED, []string{path.EndpointA.ConnectionID}, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, TestVersion, proofInit, proofHeight, icatypes.ModuleName) handler := suite.chainA.GetSimApp().MsgServiceRouter().Handler(msg) _, err = handler(suite.chainA.GetContext(), msg) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/account_test.go b/modules/apps/27-interchain-accounts/controller/keeper/account_test.go index 0cbc9f4e281..967f7511aa2 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account_test.go @@ -37,7 +37,7 @@ func (suite *KeeperTestSuite) TestInitInterchainAccount() { { "MsgChanOpenInit fails - channel is already active", func() { - portID, err := icatypes.GeneratePortID(owner, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) suite.Require().NoError(err) suite.chainA.GetSimApp().ICAControllerKeeper.SetActiveChannelID(suite.chainA.GetContext(), portID, path.EndpointA.ChannelID) @@ -59,7 +59,7 @@ func (suite *KeeperTestSuite) TestInitInterchainAccount() { tc.malleate() // malleate mutates test data - err = suite.chainA.GetSimApp().ICAControllerKeeper.InitInterchainAccount(suite.chainA.GetContext(), path.EndpointA.ConnectionID, path.EndpointB.ConnectionID, owner) + err = suite.chainA.GetSimApp().ICAControllerKeeper.InitInterchainAccount(suite.chainA.GetContext(), path.EndpointA.ConnectionID, owner) if tc.expPass { suite.Require().NoError(err) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go index 3df200e51a3..a5891773efc 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -36,13 +36,14 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { }, false, }, - { - "invalid port ID", - func() { - path.EndpointA.ChannelConfig.PortID = "invalid-port-id" - }, - false, - }, + // TODO: Validate new port id - PortPrefix-Owner + // { + // "invalid port ID", + // func() { + // path.EndpointA.ChannelConfig.PortID = "invalid-port-id" + // }, + // false, + // }, { "invalid counterparty port ID", func() { @@ -67,28 +68,32 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { }, false, }, - { - "invalid connection sequence", - func() { - portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-1", "connection-0") - suite.Require().NoError(err) - - path.EndpointA.ChannelConfig.PortID = portID - path.EndpointA.SetChannel(*channel) - }, - false, - }, - { - "invalid counterparty connection sequence", - func() { - portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-0", "connection-1") - suite.Require().NoError(err) - - path.EndpointA.ChannelConfig.PortID = portID - path.EndpointA.SetChannel(*channel) - }, - false, - }, + // TODO: Validate connection sequence + // { + // "invalid connection sequence", + // func() { + // // portID, err := icatypes.NewControllerPortID(TestOwnerAddress, "connection-1", "connection-0") + // portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + // suite.Require().NoError(err) + + // path.EndpointA.ChannelConfig.PortID = portID + // path.EndpointA.SetChannel(*channel) + // }, + // false, + // }, + // TODO: Validate counterparty connection sequence + // { + // "invalid counterparty connection sequence", + // func() { + // // portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-0", "connection-1") + // portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + // suite.Require().NoError(err) + + // path.EndpointA.ChannelConfig.PortID = portID + // path.EndpointA.SetChannel(*channel) + // }, + // false, + // }, { "channel is already active", func() { @@ -108,7 +113,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { suite.coordinator.SetupConnections(path) // mock init interchain account - portID, err := icatypes.GeneratePortID(TestOwnerAddress, path.EndpointA.ConnectionID, path.EndpointB.ConnectionID) + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) suite.Require().NoError(err) portCap := suite.chainA.GetSimApp().IBCKeeper.PortKeeper.BindPort(suite.chainA.GetContext(), portID) @@ -116,13 +121,22 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { path.EndpointA.ChannelConfig.PortID = portID // default values + metadata := icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + } + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + counterparty := channeltypes.NewCounterparty(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID) channel = &channeltypes.Channel{ State: channeltypes.INIT, Ordering: channeltypes.ORDERED, Counterparty: counterparty, ConnectionHops: []string{path.EndpointA.ConnectionID}, - Version: icatypes.VersionPrefix, + Version: string(bz), } chanCap, err = suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID)) @@ -146,9 +160,9 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { func (suite *KeeperTestSuite) TestOnChanOpenAck() { var ( - path *ibctesting.Path - expectedChannelID string - counterpartyVersion string + path *ibctesting.Path + expectedChannelID string + // counterpartyVersion string ) testCases := []struct { @@ -159,14 +173,15 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { { "success", func() {}, true, }, - { - "invalid counterparty version", - func() { - expectedChannelID = "" - counterpartyVersion = "version" - }, - false, - }, + // TODO: Validate counterpary version + // { + // "invalid counterparty version", + // func() { + // expectedChannelID = "" + // // counterpartyVersion = "version" + // }, + // false, + // }, { "invalid portID", func() { path.EndpointA.ChannelConfig.PortID = icatypes.PortID @@ -182,7 +197,17 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { suite.SetupTest() // reset path = NewICAPath(suite.chainA, suite.chainB) - counterpartyVersion = TestVersion + // counterpartyVersion = TestVersion + + metadata := icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Address: TestAccAddress.String(), + } + + bz, _ := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.coordinator.SetupConnections(path) err := InitInterchainAccount(path.EndpointA, TestOwnerAddress) @@ -195,12 +220,12 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { tc.malleate() // malleate mutates test data err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenAck(suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, counterpartyVersion, + path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, string(bz), ) activeChannelID, _ := suite.chainA.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - suite.Require().Equal(activeChannelID, expectedChannelID) + suite.Require().Equal(expectedChannelID, activeChannelID) if tc.expPass { suite.Require().NoError(err) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go index e1678689509..6a0e09a83b1 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go @@ -17,12 +17,19 @@ var ( // TestAccAddress defines a resuable bech32 address for testing purposes // TODO: update crypto.AddressHash() when sdk uses address.Module() TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), TestPortID) + // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + // TestPortID defines a resuable port identifier for testing purposes - TestPortID, _ = icatypes.GeneratePortID(TestOwnerAddress, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) + TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) + // TestVersion defines a resuable interchainaccounts version string for testing purposes - TestVersion = icatypes.NewAppVersion(icatypes.VersionPrefix, TestAccAddress.String()) + TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + })) ) type KeeperTestSuite struct { @@ -49,7 +56,7 @@ func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path.EndpointB.ChannelConfig.PortID = icatypes.PortID path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointA.ChannelConfig.Version = icatypes.VersionPrefix + path.EndpointA.ChannelConfig.Version = TestVersion path.EndpointB.ChannelConfig.Version = TestVersion return path @@ -78,14 +85,14 @@ func SetupICAPath(path *ibctesting.Path, owner string) error { // InitInterchainAccount is a helper function for starting the channel handshake func InitInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { - portID, err := icatypes.GeneratePortID(owner, endpoint.ConnectionID, endpoint.Counterparty.ConnectionID) + portID, err := icatypes.NewControllerPortID(owner) if err != nil { return err } channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) - if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.InitInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, endpoint.Counterparty.ConnectionID, owner); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.InitInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner); err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/host/ibc_module_test.go b/modules/apps/27-interchain-accounts/host/ibc_module_test.go index 1f76d661a6c..70118cbc16c 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module_test.go @@ -23,12 +23,19 @@ var ( // TestAccAddress defines a resuable bech32 address for testing purposes // TODO: update crypto.AddressHash() when sdk uses address.Module() TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), TestPortID) + // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + // TestPortID defines a resuable port identifier for testing purposes - TestPortID, _ = icatypes.GeneratePortID(TestOwnerAddress, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) + TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) + // TestVersion defines a resuable interchainaccounts version string for testing purposes - TestVersion = icatypes.NewAppVersion(icatypes.VersionPrefix, TestAccAddress.String()) + TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + })) ) type InterchainAccountsTestSuite struct { @@ -57,21 +64,21 @@ func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path.EndpointB.ChannelConfig.PortID = icatypes.PortID path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointA.ChannelConfig.Version = icatypes.VersionPrefix + path.EndpointA.ChannelConfig.Version = TestVersion path.EndpointB.ChannelConfig.Version = TestVersion return path } func InitInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { - portID, err := icatypes.GeneratePortID(owner, endpoint.ConnectionID, endpoint.Counterparty.ConnectionID) + portID, err := icatypes.NewControllerPortID(owner) if err != nil { return err } channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) - if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.InitInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, endpoint.Counterparty.ConnectionID, owner); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.InitInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner); err != nil { return err } @@ -115,7 +122,7 @@ func (suite *InterchainAccountsTestSuite) TestChanOpenInit() { suite.coordinator.SetupConnections(path) // use chainB (host) for ChanOpenInit - msg := channeltypes.NewMsgChannelOpenInit(path.EndpointB.ChannelConfig.PortID, icatypes.VersionPrefix, channeltypes.ORDERED, []string{path.EndpointB.ConnectionID}, path.EndpointA.ChannelConfig.PortID, icatypes.ModuleName) + msg := channeltypes.NewMsgChannelOpenInit(path.EndpointB.ChannelConfig.PortID, icatypes.Version, channeltypes.ORDERED, []string{path.EndpointB.ConnectionID}, path.EndpointA.ChannelConfig.PortID, icatypes.ModuleName) handler := suite.chainB.GetSimApp().MsgServiceRouter().Handler(msg) _, err := handler(suite.chainB.GetContext(), msg) @@ -181,7 +188,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenTry() { Ordering: channeltypes.ORDERED, Counterparty: counterparty, ConnectionHops: []string{path.EndpointB.ConnectionID}, - Version: "", + Version: path.EndpointB.ChannelConfig.Version, } tc.malleate() @@ -204,7 +211,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenTry() { if tc.expPass { suite.Require().NoError(err) - suite.Require().Equal(TestVersion, version) + // suite.Require().Equal(TestVersion, version) } else { suite.Require().Error(err) suite.Require().Equal("", version) diff --git a/modules/apps/27-interchain-accounts/host/keeper/account_test.go b/modules/apps/27-interchain-accounts/host/keeper/account_test.go index 0dce100888f..67828c79886 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/account_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/account_test.go @@ -4,7 +4,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" - ibctesting "github.com/cosmos/ibc-go/v3/testing" ) func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { @@ -17,7 +16,7 @@ func (suite *KeeperTestSuite) TestRegisterInterchainAccount() { err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) - portID, err := icatypes.GeneratePortID(TestOwnerAddress, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) suite.Require().NoError(err) // Get the address of the interchain account stored in state during handshake step diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go index 48179f1a8a0..fbc0e4a9f64 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -3,7 +3,6 @@ package keeper_test import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" - icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v3/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v3/testing" @@ -11,10 +10,10 @@ import ( func (suite *KeeperTestSuite) TestOnChanOpenTry() { var ( - channel *channeltypes.Channel - path *ibctesting.Path - chanCap *capabilitytypes.Capability - counterpartyVersion string + channel *channeltypes.Channel + path *ibctesting.Path + chanCap *capabilitytypes.Capability + // counterpartyVersion string ) testCases := []struct { @@ -44,13 +43,14 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { }, false, }, - { - "invalid counterparty port", - func() { - channel.Counterparty.PortId = "invalid-port-id" - }, - false, - }, + // TODO: Validate counterparty port (controller) + // { + // "invalid counterparty port", + // func() { + // channel.Counterparty.PortId = "invalid-port-id" + // }, + // false, + // }, { "connection not found", func() { @@ -59,36 +59,41 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { }, false, }, - { - "invalid connection sequence", - func() { - portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-0", "connection-1") - suite.Require().NoError(err) - - channel.Counterparty.PortId = portID - path.EndpointB.SetChannel(*channel) - }, - false, - }, - { - "invalid counterparty connection sequence", - func() { - portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-1", "connection-0") - suite.Require().NoError(err) - - channel.Counterparty.PortId = portID - path.EndpointB.SetChannel(*channel) - }, - false, - }, - { - "invalid counterparty version", - func() { - counterpartyVersion = "version" - path.EndpointB.SetChannel(*channel) - }, - false, - }, + // TODO: validate conneciton sequence + // { + // "invalid connection sequence", + // func() { + // // portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-0", "connection-1") + // portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + // suite.Require().NoError(err) + + // channel.Counterparty.PortId = portID + // path.EndpointB.SetChannel(*channel) + // }, + // false, + // }, + // TODO: validate counterparty connection sequence + // { + // "invalid counterparty connection sequence", + // func() { + // // portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-1", "connection-0") + // portID, err := icatypes.NewControllerPortID(TestOwnerAddress) + // suite.Require().NoError(err) + + // channel.Counterparty.PortId = portID + // path.EndpointB.SetChannel(*channel) + // }, + // false, + // }, + // TODO: Validate counterparty version + // { + // "invalid counterparty version", + // func() { + // // counterpartyVersion = "version" + // path.EndpointB.SetChannel(*channel) + // }, + // false, + // }, { "capability already claimed", func() { @@ -107,7 +112,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { suite.SetupTest() // reset path = NewICAPath(suite.chainA, suite.chainB) - counterpartyVersion = icatypes.VersionPrefix + // counterpartyVersion = icatypes.Version suite.coordinator.SetupConnections(path) err := InitInterchainAccount(path.EndpointA, TestOwnerAddress) @@ -133,12 +138,12 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { tc.malleate() // malleate mutates test data version, err := suite.chainB.GetSimApp().ICAHostKeeper.OnChanOpenTry(suite.chainB.GetContext(), channel.Ordering, channel.GetConnectionHops(), - path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, chanCap, channel.Counterparty, counterpartyVersion, + path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, chanCap, channel.Counterparty, TestVersion, ) if tc.expPass { suite.Require().NoError(err) - suite.Require().Equal(TestVersion, version) + // suite.Require().Equal(TestVersion, version) } else { suite.Require().Error(err) suite.Require().Equal("", version) diff --git a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go index 102cb278ebe..5342aee292b 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go @@ -17,12 +17,19 @@ var ( // TestAccAddress defines a resuable bech32 address for testing purposes // TODO: update crypto.AddressHash() when sdk uses address.Module() TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), TestPortID) + // TestOwnerAddress defines a reusable bech32 address for testing purposes TestOwnerAddress = "cosmos17dtl0mjt3t77kpuhg2edqzjpszulwhgzuj9ljs" + // TestPortID defines a resuable port identifier for testing purposes - TestPortID, _ = icatypes.GeneratePortID(TestOwnerAddress, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) + TestPortID, _ = icatypes.NewControllerPortID(TestOwnerAddress) + // TestVersion defines a resuable interchainaccounts version string for testing purposes - TestVersion = icatypes.NewAppVersion(icatypes.VersionPrefix, TestAccAddress.String()) + TestVersion = string(icatypes.ModuleCdc.MustMarshalJSON(&icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + })) ) type KeeperTestSuite struct { @@ -49,8 +56,8 @@ func NewICAPath(chainA, chainB *ibctesting.TestChain) *ibctesting.Path { path.EndpointB.ChannelConfig.PortID = icatypes.PortID path.EndpointA.ChannelConfig.Order = channeltypes.ORDERED path.EndpointB.ChannelConfig.Order = channeltypes.ORDERED - path.EndpointA.ChannelConfig.Version = icatypes.VersionPrefix - path.EndpointB.ChannelConfig.Version = icatypes.VersionPrefix + path.EndpointA.ChannelConfig.Version = TestVersion + path.EndpointB.ChannelConfig.Version = TestVersion return path } @@ -78,14 +85,14 @@ func SetupICAPath(path *ibctesting.Path, owner string) error { // InitInterchainAccount is a helper function for starting the channel handshake func InitInterchainAccount(endpoint *ibctesting.Endpoint, owner string) error { - portID, err := icatypes.GeneratePortID(owner, endpoint.ConnectionID, endpoint.Counterparty.ConnectionID) + portID, err := icatypes.NewControllerPortID(owner) if err != nil { return err } channelSequence := endpoint.Chain.App.GetIBCKeeper().ChannelKeeper.GetNextChannelSequence(endpoint.Chain.GetContext()) - if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.InitInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, endpoint.Counterparty.ConnectionID, owner); err != nil { + if err := endpoint.Chain.GetSimApp().ICAControllerKeeper.InitInterchainAccount(endpoint.Chain.GetContext(), endpoint.ConnectionID, owner); err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/host/keeper/relay_test.go b/modules/apps/27-interchain-accounts/host/keeper/relay_test.go index ef8709b5ce1..37cefe34bba 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/relay_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/relay_test.go @@ -395,7 +395,7 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() { err := SetupICAPath(path, TestOwnerAddress) suite.Require().NoError(err) - portID, err := icatypes.GeneratePortID(TestOwnerAddress, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID) + portID, err := icatypes.NewControllerPortID(TestOwnerAddress) suite.Require().NoError(err) // Get the address of the interchain account stored in state during handshake step From b8b0cbb4d6a528c43c7adc488f9ea6a0a6704aa0 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Fri, 7 Jan 2022 16:43:01 +0100 Subject: [PATCH 05/17] adding controller port and metadata validation, adding new testcases --- .../controller/ibc_module_test.go | 4 +- .../controller/keeper/handshake.go | 10 +- .../controller/keeper/handshake_test.go | 190 +++++++++++------- .../controller/keeper/keeper_test.go | 4 +- .../host/ibc_module_test.go | 4 +- .../host/keeper/handshake.go | 8 +- .../host/keeper/handshake_test.go | 116 ++++++----- .../host/keeper/keeper_test.go | 4 +- 8 files changed, 212 insertions(+), 128 deletions(-) diff --git a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go index 8f4b1c42882..68e534cda74 100644 --- a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go @@ -18,8 +18,10 @@ import ( ) var ( + // TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module() + // https://github.com/cosmos/cosmos-sdk/issues/10225 + // // TestAccAddress defines a resuable bech32 address for testing purposes - // TODO: update crypto.AddressHash() when sdk uses address.Module() TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), TestPortID) // TestOwnerAddress defines a reusable bech32 address for testing purposes diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index 24ebbfab5b5..803520f67a1 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -1,6 +1,8 @@ package keeper import ( + "strings" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" @@ -32,7 +34,9 @@ func (k Keeper) OnChanOpenInit( return sdkerrors.Wrapf(channeltypes.ErrInvalidChannelOrdering, "expected %s channel, got %s", channeltypes.ORDERED, order) } - // TODO: Validate first party port ID (controller) + if !strings.HasPrefix(portID, icatypes.PortPrefix) { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "controller port %s does not contain expected prefix %s", portID, icatypes.PortPrefix) + } if counterparty.PortId != icatypes.PortID { return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "expected %s, got %s", icatypes.PortID, counterparty.PortId) @@ -71,6 +75,10 @@ func (k Keeper) OnChanOpenAck( return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "portID cannot be host chain port ID: %s", icatypes.PortID) } + if !strings.HasPrefix(portID, icatypes.PortPrefix) { + return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "controller port %s does not contain expected prefix %s", portID, icatypes.PortPrefix) + } + var metadata icatypes.Metadata if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &metadata); err != nil { return sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account metadata") diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go index a5891773efc..618f73e0a76 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -11,9 +11,10 @@ import ( func (suite *KeeperTestSuite) TestOnChanOpenInit() { var ( - channel *channeltypes.Channel - path *ibctesting.Path - chanCap *capabilitytypes.Capability + channel *channeltypes.Channel + path *ibctesting.Path + chanCap *capabilitytypes.Capability + metadata icatypes.Metadata ) testCases := []struct { @@ -36,14 +37,13 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { }, false, }, - // TODO: Validate new port id - PortPrefix-Owner - // { - // "invalid port ID", - // func() { - // path.EndpointA.ChannelConfig.PortID = "invalid-port-id" - // }, - // false, - // }, + { + "invalid port", + func() { + path.EndpointA.ChannelConfig.PortID = "invalid-port-id" + }, + false, + }, { "invalid counterparty port ID", func() { @@ -53,10 +53,10 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { false, }, { - "invalid version", + "invalid metadata bytestring", func() { path.EndpointA.SetChannel(*channel) - channel.Version = "version" + channel.Version = "invalid-metadata-bytestring" }, false, }, @@ -68,32 +68,45 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { }, false, }, - // TODO: Validate connection sequence - // { - // "invalid connection sequence", - // func() { - // // portID, err := icatypes.NewControllerPortID(TestOwnerAddress, "connection-1", "connection-0") - // portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - // suite.Require().NoError(err) - - // path.EndpointA.ChannelConfig.PortID = portID - // path.EndpointA.SetChannel(*channel) - // }, - // false, - // }, - // TODO: Validate counterparty connection sequence - // { - // "invalid counterparty connection sequence", - // func() { - // // portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-0", "connection-1") - // portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - // suite.Require().NoError(err) - - // path.EndpointA.ChannelConfig.PortID = portID - // path.EndpointA.SetChannel(*channel) - // }, - // false, - // }, + { + "invalid controller connection ID", + func() { + metadata.ControllerConnectionId = "invalid-connnection-id" + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + channel.Version = string(bz) + path.EndpointA.SetChannel(*channel) + }, + false, + }, + { + "invalid host connection ID", + func() { + metadata.HostConnectionId = "invalid-connnection-id" + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + channel.Version = string(bz) + path.EndpointA.SetChannel(*channel) + }, + false, + }, + { + "invalid version", + func() { + metadata.Version = "invalid-version" + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + channel.Version = string(bz) + path.EndpointA.SetChannel(*channel) + }, + false, + }, { "channel is already active", func() { @@ -121,7 +134,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { path.EndpointA.ChannelConfig.PortID = portID // default values - metadata := icatypes.Metadata{ + metadata = icatypes.Metadata{ Version: icatypes.Version, ControllerConnectionId: ibctesting.FirstConnectionID, HostConnectionId: ibctesting.FirstConnectionID, @@ -145,7 +158,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { tc.malleate() // malleate mutates test data err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(), - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.GetVersion(), + path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.Version, ) if tc.expPass { @@ -160,9 +173,8 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { func (suite *KeeperTestSuite) TestOnChanOpenAck() { var ( - path *ibctesting.Path - expectedChannelID string - // counterpartyVersion string + path *ibctesting.Path + metadata icatypes.Metadata ) testCases := []struct { @@ -173,20 +185,50 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { { "success", func() {}, true, }, - // TODO: Validate counterpary version - // { - // "invalid counterparty version", - // func() { - // expectedChannelID = "" - // // counterpartyVersion = "version" - // }, - // false, - // }, { - "invalid portID", func() { + "invalid port - host chain", + func() { path.EndpointA.ChannelConfig.PortID = icatypes.PortID - expectedChannelID = "" - }, false, + }, + false, + }, + { + "invalid port - unexpected prefix", + func() { + path.EndpointA.ChannelConfig.PortID = "invalid-port-id" + }, + false, + }, + { + "invalid metadata bytestring", + func() { + path.EndpointA.Counterparty.ChannelConfig.Version = "invalid-metadata-bytestring" + }, + false, + }, + { + "invalid account address", + func() { + metadata.Address = "invalid-account-address" + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + path.EndpointA.Counterparty.ChannelConfig.Version = string(bz) + }, + false, + }, + { + "invalid counterparty version", + func() { + metadata.Version = "invalid-version" + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + path.EndpointA.Counterparty.ChannelConfig.Version = string(bz) + }, + false, }, } @@ -197,38 +239,44 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { suite.SetupTest() // reset path = NewICAPath(suite.chainA, suite.chainB) - // counterpartyVersion = TestVersion + suite.coordinator.SetupConnections(path) + + err := InitInterchainAccount(path.EndpointA, TestOwnerAddress) + suite.Require().NoError(err) + + err = path.EndpointB.ChanOpenTry() + suite.Require().NoError(err) - metadata := icatypes.Metadata{ + metadata = icatypes.Metadata{ Version: icatypes.Version, ControllerConnectionId: ibctesting.FirstConnectionID, HostConnectionId: ibctesting.FirstConnectionID, Address: TestAccAddress.String(), } - bz, _ := icatypes.ModuleCdc.MarshalJSON(&metadata) - - suite.coordinator.SetupConnections(path) - - err := InitInterchainAccount(path.EndpointA, TestOwnerAddress) + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) - err = path.EndpointB.ChanOpenTry() - suite.Require().NoError(err) - expectedChannelID = path.EndpointA.ChannelID + path.EndpointB.ChannelConfig.Version = string(bz) tc.malleate() // malleate mutates test data err = suite.chainA.GetSimApp().ICAControllerKeeper.OnChanOpenAck(suite.chainA.GetContext(), - path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, string(bz), + path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointA.Counterparty.ChannelConfig.Version, ) - activeChannelID, _ := suite.chainA.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) - - suite.Require().Equal(expectedChannelID, activeChannelID) - if tc.expPass { suite.Require().NoError(err) + + activeChannelID, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetActiveChannelID(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + suite.Require().Equal(path.EndpointA.ChannelID, activeChannelID) + + interchainAccAddress, found := suite.chainA.GetSimApp().ICAControllerKeeper.GetInterchainAccountAddress(suite.chainA.GetContext(), path.EndpointA.ChannelConfig.PortID) + suite.Require().True(found) + + suite.Require().Equal(metadata.Address, interchainAccAddress) } else { suite.Require().Error(err) } diff --git a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go index 6a0e09a83b1..75cec2c45d9 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/keeper_test.go @@ -14,8 +14,10 @@ import ( ) var ( + // TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module() + // https://github.com/cosmos/cosmos-sdk/issues/10225 + // // TestAccAddress defines a resuable bech32 address for testing purposes - // TODO: update crypto.AddressHash() when sdk uses address.Module() TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), TestPortID) // TestOwnerAddress defines a reusable bech32 address for testing purposes diff --git a/modules/apps/27-interchain-accounts/host/ibc_module_test.go b/modules/apps/27-interchain-accounts/host/ibc_module_test.go index 70118cbc16c..6745af70997 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module_test.go @@ -20,8 +20,10 @@ import ( ) var ( + // TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module() + // https://github.com/cosmos/cosmos-sdk/issues/10225 + // // TestAccAddress defines a resuable bech32 address for testing purposes - // TODO: update crypto.AddressHash() when sdk uses address.Module() TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), TestPortID) // TestOwnerAddress defines a reusable bech32 address for testing purposes diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake.go b/modules/apps/27-interchain-accounts/host/keeper/handshake.go index 289ba85334c..28d64d59c27 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake.go @@ -1,6 +1,8 @@ package keeper import ( + "strings" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" @@ -34,7 +36,9 @@ func (k Keeper) OnChanOpenTry( return "", sdkerrors.Wrapf(porttypes.ErrInvalidPort, "expected %s, got %s", icatypes.PortID, portID) } - // TODO: Validate counterparty port ID (controller) + if !strings.HasPrefix(counterparty.PortId, icatypes.PortPrefix) { + return "", sdkerrors.Wrapf(porttypes.ErrInvalidPort, "controller port %s does not contain expected prefix %s", counterparty.PortId, icatypes.PortPrefix) + } var metadata icatypes.Metadata if err := icatypes.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &metadata); err != nil { @@ -46,7 +50,7 @@ func (k Keeper) OnChanOpenTry( } if metadata.Version != icatypes.Version { - return "", sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.Version, counterpartyVersion) + return "", sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.Version, metadata.Version) } // On the host chain the capability may only be claimed during the OnChanOpenTry diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go index fbc0e4a9f64..315987f9b43 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -3,6 +3,7 @@ package keeper_test import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v3/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v3/testing" @@ -10,10 +11,10 @@ import ( func (suite *KeeperTestSuite) TestOnChanOpenTry() { var ( - channel *channeltypes.Channel - path *ibctesting.Path - chanCap *capabilitytypes.Capability - // counterpartyVersion string + channel *channeltypes.Channel + path *ibctesting.Path + chanCap *capabilitytypes.Capability + metadata icatypes.Metadata ) testCases := []struct { @@ -43,14 +44,13 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { }, false, }, - // TODO: Validate counterparty port (controller) - // { - // "invalid counterparty port", - // func() { - // channel.Counterparty.PortId = "invalid-port-id" - // }, - // false, - // }, + { + "invalid counterparty port", + func() { + channel.Counterparty.PortId = "invalid-port-id" + }, + false, + }, { "connection not found", func() { @@ -59,41 +59,49 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { }, false, }, - // TODO: validate conneciton sequence - // { - // "invalid connection sequence", - // func() { - // // portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-0", "connection-1") - // portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - // suite.Require().NoError(err) - - // channel.Counterparty.PortId = portID - // path.EndpointB.SetChannel(*channel) - // }, - // false, - // }, - // TODO: validate counterparty connection sequence - // { - // "invalid counterparty connection sequence", - // func() { - // // portID, err := icatypes.GeneratePortID(TestOwnerAddress, "connection-1", "connection-0") - // portID, err := icatypes.NewControllerPortID(TestOwnerAddress) - // suite.Require().NoError(err) - - // channel.Counterparty.PortId = portID - // path.EndpointB.SetChannel(*channel) - // }, - // false, - // }, - // TODO: Validate counterparty version - // { - // "invalid counterparty version", - // func() { - // // counterpartyVersion = "version" - // path.EndpointB.SetChannel(*channel) - // }, - // false, - // }, + { + "invalid metadata bytestring", + func() { + path.EndpointA.ChannelConfig.Version = "invalid-metadata-bytestring" + }, + false, + }, + { + "invalid controller connection ID", + func() { + metadata.ControllerConnectionId = "invalid-connnection-id" + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + path.EndpointA.ChannelConfig.Version = string(bz) + }, + false, + }, + { + "invalid host connection ID", + func() { + metadata.HostConnectionId = "invalid-connnection-id" + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + path.EndpointA.ChannelConfig.Version = string(bz) + }, + false, + }, + { + "invalid counterparty version", + func() { + metadata.Version = "invalid-version" + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + path.EndpointA.ChannelConfig.Version = string(bz) + }, + false, + }, { "capability already claimed", func() { @@ -112,7 +120,6 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { suite.SetupTest() // reset path = NewICAPath(suite.chainA, suite.chainB) - // counterpartyVersion = icatypes.Version suite.coordinator.SetupConnections(path) err := InitInterchainAccount(path.EndpointA, TestOwnerAddress) @@ -123,13 +130,22 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { path.EndpointB.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) // default values + metadata = icatypes.Metadata{ + Version: icatypes.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + } + + bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + counterparty := channeltypes.NewCounterparty(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID) channel = &channeltypes.Channel{ State: channeltypes.TRYOPEN, Ordering: channeltypes.ORDERED, Counterparty: counterparty, ConnectionHops: []string{path.EndpointB.ConnectionID}, - Version: TestVersion, + Version: string(bz), } chanCap, err = suite.chainB.App.GetScopedIBCKeeper().NewCapability(suite.chainB.GetContext(), host.ChannelCapabilityPath(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID)) @@ -138,7 +154,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { tc.malleate() // malleate mutates test data version, err := suite.chainB.GetSimApp().ICAHostKeeper.OnChanOpenTry(suite.chainB.GetContext(), channel.Ordering, channel.GetConnectionHops(), - path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, chanCap, channel.Counterparty, TestVersion, + path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, chanCap, channel.Counterparty, path.EndpointA.ChannelConfig.Version, ) if tc.expPass { diff --git a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go index 5342aee292b..e9824f6dcb2 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/keeper_test.go @@ -14,8 +14,10 @@ import ( ) var ( + // TODO: Cosmos-SDK ADR-28: Update crypto.AddressHash() when sdk uses address.Module() + // https://github.com/cosmos/cosmos-sdk/issues/10225 + // // TestAccAddress defines a resuable bech32 address for testing purposes - // TODO: update crypto.AddressHash() when sdk uses address.Module() TestAccAddress = icatypes.GenerateAddress(sdk.AccAddress(crypto.AddressHash([]byte(icatypes.ModuleName))), TestPortID) // TestOwnerAddress defines a reusable bech32 address for testing purposes From d5380eef6142d687e269e7fee90a1c50cf9a01cb Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Fri, 7 Jan 2022 17:00:59 +0100 Subject: [PATCH 06/17] updating proto doc and removing commented out code --- docs/ibc/proto-docs.md | 2 +- modules/apps/27-interchain-accounts/host/ibc_module_test.go | 1 - .../apps/27-interchain-accounts/host/keeper/handshake_test.go | 1 - modules/apps/27-interchain-accounts/types/metadata.pb.go | 2 +- proto/ibc/applications/interchain_accounts/v1/metadata.proto | 2 +- 5 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index b06a4e974ca..af2760fdb4a 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -409,7 +409,7 @@ RegisteredInterchainAccount contains a pairing of controller port ID and associa ### Metadata -Metadata defines a set of protocol specific data encoded into the channel version bytestring +Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning diff --git a/modules/apps/27-interchain-accounts/host/ibc_module_test.go b/modules/apps/27-interchain-accounts/host/ibc_module_test.go index 6745af70997..0556f5b4100 100644 --- a/modules/apps/27-interchain-accounts/host/ibc_module_test.go +++ b/modules/apps/27-interchain-accounts/host/ibc_module_test.go @@ -213,7 +213,6 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenTry() { if tc.expPass { suite.Require().NoError(err) - // suite.Require().Equal(TestVersion, version) } else { suite.Require().Error(err) suite.Require().Equal("", version) diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go index 315987f9b43..c531d290879 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -159,7 +159,6 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { if tc.expPass { suite.Require().NoError(err) - // suite.Require().Equal(TestVersion, version) } else { suite.Require().Error(err) suite.Require().Equal("", version) diff --git a/modules/apps/27-interchain-accounts/types/metadata.pb.go b/modules/apps/27-interchain-accounts/types/metadata.pb.go index 6d89668ff1a..8fc4ef47c26 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.pb.go +++ b/modules/apps/27-interchain-accounts/types/metadata.pb.go @@ -23,7 +23,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// Metadata defines a set of protocol specific data encoded into the channel version bytestring +// Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring // See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning type Metadata struct { Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` diff --git a/proto/ibc/applications/interchain_accounts/v1/metadata.proto b/proto/ibc/applications/interchain_accounts/v1/metadata.proto index 07a2a5c5d65..597cb298bbb 100644 --- a/proto/ibc/applications/interchain_accounts/v1/metadata.proto +++ b/proto/ibc/applications/interchain_accounts/v1/metadata.proto @@ -6,7 +6,7 @@ option go_package = "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-acco import "gogoproto/gogo.proto"; -// Metadata defines a set of protocol specific data encoded into the channel version bytestring +// Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring // See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning message Metadata { string version = 1; From 07a506d4ba2ed2811b7d15abb5b12c8a8c35a03f Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Mon, 10 Jan 2022 16:18:26 +0100 Subject: [PATCH 07/17] updating testcase names, adding metadata constructor func, updating PortPrefix and removing Delimiter --- .../controller/keeper/account.go | 7 +------ .../controller/keeper/handshake_test.go | 21 +++++-------------- .../host/keeper/handshake.go | 12 +++-------- .../host/keeper/handshake_test.go | 11 +++------- .../apps/27-interchain-accounts/types/keys.go | 5 +---- .../27-interchain-accounts/types/metadata.go | 11 ++++++++++ .../apps/27-interchain-accounts/types/port.go | 10 ++------- .../27-interchain-accounts/types/port_test.go | 2 +- 8 files changed, 27 insertions(+), 52 deletions(-) create mode 100644 modules/apps/27-interchain-accounts/types/metadata.go diff --git a/modules/apps/27-interchain-accounts/controller/keeper/account.go b/modules/apps/27-interchain-accounts/controller/keeper/account.go index 9b279daefc0..88c2f863759 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/account.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/account.go @@ -35,12 +35,7 @@ func (k Keeper) InitInterchainAccount(ctx sdk.Context, connectionID, owner strin return err } - metadata := icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: connectionID, - HostConnectionId: connectionEnd.GetCounterparty().GetConnectionID(), - } - + metadata := icatypes.NewMetadata(icatypes.Version, connectionID, connectionEnd.GetCounterparty().GetConnectionID(), "") bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) if err != nil { return err diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go index 618f73e0a76..09feefd0efe 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -38,7 +38,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { false, }, { - "invalid port", + "invalid port ID", func() { path.EndpointA.ChannelConfig.PortID = "invalid-port-id" }, @@ -134,12 +134,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenInit() { path.EndpointA.ChannelConfig.PortID = portID // default values - metadata = icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: ibctesting.FirstConnectionID, - HostConnectionId: ibctesting.FirstConnectionID, - } - + metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, "") bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) @@ -186,14 +181,14 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { "success", func() {}, true, }, { - "invalid port - host chain", + "invalid port ID - host chain", func() { path.EndpointA.ChannelConfig.PortID = icatypes.PortID }, false, }, { - "invalid port - unexpected prefix", + "invalid port ID - unexpected prefix", func() { path.EndpointA.ChannelConfig.PortID = "invalid-port-id" }, @@ -247,13 +242,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { err = path.EndpointB.ChanOpenTry() suite.Require().NoError(err) - metadata = icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: ibctesting.FirstConnectionID, - HostConnectionId: ibctesting.FirstConnectionID, - Address: TestAccAddress.String(), - } - + metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, TestAccAddress.String()) bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake.go b/modules/apps/27-interchain-accounts/host/keeper/handshake.go index 28d64d59c27..7949cb88a30 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake.go @@ -59,18 +59,12 @@ func (k Keeper) OnChanOpenTry( return "", sdkerrors.Wrapf(err, "failed to claim capability for channel %s on port %s", channelID, portID) } - accAddr := icatypes.GenerateAddress(k.accountKeeper.GetModuleAddress(icatypes.ModuleName), counterparty.PortId) + accAddress := icatypes.GenerateAddress(k.accountKeeper.GetModuleAddress(icatypes.ModuleName), counterparty.PortId) // Register interchain account if it does not already exist - k.RegisterInterchainAccount(ctx, accAddr, counterparty.PortId) - - metadata = icatypes.Metadata{ - Version: metadata.Version, - ControllerConnectionId: metadata.ControllerConnectionId, - HostConnectionId: metadata.HostConnectionId, - Address: accAddr.String(), - } + k.RegisterInterchainAccount(ctx, accAddress, counterparty.PortId) + metadata.Address = accAddress.String() bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) if err != nil { return "", err diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go index c531d290879..4aa7b1a5a43 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake_test.go @@ -38,14 +38,14 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { false, }, { - "invalid port", + "invalid port ID", func() { path.EndpointB.ChannelConfig.PortID = "invalid-port-id" }, false, }, { - "invalid counterparty port", + "invalid counterparty port ID", func() { channel.Counterparty.PortId = "invalid-port-id" }, @@ -130,12 +130,7 @@ func (suite *KeeperTestSuite) TestOnChanOpenTry() { path.EndpointB.ChannelID = channeltypes.FormatChannelIdentifier(channelSequence) // default values - metadata = icatypes.Metadata{ - Version: icatypes.Version, - ControllerConnectionId: ibctesting.FirstConnectionID, - HostConnectionId: ibctesting.FirstConnectionID, - } - + metadata = icatypes.NewMetadata(icatypes.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, "") bz, err := icatypes.ModuleCdc.MarshalJSON(&metadata) suite.Require().NoError(err) diff --git a/modules/apps/27-interchain-accounts/types/keys.go b/modules/apps/27-interchain-accounts/types/keys.go index 7a9f96bf97f..a855d878d30 100644 --- a/modules/apps/27-interchain-accounts/types/keys.go +++ b/modules/apps/27-interchain-accounts/types/keys.go @@ -12,7 +12,7 @@ const ( PortID = "interchain-account" // PortPrefix is the default port prefix that the interchain accounts controller submodule binds to - PortPrefix = "ics27" + PortPrefix = "ics27-" // Version defines the current version for interchain accounts Version = "ics27-1" @@ -25,9 +25,6 @@ const ( // QuerierRoute is the querier route for interchain accounts QuerierRoute = ModuleName - - // Delimiter is the delimiter used for the interchain accounts controller port - Delimiter = "-" ) var ( diff --git a/modules/apps/27-interchain-accounts/types/metadata.go b/modules/apps/27-interchain-accounts/types/metadata.go new file mode 100644 index 00000000000..c770b74ca3a --- /dev/null +++ b/modules/apps/27-interchain-accounts/types/metadata.go @@ -0,0 +1,11 @@ +package types + +// NewMetadata creates and returns a new ICS27 Metadata instance +func NewMetadata(version, controllerConnectionID, hostConnectionID, accAddress string) Metadata { + return Metadata{ + Version: version, + ControllerConnectionId: controllerConnectionID, + HostConnectionId: hostConnectionID, + Address: accAddress, + } +} diff --git a/modules/apps/27-interchain-accounts/types/port.go b/modules/apps/27-interchain-accounts/types/port.go index ea6f9448e36..54949b8a1c4 100644 --- a/modules/apps/27-interchain-accounts/types/port.go +++ b/modules/apps/27-interchain-accounts/types/port.go @@ -7,17 +7,11 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) -const ( - // ControllerPortFormat is the expected port identifier format to which controller chains must conform - // See (TODO: Link to spec when updated) - ControllerPortFormat = "..." -) - -// NewControllerPortID creates and returns a new controller port identifier in the expected format +// NewControllerPortID creates and returns a new prefixed controller port identifier using the provided owner string func NewControllerPortID(owner string) (string, error) { if strings.TrimSpace(owner) == "" { return "", sdkerrors.Wrap(ErrInvalidAccountAddress, "owner address cannot be empty") } - return fmt.Sprint(PortPrefix, Delimiter, owner), nil + return fmt.Sprint(PortPrefix, owner), nil } diff --git a/modules/apps/27-interchain-accounts/types/port_test.go b/modules/apps/27-interchain-accounts/types/port_test.go index 5fc86be4991..bdef740cd98 100644 --- a/modules/apps/27-interchain-accounts/types/port_test.go +++ b/modules/apps/27-interchain-accounts/types/port_test.go @@ -22,7 +22,7 @@ func (suite *TypesTestSuite) TestNewControllerPortID() { { "success", func() {}, - fmt.Sprint(types.PortPrefix, types.Delimiter, TestOwnerAddress), + fmt.Sprint(types.PortPrefix, TestOwnerAddress), true, }, { From 264b3079622de262bf51a86fe5cab99ba5dec4b3 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Mon, 10 Jan 2022 17:30:06 +0100 Subject: [PATCH 08/17] adding ErrInvalidControllerPort and ErrInvalidHostPort --- .../27-interchain-accounts/controller/keeper/handshake.go | 8 ++++---- .../apps/27-interchain-accounts/host/keeper/handshake.go | 5 ++--- modules/apps/27-interchain-accounts/types/errors.go | 2 ++ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index 803520f67a1..ce81271eb80 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -35,11 +35,11 @@ func (k Keeper) OnChanOpenInit( } if !strings.HasPrefix(portID, icatypes.PortPrefix) { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "controller port %s does not contain expected prefix %s", portID, icatypes.PortPrefix) + return sdkerrors.Wrapf(icatypes.ErrInvalidControllerPort, "controller port %s does not contain expected prefix %s", portID, icatypes.PortPrefix) } if counterparty.PortId != icatypes.PortID { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "expected %s, got %s", icatypes.PortID, counterparty.PortId) + return sdkerrors.Wrapf(icatypes.ErrInvalidHostPort, "expected %s, got %s", icatypes.PortID, counterparty.PortId) } var metadata icatypes.Metadata @@ -72,11 +72,11 @@ func (k Keeper) OnChanOpenAck( counterpartyVersion string, ) error { if portID == icatypes.PortID { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "portID cannot be host chain port ID: %s", icatypes.PortID) + return sdkerrors.Wrapf(icatypes.ErrInvalidControllerPort, "portID cannot be host chain port ID: %s", icatypes.PortID) } if !strings.HasPrefix(portID, icatypes.PortPrefix) { - return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "controller port %s does not contain expected prefix %s", portID, icatypes.PortPrefix) + return sdkerrors.Wrapf(icatypes.ErrInvalidControllerPort, "controller port %s does not contain expected prefix %s", portID, icatypes.PortPrefix) } var metadata icatypes.Metadata diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake.go b/modules/apps/27-interchain-accounts/host/keeper/handshake.go index 7949cb88a30..0b316134f1d 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake.go @@ -10,7 +10,6 @@ import ( icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" connectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" - porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v3/modules/core/24-host" ) @@ -33,11 +32,11 @@ func (k Keeper) OnChanOpenTry( } if portID != icatypes.PortID { - return "", sdkerrors.Wrapf(porttypes.ErrInvalidPort, "expected %s, got %s", icatypes.PortID, portID) + return "", sdkerrors.Wrapf(icatypes.ErrInvalidHostPort, "expected %s, got %s", icatypes.PortID, portID) } if !strings.HasPrefix(counterparty.PortId, icatypes.PortPrefix) { - return "", sdkerrors.Wrapf(porttypes.ErrInvalidPort, "controller port %s does not contain expected prefix %s", counterparty.PortId, icatypes.PortPrefix) + return "", sdkerrors.Wrapf(icatypes.ErrInvalidControllerPort, "controller port %s does not contain expected prefix %s", counterparty.PortId, icatypes.PortPrefix) } var metadata icatypes.Metadata diff --git a/modules/apps/27-interchain-accounts/types/errors.go b/modules/apps/27-interchain-accounts/types/errors.go index 6061c6ae243..575d619d516 100644 --- a/modules/apps/27-interchain-accounts/types/errors.go +++ b/modules/apps/27-interchain-accounts/types/errors.go @@ -17,4 +17,6 @@ var ( ErrInvalidVersion = sdkerrors.Register(ModuleName, 11, "invalid interchain accounts version") ErrInvalidAccountAddress = sdkerrors.Register(ModuleName, 12, "invalid account address") ErrUnsupported = sdkerrors.Register(ModuleName, 13, "interchain account does not support this action") + ErrInvalidControllerPort = sdkerrors.Register(ModuleName, 14, "invalid controller port") + ErrInvalidHostPort = sdkerrors.Register(ModuleName, 15, "invalid host port") ) From 42677999bb7a179508d7113afb84bbe15f3093b9 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Mon, 10 Jan 2022 20:54:40 +0100 Subject: [PATCH 09/17] refactoring metadata validation to reusable func --- .../controller/keeper/handshake.go | 35 ++----- .../host/keeper/handshake.go | 26 +---- .../27-interchain-accounts/types/metadata.go | 35 +++++++ .../types/metadata_test.go | 98 +++++++++++++++++++ 4 files changed, 140 insertions(+), 54 deletions(-) create mode 100644 modules/apps/27-interchain-accounts/types/metadata_test.go diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index ce81271eb80..8f8749eeb85 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -8,7 +8,6 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" - connectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" ) @@ -47,14 +46,10 @@ func (k Keeper) OnChanOpenInit( return sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account metadata") } - if err := k.validateConnectionParams(ctx, connectionHops, metadata.ControllerConnectionId, metadata.HostConnectionId); err != nil { + if err := icatypes.ValidateMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { return err } - if metadata.Version != icatypes.Version { - return sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.Version, metadata.Version) - } - activeChannelID, found := k.GetActiveChannelID(ctx, portID) if found { return sdkerrors.Wrapf(porttypes.ErrInvalidPort, "existing active channel %s for portID %s", activeChannelID, portID) @@ -84,12 +79,13 @@ func (k Keeper) OnChanOpenAck( return sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account metadata") } - if err := icatypes.ValidateAccountAddress(metadata.Address); err != nil { - return err + channel, found := k.channelKeeper.GetChannel(ctx, portID, channelID) + if !found { + return sdkerrors.Wrapf(channeltypes.ErrChannelNotFound, "failed to retrieve channel %s on port %s", channelID, portID) } - if metadata.Version != icatypes.Version { - return sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.Version, metadata.Version) + if err := icatypes.ValidateMetadata(ctx, k.channelKeeper, channel.ConnectionHops, metadata); err != nil { + return err } k.SetActiveChannelID(ctx, portID, channelID) @@ -109,22 +105,3 @@ func (k Keeper) OnChanCloseConfirm( return nil } - -// validateConnectionParams asserts the provided controller and host connection identifiers match that of the associated connection stored in state -func (k Keeper) validateConnectionParams(ctx sdk.Context, connectionHops []string, controllerConnectionID, hostConnectionID string) error { - connectionID := connectionHops[0] - connection, err := k.channelKeeper.GetConnection(ctx, connectionID) - if err != nil { - return err - } - - if controllerConnectionID != connectionID { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionID, controllerConnectionID) - } - - if hostConnectionID != connection.GetCounterparty().GetConnectionID() { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), hostConnectionID) - } - - return nil -} diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake.go b/modules/apps/27-interchain-accounts/host/keeper/handshake.go index 0b316134f1d..4c9b8177dc8 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake.go @@ -8,7 +8,6 @@ import ( capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" icatypes "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" - connectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" host "github.com/cosmos/ibc-go/v3/modules/core/24-host" ) @@ -44,14 +43,10 @@ func (k Keeper) OnChanOpenTry( return "", sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain account metadata") } - if err := k.validateConnectionParams(ctx, connectionHops, metadata.ControllerConnectionId, metadata.HostConnectionId); err != nil { + if err := icatypes.ValidateMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { return "", err } - if metadata.Version != icatypes.Version { - return "", sdkerrors.Wrapf(icatypes.ErrInvalidVersion, "expected %s, got %s", icatypes.Version, metadata.Version) - } - // On the host chain the capability may only be claimed during the OnChanOpenTry // The capability being claimed in OpenInit is for a controller chain (the port is different) if err := k.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil { @@ -95,22 +90,3 @@ func (k Keeper) OnChanCloseConfirm( return nil } - -// validateConnectionParams asserts the provided controller and host connection identifiers match that of the associated connection stored in state -func (k Keeper) validateConnectionParams(ctx sdk.Context, connectionHops []string, controllerConnectionID, hostConnectionID string) error { - connectionID := connectionHops[0] - connection, err := k.channelKeeper.GetConnection(ctx, connectionID) - if err != nil { - return err - } - - if hostConnectionID != connectionID { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionID, controllerConnectionID) - } - - if controllerConnectionID != connection.GetCounterparty().GetConnectionID() { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), hostConnectionID) - } - - return nil -} diff --git a/modules/apps/27-interchain-accounts/types/metadata.go b/modules/apps/27-interchain-accounts/types/metadata.go index c770b74ca3a..0a1a0f43076 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.go +++ b/modules/apps/27-interchain-accounts/types/metadata.go @@ -1,5 +1,12 @@ package types +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + connectiontypes "github.com/cosmos/ibc-go/v3/modules/core/03-connection/types" +) + // NewMetadata creates and returns a new ICS27 Metadata instance func NewMetadata(version, controllerConnectionID, hostConnectionID, accAddress string) Metadata { return Metadata{ @@ -9,3 +16,31 @@ func NewMetadata(version, controllerConnectionID, hostConnectionID, accAddress s Address: accAddress, } } + +// ValidateMetadata performs validation of the provided ICS27 metadata parameters +func ValidateMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connectionHops []string, metadata Metadata) error { + connection, err := channelKeeper.GetConnection(ctx, connectionHops[0]) + if err != nil { + return err + } + + if metadata.ControllerConnectionId != connectionHops[0] { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionHops[0], metadata.ControllerConnectionId) + } + + if metadata.HostConnectionId != connection.GetCounterparty().GetConnectionID() { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), metadata.HostConnectionId) + } + + if metadata.Address != "" { + if err := ValidateAccountAddress(metadata.Address); err != nil { + return err + } + } + + if metadata.Version != Version { + return sdkerrors.Wrap(ErrUnsupported, "") + } + + return nil +} diff --git a/modules/apps/27-interchain-accounts/types/metadata_test.go b/modules/apps/27-interchain-accounts/types/metadata_test.go new file mode 100644 index 00000000000..52940b0706f --- /dev/null +++ b/modules/apps/27-interchain-accounts/types/metadata_test.go @@ -0,0 +1,98 @@ +package types_test + +import ( + "github.com/cosmos/ibc-go/v3/modules/apps/27-interchain-accounts/types" + ibctesting "github.com/cosmos/ibc-go/v3/testing" +) + +func (suite *TypesTestSuite) TestValidateMetadata() { + + var metadata types.Metadata + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid controller connection", + func() { + metadata = types.Metadata{ + Version: types.Version, + ControllerConnectionId: "connection-10", + HostConnectionId: ibctesting.FirstConnectionID, + Address: TestOwnerAddress, + } + }, + false, + }, + { + "invalid host connection", + func() { + metadata = types.Metadata{ + Version: types.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: "connection-10", + Address: TestOwnerAddress, + } + }, + false, + }, + { + "invalid address", + func() { + metadata = types.Metadata{ + Version: types.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Address: " ", + } + }, + false, + }, + { + "invalid version", + func() { + metadata = types.Metadata{ + Version: "invalid version", + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Address: TestOwnerAddress, + } + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + metadata = types.NewMetadata(types.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, TestOwnerAddress) + + tc.malleate() // malleate mutates test data + + err := types.ValidateMetadata( + suite.chainA.GetContext(), + suite.chainA.App.GetIBCKeeper().ChannelKeeper, + []string{ibctesting.FirstConnectionID}, + metadata, + ) + + if tc.expPass { + suite.Require().NoError(err, tc.name) + } else { + suite.Require().Error(err, tc.name) + } + }) + } +} From 6ef89979e63cbfbcb9693523dc833cfdc50dde35 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Mon, 10 Jan 2022 21:03:34 +0100 Subject: [PATCH 10/17] returning correct err type --- modules/apps/27-interchain-accounts/types/metadata.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/apps/27-interchain-accounts/types/metadata.go b/modules/apps/27-interchain-accounts/types/metadata.go index 0a1a0f43076..3b1073328ab 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.go +++ b/modules/apps/27-interchain-accounts/types/metadata.go @@ -39,7 +39,7 @@ func ValidateMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connectionHo } if metadata.Version != Version { - return sdkerrors.Wrap(ErrUnsupported, "") + return sdkerrors.Wrapf(ErrInvalidVersion, "expected %s, got %s", Version, metadata.Version) } return nil From dc73e95c34eb65e581b03e9fd6fe14fc91375cc6 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 13 Jan 2022 15:08:21 +0100 Subject: [PATCH 11/17] regenerating protos after merge conflicts --- docs/ibc/proto-docs.md | 7 --- .../controller/types/controller.pb.go | 36 +++++++-------- .../controller/types/query.pb.go | 42 +++++++++--------- .../host/types/host.pb.go | 40 ++++++++--------- .../host/types/query.pb.go | 44 +++++++++---------- .../interchain_accounts/v1/metadata.proto | 7 --- 6 files changed, 77 insertions(+), 99 deletions(-) diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md index bc1b95a49e6..9ac5b0eac5c 100644 --- a/docs/ibc/proto-docs.md +++ b/docs/ibc/proto-docs.md @@ -417,17 +417,10 @@ See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel- | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -<<<<<<< HEAD -| `version` | [string](#string) | | | -| `controller_connection_id` | [string](#string) | | | -| `host_connection_id` | [string](#string) | | | -| `address` | [string](#string) | | | -======= | `version` | [string](#string) | | version defines the ICS27 protocol version | | `controller_connection_id` | [string](#string) | | controller_connection_id is the connection identifier associated with the controller chain | | `host_connection_id` | [string](#string) | | host_connection_id is the connection identifier associated with the host chain | | `address` | [string](#string) | | address defines the interchain account address to be fulfilled upon the OnChanOpenTry handshake step NOTE: the address field is empty on the OnChanOpenInit handshake step | ->>>>>>> main diff --git a/modules/apps/27-interchain-accounts/controller/types/controller.pb.go b/modules/apps/27-interchain-accounts/controller/types/controller.pb.go index 27bf1003f8e..dfa8bd31512 100644 --- a/modules/apps/27-interchain-accounts/controller/types/controller.pb.go +++ b/modules/apps/27-interchain-accounts/controller/types/controller.pb.go @@ -5,7 +5,6 @@ package types import ( fmt "fmt" - _ "github.com/cosmos/cosmos-sdk/codec/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" io "io" @@ -80,24 +79,23 @@ func init() { } var fileDescriptor_177fd0fec5eb3400 = []byte{ - // 269 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xb1, 0x4e, 0xc3, 0x30, - 0x14, 0x45, 0x9b, 0xa5, 0x42, 0xd9, 0x88, 0x18, 0x68, 0x25, 0x0c, 0xca, 0xc4, 0x92, 0x3c, 0xb5, - 0x1d, 0x90, 0x18, 0x8b, 0xd8, 0x18, 0x2a, 0x06, 0x06, 0x96, 0xca, 0x7e, 0x35, 0xae, 0x91, 0xe3, - 0x17, 0xc5, 0x4e, 0xa4, 0xfc, 0x05, 0x9f, 0xc5, 0xd8, 0x91, 0x09, 0xa1, 0xe4, 0x0f, 0xf8, 0x02, - 0xd4, 0x64, 0x48, 0x24, 0xba, 0x5d, 0x1f, 0xf9, 0x1d, 0xe9, 0xde, 0xf0, 0x41, 0x0b, 0x04, 0x9e, - 0xe7, 0x46, 0x23, 0xf7, 0x9a, 0xac, 0x03, 0x6d, 0xbd, 0x2c, 0x70, 0xcf, 0xb5, 0xdd, 0x72, 0x44, - 0x2a, 0xad, 0x77, 0x80, 0x64, 0x7d, 0x41, 0xc6, 0xc8, 0x02, 0xaa, 0xc5, 0xe8, 0x95, 0xe6, 0x05, - 0x79, 0x8a, 0x96, 0x5a, 0x60, 0x3a, 0x96, 0xa4, 0x27, 0x24, 0xe9, 0xe8, 0xac, 0x5a, 0xcc, 0x67, - 0x8a, 0x48, 0x19, 0x09, 0x9d, 0x41, 0x94, 0x6f, 0xc0, 0x6d, 0xdd, 0xeb, 0xe6, 0x17, 0x8a, 0x14, - 0x75, 0x11, 0x8e, 0xa9, 0xa7, 0xf1, 0x4b, 0x38, 0xdd, 0xf0, 0x82, 0x67, 0x2e, 0x7a, 0x0a, 0xa3, - 0xc1, 0xb5, 0x95, 0x96, 0x0b, 0x23, 0x77, 0x97, 0xc1, 0x4d, 0x70, 0x7b, 0xb6, 0xbe, 0xfa, 0xfd, - 0xbe, 0x9e, 0xd5, 0x3c, 0x33, 0xf7, 0xf1, 0xff, 0x3f, 0xf1, 0xf3, 0xf9, 0x00, 0x1f, 0x7b, 0xb6, - 0x7e, 0xff, 0x6c, 0x58, 0x70, 0x68, 0x58, 0xf0, 0xd3, 0xb0, 0xe0, 0xa3, 0x65, 0x93, 0x43, 0xcb, - 0x26, 0x5f, 0x2d, 0x9b, 0xbc, 0x6e, 0x94, 0xf6, 0xfb, 0x52, 0xa4, 0x48, 0x19, 0x20, 0xb9, 0x8c, - 0x1c, 0x68, 0x81, 0x89, 0x22, 0xa8, 0x56, 0x90, 0xd1, 0xae, 0x34, 0xd2, 0x1d, 0xb7, 0x73, 0xb0, - 0xbc, 0x4b, 0x86, 0xc6, 0xc9, 0xa9, 0xd9, 0x7c, 0x9d, 0x4b, 0x27, 0xa6, 0x5d, 0x95, 0xd5, 0x5f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x19, 0x5d, 0x5d, 0x76, 0x01, 0x00, 0x00, + // 254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x72, 0xce, 0x4c, 0x4a, 0xd6, + 0x4f, 0x2c, 0x28, 0xc8, 0xc9, 0x4c, 0x4e, 0x2c, 0xc9, 0xcc, 0xcf, 0x2b, 0xd6, 0xcf, 0xcc, 0x2b, + 0x49, 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0x8b, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0x29, + 0xd6, 0x4f, 0xce, 0xcf, 0x2b, 0x29, 0xca, 0xcf, 0xc9, 0x49, 0x2d, 0xd2, 0x2f, 0x33, 0x44, 0xe2, + 0xe9, 0x15, 0x14, 0xe5, 0x97, 0xe4, 0x0b, 0x19, 0x65, 0x26, 0x25, 0xeb, 0x21, 0x1b, 0xa2, 0x87, + 0xc5, 0x10, 0x3d, 0x24, 0x6d, 0x65, 0x86, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0xed, 0xfa, + 0x20, 0x16, 0xc4, 0x24, 0xa5, 0x30, 0x2e, 0xb6, 0x80, 0xc4, 0xa2, 0xc4, 0xdc, 0x62, 0x21, 0x1f, + 0x2e, 0x21, 0x84, 0x86, 0xf8, 0xd4, 0xbc, 0xc4, 0xa4, 0x9c, 0xd4, 0x14, 0x09, 0x46, 0x05, 0x46, + 0x0d, 0x0e, 0x27, 0xd9, 0x4f, 0xf7, 0xe4, 0x25, 0x2b, 0x13, 0x73, 0x73, 0xac, 0x94, 0x30, 0xd5, + 0x28, 0x05, 0x09, 0x22, 0x04, 0x5d, 0x21, 0x62, 0x4e, 0x59, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, + 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, + 0x78, 0x2c, 0xc7, 0x10, 0x15, 0x90, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, + 0x9f, 0x9c, 0x5f, 0x9c, 0x9b, 0x5f, 0xac, 0x9f, 0x99, 0x94, 0xac, 0x9b, 0x9e, 0xaf, 0x5f, 0x66, + 0xac, 0x9f, 0x9b, 0x9f, 0x52, 0x9a, 0x93, 0x5a, 0x0c, 0x0a, 0xa0, 0x62, 0x7d, 0x23, 0x73, 0x5d, + 0x84, 0xb7, 0x74, 0xb1, 0x85, 0x4d, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x2b, 0xc6, + 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x79, 0xfc, 0x19, 0x5b, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { diff --git a/modules/apps/27-interchain-accounts/controller/types/query.pb.go b/modules/apps/27-interchain-accounts/controller/types/query.pb.go index c200a17986a..dbbdfeec611 100644 --- a/modules/apps/27-interchain-accounts/controller/types/query.pb.go +++ b/modules/apps/27-interchain-accounts/controller/types/query.pb.go @@ -6,7 +6,6 @@ package types import ( context "context" fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -122,28 +121,27 @@ func init() { } var fileDescriptor_df0d8b259d72854e = []byte{ - // 325 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x91, 0x31, 0x4b, 0x03, 0x31, - 0x1c, 0xc5, 0x1b, 0xc1, 0x0e, 0xe7, 0x76, 0x76, 0x90, 0x22, 0x87, 0x74, 0x72, 0x69, 0xfe, 0xf4, + // 315 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x91, 0x31, 0x4b, 0x33, 0x31, + 0x1c, 0xc6, 0x9b, 0x17, 0xde, 0x0e, 0x71, 0x8b, 0x0e, 0x52, 0x24, 0x48, 0x27, 0x97, 0x26, 0xf4, 0x2a, 0x08, 0x1d, 0x1c, 0x14, 0x74, 0xad, 0x1d, 0x5d, 0x24, 0x17, 0xc3, 0x35, 0x72, 0x97, 0x7f, - 0x9a, 0xe4, 0x0a, 0x5d, 0xfd, 0x04, 0x82, 0x5f, 0xca, 0xb1, 0x20, 0x82, 0x9b, 0xd2, 0xfa, 0x41, - 0xe4, 0x2e, 0x07, 0xad, 0xd8, 0x41, 0xeb, 0x16, 0xf2, 0xe7, 0xfd, 0xde, 0x7b, 0xbc, 0xe0, 0x4c, - 0x26, 0x1c, 0x98, 0xd6, 0x99, 0xe4, 0xcc, 0x49, 0x54, 0x16, 0xa4, 0x72, 0xc2, 0xf0, 0x31, 0x93, - 0xea, 0x96, 0x71, 0x8e, 0x85, 0x72, 0x16, 0x38, 0x2a, 0x67, 0x30, 0xcb, 0x84, 0x81, 0x69, 0x0f, - 0x26, 0x85, 0x30, 0x33, 0xaa, 0x0d, 0x3a, 0x0c, 0x63, 0x99, 0x70, 0xba, 0xae, 0xa7, 0x1b, 0xf4, - 0x74, 0xa5, 0xa7, 0xd3, 0x5e, 0xbb, 0x95, 0x62, 0x8a, 0x95, 0x1c, 0xca, 0x97, 0x27, 0xb5, 0x2f, - 0xb6, 0x48, 0xb2, 0xc6, 0xf5, 0x90, 0xc3, 0x14, 0x31, 0xcd, 0x04, 0x30, 0x2d, 0x81, 0x29, 0x85, - 0xae, 0x0e, 0x55, 0x5d, 0x3b, 0xad, 0x20, 0xbc, 0x2e, 0xb3, 0x0f, 0x99, 0x61, 0xb9, 0x1d, 0x89, - 0x49, 0x21, 0xac, 0xeb, 0xc8, 0x60, 0xff, 0xdb, 0xaf, 0xd5, 0xa8, 0xac, 0x08, 0x47, 0x41, 0x53, - 0x57, 0x3f, 0x07, 0xe4, 0x88, 0x1c, 0xef, 0xc5, 0x03, 0xfa, 0xf7, 0xaa, 0xb4, 0x66, 0xd6, 0xa4, - 0xf8, 0x9d, 0x04, 0xbb, 0x95, 0x57, 0xf8, 0x4a, 0x82, 0xa6, 0x3f, 0x86, 0x97, 0xdb, 0x80, 0x7f, - 0xf6, 0x68, 0x5f, 0xfd, 0x9b, 0xe3, 0x9b, 0x77, 0x06, 0x0f, 0x2f, 0x9f, 0x4f, 0x3b, 0x27, 0x61, - 0x0c, 0xf5, 0x24, 0xbf, 0x99, 0xc2, 0x37, 0x3c, 0xbf, 0x7f, 0x5e, 0x44, 0x64, 0xbe, 0x88, 0xc8, - 0xc7, 0x22, 0x22, 0x8f, 0xcb, 0xa8, 0x31, 0x5f, 0x46, 0x8d, 0xb7, 0x65, 0xd4, 0xb8, 0x19, 0xa6, - 0xd2, 0x8d, 0x8b, 0x84, 0x72, 0xcc, 0x81, 0xa3, 0xcd, 0xd1, 0x96, 0xf8, 0x6e, 0x8a, 0x30, 0xed, - 0x43, 0x8e, 0x77, 0x45, 0x26, 0xac, 0x37, 0x8b, 0x4f, 0xbb, 0x2b, 0xbf, 0xee, 0x26, 0x3f, 0x37, - 0xd3, 0xc2, 0x26, 0xcd, 0x6a, 0xd5, 0xfe, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9f, 0x0c, 0xad, - 0x99, 0xc4, 0x02, 0x00, 0x00, + 0x9a, 0xe4, 0x0a, 0x5d, 0xfd, 0x04, 0x82, 0x5f, 0xca, 0xb1, 0x20, 0x82, 0x9b, 0x72, 0xe7, 0x07, + 0x91, 0xde, 0x1d, 0xb4, 0x62, 0x07, 0xad, 0x6b, 0xfe, 0x3c, 0xbf, 0x5f, 0x1e, 0x1e, 0x7c, 0xaa, + 0x63, 0xc9, 0x85, 0xb5, 0xa9, 0x96, 0x22, 0x68, 0x30, 0x9e, 0x6b, 0x13, 0x94, 0x93, 0x13, 0xa1, + 0xcd, 0x8d, 0x90, 0x12, 0x72, 0x13, 0x3c, 0x97, 0x60, 0x82, 0x83, 0x34, 0x55, 0x8e, 0xcf, 0xfa, + 0x7c, 0x9a, 0x2b, 0x37, 0x67, 0xd6, 0x41, 0x00, 0x12, 0xe9, 0x58, 0xb2, 0xf5, 0x3c, 0xdb, 0x90, + 0x67, 0xab, 0x3c, 0x9b, 0xf5, 0x3b, 0xe7, 0x5b, 0x38, 0xd7, 0x08, 0x95, 0xb8, 0x73, 0x90, 0x00, + 0x24, 0xa9, 0xe2, 0xc2, 0x6a, 0x2e, 0x8c, 0x81, 0xd0, 0xe8, 0xab, 0x6b, 0x77, 0x0f, 0x93, 0xab, + 0xe5, 0x2f, 0x47, 0xc2, 0x89, 0xcc, 0x8f, 0xd5, 0x34, 0x57, 0x3e, 0x74, 0x35, 0xde, 0xfd, 0xf2, + 0xea, 0x2d, 0x18, 0xaf, 0xc8, 0x18, 0xb7, 0x6d, 0xf5, 0xb2, 0x8f, 0x0e, 0xd1, 0xd1, 0x4e, 0x34, + 0x64, 0xbf, 0x2f, 0xc5, 0x1a, 0x66, 0x43, 0x8a, 0xde, 0x10, 0xfe, 0x5f, 0xb9, 0xc8, 0x0b, 0xc2, + 0xed, 0xfa, 0x48, 0x2e, 0xb6, 0x01, 0x7f, 0xef, 0xd1, 0xb9, 0xfc, 0x33, 0xa7, 0x6e, 0xde, 0x1d, + 0xde, 0x3f, 0x7f, 0x3c, 0xfe, 0x3b, 0x26, 0x11, 0x6f, 0x26, 0xf9, 0xc9, 0x14, 0x75, 0xc3, 0xb3, + 0xbb, 0xa7, 0x82, 0xa2, 0x45, 0x41, 0xd1, 0x7b, 0x41, 0xd1, 0x43, 0x49, 0x5b, 0x8b, 0x92, 0xb6, + 0x5e, 0x4b, 0xda, 0xba, 0x1e, 0x25, 0x3a, 0x4c, 0xf2, 0x98, 0x49, 0xc8, 0xb8, 0x04, 0x9f, 0x81, + 0x5f, 0xe2, 0x7b, 0x09, 0xf0, 0xd9, 0x80, 0x67, 0x70, 0x9b, 0xa7, 0xca, 0xd7, 0xb2, 0xe8, 0xa4, + 0xb7, 0xf2, 0xf5, 0x36, 0xf9, 0xc2, 0xdc, 0x2a, 0x1f, 0xb7, 0xab, 0x55, 0x07, 0x9f, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x49, 0xe2, 0x61, 0x29, 0xae, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/apps/27-interchain-accounts/host/types/host.pb.go b/modules/apps/27-interchain-accounts/host/types/host.pb.go index 1aeef028f3a..e944986eb4c 100644 --- a/modules/apps/27-interchain-accounts/host/types/host.pb.go +++ b/modules/apps/27-interchain-accounts/host/types/host.pb.go @@ -5,7 +5,6 @@ package types import ( fmt "fmt" - _ "github.com/cosmos/cosmos-sdk/codec/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" io "io" @@ -89,26 +88,25 @@ func init() { } var fileDescriptor_48e202774f13d08e = []byte{ - // 306 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0xbf, 0x6a, 0x32, 0x41, - 0x14, 0xc5, 0xdd, 0xef, 0x03, 0x49, 0x36, 0x7f, 0x0a, 0x93, 0x10, 0xb5, 0x58, 0x65, 0x2b, 0x8b, - 0xb8, 0x17, 0x63, 0x21, 0x58, 0x05, 0x21, 0x4d, 0x20, 0x10, 0x2c, 0xd3, 0xc8, 0xcc, 0x38, 0x19, - 0x07, 0x66, 0xe7, 0x2e, 0xde, 0x59, 0x83, 0x2f, 0x90, 0x3a, 0x8f, 0x95, 0xd2, 0x32, 0x95, 0x04, - 0x7d, 0x03, 0x9f, 0x20, 0xec, 0x6c, 0x20, 0x0a, 0xa9, 0xe6, 0x9e, 0x73, 0xf8, 0x1d, 0x98, 0x13, - 0x0e, 0x34, 0x17, 0xc0, 0xb2, 0xcc, 0x68, 0xc1, 0x9c, 0x46, 0x4b, 0xa0, 0xad, 0x93, 0x73, 0x31, - 0x63, 0xda, 0x4e, 0x98, 0x10, 0x98, 0x5b, 0x47, 0x30, 0x43, 0x72, 0xb0, 0xe8, 0xf9, 0x37, 0xc9, - 0xe6, 0xe8, 0xb0, 0x76, 0xa3, 0xb9, 0x48, 0xf6, 0xc1, 0xe4, 0x0f, 0x30, 0xf1, 0xc0, 0xa2, 0xd7, - 0x6c, 0x28, 0x44, 0x65, 0x24, 0x78, 0x96, 0xe7, 0x2f, 0xc0, 0xec, 0xb2, 0x2c, 0x6a, 0x5e, 0x2a, - 0x54, 0xe8, 0x4f, 0x28, 0xae, 0xd2, 0x8d, 0xdf, 0x82, 0xb0, 0xfa, 0xc4, 0xe6, 0x2c, 0xa5, 0xda, - 0x30, 0x3c, 0x2d, 0x6a, 0x26, 0xd2, 0x32, 0x6e, 0xe4, 0xb4, 0x1e, 0xb4, 0x83, 0xce, 0xd1, 0xe8, - 0x7a, 0xb7, 0x6e, 0x5d, 0x2c, 0x59, 0x6a, 0x86, 0xf1, 0x7e, 0x1a, 0x8f, 0x4f, 0x0a, 0x79, 0x5f, - 0xaa, 0xda, 0x5d, 0x78, 0xce, 0x8c, 0xc1, 0xd7, 0x49, 0x2a, 0x89, 0x98, 0x92, 0x54, 0xff, 0xd7, - 0xfe, 0xdf, 0x39, 0x1e, 0x35, 0x76, 0xeb, 0xd6, 0x55, 0x49, 0x1f, 0xe6, 0xf1, 0xf8, 0xcc, 0x1b, - 0x8f, 0x3f, 0x7a, 0x34, 0xfd, 0xd8, 0x44, 0xc1, 0x6a, 0x13, 0x05, 0x5f, 0x9b, 0x28, 0x78, 0xdf, - 0x46, 0x95, 0xd5, 0x36, 0xaa, 0x7c, 0x6e, 0xa3, 0xca, 0xf3, 0x83, 0xd2, 0x6e, 0x96, 0xf3, 0x44, - 0x60, 0x0a, 0x02, 0x29, 0x45, 0x02, 0xcd, 0x45, 0x57, 0x21, 0x2c, 0xfa, 0x90, 0xe2, 0x34, 0x37, - 0x92, 0x8a, 0x69, 0x09, 0x6e, 0x07, 0xdd, 0xdf, 0x71, 0xba, 0x87, 0xab, 0xba, 0x65, 0x26, 0x89, - 0x57, 0xfd, 0xaf, 0xfb, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x1e, 0x18, 0xa5, 0x8f, 0x01, + // 290 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0xcf, 0x4c, 0x4a, 0xd6, + 0x4f, 0x2c, 0x28, 0xc8, 0xc9, 0x4c, 0x4e, 0x2c, 0xc9, 0xcc, 0xcf, 0x2b, 0xd6, 0xcf, 0xcc, 0x2b, + 0x49, 0x2d, 0x4a, 0xce, 0x48, 0xcc, 0xcc, 0x8b, 0x4f, 0x4c, 0x4e, 0xce, 0x2f, 0xcd, 0x2b, 0x29, + 0xd6, 0xcf, 0xc8, 0x2f, 0x2e, 0xd1, 0x2f, 0x33, 0x04, 0xd3, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, + 0x42, 0x3a, 0x99, 0x49, 0xc9, 0x7a, 0xc8, 0x1a, 0xf5, 0xb0, 0x68, 0xd4, 0x03, 0x6b, 0x28, 0x33, + 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x6b, 0xd4, 0x07, 0xb1, 0x20, 0x66, 0x28, 0xb5, 0x31, + 0x72, 0xb1, 0x05, 0x24, 0x16, 0x25, 0xe6, 0x16, 0x0b, 0x59, 0x71, 0xf1, 0x80, 0xd4, 0xc6, 0xa7, + 0xe6, 0x25, 0x26, 0xe5, 0xa4, 0xa6, 0x48, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x38, 0x89, 0x7f, 0xba, + 0x27, 0x2f, 0x5c, 0x99, 0x98, 0x9b, 0x63, 0xa5, 0x84, 0x2c, 0xab, 0x14, 0xc4, 0x0d, 0xe2, 0xba, + 0x42, 0x78, 0x42, 0x0e, 0x5c, 0x7c, 0x89, 0x39, 0x39, 0xf9, 0xe5, 0xf1, 0xb9, 0xa9, 0xc5, 0xc5, + 0x89, 0xe9, 0xa9, 0xc5, 0x12, 0x4c, 0x0a, 0xcc, 0x1a, 0x9c, 0x4e, 0x92, 0x9f, 0xee, 0xc9, 0x8b, + 0x42, 0x74, 0xa3, 0xca, 0x2b, 0x05, 0xf1, 0x82, 0x05, 0x7c, 0xa1, 0x7c, 0xa7, 0x94, 0x13, 0x8f, + 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, + 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xf2, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, + 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0xcf, 0x4c, 0x4a, 0xd6, 0x4d, + 0xcf, 0xd7, 0x2f, 0x33, 0xd6, 0xcf, 0xcd, 0x4f, 0x29, 0xcd, 0x49, 0x2d, 0x06, 0x85, 0x5f, 0xb1, + 0xbe, 0x91, 0xb9, 0x2e, 0x22, 0x04, 0x74, 0x51, 0x83, 0xae, 0xa4, 0xb2, 0x20, 0xb5, 0x38, 0x89, + 0x0d, 0xec, 0x6b, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xc9, 0x05, 0x61, 0x74, 0x01, 0x00, 0x00, } diff --git a/modules/apps/27-interchain-accounts/host/types/query.pb.go b/modules/apps/27-interchain-accounts/host/types/query.pb.go index 4651e134ad5..c468e841945 100644 --- a/modules/apps/27-interchain-accounts/host/types/query.pb.go +++ b/modules/apps/27-interchain-accounts/host/types/query.pb.go @@ -6,7 +6,6 @@ package types import ( context "context" fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" grpc1 "github.com/gogo/protobuf/grpc" proto "github.com/gogo/protobuf/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -122,28 +121,27 @@ func init() { } var fileDescriptor_e6b7e23fc90c353a = []byte{ - // 321 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x91, 0x3f, 0x4b, 0x03, 0x31, - 0x18, 0xc6, 0x1b, 0xc1, 0x0e, 0xe7, 0x76, 0x76, 0x90, 0x22, 0x41, 0x3a, 0x39, 0xb4, 0x79, 0xe9, - 0x1f, 0xa8, 0xa3, 0x3a, 0x8a, 0x83, 0x3a, 0xba, 0x48, 0x2e, 0x0d, 0x69, 0xa0, 0x97, 0x37, 0xbd, - 0xe4, 0x0a, 0x5d, 0xfd, 0x04, 0x82, 0x1f, 0xc9, 0xc5, 0x45, 0x28, 0xb8, 0x38, 0x4a, 0xeb, 0x07, - 0x91, 0xcb, 0x1d, 0x68, 0x51, 0x84, 0xc3, 0xed, 0xe5, 0x0d, 0xcf, 0xef, 0x79, 0x9e, 0x37, 0xd1, - 0x89, 0x4e, 0x04, 0x70, 0x6b, 0x67, 0x5a, 0x70, 0xaf, 0xd1, 0x38, 0xd0, 0xc6, 0xcb, 0x4c, 0x4c, - 0xb9, 0x36, 0x77, 0x5c, 0x08, 0xcc, 0x8d, 0x77, 0x30, 0x45, 0xe7, 0x61, 0xd1, 0x87, 0x79, 0x2e, - 0xb3, 0x25, 0xb3, 0x19, 0x7a, 0x8c, 0xbb, 0x3a, 0x11, 0xec, 0xbb, 0x92, 0xfd, 0xa2, 0x64, 0x85, - 0x92, 0x2d, 0xfa, 0xed, 0x43, 0x85, 0xa8, 0x66, 0x12, 0xb8, 0xd5, 0xc0, 0x8d, 0x41, 0x5f, 0x69, - 0x02, 0xab, 0xdd, 0x52, 0xa8, 0x30, 0x8c, 0x50, 0x4c, 0xd5, 0x76, 0x5c, 0x2b, 0x5b, 0x70, 0x0a, - 0xc2, 0x4e, 0x2b, 0x8a, 0xaf, 0x8b, 0xa4, 0x57, 0x3c, 0xe3, 0xa9, 0xbb, 0x91, 0xf3, 0x5c, 0x3a, - 0xdf, 0x11, 0xd1, 0xfe, 0xd6, 0xd6, 0x59, 0x34, 0x4e, 0xc6, 0x97, 0x51, 0xd3, 0x86, 0xcd, 0x01, - 0x39, 0x22, 0xc7, 0x7b, 0x83, 0x11, 0xab, 0x53, 0x8c, 0x55, 0xb4, 0x8a, 0x31, 0x78, 0x21, 0xd1, - 0x6e, 0x70, 0x89, 0x9f, 0x48, 0xd4, 0x2c, 0x1f, 0xe3, 0xd3, 0x7a, 0xc8, 0x9f, 0xd9, 0xdb, 0x67, - 0xff, 0x20, 0x94, 0x3d, 0x3b, 0xa3, 0xfb, 0xd7, 0x8f, 0xc7, 0x1d, 0x16, 0x77, 0xa1, 0x3a, 0xeb, - 0xdf, 0xe7, 0x2c, 0xfb, 0x9c, 0x4f, 0x9e, 0xd7, 0x94, 0xac, 0xd6, 0x94, 0xbc, 0xaf, 0x29, 0x79, - 0xd8, 0xd0, 0xc6, 0x6a, 0x43, 0x1b, 0x6f, 0x1b, 0xda, 0xb8, 0xbd, 0x50, 0xda, 0x4f, 0xf3, 0x84, - 0x09, 0x4c, 0x41, 0xa0, 0x4b, 0xd1, 0x15, 0xe0, 0x9e, 0x42, 0x58, 0x0c, 0x21, 0xc5, 0x49, 0x3e, - 0x93, 0xae, 0xb4, 0x19, 0x8c, 0x7b, 0x5f, 0x4e, 0xbd, 0x6d, 0x27, 0xbf, 0xb4, 0xd2, 0x25, 0xcd, - 0xf0, 0x6f, 0xc3, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7, 0xea, 0x8f, 0x11, 0x8e, 0x02, 0x00, - 0x00, + // 312 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x91, 0x3f, 0x4b, 0x3b, 0x31, + 0x18, 0xc7, 0x9b, 0x1f, 0xfc, 0x3a, 0xc4, 0x2d, 0x3a, 0x48, 0x91, 0x20, 0x9d, 0x1c, 0xda, 0x84, + 0xfe, 0x81, 0x3a, 0xaa, 0xa3, 0x38, 0xa8, 0xa3, 0x8b, 0xe4, 0xd2, 0x70, 0x0d, 0xf4, 0xf2, 0xa4, + 0x97, 0xdc, 0x41, 0x57, 0x5f, 0x81, 0xe0, 0x4b, 0x72, 0x71, 0x11, 0x0a, 0x2e, 0x8e, 0x72, 0xe7, + 0x0b, 0x91, 0xcb, 0x1d, 0x68, 0x51, 0x84, 0xc3, 0xf5, 0x09, 0x9f, 0xcf, 0xf7, 0xf9, 0x3e, 0xc1, + 0xc7, 0x3a, 0x92, 0x5c, 0x58, 0xbb, 0xd4, 0x52, 0x78, 0x0d, 0xc6, 0x71, 0x6d, 0xbc, 0x4a, 0xe5, + 0x42, 0x68, 0x73, 0x2b, 0xa4, 0x84, 0xcc, 0x78, 0xc7, 0x17, 0xe0, 0x3c, 0xcf, 0x47, 0x7c, 0x95, + 0xa9, 0x74, 0xcd, 0x6c, 0x0a, 0x1e, 0xc8, 0x40, 0x47, 0x92, 0x7d, 0x25, 0xd9, 0x0f, 0x24, 0xab, + 0x48, 0x96, 0x8f, 0x7a, 0x07, 0x31, 0x40, 0xbc, 0x54, 0x5c, 0x58, 0xcd, 0x85, 0x31, 0xe0, 0x1b, + 0x26, 0xb8, 0x7a, 0xb3, 0x56, 0x5b, 0x04, 0x67, 0x00, 0xfb, 0x7b, 0x98, 0x5c, 0x55, 0x3b, 0x5d, + 0x8a, 0x54, 0x24, 0xee, 0x5a, 0xad, 0x32, 0xe5, 0x7c, 0x5f, 0xe2, 0xdd, 0xad, 0xa9, 0xb3, 0x60, + 0x9c, 0x22, 0x17, 0xb8, 0x6b, 0xc3, 0x64, 0x1f, 0x1d, 0xa2, 0xa3, 0x9d, 0xf1, 0x94, 0xb5, 0xa9, + 0xc0, 0x1a, 0x5b, 0xe3, 0x18, 0x3f, 0x23, 0xfc, 0x3f, 0xa4, 0x90, 0x47, 0x84, 0xbb, 0xf5, 0x23, + 0x39, 0x69, 0xa7, 0xfc, 0xbe, 0x7b, 0xef, 0xf4, 0x0f, 0x86, 0xba, 0x67, 0x7f, 0x7a, 0xf7, 0xf2, + 0xfe, 0xf0, 0x8f, 0x91, 0x01, 0x6f, 0xce, 0xfa, 0xfb, 0x39, 0xeb, 0x3e, 0x67, 0xf3, 0xa7, 0x82, + 0xa2, 0x4d, 0x41, 0xd1, 0x5b, 0x41, 0xd1, 0x7d, 0x49, 0x3b, 0x9b, 0x92, 0x76, 0x5e, 0x4b, 0xda, + 0xb9, 0x39, 0x8f, 0xb5, 0x5f, 0x64, 0x11, 0x93, 0x90, 0x70, 0x09, 0x2e, 0x01, 0x57, 0x89, 0x87, + 0x31, 0xf0, 0x7c, 0xc2, 0x13, 0x98, 0x67, 0x4b, 0xe5, 0xea, 0x98, 0xf1, 0x6c, 0xf8, 0x99, 0x34, + 0xdc, 0x4e, 0xf2, 0x6b, 0xab, 0x5c, 0xd4, 0x0d, 0xff, 0x36, 0xf9, 0x08, 0x00, 0x00, 0xff, 0xff, + 0x7d, 0xf5, 0x90, 0xb6, 0x78, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/proto/ibc/applications/interchain_accounts/v1/metadata.proto b/proto/ibc/applications/interchain_accounts/v1/metadata.proto index 8ddb42bc332..acc338466af 100644 --- a/proto/ibc/applications/interchain_accounts/v1/metadata.proto +++ b/proto/ibc/applications/interchain_accounts/v1/metadata.proto @@ -9,12 +9,6 @@ import "gogoproto/gogo.proto"; // Metadata defines a set of protocol specific data encoded into the ICS27 channel version bytestring // See ICS004: https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#Versioning message Metadata { -<<<<<<< HEAD - string version = 1; - string controller_connection_id = 2 [(gogoproto.moretags) = "yaml:\"controller_connection_id\""]; - string host_connection_id = 3 [(gogoproto.moretags) = "yaml:\"host_connection_id\""]; - string address = 4; -======= // version defines the ICS27 protocol version string version = 1; // controller_connection_id is the connection identifier associated with the controller chain @@ -24,5 +18,4 @@ message Metadata { // address defines the interchain account address to be fulfilled upon the OnChanOpenTry handshake step // NOTE: the address field is empty on the OnChanOpenInit handshake step string address = 4; ->>>>>>> main } From 3257aa43919b00e06f855f0635f8e8e4528ea4f8 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 13 Jan 2022 15:28:19 +0100 Subject: [PATCH 12/17] adding separate validation funcs for controller and host --- .../controller/keeper/handshake.go | 4 +- .../host/keeper/handshake.go | 2 +- .../27-interchain-accounts/types/metadata.go | 32 ++++++- .../types/metadata_test.go | 96 ++++++++++++++++++- 4 files changed, 127 insertions(+), 7 deletions(-) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index 2912fa708ed..945e63eef61 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -46,7 +46,7 @@ func (k Keeper) OnChanOpenInit( return sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") } - if err := icatypes.ValidateMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { + if err := icatypes.ValidateControllerMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { return err } @@ -84,7 +84,7 @@ func (k Keeper) OnChanOpenAck( return sdkerrors.Wrapf(channeltypes.ErrChannelNotFound, "failed to retrieve channel %s on port %s", channelID, portID) } - if err := icatypes.ValidateMetadata(ctx, k.channelKeeper, channel.ConnectionHops, metadata); err != nil { + if err := icatypes.ValidateControllerMetadata(ctx, k.channelKeeper, channel.ConnectionHops, metadata); err != nil { return err } diff --git a/modules/apps/27-interchain-accounts/host/keeper/handshake.go b/modules/apps/27-interchain-accounts/host/keeper/handshake.go index aae28036178..ffd2d1ae4da 100644 --- a/modules/apps/27-interchain-accounts/host/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/host/keeper/handshake.go @@ -43,7 +43,7 @@ func (k Keeper) OnChanOpenTry( return "", sdkerrors.Wrapf(icatypes.ErrUnknownDataType, "cannot unmarshal ICS-27 interchain accounts metadata") } - if err := icatypes.ValidateMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { + if err := icatypes.ValidateHostMetadata(ctx, k.channelKeeper, connectionHops, metadata); err != nil { return "", err } diff --git a/modules/apps/27-interchain-accounts/types/metadata.go b/modules/apps/27-interchain-accounts/types/metadata.go index 3b1073328ab..6e9975f391c 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.go +++ b/modules/apps/27-interchain-accounts/types/metadata.go @@ -17,8 +17,8 @@ func NewMetadata(version, controllerConnectionID, hostConnectionID, accAddress s } } -// ValidateMetadata performs validation of the provided ICS27 metadata parameters -func ValidateMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connectionHops []string, metadata Metadata) error { +// ValidateControllerMetadata performs validation of the provided ICS27 controller metadata parameters +func ValidateControllerMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connectionHops []string, metadata Metadata) error { connection, err := channelKeeper.GetConnection(ctx, connectionHops[0]) if err != nil { return err @@ -44,3 +44,31 @@ func ValidateMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connectionHo return nil } + +// ValidateHostMetadata performs validation of the provided ICS27 host metadata parameters +func ValidateHostMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connectionHops []string, metadata Metadata) error { + connection, err := channelKeeper.GetConnection(ctx, connectionHops[0]) + if err != nil { + return err + } + + if metadata.ControllerConnectionId != connection.GetCounterparty().GetConnectionID() { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionHops[0], metadata.ControllerConnectionId) + } + + if metadata.HostConnectionId != connectionHops[0] { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), metadata.HostConnectionId) + } + + if metadata.Address != "" { + if err := ValidateAccountAddress(metadata.Address); err != nil { + return err + } + } + + if metadata.Version != Version { + return sdkerrors.Wrapf(ErrInvalidVersion, "expected %s, got %s", Version, metadata.Version) + } + + return nil +} diff --git a/modules/apps/27-interchain-accounts/types/metadata_test.go b/modules/apps/27-interchain-accounts/types/metadata_test.go index 52940b0706f..7c19b2a814d 100644 --- a/modules/apps/27-interchain-accounts/types/metadata_test.go +++ b/modules/apps/27-interchain-accounts/types/metadata_test.go @@ -5,7 +5,7 @@ import ( ibctesting "github.com/cosmos/ibc-go/v3/testing" ) -func (suite *TypesTestSuite) TestValidateMetadata() { +func (suite *TypesTestSuite) TestValidateControllerMetadata() { var metadata types.Metadata @@ -81,7 +81,99 @@ func (suite *TypesTestSuite) TestValidateMetadata() { tc.malleate() // malleate mutates test data - err := types.ValidateMetadata( + err := types.ValidateControllerMetadata( + suite.chainA.GetContext(), + suite.chainA.App.GetIBCKeeper().ChannelKeeper, + []string{ibctesting.FirstConnectionID}, + metadata, + ) + + if tc.expPass { + suite.Require().NoError(err, tc.name) + } else { + suite.Require().Error(err, tc.name) + } + }) + } +} + +func (suite *TypesTestSuite) TestValidateHostMetadata() { + + var metadata types.Metadata + + testCases := []struct { + name string + malleate func() + expPass bool + }{ + { + "success", + func() {}, + true, + }, + { + "invalid controller connection", + func() { + metadata = types.Metadata{ + Version: types.Version, + ControllerConnectionId: "connection-10", + HostConnectionId: ibctesting.FirstConnectionID, + Address: TestOwnerAddress, + } + }, + false, + }, + { + "invalid host connection", + func() { + metadata = types.Metadata{ + Version: types.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: "connection-10", + Address: TestOwnerAddress, + } + }, + false, + }, + { + "invalid address", + func() { + metadata = types.Metadata{ + Version: types.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Address: " ", + } + }, + false, + }, + { + "invalid version", + func() { + metadata = types.Metadata{ + Version: "invalid version", + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Address: TestOwnerAddress, + } + }, + false, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path := ibctesting.NewPath(suite.chainA, suite.chainB) + suite.coordinator.SetupConnections(path) + + metadata = types.NewMetadata(types.Version, ibctesting.FirstConnectionID, ibctesting.FirstConnectionID, TestOwnerAddress) + + tc.malleate() // malleate mutates test data + + err := types.ValidateHostMetadata( suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ChannelKeeper, []string{ibctesting.FirstConnectionID}, From 9dc5386075ed3ce5e908ae2367f9b7c021be1c30 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 13 Jan 2022 16:21:16 +0100 Subject: [PATCH 13/17] correcting error msg in ValidateHostMetadata --- modules/apps/27-interchain-accounts/types/metadata.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/apps/27-interchain-accounts/types/metadata.go b/modules/apps/27-interchain-accounts/types/metadata.go index 6e9975f391c..2ceae5d3f6b 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.go +++ b/modules/apps/27-interchain-accounts/types/metadata.go @@ -53,11 +53,11 @@ func ValidateHostMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connecti } if metadata.ControllerConnectionId != connection.GetCounterparty().GetConnectionID() { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionHops[0], metadata.ControllerConnectionId) + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), metadata.ControllerConnectionId) } if metadata.HostConnectionId != connectionHops[0] { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), metadata.HostConnectionId) + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionHops[0], metadata.HostConnectionId) } if metadata.Address != "" { From 3a99f1ba2f07417dd802afaef1a7c579ecb2feea Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 13 Jan 2022 16:49:14 +0100 Subject: [PATCH 14/17] updating with review suggestions --- .../27-interchain-accounts/types/metadata.go | 29 +++++++++++-------- .../types/metadata_test.go | 12 ++++++++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/modules/apps/27-interchain-accounts/types/metadata.go b/modules/apps/27-interchain-accounts/types/metadata.go index 2ceae5d3f6b..acc1dcb940b 100644 --- a/modules/apps/27-interchain-accounts/types/metadata.go +++ b/modules/apps/27-interchain-accounts/types/metadata.go @@ -24,12 +24,8 @@ func ValidateControllerMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, co return err } - if metadata.ControllerConnectionId != connectionHops[0] { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionHops[0], metadata.ControllerConnectionId) - } - - if metadata.HostConnectionId != connection.GetCounterparty().GetConnectionID() { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), metadata.HostConnectionId) + if err := validateConnectionParams(metadata, connectionHops[0], connection.GetCounterparty().GetConnectionID()); err != nil { + return err } if metadata.Address != "" { @@ -52,12 +48,8 @@ func ValidateHostMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connecti return err } - if metadata.ControllerConnectionId != connection.GetCounterparty().GetConnectionID() { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connection.GetCounterparty().GetConnectionID(), metadata.ControllerConnectionId) - } - - if metadata.HostConnectionId != connectionHops[0] { - return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", connectionHops[0], metadata.HostConnectionId) + if err := validateConnectionParams(metadata, connection.GetCounterparty().GetConnectionID(), connectionHops[0]); err != nil { + return err } if metadata.Address != "" { @@ -72,3 +64,16 @@ func ValidateHostMetadata(ctx sdk.Context, channelKeeper ChannelKeeper, connecti return nil } + +// validateConnectionParams compares the given the controller and host connection IDs to those set in the provided ICS27 Metadata +func validateConnectionParams(metadata Metadata, controllerConnectionID, hostConnectionID string) error { + if metadata.ControllerConnectionId != controllerConnectionID { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", controllerConnectionID, metadata.ControllerConnectionId) + } + + if metadata.HostConnectionId != hostConnectionID { + return sdkerrors.Wrapf(connectiontypes.ErrInvalidConnection, "expected %s, got %s", hostConnectionID, metadata.HostConnectionId) + } + + return nil +} diff --git a/modules/apps/27-interchain-accounts/types/metadata_test.go b/modules/apps/27-interchain-accounts/types/metadata_test.go index 7c19b2a814d..459df070baf 100644 --- a/modules/apps/27-interchain-accounts/types/metadata_test.go +++ b/modules/apps/27-interchain-accounts/types/metadata_test.go @@ -19,6 +19,18 @@ func (suite *TypesTestSuite) TestValidateControllerMetadata() { func() {}, true, }, + { + "success with empty account address", + func() { + metadata = types.Metadata{ + Version: types.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Address: "", + } + }, + true, + }, { "invalid controller connection", func() { From 2214791897f7a456395236ed0d0682c5590eb5cf Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 13 Jan 2022 17:24:48 +0100 Subject: [PATCH 15/17] adding additional empty address check to ACK step, adding test case --- .../controller/keeper/handshake.go | 4 ++++ .../controller/keeper/handshake_test.go | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index 945e63eef61..12c3ec10983 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -88,6 +88,10 @@ func (k Keeper) OnChanOpenAck( return err } + if metadata.Address == "" { + return sdkerrors.Wrap(icatypes.ErrInvalidAccountAddress, "interchain account address cannot be empty") + } + k.SetActiveChannelID(ctx, portID, channelID) k.SetInterchainAccountAddress(ctx, portID, metadata.Address) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go index 9e902c41084..c1aafb7aaff 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go @@ -213,6 +213,18 @@ func (suite *KeeperTestSuite) TestOnChanOpenAck() { }, false, }, + { + "empty account address", + func() { + metadata.Address = "" + + versionBytes, err := icatypes.ModuleCdc.MarshalJSON(&metadata) + suite.Require().NoError(err) + + path.EndpointA.Counterparty.ChannelConfig.Version = string(versionBytes) + }, + false, + }, { "invalid counterparty version", func() { From 8d34265e4133d4f617327605e4aa1526380b96ec Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 13 Jan 2022 17:26:59 +0100 Subject: [PATCH 16/17] adding strings.Trimspace --- .../apps/27-interchain-accounts/controller/keeper/handshake.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go index 12c3ec10983..f8a1b579862 100644 --- a/modules/apps/27-interchain-accounts/controller/keeper/handshake.go +++ b/modules/apps/27-interchain-accounts/controller/keeper/handshake.go @@ -88,7 +88,7 @@ func (k Keeper) OnChanOpenAck( return err } - if metadata.Address == "" { + if strings.TrimSpace(metadata.Address) == "" { return sdkerrors.Wrap(icatypes.ErrInvalidAccountAddress, "interchain account address cannot be empty") } From 69411d0fd25b477f8a045d450f8e5f23665a5393 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Fri, 14 Jan 2022 11:04:07 +0100 Subject: [PATCH 17/17] adding success with empty address testcase for ValidateHostMetadata --- .../27-interchain-accounts/types/metadata_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/apps/27-interchain-accounts/types/metadata_test.go b/modules/apps/27-interchain-accounts/types/metadata_test.go index 459df070baf..2e569549647 100644 --- a/modules/apps/27-interchain-accounts/types/metadata_test.go +++ b/modules/apps/27-interchain-accounts/types/metadata_test.go @@ -123,6 +123,18 @@ func (suite *TypesTestSuite) TestValidateHostMetadata() { func() {}, true, }, + { + "success with empty account address", + func() { + metadata = types.Metadata{ + Version: types.Version, + ControllerConnectionId: ibctesting.FirstConnectionID, + HostConnectionId: ibctesting.FirstConnectionID, + Address: "", + } + }, + true, + }, { "invalid controller connection", func() {