From 2b8ebde3a934c709c33c471577c76a6ab8e861a0 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 25 Apr 2025 12:28:00 +0300 Subject: [PATCH 01/46] feat: added proto types --- proto/ibc/applications/gmp/v1/account.proto | 27 ++++++++++++ proto/ibc/applications/gmp/v1/packet.proto | 19 ++++++++ proto/ibc/applications/gmp/v1/tx.proto | 48 +++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 proto/ibc/applications/gmp/v1/account.proto create mode 100644 proto/ibc/applications/gmp/v1/packet.proto create mode 100644 proto/ibc/applications/gmp/v1/tx.proto diff --git a/proto/ibc/applications/gmp/v1/account.proto b/proto/ibc/applications/gmp/v1/account.proto new file mode 100644 index 00000000000..1bb16d2a4f6 --- /dev/null +++ b/proto/ibc/applications/gmp/v1/account.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/auth/v1beta1/auth.proto"; + +// AccountIdentifier is used to identify a ICS27 account. +message AccountIdentifier { + // The (local) client identifier + string client_id = 1; + // The sender of the packet + string sender = 2; + // The salt of the packet + bytes salt = 3; +} + +// An ICS27Account is defined as a BaseAccount & the account identifier +message ICS27Account { + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; + AccountIdentifier account_id = 2; +} diff --git a/proto/ibc/applications/gmp/v1/packet.proto b/proto/ibc/applications/gmp/v1/packet.proto new file mode 100644 index 00000000000..da295018e1d --- /dev/null +++ b/proto/ibc/applications/gmp/v1/packet.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +// GMPPacketData defines a struct for the packet payload +message GMPPacketData { + // the sender address + string sender = 1; + // the recipient address on the destination chain + string receiver = 2; + // The salt used to generate the caller account address + bytes salt = 3; + // The payload of the call + bytes payload = 4; + // optional memo + string memo = 5; +} diff --git a/proto/ibc/applications/gmp/v1/tx.proto b/proto/ibc/applications/gmp/v1/tx.proto new file mode 100644 index 00000000000..d3942230f51 --- /dev/null +++ b/proto/ibc/applications/gmp/v1/tx.proto @@ -0,0 +1,48 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/msg/v1/msg.proto"; + +// Msg defines the ibc/gmp Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // SendCall defines a rpc handler method for MsgSendCall. + rpc SendCall(MsgSendCall) returns (MsgSendCallResponse); +} + +// MsgSendCall defines a msg to send a call to a contract/receiver on a ICS27-2 enabled chain. +message MsgSendCall { + option (cosmos.msg.v1.signer) = "sender"; + + option (gogoproto.goproto_getters) = false; + + // the client by which the packet will be sent + string source_client = 1; + // the sender address + string sender = 2; + // the recipient address on the destination chain + string receiver = 3; + // The salt used to generate the caller account address + bytes salt = 4; + // The payload of the call + bytes payload = 5; + // Timeout timestamp in absolute nanoseconds since unix epoch. + uint64 timeout_timestamp = 6; + // optional memo + string memo = 7; + // optional encoding + string encoding = 8; +} + +// MsgSendCallResponse defines the Msg/SendCall response type. +message MsgSendCallResponse { + option (gogoproto.goproto_getters) = false; + + // sequence number of the GMP packet sent + uint64 sequence = 1; +} From e64d4b8ba245ca8f5821d5c05cf59814c0b19098 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 2 May 2025 11:34:29 +0400 Subject: [PATCH 02/46] chore: ran proto-all --- proto/ibc/applications/gmp/v1/account.proto | 12 ++++++------ proto/ibc/core/client/v1/tx.proto | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/proto/ibc/applications/gmp/v1/account.proto b/proto/ibc/applications/gmp/v1/account.proto index 1bb16d2a4f6..76ed9cd1ec7 100644 --- a/proto/ibc/applications/gmp/v1/account.proto +++ b/proto/ibc/applications/gmp/v1/account.proto @@ -12,16 +12,16 @@ message AccountIdentifier { // The (local) client identifier string client_id = 1; // The sender of the packet - string sender = 2; + string sender = 2; // The salt of the packet - bytes salt = 3; + bytes salt = 3; } // An ICS27Account is defined as a BaseAccount & the account identifier message ICS27Account { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; - cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; - AccountIdentifier account_id = 2; + cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; + AccountIdentifier account_id = 2; } diff --git a/proto/ibc/core/client/v1/tx.proto b/proto/ibc/core/client/v1/tx.proto index 45e4febfaad..dc1a38419a4 100644 --- a/proto/ibc/core/client/v1/tx.proto +++ b/proto/ibc/core/client/v1/tx.proto @@ -195,4 +195,3 @@ message MsgDeleteClientCreator { // MsgDeleteClientCreatorResponse defines the Msg/DeleteClientCreator response type. message MsgDeleteClientCreatorResponse {} - From 7f984282f3875d5223b379beb46273e29a9d0a3c Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 2 May 2025 11:48:11 +0400 Subject: [PATCH 03/46] chore: generate proto --- modules/apps/27-gmp/types/account.pb.go | 664 ++++++++++++++++++ modules/apps/27-gmp/types/packet.pb.go | 536 +++++++++++++++ modules/apps/27-gmp/types/tx.pb.go | 867 ++++++++++++++++++++++++ 3 files changed, 2067 insertions(+) create mode 100644 modules/apps/27-gmp/types/account.pb.go create mode 100644 modules/apps/27-gmp/types/packet.pb.go create mode 100644 modules/apps/27-gmp/types/tx.pb.go diff --git a/modules/apps/27-gmp/types/account.pb.go b/modules/apps/27-gmp/types/account.pb.go new file mode 100644 index 00000000000..6e56fca45c5 --- /dev/null +++ b/modules/apps/27-gmp/types/account.pb.go @@ -0,0 +1,664 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/account.proto + +package types + +import ( + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/x/auth/types" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/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 + +// AccountIdentifier is used to identify a ICS27 account. +type AccountIdentifier struct { + // The (local) client identifier + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // The sender of the packet + Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` + // The salt of the packet + Salt []byte `protobuf:"bytes,3,opt,name=salt,proto3" json:"salt,omitempty"` +} + +func (m *AccountIdentifier) Reset() { *m = AccountIdentifier{} } +func (m *AccountIdentifier) String() string { return proto.CompactTextString(m) } +func (*AccountIdentifier) ProtoMessage() {} +func (*AccountIdentifier) Descriptor() ([]byte, []int) { + return fileDescriptor_5d5b886ccdedc1db, []int{0} +} +func (m *AccountIdentifier) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AccountIdentifier) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AccountIdentifier.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 *AccountIdentifier) XXX_Merge(src proto.Message) { + xxx_messageInfo_AccountIdentifier.Merge(m, src) +} +func (m *AccountIdentifier) XXX_Size() int { + return m.Size() +} +func (m *AccountIdentifier) XXX_DiscardUnknown() { + xxx_messageInfo_AccountIdentifier.DiscardUnknown(m) +} + +var xxx_messageInfo_AccountIdentifier proto.InternalMessageInfo + +func (m *AccountIdentifier) GetClientId() string { + if m != nil { + return m.ClientId + } + return "" +} + +func (m *AccountIdentifier) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *AccountIdentifier) GetSalt() []byte { + if m != nil { + return m.Salt + } + return nil +} + +// An ICS27Account is defined as a BaseAccount & the account identifier +type ICS27Account struct { + *types.BaseAccount `protobuf:"bytes,1,opt,name=base_account,json=baseAccount,proto3,embedded=base_account" json:"base_account,omitempty"` + AccountId *AccountIdentifier `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` +} + +func (m *ICS27Account) Reset() { *m = ICS27Account{} } +func (*ICS27Account) ProtoMessage() {} +func (*ICS27Account) Descriptor() ([]byte, []int) { + return fileDescriptor_5d5b886ccdedc1db, []int{1} +} +func (m *ICS27Account) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ICS27Account) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ICS27Account.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 *ICS27Account) XXX_Merge(src proto.Message) { + xxx_messageInfo_ICS27Account.Merge(m, src) +} +func (m *ICS27Account) XXX_Size() int { + return m.Size() +} +func (m *ICS27Account) XXX_DiscardUnknown() { + xxx_messageInfo_ICS27Account.DiscardUnknown(m) +} + +var xxx_messageInfo_ICS27Account proto.InternalMessageInfo + +func init() { + proto.RegisterType((*AccountIdentifier)(nil), "ibc.applications.gmp.v1.AccountIdentifier") + proto.RegisterType((*ICS27Account)(nil), "ibc.applications.gmp.v1.ICS27Account") +} + +func init() { + proto.RegisterFile("ibc/applications/gmp/v1/account.proto", fileDescriptor_5d5b886ccdedc1db) +} + +var fileDescriptor_5d5b886ccdedc1db = []byte{ + // 353 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x51, 0xc1, 0x4a, 0xeb, 0x40, + 0x14, 0xcd, 0xf4, 0x95, 0xd2, 0x4e, 0xbb, 0x79, 0xe1, 0xf1, 0x2c, 0x15, 0xd2, 0x52, 0x10, 0x8a, + 0xd0, 0x19, 0x53, 0xc1, 0x82, 0x3b, 0xeb, 0x2a, 0x3b, 0x89, 0x3b, 0x11, 0xca, 0xcc, 0x64, 0x4c, + 0x07, 0x92, 0x4c, 0xe8, 0x4c, 0x02, 0xfe, 0x81, 0x4b, 0x97, 0x2e, 0xfb, 0x05, 0x7e, 0x87, 0xcb, + 0x2e, 0x5d, 0x89, 0xb4, 0x3f, 0x22, 0x99, 0x8c, 0x28, 0x88, 0xbb, 0x7b, 0xcf, 0x3d, 0x73, 0xe6, + 0xdc, 0x73, 0xe1, 0x91, 0xa0, 0x0c, 0x93, 0x3c, 0x4f, 0x04, 0x23, 0x5a, 0xc8, 0x4c, 0xe1, 0x38, + 0xcd, 0x71, 0xe9, 0x63, 0xc2, 0x98, 0x2c, 0x32, 0x8d, 0xf2, 0xb5, 0xd4, 0xd2, 0x3d, 0x10, 0x94, + 0xa1, 0xef, 0x34, 0x14, 0xa7, 0x39, 0x2a, 0xfd, 0xc1, 0xbf, 0x58, 0xc6, 0xd2, 0x70, 0x70, 0x55, + 0xd5, 0xf4, 0x81, 0xc7, 0xa4, 0x4a, 0xa5, 0xc2, 0xa4, 0xd0, 0x2b, 0x5c, 0xfa, 0x94, 0x6b, 0xe2, + 0x9b, 0xa6, 0x9e, 0x8f, 0x6f, 0xe1, 0xdf, 0x8b, 0x5a, 0x3f, 0x88, 0x78, 0xa6, 0xc5, 0x9d, 0xe0, + 0x6b, 0xf7, 0x10, 0x76, 0x58, 0x22, 0x78, 0xa6, 0x97, 0x22, 0xea, 0x83, 0x11, 0x98, 0x74, 0xc2, + 0x76, 0x0d, 0x04, 0x91, 0xfb, 0x1f, 0xb6, 0x14, 0xcf, 0x22, 0xbe, 0xee, 0x37, 0xcc, 0xc4, 0x76, + 0xae, 0x0b, 0x9b, 0x8a, 0x24, 0xba, 0xff, 0x67, 0x04, 0x26, 0xbd, 0xd0, 0xd4, 0xe3, 0x67, 0x00, + 0x7b, 0xc1, 0xe5, 0xf5, 0x6c, 0x6e, 0xff, 0x70, 0x03, 0xd8, 0xa3, 0x44, 0xf1, 0xa5, 0xdd, 0xc9, + 0x88, 0x77, 0x67, 0x23, 0x54, 0xbb, 0x44, 0xc6, 0x98, 0x75, 0x89, 0x16, 0x44, 0x71, 0xfb, 0x6e, + 0xd1, 0xdc, 0xbe, 0x0d, 0x41, 0xd8, 0xa5, 0x5f, 0x90, 0x1b, 0x40, 0x68, 0x55, 0x2a, 0x97, 0x0d, + 0x23, 0x74, 0x8c, 0x7e, 0x49, 0x07, 0xfd, 0x58, 0x32, 0xec, 0x90, 0x4f, 0xe8, 0xbc, 0xfd, 0xb0, + 0x19, 0x3a, 0x4f, 0x9b, 0xa1, 0xb3, 0xb8, 0x7a, 0xd9, 0x79, 0x60, 0xbb, 0xf3, 0xc0, 0xfb, 0xce, + 0x03, 0x8f, 0x7b, 0xcf, 0xd9, 0xee, 0x3d, 0xe7, 0x75, 0xef, 0x39, 0x37, 0x67, 0xb1, 0xd0, 0xab, + 0x82, 0x22, 0x26, 0x53, 0x6c, 0x33, 0x15, 0x94, 0x4d, 0x63, 0x89, 0x4b, 0xff, 0x04, 0xa7, 0x32, + 0x2a, 0x12, 0xae, 0xaa, 0xfb, 0x29, 0x3c, 0x9b, 0x4f, 0xab, 0xd3, 0xe9, 0xfb, 0x9c, 0x2b, 0xda, + 0x32, 0x39, 0x9f, 0x7e, 0x04, 0x00, 0x00, 0xff, 0xff, 0x0c, 0xaf, 0x35, 0x38, 0xdf, 0x01, 0x00, + 0x00, +} + +func (m *AccountIdentifier) 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 *AccountIdentifier) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AccountIdentifier) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintAccount(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x1a + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintAccount(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0x12 + } + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintAccount(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ICS27Account) 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 *ICS27Account) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ICS27Account) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.AccountId != nil { + { + size, err := m.AccountId.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccount(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.BaseAccount != nil { + { + size, err := m.BaseAccount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccount(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintAccount(dAtA []byte, offset int, v uint64) int { + offset -= sovAccount(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *AccountIdentifier) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovAccount(uint64(l)) + } + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovAccount(uint64(l)) + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovAccount(uint64(l)) + } + return n +} + +func (m *ICS27Account) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BaseAccount != nil { + l = m.BaseAccount.Size() + n += 1 + l + sovAccount(uint64(l)) + } + if m.AccountId != nil { + l = m.AccountId.Size() + n += 1 + l + sovAccount(uint64(l)) + } + return n +} + +func sovAccount(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozAccount(x uint64) (n int) { + return sovAccount(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *AccountIdentifier) 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 ErrIntOverflowAccount + } + 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: AccountIdentifier: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccountIdentifier: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + 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 ErrInvalidLengthAccount + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + 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 ErrInvalidLengthAccount + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = append(m.Salt[:0], dAtA[iNdEx:postIndex]...) + if m.Salt == nil { + m.Salt = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAccount(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccount + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ICS27Account) 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 ErrIntOverflowAccount + } + 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: ICS27Account: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ICS27Account: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BaseAccount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BaseAccount == nil { + m.BaseAccount = &types.BaseAccount{} + } + if err := m.BaseAccount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AccountId == nil { + m.AccountId = &AccountIdentifier{} + } + if err := m.AccountId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAccount(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccount + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAccount(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, ErrIntOverflowAccount + } + 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, ErrIntOverflowAccount + } + 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, ErrIntOverflowAccount + } + 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, ErrInvalidLengthAccount + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAccount + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAccount + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAccount = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAccount = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAccount = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-gmp/types/packet.pb.go b/modules/apps/27-gmp/types/packet.pb.go new file mode 100644 index 00000000000..f9c6538c03f --- /dev/null +++ b/modules/apps/27-gmp/types/packet.pb.go @@ -0,0 +1,536 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/packet.proto + +package types + +import ( + fmt "fmt" + proto "github.com/cosmos/gogoproto/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 + +// GMPPacketData defines a struct for the packet payload +type GMPPacketData struct { + // the sender address + Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"` + // the recipient address on the destination chain + Receiver string `protobuf:"bytes,2,opt,name=receiver,proto3" json:"receiver,omitempty"` + // The salt used to generate the caller account address + Salt []byte `protobuf:"bytes,3,opt,name=salt,proto3" json:"salt,omitempty"` + // The payload of the call + Payload []byte `protobuf:"bytes,4,opt,name=payload,proto3" json:"payload,omitempty"` + // optional memo + Memo string `protobuf:"bytes,5,opt,name=memo,proto3" json:"memo,omitempty"` +} + +func (m *GMPPacketData) Reset() { *m = GMPPacketData{} } +func (m *GMPPacketData) String() string { return proto.CompactTextString(m) } +func (*GMPPacketData) ProtoMessage() {} +func (*GMPPacketData) Descriptor() ([]byte, []int) { + return fileDescriptor_2a0b0887619370c4, []int{0} +} +func (m *GMPPacketData) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GMPPacketData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GMPPacketData.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 *GMPPacketData) XXX_Merge(src proto.Message) { + xxx_messageInfo_GMPPacketData.Merge(m, src) +} +func (m *GMPPacketData) XXX_Size() int { + return m.Size() +} +func (m *GMPPacketData) XXX_DiscardUnknown() { + xxx_messageInfo_GMPPacketData.DiscardUnknown(m) +} + +var xxx_messageInfo_GMPPacketData proto.InternalMessageInfo + +func (m *GMPPacketData) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *GMPPacketData) GetReceiver() string { + if m != nil { + return m.Receiver + } + return "" +} + +func (m *GMPPacketData) GetSalt() []byte { + if m != nil { + return m.Salt + } + return nil +} + +func (m *GMPPacketData) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + +func (m *GMPPacketData) GetMemo() string { + if m != nil { + return m.Memo + } + return "" +} + +func init() { + proto.RegisterType((*GMPPacketData)(nil), "ibc.applications.gmp.v1.GMPPacketData") +} + +func init() { + proto.RegisterFile("ibc/applications/gmp/v1/packet.proto", fileDescriptor_2a0b0887619370c4) +} + +var fileDescriptor_2a0b0887619370c4 = []byte{ + // 254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xb1, 0x4a, 0x04, 0x31, + 0x10, 0x86, 0x37, 0x7a, 0x9e, 0x1a, 0xb4, 0x49, 0xa1, 0xc1, 0x22, 0x1c, 0x62, 0x71, 0xcd, 0x6d, + 0x5c, 0x05, 0xed, 0x45, 0xb0, 0x12, 0x96, 0x2b, 0xed, 0x92, 0xec, 0xb0, 0x06, 0x37, 0x37, 0x61, + 0x93, 0x5b, 0xb8, 0x07, 0xb0, 0xf7, 0xb1, 0x2c, 0xaf, 0xb4, 0x94, 0xdd, 0x17, 0x91, 0x0d, 0x2a, + 0xd7, 0xfd, 0xdf, 0xcc, 0xc7, 0xc0, 0x3f, 0xf4, 0xca, 0x6a, 0x23, 0x95, 0xf7, 0x8d, 0x35, 0x2a, + 0x5a, 0x5c, 0x05, 0x59, 0x3b, 0x2f, 0xbb, 0x42, 0x7a, 0x65, 0xde, 0x20, 0xe6, 0xbe, 0xc5, 0x88, + 0xec, 0xdc, 0x6a, 0x93, 0xef, 0x5a, 0x79, 0xed, 0x7c, 0xde, 0x15, 0x97, 0xef, 0x84, 0x9e, 0x3e, + 0x3d, 0x97, 0x65, 0x92, 0x1f, 0x55, 0x54, 0xec, 0x8c, 0x4e, 0x03, 0xac, 0x2a, 0x68, 0x39, 0x99, + 0x91, 0xf9, 0xf1, 0xf2, 0x97, 0xd8, 0x05, 0x3d, 0x6a, 0xc1, 0x80, 0xed, 0xa0, 0xe5, 0x7b, 0x69, + 0xf3, 0xcf, 0x8c, 0xd1, 0x49, 0x50, 0x4d, 0xe4, 0xfb, 0x33, 0x32, 0x3f, 0x59, 0xa6, 0xcc, 0x38, + 0x3d, 0xf4, 0x6a, 0xd3, 0xa0, 0xaa, 0xf8, 0x24, 0x8d, 0xff, 0x70, 0xb4, 0x1d, 0x38, 0xe4, 0x07, + 0xe9, 0x4a, 0xca, 0x0f, 0xe5, 0x67, 0x2f, 0xc8, 0xb6, 0x17, 0xe4, 0xbb, 0x17, 0xe4, 0x63, 0x10, + 0xd9, 0x76, 0x10, 0xd9, 0xd7, 0x20, 0xb2, 0x97, 0xbb, 0xda, 0xc6, 0xd7, 0xb5, 0xce, 0x0d, 0x3a, + 0x69, 0x30, 0x38, 0x0c, 0xd2, 0x6a, 0xb3, 0xa8, 0x51, 0x76, 0xc5, 0xb5, 0x74, 0x58, 0xad, 0x1b, + 0x08, 0xe3, 0x07, 0x82, 0xbc, 0xb9, 0x5f, 0x8c, 0xe5, 0xe3, 0xc6, 0x43, 0xd0, 0xd3, 0xd4, 0xfc, + 0xf6, 0x27, 0x00, 0x00, 0xff, 0xff, 0x92, 0x87, 0x05, 0xc8, 0x21, 0x01, 0x00, 0x00, +} + +func (m *GMPPacketData) 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 *GMPPacketData) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GMPPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Memo))) + i-- + dAtA[i] = 0x2a + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x22 + } + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x1a + } + if len(m.Receiver) > 0 { + i -= len(m.Receiver) + copy(dAtA[i:], m.Receiver) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Receiver))) + i-- + dAtA[i] = 0x12 + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintPacket(dAtA []byte, offset int, v uint64) int { + offset -= sovPacket(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GMPPacketData) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Receiver) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + l = len(m.Memo) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + return n +} + +func sovPacket(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozPacket(x uint64) (n int) { + return sovPacket(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GMPPacketData) 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 ErrIntOverflowPacket + } + 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: GMPPacketData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GMPPacketData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + 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 ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Receiver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + 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 ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Receiver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = append(m.Salt[:0], dAtA[iNdEx:postIndex]...) + if m.Salt == nil { + m.Salt = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + 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 ErrInvalidLengthPacket + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Memo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPacket(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPacket + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPacket(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, ErrIntOverflowPacket + } + 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, ErrIntOverflowPacket + } + 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, ErrIntOverflowPacket + } + 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, ErrInvalidLengthPacket + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPacket + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthPacket + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthPacket = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPacket = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPacket = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-gmp/types/tx.pb.go b/modules/apps/27-gmp/types/tx.pb.go new file mode 100644 index 00000000000..63af1d98ca5 --- /dev/null +++ b/modules/apps/27-gmp/types/tx.pb.go @@ -0,0 +1,867 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 + +// MsgSendCall defines a msg to send a call to a contract/receiver on a ICS27-2 enabled chain. +type MsgSendCall struct { + // the client by which the packet will be sent + SourceClient string `protobuf:"bytes,1,opt,name=source_client,json=sourceClient,proto3" json:"source_client,omitempty"` + // the sender address + Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` + // the recipient address on the destination chain + Receiver string `protobuf:"bytes,3,opt,name=receiver,proto3" json:"receiver,omitempty"` + // The salt used to generate the caller account address + Salt []byte `protobuf:"bytes,4,opt,name=salt,proto3" json:"salt,omitempty"` + // The payload of the call + Payload []byte `protobuf:"bytes,5,opt,name=payload,proto3" json:"payload,omitempty"` + // Timeout timestamp in absolute nanoseconds since unix epoch. + TimeoutTimestamp uint64 `protobuf:"varint,6,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty"` + // optional memo + Memo string `protobuf:"bytes,7,opt,name=memo,proto3" json:"memo,omitempty"` + // optional encoding + Encoding string `protobuf:"bytes,8,opt,name=encoding,proto3" json:"encoding,omitempty"` +} + +func (m *MsgSendCall) Reset() { *m = MsgSendCall{} } +func (m *MsgSendCall) String() string { return proto.CompactTextString(m) } +func (*MsgSendCall) ProtoMessage() {} +func (*MsgSendCall) Descriptor() ([]byte, []int) { + return fileDescriptor_32bfd6a386d18ce5, []int{0} +} +func (m *MsgSendCall) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendCall) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendCall.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 *MsgSendCall) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendCall.Merge(m, src) +} +func (m *MsgSendCall) XXX_Size() int { + return m.Size() +} +func (m *MsgSendCall) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendCall.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendCall proto.InternalMessageInfo + +// MsgSendCallResponse defines the Msg/SendCall response type. +type MsgSendCallResponse struct { + // sequence number of the GMP packet sent + Sequence uint64 `protobuf:"varint,1,opt,name=sequence,proto3" json:"sequence,omitempty"` +} + +func (m *MsgSendCallResponse) Reset() { *m = MsgSendCallResponse{} } +func (m *MsgSendCallResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSendCallResponse) ProtoMessage() {} +func (*MsgSendCallResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_32bfd6a386d18ce5, []int{1} +} +func (m *MsgSendCallResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSendCallResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSendCallResponse.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 *MsgSendCallResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSendCallResponse.Merge(m, src) +} +func (m *MsgSendCallResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSendCallResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSendCallResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSendCallResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgSendCall)(nil), "ibc.applications.gmp.v1.MsgSendCall") + proto.RegisterType((*MsgSendCallResponse)(nil), "ibc.applications.gmp.v1.MsgSendCallResponse") +} + +func init() { proto.RegisterFile("ibc/applications/gmp/v1/tx.proto", fileDescriptor_32bfd6a386d18ce5) } + +var fileDescriptor_32bfd6a386d18ce5 = []byte{ + // 422 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xb1, 0x6e, 0x14, 0x31, + 0x10, 0xbd, 0x4d, 0x36, 0x97, 0xc3, 0x04, 0x01, 0x06, 0x11, 0x6b, 0x8b, 0xe5, 0x14, 0x28, 0x4e, + 0x81, 0xac, 0xb9, 0x20, 0x11, 0x29, 0x25, 0xa9, 0x23, 0xa1, 0x85, 0x8a, 0x82, 0x68, 0xd7, 0x3b, + 0x32, 0x96, 0xd6, 0x6b, 0xb3, 0xe3, 0x3d, 0x91, 0x0e, 0xa5, 0xa2, 0xe4, 0x13, 0xf8, 0x84, 0x7c, + 0x06, 0x65, 0x4a, 0x4a, 0x74, 0x57, 0xe4, 0x37, 0x90, 0x7d, 0xb7, 0xa7, 0x6b, 0x90, 0xa8, 0x3c, + 0x6f, 0xde, 0xd3, 0xf3, 0xd3, 0xcc, 0x90, 0xb1, 0x2a, 0x05, 0x2f, 0xac, 0xad, 0x95, 0x28, 0x9c, + 0x32, 0x0d, 0x72, 0xa9, 0x2d, 0x9f, 0x4d, 0xb9, 0xfb, 0x9a, 0xd9, 0xd6, 0x38, 0x43, 0xf7, 0x55, + 0x29, 0xb2, 0x4d, 0x45, 0x26, 0xb5, 0xcd, 0x66, 0xd3, 0xe4, 0xb1, 0x34, 0xd2, 0x04, 0x0d, 0xf7, + 0xd5, 0x52, 0x9e, 0xec, 0x0b, 0x83, 0xda, 0x20, 0xd7, 0x28, 0xbd, 0x8d, 0x46, 0xb9, 0x24, 0x0e, + 0xae, 0xb6, 0xc8, 0xdd, 0x73, 0x94, 0xef, 0xa1, 0xa9, 0xce, 0x8a, 0xba, 0xa6, 0xcf, 0xc8, 0x3d, + 0x34, 0x5d, 0x2b, 0xe0, 0x42, 0xd4, 0x0a, 0x1a, 0xc7, 0xa2, 0x71, 0x34, 0xb9, 0x93, 0xef, 0x2d, + 0x9b, 0x67, 0xa1, 0x47, 0x9f, 0x90, 0x21, 0x42, 0x53, 0x41, 0xcb, 0xb6, 0x02, 0xbb, 0x42, 0x34, + 0x21, 0xa3, 0x16, 0x04, 0xa8, 0x19, 0xb4, 0x6c, 0x3b, 0x30, 0x6b, 0x4c, 0x29, 0x89, 0xb1, 0xa8, + 0x1d, 0x8b, 0xc7, 0xd1, 0x64, 0x2f, 0x0f, 0x35, 0x65, 0x64, 0xd7, 0x16, 0x97, 0xb5, 0x29, 0x2a, + 0xb6, 0x13, 0xda, 0x3d, 0xa4, 0x2f, 0xc8, 0x43, 0xa7, 0x34, 0x98, 0xce, 0x5d, 0xf8, 0x17, 0x5d, + 0xa1, 0x2d, 0x1b, 0x8e, 0xa3, 0x49, 0x9c, 0x3f, 0x58, 0x11, 0x1f, 0xfa, 0xbe, 0xb7, 0xd6, 0xa0, + 0x0d, 0xdb, 0x0d, 0x5f, 0x86, 0xda, 0x47, 0x81, 0x46, 0x98, 0x4a, 0x35, 0x92, 0x8d, 0x96, 0x51, + 0x7a, 0x7c, 0x7a, 0xff, 0xfb, 0xcf, 0xa7, 0x83, 0xab, 0xdb, 0xeb, 0xc3, 0x55, 0xee, 0x83, 0x13, + 0xf2, 0x68, 0x63, 0x06, 0x39, 0xa0, 0x35, 0x0d, 0x82, 0xf7, 0x40, 0xf8, 0xd2, 0x41, 0x23, 0x20, + 0x8c, 0x21, 0xce, 0xd7, 0xf8, 0x34, 0xf6, 0x1e, 0xc7, 0x35, 0xd9, 0x3e, 0x47, 0x49, 0x3f, 0x91, + 0xd1, 0x7a, 0x80, 0xcf, 0xb3, 0x7f, 0x6c, 0x26, 0xdb, 0xf8, 0x22, 0x79, 0xf9, 0x3f, 0xaa, 0x3e, + 0x48, 0xb2, 0xf3, 0xed, 0xf6, 0xfa, 0x30, 0x7a, 0xfb, 0xee, 0xd7, 0x3c, 0x8d, 0x6e, 0xe6, 0x69, + 0xf4, 0x67, 0x9e, 0x46, 0x3f, 0x16, 0xe9, 0xe0, 0x66, 0x91, 0x0e, 0x7e, 0x2f, 0xd2, 0xc1, 0xc7, + 0x37, 0x52, 0xb9, 0xcf, 0x5d, 0x99, 0x09, 0xa3, 0xf9, 0x6a, 0xd3, 0xaa, 0x14, 0x47, 0xd2, 0xf0, + 0xd9, 0xf4, 0x15, 0xd7, 0xa6, 0xea, 0x6a, 0x40, 0x7f, 0x50, 0xc8, 0x8f, 0x4f, 0x8e, 0xfc, 0x2d, + 0xb9, 0x4b, 0x0b, 0x58, 0x0e, 0xc3, 0x11, 0xbc, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x54, 0x14, + 0xab, 0xb4, 0x70, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // SendCall defines a rpc handler method for MsgSendCall. + SendCall(ctx context.Context, in *MsgSendCall, opts ...grpc.CallOption) (*MsgSendCallResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) SendCall(ctx context.Context, in *MsgSendCall, opts ...grpc.CallOption) (*MsgSendCallResponse, error) { + out := new(MsgSendCallResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.gmp.v1.Msg/SendCall", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // SendCall defines a rpc handler method for MsgSendCall. + SendCall(context.Context, *MsgSendCall) (*MsgSendCallResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) SendCall(ctx context.Context, req *MsgSendCall) (*MsgSendCallResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendCall not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_SendCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSendCall) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SendCall(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.gmp.v1.Msg/SendCall", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SendCall(ctx, req.(*MsgSendCall)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.applications.gmp.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "SendCall", + Handler: _Msg_SendCall_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/applications/gmp/v1/tx.proto", +} + +func (m *MsgSendCall) 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 *MsgSendCall) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendCall) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Encoding) > 0 { + i -= len(m.Encoding) + copy(dAtA[i:], m.Encoding) + i = encodeVarintTx(dAtA, i, uint64(len(m.Encoding))) + i-- + dAtA[i] = 0x42 + } + if len(m.Memo) > 0 { + i -= len(m.Memo) + copy(dAtA[i:], m.Memo) + i = encodeVarintTx(dAtA, i, uint64(len(m.Memo))) + i-- + dAtA[i] = 0x3a + } + if m.TimeoutTimestamp != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.TimeoutTimestamp)) + i-- + dAtA[i] = 0x30 + } + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintTx(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0x2a + } + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintTx(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x22 + } + if len(m.Receiver) > 0 { + i -= len(m.Receiver) + copy(dAtA[i:], m.Receiver) + i = encodeVarintTx(dAtA, i, uint64(len(m.Receiver))) + i-- + dAtA[i] = 0x1a + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0x12 + } + if len(m.SourceClient) > 0 { + i -= len(m.SourceClient) + copy(dAtA[i:], m.SourceClient) + i = encodeVarintTx(dAtA, i, uint64(len(m.SourceClient))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgSendCallResponse) 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 *MsgSendCallResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSendCallResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Sequence != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Sequence)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgSendCall) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SourceClient) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Receiver) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.TimeoutTimestamp != 0 { + n += 1 + sovTx(uint64(m.TimeoutTimestamp)) + } + l = len(m.Memo) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Encoding) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgSendCallResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sequence != 0 { + n += 1 + sovTx(uint64(m.Sequence)) + } + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgSendCall) 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 ErrIntOverflowTx + } + 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: MsgSendCall: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendCall: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceClient", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourceClient = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Receiver", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Receiver = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = append(m.Salt[:0], dAtA[iNdEx:postIndex]...) + if m.Salt == nil { + m.Salt = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType) + } + m.TimeoutTimestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TimeoutTimestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memo", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Memo = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Encoding", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Encoding = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSendCallResponse) 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 ErrIntOverflowTx + } + 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: MsgSendCallResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSendCallResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + m.Sequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) From 2b29b85675483f6cdf869cd5f6d602d4301d722b Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 2 May 2025 12:46:59 +0400 Subject: [PATCH 04/46] imp: added type helpers --- modules/apps/27-gmp/types/codec.go | 24 +++++++++ modules/apps/27-gmp/types/errors.go | 12 +++++ modules/apps/27-gmp/types/keys.go | 21 ++++++++ modules/apps/27-gmp/types/msgs.go | 76 +++++++++++++++++++++++++++++ modules/apps/27-gmp/types/packet.go | 7 +++ 5 files changed, 140 insertions(+) create mode 100644 modules/apps/27-gmp/types/codec.go create mode 100644 modules/apps/27-gmp/types/errors.go create mode 100644 modules/apps/27-gmp/types/keys.go create mode 100644 modules/apps/27-gmp/types/msgs.go create mode 100644 modules/apps/27-gmp/types/packet.go diff --git a/modules/apps/27-gmp/types/codec.go b/modules/apps/27-gmp/types/codec.go new file mode 100644 index 00000000000..0706cae43da --- /dev/null +++ b/modules/apps/27-gmp/types/codec.go @@ -0,0 +1,24 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// ModuleCdc references the global gmp module codec. Note, the codec +// should ONLY be used in certain instances of tests and for JSON encoding. +// +// The actual codec used for serialization should be provided to interchain accounts and +// defined at the application level. +var ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) + +// RegisterInterfaces registers the gmp types and the concrete ICS27Account implementation +// against the associated x/auth AccountI and GenesisAccount interfaces. +func RegisterInterfaces(registry codectypes.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.AccountI)(nil), &ICS27Account{}) + registry.RegisterImplementations((*authtypes.GenesisAccount)(nil), &ICS27Account{}) + + registry.RegisterImplementations((*sdk.Msg)(nil), &MsgSendCall{}) +} diff --git a/modules/apps/27-gmp/types/errors.go b/modules/apps/27-gmp/types/errors.go new file mode 100644 index 00000000000..d4018f56033 --- /dev/null +++ b/modules/apps/27-gmp/types/errors.go @@ -0,0 +1,12 @@ +package types + +import errorsmod "cosmossdk.io/errors" + +var ( + ErrInvalidCodec = errorsmod.Register(ModuleName, 1, "codec is not supported") + ErrInvalidMemo = errorsmod.Register(ModuleName, 2, "invalid memo") + ErrInvalidSalt = errorsmod.Register(ModuleName, 3, "invalid salt") + ErrInvalidPayload = errorsmod.Register(ModuleName, 4, "invalid payload") + ErrInvalidTimeoutTimestamp = errorsmod.Register(ModuleName, 5, "invalid timeout timestamp") + ErrInvalidEncoding = errorsmod.Register(ModuleName, 6, "invalid encoding") +) diff --git a/modules/apps/27-gmp/types/keys.go b/modules/apps/27-gmp/types/keys.go new file mode 100644 index 00000000000..5198100358a --- /dev/null +++ b/modules/apps/27-gmp/types/keys.go @@ -0,0 +1,21 @@ +package types + +const ( + // ModuleName defines the interchain accounts module name + ModuleName = "gmp" + + // PortID is the default IBC port id that the gmp module + PortID = "gmpport" + + // Version defines the current version for gmp + Version = "ics27-2" + + // RouterKey is the message route for gmp + RouterKey = ModuleName + + // QuerierRoute is the querier route for gmp + QuerierRoute = ModuleName + + // accountsKey is the key used when generating a module address for the gmp module + accountsKey = "gmp-accounts" +) diff --git a/modules/apps/27-gmp/types/msgs.go b/modules/apps/27-gmp/types/msgs.go new file mode 100644 index 00000000000..0b5c9d56ffe --- /dev/null +++ b/modules/apps/27-gmp/types/msgs.go @@ -0,0 +1,76 @@ +package types + +import ( + "strings" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + host "github.com/cosmos/ibc-go/v10/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +const ( + MaximumReceiverLength = 2048 // maximum length of the receiver address in bytes (value chosen arbitrarily) + MaximumMemoLength = 32768 // maximum length of the memo in bytes (value chosen arbitrarily) + MaximumSaltLength = 32 // maximum length of the salt in bytes (value chosen arbitrarily) + MaximumPayloadLength = 32768 // maximum length of the payload in bytes (value chosen arbitrarily) +) + +var ( + _ sdk.Msg = (*MsgSendCall)(nil) + _ sdk.HasValidateBasic = (*MsgSendCall)(nil) +) + +// ValidateBasic performs a basic check of the MsgSendCall fields. +// NOTE: The recipient addresses format is not validated as the format defined by +// the chain is not known to IBC. +func (msg MsgSendCall) ValidateBasic() error { + if err := msg.validateIdentifiers(); err != nil { + return err + } + + if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + if strings.TrimSpace(msg.Receiver) == "" { + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing recipient address") + } + if len(msg.Receiver) > MaximumReceiverLength { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "recipient address must not exceed %d bytes", MaximumReceiverLength) + } + if len(msg.Payload) > MaximumPayloadLength { + return errorsmod.Wrapf(ErrInvalidPayload, "payload must not exceed %d bytes", MaximumPayloadLength) + } + if len(msg.Memo) > MaximumMemoLength { + return errorsmod.Wrapf(ErrInvalidMemo, "memo must not exceed %d bytes", MaximumMemoLength) + } + if msg.TimeoutTimestamp == 0 { + return errorsmod.Wrap(ErrInvalidTimeoutTimestamp, "timeout timestamp must be greater than 0") + } + if err := validateEncoding(msg.Encoding); err != nil { + return err + } + + return nil +} + +// validateIdentifiers checks if the IBC identifiers are valid +func (msg MsgSendCall) validateIdentifiers() error { + if err := host.ClientIdentifierValidator(msg.SourceClient); err != nil { + return errorsmod.Wrapf(err, "invalid source client ID %s", msg.SourceClient) + } + + return nil +} + +// validateEncoding checks if the encoding is valid +func validateEncoding(encoding string) error { + switch encoding { + case "", EncodingProtobuf, EncodingJSON, EncodingABI: + return nil + default: + return errorsmod.Wrapf(ErrInvalidEncoding, "unsupported encoding format %s", encoding) + } +} diff --git a/modules/apps/27-gmp/types/packet.go b/modules/apps/27-gmp/types/packet.go new file mode 100644 index 00000000000..b192f0c6e80 --- /dev/null +++ b/modules/apps/27-gmp/types/packet.go @@ -0,0 +1,7 @@ +package types + +const ( + EncodingJSON = "application/json" + EncodingProtobuf = "application/x-protobuf" + EncodingABI = "application/x-solidity-abi" +) From 5b198c7c32c7697267689cb18c76b5ff83f5a184 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 2 May 2025 12:55:34 +0400 Subject: [PATCH 05/46] imp: added new proto --- proto/ibc/applications/gmp/v1/genesis.proto | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 proto/ibc/applications/gmp/v1/genesis.proto diff --git a/proto/ibc/applications/gmp/v1/genesis.proto b/proto/ibc/applications/gmp/v1/genesis.proto new file mode 100644 index 00000000000..8a0e2d04601 --- /dev/null +++ b/proto/ibc/applications/gmp/v1/genesis.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +import "ibc/applications/gmp/v1/account.proto"; +import "gogoproto/gogo.proto"; + +// GenesisState defines the 27-gmp genesis state +message GenesisState { + // The list of registered ICS27 accounts + repeated RegisteredICS27Account ics27_accounts = 2 [(gogoproto.nullable) = false]; +} + +// RegisteredICS27Account contains an account identifier and associated interchain account address +message RegisteredICS27Account { + /// The address of the ics27 account + string account_address = 1; + /// The account identifier + AccountIdentifier account_id = 2 [(gogoproto.nullable) = false]; +} From c7289d586d9b44b7d6795e1a3ed5210e8b03fadc Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 2 May 2025 16:21:14 +0400 Subject: [PATCH 06/46] imp: added query.proto --- proto/ibc/applications/gmp/v1/query.proto | 32 +++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 proto/ibc/applications/gmp/v1/query.proto diff --git a/proto/ibc/applications/gmp/v1/query.proto b/proto/ibc/applications/gmp/v1/query.proto new file mode 100644 index 00000000000..3532e8ecaad --- /dev/null +++ b/proto/ibc/applications/gmp/v1/query.proto @@ -0,0 +1,32 @@ +syntax = "proto3"; + +package ibc.applications.gmp.v1; + +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; + +// Query provides defines the gRPC querier service. +service Query { + // AccountAddress queries the interchain account address for a given client_id, sender, and salt. + // If the account is not registered, the address is computed deterministically + rpc AccountAddress(QueryAccountAddressRequest) returns (QueryAccountAddressResponse) { + option (google.api.http).get = "/ibc/apps/gmp/v1/clients/{client_id}/accounts/{sender}/{salt=**}"; + } +} + +// QueryAccountAddressRequest is the request type for the Query/AccountAddress RPC method. +message QueryAccountAddressRequest { + // The (local) client identifier + string client_id = 1; + // The sender of the packet + string sender = 2; + // The salt of the packet (in hex format) + string salt = 3; +} + +// QueryAccountAddressResponse is the response type for the Query/AccountAddress RPC method. +message QueryAccountAddressResponse { + // The interchain account address + string account_address = 1; +} From 83be76379384ab636b1ff73a592c82e114a26b1b Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 2 May 2025 16:25:12 +0400 Subject: [PATCH 07/46] chore: gen proto types --- modules/apps/27-gmp/types/genesis.pb.go | 566 ++++++++++++++++++ modules/apps/27-gmp/types/query.pb.go | 697 +++++++++++++++++++++++ modules/apps/27-gmp/types/query.pb.gw.go | 233 ++++++++ 3 files changed, 1496 insertions(+) create mode 100644 modules/apps/27-gmp/types/genesis.pb.go create mode 100644 modules/apps/27-gmp/types/query.pb.go create mode 100644 modules/apps/27-gmp/types/query.pb.gw.go diff --git a/modules/apps/27-gmp/types/genesis.pb.go b/modules/apps/27-gmp/types/genesis.pb.go new file mode 100644 index 00000000000..0fd1913b2ee --- /dev/null +++ b/modules/apps/27-gmp/types/genesis.pb.go @@ -0,0 +1,566 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/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 + +// GenesisState defines the 27-gmp genesis state +type GenesisState struct { + // The list of registered ICS27 accounts + Ics27Accounts []RegisteredICS27Account `protobuf:"bytes,2,rep,name=ics27_accounts,json=ics27Accounts,proto3" json:"ics27_accounts"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_7cccbdb788964d3f, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetIcs27Accounts() []RegisteredICS27Account { + if m != nil { + return m.Ics27Accounts + } + return nil +} + +// RegisteredICS27Account contains an account identifier and associated interchain account address +type RegisteredICS27Account struct { + /// The address of the ics27 account + AccountAddress string `protobuf:"bytes,1,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` + /// The account identifier + AccountId AccountIdentifier `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id"` +} + +func (m *RegisteredICS27Account) Reset() { *m = RegisteredICS27Account{} } +func (m *RegisteredICS27Account) String() string { return proto.CompactTextString(m) } +func (*RegisteredICS27Account) ProtoMessage() {} +func (*RegisteredICS27Account) Descriptor() ([]byte, []int) { + return fileDescriptor_7cccbdb788964d3f, []int{1} +} +func (m *RegisteredICS27Account) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RegisteredICS27Account) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RegisteredICS27Account.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 *RegisteredICS27Account) XXX_Merge(src proto.Message) { + xxx_messageInfo_RegisteredICS27Account.Merge(m, src) +} +func (m *RegisteredICS27Account) XXX_Size() int { + return m.Size() +} +func (m *RegisteredICS27Account) XXX_DiscardUnknown() { + xxx_messageInfo_RegisteredICS27Account.DiscardUnknown(m) +} + +var xxx_messageInfo_RegisteredICS27Account proto.InternalMessageInfo + +func (m *RegisteredICS27Account) GetAccountAddress() string { + if m != nil { + return m.AccountAddress + } + return "" +} + +func (m *RegisteredICS27Account) GetAccountId() AccountIdentifier { + if m != nil { + return m.AccountId + } + return AccountIdentifier{} +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "ibc.applications.gmp.v1.GenesisState") + proto.RegisterType((*RegisteredICS27Account)(nil), "ibc.applications.gmp.v1.RegisteredICS27Account") +} + +func init() { + proto.RegisterFile("ibc/applications/gmp/v1/genesis.proto", fileDescriptor_7cccbdb788964d3f) +} + +var fileDescriptor_7cccbdb788964d3f = []byte{ + // 320 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0x41, 0x4b, 0x3a, 0x41, + 0x18, 0xc6, 0x77, 0xfc, 0xff, 0x09, 0x1c, 0xcb, 0x60, 0x89, 0x12, 0x0f, 0x9b, 0x08, 0x91, 0x04, + 0xce, 0xe4, 0x06, 0x79, 0xd6, 0x0e, 0xe1, 0xa9, 0xd0, 0x5b, 0x04, 0xb2, 0x3b, 0x3b, 0x4d, 0x2f, + 0xb8, 0x3b, 0xc3, 0xbe, 0xa3, 0xd0, 0xb7, 0x88, 0x3e, 0x95, 0x47, 0x8f, 0x9d, 0x22, 0xf4, 0x8b, + 0x84, 0xee, 0x08, 0x1d, 0xda, 0xdb, 0xcb, 0xf3, 0x3e, 0xbf, 0xf7, 0x79, 0x79, 0xe8, 0x05, 0xc4, + 0x82, 0x47, 0xc6, 0xcc, 0x40, 0x44, 0x16, 0x74, 0x86, 0x5c, 0xa5, 0x86, 0x2f, 0x7a, 0x5c, 0xc9, + 0x4c, 0x22, 0x20, 0x33, 0xb9, 0xb6, 0xda, 0x3f, 0x83, 0x58, 0xb0, 0xdf, 0x36, 0xa6, 0x52, 0xc3, + 0x16, 0xbd, 0x66, 0x29, 0x1f, 0x09, 0xa1, 0xe7, 0x99, 0x2d, 0xf8, 0xe6, 0x89, 0xd2, 0x4a, 0xef, + 0x46, 0xbe, 0x9d, 0x0a, 0xb5, 0x3d, 0xa3, 0x87, 0xf7, 0x45, 0xcc, 0xc4, 0x46, 0x56, 0xfa, 0xcf, + 0xb4, 0x0e, 0x02, 0xc3, 0xfe, 0xd4, 0xc1, 0xd8, 0xa8, 0xb4, 0xfe, 0x75, 0x6a, 0x21, 0x67, 0x25, + 0xf1, 0x6c, 0x2c, 0x15, 0xa0, 0x95, 0xb9, 0x4c, 0x46, 0x77, 0x93, 0xb0, 0x3f, 0x28, 0xb8, 0xe1, + 0xff, 0xe5, 0xd7, 0xb9, 0x37, 0x3e, 0xda, 0x1d, 0x73, 0x1a, 0xb6, 0x3f, 0x08, 0x3d, 0xfd, 0xdb, + 0xef, 0x5f, 0xd2, 0x63, 0x17, 0x39, 0x8d, 0x92, 0x24, 0x97, 0x88, 0x0d, 0xd2, 0x22, 0x9d, 0xea, + 0xb8, 0xee, 0xe4, 0x41, 0xa1, 0xfa, 0x0f, 0x94, 0xee, 0x8d, 0x90, 0x34, 0x2a, 0x2d, 0xd2, 0xa9, + 0x85, 0x57, 0xa5, 0xdf, 0xb9, 0xf3, 0xa3, 0x44, 0x66, 0x16, 0x5e, 0x40, 0xe6, 0xee, 0xb1, 0x6a, + 0xb4, 0x5f, 0x0c, 0x1f, 0x97, 0xeb, 0x80, 0xac, 0xd6, 0x01, 0xf9, 0x5e, 0x07, 0xe4, 0x7d, 0x13, + 0x78, 0xab, 0x4d, 0xe0, 0x7d, 0x6e, 0x02, 0xef, 0xe9, 0x56, 0x81, 0x7d, 0x9d, 0xc7, 0x4c, 0xe8, + 0x94, 0x0b, 0x8d, 0xa9, 0x46, 0x0e, 0xb1, 0xe8, 0x2a, 0xcd, 0x17, 0xbd, 0x6b, 0x9e, 0xea, 0x64, + 0x3e, 0x93, 0xb8, 0xad, 0x1e, 0x79, 0xd8, 0xef, 0x6e, 0x5b, 0xb7, 0x6f, 0x46, 0x62, 0x7c, 0xb0, + 0xeb, 0xf6, 0xe6, 0x27, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x8a, 0x64, 0xe8, 0xda, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ics27Accounts) > 0 { + for iNdEx := len(m.Ics27Accounts) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Ics27Accounts[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + return len(dAtA) - i, nil +} + +func (m *RegisteredICS27Account) 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 *RegisteredICS27Account) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RegisteredICS27Account) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.AccountId.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.AccountAddress) > 0 { + i -= len(m.AccountAddress) + copy(dAtA[i:], m.AccountAddress) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.AccountAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ics27Accounts) > 0 { + for _, e := range m.Ics27Accounts { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *RegisteredICS27Account) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AccountAddress) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = m.AccountId.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis + } + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ics27Accounts", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Ics27Accounts = append(m.Ics27Accounts, RegisteredICS27Account{}) + if err := m.Ics27Accounts[len(m.Ics27Accounts)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RegisteredICS27Account) 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 ErrIntOverflowGenesis + } + 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: RegisteredICS27Account: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RegisteredICS27Account: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + 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 ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccountAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountId", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.AccountId.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-gmp/types/query.pb.go b/modules/apps/27-gmp/types/query.pb.go new file mode 100644 index 00000000000..97809332d9d --- /dev/null +++ b/modules/apps/27-gmp/types/query.pb.go @@ -0,0 +1,697 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/gmp/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 + +// QueryAccountAddressRequest is the request type for the Query/AccountAddress RPC method. +type QueryAccountAddressRequest struct { + // The (local) client identifier + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // The sender of the packet + Sender string `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"` + // The salt of the packet (in hex format) + Salt string `protobuf:"bytes,3,opt,name=salt,proto3" json:"salt,omitempty"` +} + +func (m *QueryAccountAddressRequest) Reset() { *m = QueryAccountAddressRequest{} } +func (m *QueryAccountAddressRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAccountAddressRequest) ProtoMessage() {} +func (*QueryAccountAddressRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_0d55aa1ab285a918, []int{0} +} +func (m *QueryAccountAddressRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAccountAddressRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAccountAddressRequest.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 *QueryAccountAddressRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAccountAddressRequest.Merge(m, src) +} +func (m *QueryAccountAddressRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAccountAddressRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAccountAddressRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAccountAddressRequest proto.InternalMessageInfo + +func (m *QueryAccountAddressRequest) GetClientId() string { + if m != nil { + return m.ClientId + } + return "" +} + +func (m *QueryAccountAddressRequest) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +func (m *QueryAccountAddressRequest) GetSalt() string { + if m != nil { + return m.Salt + } + return "" +} + +// QueryAccountAddressResponse is the response type for the Query/AccountAddress RPC method. +type QueryAccountAddressResponse struct { + // The interchain account address + AccountAddress string `protobuf:"bytes,1,opt,name=account_address,json=accountAddress,proto3" json:"account_address,omitempty"` +} + +func (m *QueryAccountAddressResponse) Reset() { *m = QueryAccountAddressResponse{} } +func (m *QueryAccountAddressResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAccountAddressResponse) ProtoMessage() {} +func (*QueryAccountAddressResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_0d55aa1ab285a918, []int{1} +} +func (m *QueryAccountAddressResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAccountAddressResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAccountAddressResponse.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 *QueryAccountAddressResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAccountAddressResponse.Merge(m, src) +} +func (m *QueryAccountAddressResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAccountAddressResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAccountAddressResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAccountAddressResponse proto.InternalMessageInfo + +func (m *QueryAccountAddressResponse) GetAccountAddress() string { + if m != nil { + return m.AccountAddress + } + return "" +} + +func init() { + proto.RegisterType((*QueryAccountAddressRequest)(nil), "ibc.applications.gmp.v1.QueryAccountAddressRequest") + proto.RegisterType((*QueryAccountAddressResponse)(nil), "ibc.applications.gmp.v1.QueryAccountAddressResponse") +} + +func init() { + proto.RegisterFile("ibc/applications/gmp/v1/query.proto", fileDescriptor_0d55aa1ab285a918) +} + +var fileDescriptor_0d55aa1ab285a918 = []byte{ + // 358 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x51, 0x41, 0x4b, 0x3a, 0x41, + 0x1c, 0x75, 0xfd, 0xff, 0x93, 0x9c, 0x83, 0xc1, 0x1c, 0x4a, 0x34, 0x96, 0xb0, 0x43, 0x21, 0xb8, + 0x93, 0x1a, 0x75, 0x0a, 0xd2, 0x43, 0xd4, 0xad, 0x3c, 0x76, 0x91, 0xd9, 0xd9, 0x61, 0x1b, 0xd8, + 0xdd, 0x19, 0xf7, 0x37, 0x2b, 0x88, 0x78, 0xe9, 0x13, 0x04, 0x7d, 0xa6, 0xa0, 0x5b, 0x42, 0x97, + 0x8e, 0xa1, 0x7d, 0x90, 0xd8, 0x9d, 0x45, 0x12, 0xf2, 0xd0, 0x6d, 0xe6, 0xf7, 0xe6, 0xbd, 0x37, + 0xbf, 0xf7, 0xd0, 0xa1, 0x70, 0x19, 0xa1, 0x4a, 0x05, 0x82, 0x51, 0x2d, 0x64, 0x04, 0xc4, 0x0f, + 0x15, 0x19, 0xb7, 0xc9, 0x28, 0xe1, 0xf1, 0xc4, 0x51, 0xb1, 0xd4, 0x12, 0xef, 0x09, 0x97, 0x39, + 0x3f, 0x1f, 0x39, 0x7e, 0xa8, 0x9c, 0x71, 0xbb, 0xb6, 0xef, 0x4b, 0xe9, 0x07, 0x9c, 0x50, 0x25, + 0x08, 0x8d, 0x22, 0xa9, 0x73, 0x38, 0xa3, 0x35, 0x38, 0xaa, 0xdd, 0xa5, 0x2a, 0x3d, 0xc6, 0x64, + 0x12, 0xe9, 0x9e, 0xe7, 0xc5, 0x1c, 0x60, 0xc0, 0x47, 0x09, 0x07, 0x8d, 0xeb, 0xa8, 0xcc, 0x02, + 0xc1, 0x23, 0x3d, 0x14, 0x5e, 0xd5, 0x3a, 0xb0, 0x8e, 0xcb, 0x83, 0x6d, 0x33, 0xb8, 0xf1, 0xf0, + 0x2e, 0x2a, 0x01, 0x8f, 0x3c, 0x1e, 0x57, 0x8b, 0x19, 0x92, 0xdf, 0x30, 0x46, 0xff, 0x81, 0x06, + 0xba, 0xfa, 0x2f, 0x9b, 0x66, 0xe7, 0xc6, 0x15, 0xaa, 0xff, 0x6a, 0x03, 0x4a, 0x46, 0xc0, 0xf1, + 0x11, 0xda, 0xa1, 0x06, 0x19, 0x52, 0x03, 0xe5, 0x6e, 0x15, 0xba, 0x46, 0xe8, 0xbc, 0x59, 0x68, + 0x2b, 0x13, 0xc2, 0x2f, 0x16, 0xaa, 0xac, 0xab, 0xe1, 0xae, 0xb3, 0x21, 0x03, 0x67, 0xf3, 0x8a, + 0xb5, 0xd3, 0xbf, 0x91, 0xcc, 0x87, 0x1b, 0xd7, 0x8f, 0xef, 0x5f, 0xcf, 0xc5, 0x3e, 0xbe, 0x24, + 0x79, 0x37, 0xab, 0x4e, 0x4c, 0x3c, 0x40, 0xa6, 0xab, 0xe0, 0x66, 0x24, 0x5f, 0x02, 0xc8, 0xd4, + 0x44, 0x34, 0x23, 0xd3, 0x34, 0x95, 0x8b, 0x66, 0x73, 0xd6, 0xbf, 0x7d, 0x5d, 0xd8, 0xd6, 0x7c, + 0x61, 0x5b, 0x9f, 0x0b, 0xdb, 0x7a, 0x5a, 0xda, 0x85, 0xf9, 0xd2, 0x2e, 0x7c, 0x2c, 0xed, 0xc2, + 0xfd, 0x99, 0x2f, 0xf4, 0x43, 0xe2, 0x3a, 0x4c, 0x86, 0x84, 0x49, 0x08, 0x25, 0xa4, 0x66, 0x2d, + 0x5f, 0x92, 0x71, 0xfb, 0x84, 0x84, 0xd2, 0x4b, 0x02, 0x0e, 0xc6, 0xbb, 0x73, 0xde, 0x4a, 0xed, + 0xf5, 0x44, 0x71, 0x70, 0x4b, 0x59, 0xb3, 0xdd, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x08, 0xbf, + 0x5a, 0x74, 0x37, 0x02, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // AccountAddress queries the interchain account address for a given client_id, sender, and salt. + // If the account is not registered, the address is computed deterministically + AccountAddress(ctx context.Context, in *QueryAccountAddressRequest, opts ...grpc.CallOption) (*QueryAccountAddressResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) AccountAddress(ctx context.Context, in *QueryAccountAddressRequest, opts ...grpc.CallOption) (*QueryAccountAddressResponse, error) { + out := new(QueryAccountAddressResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.gmp.v1.Query/AccountAddress", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // AccountAddress queries the interchain account address for a given client_id, sender, and salt. + // If the account is not registered, the address is computed deterministically + AccountAddress(context.Context, *QueryAccountAddressRequest) (*QueryAccountAddressResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) AccountAddress(ctx context.Context, req *QueryAccountAddressRequest) (*QueryAccountAddressResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AccountAddress not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_AccountAddress_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAccountAddressRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AccountAddress(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.gmp.v1.Query/AccountAddress", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AccountAddress(ctx, req.(*QueryAccountAddressRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.applications.gmp.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AccountAddress", + Handler: _Query_AccountAddress_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/applications/gmp/v1/query.proto", +} + +func (m *QueryAccountAddressRequest) 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 *QueryAccountAddressRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAccountAddressRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Salt) > 0 { + i -= len(m.Salt) + copy(dAtA[i:], m.Salt) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Salt))) + i-- + dAtA[i] = 0x1a + } + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0x12 + } + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAccountAddressResponse) 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 *QueryAccountAddressResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAccountAddressResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AccountAddress) > 0 { + i -= len(m.AccountAddress) + copy(dAtA[i:], m.AccountAddress) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AccountAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryAccountAddressRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Salt) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAccountAddressResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.AccountAddress) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryAccountAddressRequest) 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 ErrIntOverflowQuery + } + 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: QueryAccountAddressRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAccountAddressRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ClientId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Salt", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Salt = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAccountAddressResponse) 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 ErrIntOverflowQuery + } + 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: QueryAccountAddressResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAccountAddressResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccountAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/27-gmp/types/query.pb.gw.go b/modules/apps/27-gmp/types/query.pb.gw.go new file mode 100644 index 00000000000..0fa9f5f2299 --- /dev/null +++ b/modules/apps/27-gmp/types/query.pb.gw.go @@ -0,0 +1,233 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: ibc/applications/gmp/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_AccountAddress_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAccountAddressRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["client_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "client_id") + } + + protoReq.ClientId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) + } + + val, ok = pathParams["sender"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "sender") + } + + protoReq.Sender, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "sender", err) + } + + val, ok = pathParams["salt"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "salt") + } + + protoReq.Salt, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "salt", err) + } + + msg, err := client.AccountAddress(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AccountAddress_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAccountAddressRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["client_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "client_id") + } + + protoReq.ClientId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "client_id", err) + } + + val, ok = pathParams["sender"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "sender") + } + + protoReq.Sender, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "sender", err) + } + + val, ok = pathParams["salt"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "salt") + } + + protoReq.Salt, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "salt", err) + } + + msg, err := server.AccountAddress(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_AccountAddress_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AccountAddress_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AccountAddress_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_AccountAddress_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AccountAddress_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AccountAddress_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_AccountAddress_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6, 1, 0, 4, 1, 5, 7, 3, 0, 4, 1, 5, 8}, []string{"ibc", "apps", "gmp", "v1", "clients", "client_id", "accounts", "sender", "salt"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_AccountAddress_0 = runtime.ForwardResponseMessage +) From 0394e66210f9ec161b1bdd60bce21602959ccb52 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 2 May 2025 17:57:12 +0400 Subject: [PATCH 08/46] imp: regen proto --- modules/apps/27-gmp/types/account.pb.go | 106 ++++++++++---------- modules/apps/27-gmp/types/genesis.go | 38 +++++++ modules/apps/27-gmp/types/keys.go | 7 ++ modules/apps/27-gmp/types/msgs.go | 3 + modules/apps/27-gmp/types/router.go | 12 +++ proto/ibc/applications/gmp/v1/account.proto | 10 +- 6 files changed, 117 insertions(+), 59 deletions(-) create mode 100644 modules/apps/27-gmp/types/genesis.go create mode 100644 modules/apps/27-gmp/types/router.go diff --git a/modules/apps/27-gmp/types/account.pb.go b/modules/apps/27-gmp/types/account.pb.go index 6e56fca45c5..523ce488779 100644 --- a/modules/apps/27-gmp/types/account.pb.go +++ b/modules/apps/27-gmp/types/account.pb.go @@ -5,8 +5,7 @@ package types import ( fmt "fmt" - types "github.com/cosmos/cosmos-sdk/x/auth/types" - _ "github.com/cosmos/gogoproto/gogoproto" + _ "github.com/cosmos/cosmos-proto" proto "github.com/cosmos/gogoproto/proto" io "io" math "math" @@ -90,12 +89,13 @@ func (m *AccountIdentifier) GetSalt() []byte { // An ICS27Account is defined as a BaseAccount & the account identifier type ICS27Account struct { - *types.BaseAccount `protobuf:"bytes,1,opt,name=base_account,json=baseAccount,proto3,embedded=base_account" json:"base_account,omitempty"` - AccountId *AccountIdentifier `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + AccountId *AccountIdentifier `protobuf:"bytes,2,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` } -func (m *ICS27Account) Reset() { *m = ICS27Account{} } -func (*ICS27Account) ProtoMessage() {} +func (m *ICS27Account) Reset() { *m = ICS27Account{} } +func (m *ICS27Account) String() string { return proto.CompactTextString(m) } +func (*ICS27Account) ProtoMessage() {} func (*ICS27Account) Descriptor() ([]byte, []int) { return fileDescriptor_5d5b886ccdedc1db, []int{1} } @@ -126,6 +126,20 @@ func (m *ICS27Account) XXX_DiscardUnknown() { var xxx_messageInfo_ICS27Account proto.InternalMessageInfo +func (m *ICS27Account) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *ICS27Account) GetAccountId() *AccountIdentifier { + if m != nil { + return m.AccountId + } + return nil +} + func init() { proto.RegisterType((*AccountIdentifier)(nil), "ibc.applications.gmp.v1.AccountIdentifier") proto.RegisterType((*ICS27Account)(nil), "ibc.applications.gmp.v1.ICS27Account") @@ -136,30 +150,27 @@ func init() { } var fileDescriptor_5d5b886ccdedc1db = []byte{ - // 353 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x51, 0xc1, 0x4a, 0xeb, 0x40, - 0x14, 0xcd, 0xf4, 0x95, 0xd2, 0x4e, 0xbb, 0x79, 0xe1, 0xf1, 0x2c, 0x15, 0xd2, 0x52, 0x10, 0x8a, - 0xd0, 0x19, 0x53, 0xc1, 0x82, 0x3b, 0xeb, 0x2a, 0x3b, 0x89, 0x3b, 0x11, 0xca, 0xcc, 0x64, 0x4c, - 0x07, 0x92, 0x4c, 0xe8, 0x4c, 0x02, 0xfe, 0x81, 0x4b, 0x97, 0x2e, 0xfb, 0x05, 0x7e, 0x87, 0xcb, - 0x2e, 0x5d, 0x89, 0xb4, 0x3f, 0x22, 0x99, 0x8c, 0x28, 0x88, 0xbb, 0x7b, 0xcf, 0x3d, 0x73, 0xe6, - 0xdc, 0x73, 0xe1, 0x91, 0xa0, 0x0c, 0x93, 0x3c, 0x4f, 0x04, 0x23, 0x5a, 0xc8, 0x4c, 0xe1, 0x38, - 0xcd, 0x71, 0xe9, 0x63, 0xc2, 0x98, 0x2c, 0x32, 0x8d, 0xf2, 0xb5, 0xd4, 0xd2, 0x3d, 0x10, 0x94, - 0xa1, 0xef, 0x34, 0x14, 0xa7, 0x39, 0x2a, 0xfd, 0xc1, 0xbf, 0x58, 0xc6, 0xd2, 0x70, 0x70, 0x55, - 0xd5, 0xf4, 0x81, 0xc7, 0xa4, 0x4a, 0xa5, 0xc2, 0xa4, 0xd0, 0x2b, 0x5c, 0xfa, 0x94, 0x6b, 0xe2, - 0x9b, 0xa6, 0x9e, 0x8f, 0x6f, 0xe1, 0xdf, 0x8b, 0x5a, 0x3f, 0x88, 0x78, 0xa6, 0xc5, 0x9d, 0xe0, - 0x6b, 0xf7, 0x10, 0x76, 0x58, 0x22, 0x78, 0xa6, 0x97, 0x22, 0xea, 0x83, 0x11, 0x98, 0x74, 0xc2, - 0x76, 0x0d, 0x04, 0x91, 0xfb, 0x1f, 0xb6, 0x14, 0xcf, 0x22, 0xbe, 0xee, 0x37, 0xcc, 0xc4, 0x76, - 0xae, 0x0b, 0x9b, 0x8a, 0x24, 0xba, 0xff, 0x67, 0x04, 0x26, 0xbd, 0xd0, 0xd4, 0xe3, 0x67, 0x00, - 0x7b, 0xc1, 0xe5, 0xf5, 0x6c, 0x6e, 0xff, 0x70, 0x03, 0xd8, 0xa3, 0x44, 0xf1, 0xa5, 0xdd, 0xc9, - 0x88, 0x77, 0x67, 0x23, 0x54, 0xbb, 0x44, 0xc6, 0x98, 0x75, 0x89, 0x16, 0x44, 0x71, 0xfb, 0x6e, - 0xd1, 0xdc, 0xbe, 0x0d, 0x41, 0xd8, 0xa5, 0x5f, 0x90, 0x1b, 0x40, 0x68, 0x55, 0x2a, 0x97, 0x0d, - 0x23, 0x74, 0x8c, 0x7e, 0x49, 0x07, 0xfd, 0x58, 0x32, 0xec, 0x90, 0x4f, 0xe8, 0xbc, 0xfd, 0xb0, - 0x19, 0x3a, 0x4f, 0x9b, 0xa1, 0xb3, 0xb8, 0x7a, 0xd9, 0x79, 0x60, 0xbb, 0xf3, 0xc0, 0xfb, 0xce, - 0x03, 0x8f, 0x7b, 0xcf, 0xd9, 0xee, 0x3d, 0xe7, 0x75, 0xef, 0x39, 0x37, 0x67, 0xb1, 0xd0, 0xab, - 0x82, 0x22, 0x26, 0x53, 0x6c, 0x33, 0x15, 0x94, 0x4d, 0x63, 0x89, 0x4b, 0xff, 0x04, 0xa7, 0x32, - 0x2a, 0x12, 0xae, 0xaa, 0xfb, 0x29, 0x3c, 0x9b, 0x4f, 0xab, 0xd3, 0xe9, 0xfb, 0x9c, 0x2b, 0xda, - 0x32, 0x39, 0x9f, 0x7e, 0x04, 0x00, 0x00, 0xff, 0xff, 0x0c, 0xaf, 0x35, 0x38, 0xdf, 0x01, 0x00, - 0x00, + // 314 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x51, 0x4f, 0x4b, 0xc3, 0x30, + 0x14, 0x5f, 0x54, 0xa6, 0x8b, 0xbb, 0x18, 0x44, 0xab, 0x42, 0x19, 0x03, 0x61, 0x08, 0x4b, 0x5c, + 0x05, 0x77, 0xde, 0x3c, 0xf5, 0x26, 0xdd, 0x4d, 0x84, 0x91, 0x26, 0xb1, 0x06, 0xda, 0x24, 0x34, + 0xd9, 0xc0, 0x0f, 0x21, 0xf8, 0x61, 0xfc, 0x10, 0x1e, 0x87, 0x27, 0x8f, 0xb2, 0x7d, 0x11, 0x69, + 0xd3, 0x81, 0x20, 0xde, 0xf2, 0xde, 0xfb, 0xe5, 0xfd, 0xfe, 0x3c, 0x78, 0x29, 0x53, 0x46, 0xa8, + 0x31, 0xb9, 0x64, 0xd4, 0x49, 0xad, 0x2c, 0xc9, 0x0a, 0x43, 0x96, 0x23, 0x42, 0x19, 0xd3, 0x0b, + 0xe5, 0xb0, 0x29, 0xb5, 0xd3, 0xe8, 0x54, 0xa6, 0x0c, 0xff, 0x86, 0xe1, 0xac, 0x30, 0x78, 0x39, + 0x3a, 0x3f, 0x63, 0xda, 0x16, 0xda, 0xce, 0x6b, 0x18, 0xf1, 0x85, 0xff, 0xd3, 0x7f, 0x84, 0x47, + 0x13, 0xbf, 0x24, 0xe6, 0x42, 0x39, 0xf9, 0x24, 0x45, 0x89, 0x2e, 0x60, 0x87, 0xe5, 0x52, 0x28, + 0x37, 0x97, 0x3c, 0x00, 0x3d, 0x30, 0xe8, 0x24, 0x07, 0xbe, 0x11, 0x73, 0x74, 0x02, 0xdb, 0x56, + 0x28, 0x2e, 0xca, 0x60, 0xa7, 0x9e, 0x34, 0x15, 0x42, 0x70, 0xcf, 0xd2, 0xdc, 0x05, 0xbb, 0x3d, + 0x30, 0xe8, 0x26, 0xf5, 0xbb, 0xff, 0x0a, 0x60, 0x37, 0xbe, 0x9b, 0x45, 0xe3, 0x86, 0x03, 0x45, + 0x70, 0x9f, 0x72, 0x5e, 0x0a, 0x6b, 0xfd, 0xde, 0x69, 0xf0, 0xf9, 0x3e, 0x3c, 0x6e, 0x14, 0x4d, + 0xfc, 0x64, 0xe6, 0x4a, 0xa9, 0xb2, 0x64, 0x0b, 0x44, 0x31, 0x84, 0x8d, 0xcf, 0x4a, 0x4e, 0x45, + 0x7a, 0x18, 0x5d, 0xe1, 0x7f, 0xbc, 0xe2, 0x3f, 0x6e, 0x92, 0x0e, 0xdd, 0xb6, 0xa6, 0xf7, 0x1f, + 0xeb, 0x10, 0xac, 0xd6, 0x21, 0xf8, 0x5e, 0x87, 0xe0, 0x6d, 0x13, 0xb6, 0x56, 0x9b, 0xb0, 0xf5, + 0xb5, 0x09, 0x5b, 0x0f, 0xb7, 0x99, 0x74, 0xcf, 0x8b, 0x14, 0x33, 0x5d, 0x34, 0x01, 0x11, 0x99, + 0xb2, 0x61, 0xa6, 0xc9, 0x72, 0x74, 0x4d, 0x0a, 0xcd, 0x17, 0xb9, 0xb0, 0xd5, 0x0d, 0x2c, 0x89, + 0xc6, 0xc3, 0x2a, 0x7e, 0xf7, 0x62, 0x84, 0x4d, 0xdb, 0x75, 0x8c, 0x37, 0x3f, 0x01, 0x00, 0x00, + 0xff, 0xff, 0x9a, 0x1a, 0xd8, 0x45, 0xa3, 0x01, 0x00, 0x00, } func (m *AccountIdentifier) Marshal() (dAtA []byte, err error) { @@ -238,15 +249,10 @@ func (m *ICS27Account) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if m.BaseAccount != nil { - { - size, err := m.BaseAccount.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintAccount(dAtA, i, uint64(size)) - } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintAccount(dAtA, i, uint64(len(m.Address))) i-- dAtA[i] = 0xa } @@ -291,8 +297,8 @@ func (m *ICS27Account) Size() (n int) { } var l int _ = l - if m.BaseAccount != nil { - l = m.BaseAccount.Size() + l = len(m.Address) + if l > 0 { n += 1 + l + sovAccount(uint64(l)) } if m.AccountId != nil { @@ -487,9 +493,9 @@ func (m *ICS27Account) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BaseAccount", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowAccount @@ -499,27 +505,23 @@ func (m *ICS27Account) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthAccount } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthAccount } if postIndex > l { return io.ErrUnexpectedEOF } - if m.BaseAccount == nil { - m.BaseAccount = &types.BaseAccount{} - } - if err := m.BaseAccount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Address = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { diff --git a/modules/apps/27-gmp/types/genesis.go b/modules/apps/27-gmp/types/genesis.go new file mode 100644 index 00000000000..193c6cf4d01 --- /dev/null +++ b/modules/apps/27-gmp/types/genesis.go @@ -0,0 +1,38 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + host "github.com/cosmos/ibc-go/v10/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// DefaultGenesisState returns the default GenesisState. +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + Ics27Accounts: []RegisteredICS27Account{}, + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + for _, account := range gs.Ics27Accounts { + if _, err := sdk.AccAddressFromBech32(account.AccountAddress); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + if _, err := sdk.AccAddressFromBech32(account.AccountId.Sender); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + if err := host.ClientIdentifierValidator(account.AccountId.ClientId); err != nil { + return errorsmod.Wrapf(err, "invalid source client ID %s", account.AccountId.ClientId) + } + if len(account.AccountId.Salt) > MaximumSaltLength { + return errorsmod.Wrapf(ErrInvalidSalt, "salt must not exceed %d bytes", MaximumSaltLength) + } + } + + return nil +} diff --git a/modules/apps/27-gmp/types/keys.go b/modules/apps/27-gmp/types/keys.go index 5198100358a..c15ff8535a4 100644 --- a/modules/apps/27-gmp/types/keys.go +++ b/modules/apps/27-gmp/types/keys.go @@ -1,5 +1,7 @@ package types +import "cosmossdk.io/collections" + const ( // ModuleName defines the interchain accounts module name ModuleName = "gmp" @@ -19,3 +21,8 @@ const ( // accountsKey is the key used when generating a module address for the gmp module accountsKey = "gmp-accounts" ) + +var ( + // AccountsKey is the key used to store the accounts in the keeper + AccountsKey = collections.NewPrefix(0) +) diff --git a/modules/apps/27-gmp/types/msgs.go b/modules/apps/27-gmp/types/msgs.go index 0b5c9d56ffe..c834b343697 100644 --- a/modules/apps/27-gmp/types/msgs.go +++ b/modules/apps/27-gmp/types/msgs.go @@ -43,6 +43,9 @@ func (msg MsgSendCall) ValidateBasic() error { if len(msg.Payload) > MaximumPayloadLength { return errorsmod.Wrapf(ErrInvalidPayload, "payload must not exceed %d bytes", MaximumPayloadLength) } + if len(msg.Salt) > MaximumSaltLength { + return errorsmod.Wrapf(ErrInvalidSalt, "salt must not exceed %d bytes", MaximumSaltLength) + } if len(msg.Memo) > MaximumMemoLength { return errorsmod.Wrapf(ErrInvalidMemo, "memo must not exceed %d bytes", MaximumMemoLength) } diff --git a/modules/apps/27-gmp/types/router.go b/modules/apps/27-gmp/types/router.go new file mode 100644 index 00000000000..dd1cfb4d3cf --- /dev/null +++ b/modules/apps/27-gmp/types/router.go @@ -0,0 +1,12 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// MessageRouter ADR 031 request type routing +// https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-031-msg-service.md +type MessageRouter interface { + Handler(msg sdk.Msg) baseapp.MsgServiceHandler +} diff --git a/proto/ibc/applications/gmp/v1/account.proto b/proto/ibc/applications/gmp/v1/account.proto index 76ed9cd1ec7..a683470b737 100644 --- a/proto/ibc/applications/gmp/v1/account.proto +++ b/proto/ibc/applications/gmp/v1/account.proto @@ -4,8 +4,7 @@ package ibc.applications.gmp.v1; option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; -import "gogoproto/gogo.proto"; -import "cosmos/auth/v1beta1/auth.proto"; +import "cosmos_proto/cosmos.proto"; // AccountIdentifier is used to identify a ICS27 account. message AccountIdentifier { @@ -19,9 +18,6 @@ message AccountIdentifier { // An ICS27Account is defined as a BaseAccount & the account identifier message ICS27Account { - option (gogoproto.goproto_getters) = false; - option (gogoproto.goproto_stringer) = false; - - cosmos.auth.v1beta1.BaseAccount base_account = 1 [(gogoproto.embed) = true]; - AccountIdentifier account_id = 2; + string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + AccountIdentifier account_id = 2; } From 0f5dbfb47368f1e0e8e6759bc27435423d52f7db Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 2 May 2025 18:39:26 +0400 Subject: [PATCH 09/46] imp: save progress --- go.mod | 2 +- modules/apps/27-gmp/keeper/genesis.go | 53 +++++++ modules/apps/27-gmp/keeper/keeper.go | 59 ++++++++ modules/apps/27-gmp/keeper/msg_server.go | 15 ++ modules/apps/27-gmp/keeper/query_server.go | 15 ++ modules/apps/27-gmp/module.go | 158 +++++++++++++++++++++ 6 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 modules/apps/27-gmp/keeper/genesis.go create mode 100644 modules/apps/27-gmp/keeper/keeper.go create mode 100644 modules/apps/27-gmp/keeper/msg_server.go create mode 100644 modules/apps/27-gmp/keeper/query_server.go create mode 100644 modules/apps/27-gmp/module.go diff --git a/go.mod b/go.mod index 4e5a8a3ebe4..bb7f1704c11 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.2021 require ( cosmossdk.io/api v0.9.2 + cosmossdk.io/collections v1.2.0 cosmossdk.io/core v0.11.3 cosmossdk.io/errors v1.0.2 cosmossdk.io/log v1.5.1 @@ -41,7 +42,6 @@ require ( cloud.google.com/go/iam v1.2.2 // indirect cloud.google.com/go/monitoring v1.21.2 // indirect cloud.google.com/go/storage v1.49.0 // indirect - cosmossdk.io/collections v1.2.0 // indirect cosmossdk.io/depinject v1.2.0 // indirect cosmossdk.io/schema v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect diff --git a/modules/apps/27-gmp/keeper/genesis.go b/modules/apps/27-gmp/keeper/genesis.go new file mode 100644 index 00000000000..c45447f4ca3 --- /dev/null +++ b/modules/apps/27-gmp/keeper/genesis.go @@ -0,0 +1,53 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/collections" + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// InitGenesis initializes the module state from a genesis state. +func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error { + for _, account := range data.Ics27Accounts { + if _, err := sdk.AccAddressFromBech32(account.AccountAddress); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + if _, err := sdk.AccAddressFromBech32(account.AccountId.Sender); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + if err := k.Accounts.Set(ctx, collections.Join3(account.AccountId.ClientId, account.AccountId.Sender, account.AccountId.Salt), types.ICS27Account{ + Address: account.AccountAddress, + AccountId: &account.AccountId, + }); err != nil { + return err + } + } + + return nil +} + +// ExportGenesis exports the module state to a genesis state. +func (k *Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) { + var accounts []types.RegisteredICS27Account + if err := k.Accounts.Walk(ctx, nil, func(key collections.Triple[string, string, []byte], value types.ICS27Account) (bool, error) { + accounts = append(accounts, types.RegisteredICS27Account{ + AccountAddress: value.Address, + AccountId: *value.AccountId, + }) + + return false, nil + }); err != nil { + return nil, err + } + + return &types.GenesisState{ + Ics27Accounts: accounts, + }, nil +} diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go new file mode 100644 index 00000000000..38427112645 --- /dev/null +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -0,0 +1,59 @@ +package keeper + +import ( + "errors" + "strings" + + "cosmossdk.io/collections" + storetypes "cosmossdk.io/core/store" + + "github.com/cosmos/cosmos-sdk/codec" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" +) + +// Keeper defines the IBC fungible transfer keeper +type Keeper struct { + cdc codec.BinaryCodec + + ics4Wrapper porttypes.ICS4Wrapper + msgRouter types.MessageRouter + + // the address capable of executing a MsgUpdateParams message. Typically, this + // should be the x/gov module account. + authority string + + // state management + Schema collections.Schema + // Accounts is a map of (ClientID, Sender, Salt) to ICS27Account + Accounts collections.Map[collections.Triple[string, string, []byte], types.ICS27Account] +} + +// NewKeeper creates a new Keeper instance +func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService, authority string) Keeper { + if strings.TrimSpace(authority) == "" { + panic(errors.New("authority must be non-empty")) + } + + sb := collections.NewSchemaBuilder(storeService) + k := Keeper{ + cdc: cdc, + authority: authority, + Accounts: collections.NewMap(sb, types.AccountsKey, "accounts", collections.TripleKeyCodec(collections.StringKey, collections.StringKey, collections.BytesKey), codec.CollValue[types.ICS27Account](cdc)), + } + + schema, err := sb.Build() + if err != nil { + panic(err) + } + + k.Schema = schema + + return k +} + +// GetAuthority returns the module's authority. +func (k Keeper) GetAuthority() string { + return k.authority +} diff --git a/modules/apps/27-gmp/keeper/msg_server.go b/modules/apps/27-gmp/keeper/msg_server.go new file mode 100644 index 00000000000..7147e1d373f --- /dev/null +++ b/modules/apps/27-gmp/keeper/msg_server.go @@ -0,0 +1,15 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" +) + +var _ types.MsgServer = (*Keeper)(nil) + +// SendCall defines the handler for the MsgSendCall message. +func (k Keeper) SendCall(ctx context.Context, msg *types.MsgSendCall) (*types.MsgSendCallResponse, error) { + // TODO: Add logic + panic("not implemented") +} diff --git a/modules/apps/27-gmp/keeper/query_server.go b/modules/apps/27-gmp/keeper/query_server.go new file mode 100644 index 00000000000..5a4b7cff890 --- /dev/null +++ b/modules/apps/27-gmp/keeper/query_server.go @@ -0,0 +1,15 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" +) + +var _ types.QueryServer = (*Keeper)(nil) + +// AccountAddress defines the handler for the Query/AccountAddress RPC method. +func (k Keeper) AccountAddress(ctx context.Context, req *types.QueryAccountAddressRequest) (*types.QueryAccountAddressResponse, error) { + // TODO: Add logic + panic("not implemented") +} diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go new file mode 100644 index 00000000000..2b919fe5064 --- /dev/null +++ b/modules/apps/27-gmp/module.go @@ -0,0 +1,158 @@ +package gmp + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + "cosmossdk.io/core/appmodule" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + // "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/client/cli" + // "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/simulation" + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" +) + +var ( + _ module.AppModule = (*AppModule)(nil) + _ module.AppModuleBasic = (*AppModuleBasic)(nil) + // _ module.AppModuleSimulation = (*AppModule)(nil) + _ module.HasGenesis = (*AppModule)(nil) + _ module.HasName = (*AppModule)(nil) + _ module.HasConsensusVersion = (*AppModule)(nil) + _ module.HasServices = (*AppModule)(nil) + // _ module.HasProposalMsgs = (*AppModule)(nil) + _ appmodule.AppModule = (*AppModule)(nil) + + // TODO: add IBCModule + // _ porttypes.IBCModule = (*IBCModule)(nil) +) + +// AppModuleBasic is the IBC Transfer AppModuleBasic +type AppModuleBasic struct{} + +// Name implements AppModuleBasic interface +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (AppModule) IsOnePerModuleType() {} + +// IsAppModule implements the appmodule.AppModule interface. +func (AppModule) IsAppModule() {} + +// RegisterLegacyAminoCodec implements AppModuleBasic interface +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} + +// RegisterInterfaces registers module concrete types into protobuf Any. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + types.RegisterInterfaces(registry) +} + +// DefaultGenesis returns default genesis state as raw bytes for the ibc +// transfer module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the ibc transfer module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var gs types.GenesisState + if err := cdc.UnmarshalJSON(bz, &gs); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + + return gs.Validate() +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-transfer module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } +} + +// GetTxCmd implements AppModuleBasic interface +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.NewTxCmd() +} + +// GetQueryCmd implements AppModuleBasic interface +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// AppModule represents the AppModule for this module +type AppModule struct { + AppModuleBasic + keeper keeper.Keeper +} + +// NewAppModule creates a new 20-transfer module +func NewAppModule(k keeper.Keeper) AppModule { + return AppModule{ + keeper: k, + } +} + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), am.keeper) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// InitGenesis performs genesis initialization for the ibc-transfer module. It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + am.keeper.InitGenesis(ctx, &genesisState) +} + +// ExportGenesis returns the exported genesis state as raw bytes for the ibc-transfer +// module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs, err := am.keeper.ExportGenesis(ctx) + if err != nil { + panic(fmt.Errorf("failed to export %s genesis state: %w", types.ModuleName, err)) + } + + return cdc.MustMarshalJSON(gs) +} + +// ConsensusVersion implements AppModule/ConsensusVersion defining the current version of transfer. +func (AppModule) ConsensusVersion() uint64 { return 6 } + +/* +// AppModuleSimulation functions + +// GenerateGenesisState creates a randomized GenState of the transfer module. +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState) +} + +// ProposalMsgs returns msgs used for governance proposals for simulations. +func (AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg { + return simulation.ProposalMsgs() +} + +// RegisterStoreDecoder registers a decoder for transfer module's types +func (AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) { + sdr[types.StoreKey] = simulation.NewDecodeStore() +} + +// WeightedOperations returns the all the transfer module operations with their respective weights. +func (AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + return nil +} +*/ From 4fed4b941048013cc02ffc5cee63ba79267933d0 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sun, 4 May 2025 18:24:13 +0400 Subject: [PATCH 10/46] feat: implemented basic module with autocli --- modules/apps/27-gmp/module.go | 19 ++++-------- modules/apps/27-gmp/types/autocli.go | 46 ++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 modules/apps/27-gmp/types/autocli.go diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index 2b919fe5064..d6f81ad9d99 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -6,8 +6,8 @@ import ( "fmt" "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" "cosmossdk.io/core/appmodule" "github.com/cosmos/cosmos-sdk/client" @@ -16,8 +16,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - // "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/client/cli" - // "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/simulation" "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" ) @@ -82,16 +80,6 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r } } -// GetTxCmd implements AppModuleBasic interface -func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.NewTxCmd() -} - -// GetQueryCmd implements AppModuleBasic interface -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() -} - // AppModule represents the AppModule for this module type AppModule struct { AppModuleBasic @@ -105,6 +93,11 @@ func NewAppModule(k keeper.Keeper) AppModule { } } +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { + return types.AutoCLIOptions() +} + // RegisterServices registers module services. func (am AppModule) RegisterServices(cfg module.Configurator) { types.RegisterMsgServer(cfg.MsgServer(), am.keeper) diff --git a/modules/apps/27-gmp/types/autocli.go b/modules/apps/27-gmp/types/autocli.go new file mode 100644 index 00000000000..ddddf306067 --- /dev/null +++ b/modules/apps/27-gmp/types/autocli.go @@ -0,0 +1,46 @@ +package types + +import ( + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" +) + +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func AutoCLIOptions() *autocliv1.ModuleOptions { + return &autocliv1.ModuleOptions{ + Query: &autocliv1.ServiceCommandDescriptor{ + Service: _Query_serviceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "AccountAddress", + Use: "get-address [client_id] [sender] [salt]", + Short: "Get or pre-compute the address of an ICS27 GMP account", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "client_id"}, + {ProtoField: "sender"}, + {ProtoField: "salt"}, + }, + }, + }, + }, + Tx: &autocliv1.ServiceCommandDescriptor{ + Service: _Msg_serviceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "SendCall", + Use: "send-call [source_client] [sender] [receiver] [salt] [payload] [timeout_timestamp] [memo] [encoding]", + Short: "Send a call to an ICS27 GMP account", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "source_client"}, + {ProtoField: "sender"}, + {ProtoField: "receiver"}, + {ProtoField: "salt"}, + {ProtoField: "payload"}, + {ProtoField: "timeout_timestamp"}, + {ProtoField: "memo"}, + {ProtoField: "encoding", Optional: true}, + }, + }, + }, + }, + } +} From 2d21a1e1cc720bac77c64d4795c4846fb5ec3199 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sun, 4 May 2025 22:47:31 +0400 Subject: [PATCH 11/46] imp: added ibc boilerplate --- modules/apps/27-gmp/ibc_module.go | 43 +++++++++++++++++++++++++++++++ modules/apps/27-gmp/module.go | 3 --- 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 modules/apps/27-gmp/ibc_module.go diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go new file mode 100644 index 00000000000..533cd9a6db9 --- /dev/null +++ b/modules/apps/27-gmp/ibc_module.go @@ -0,0 +1,43 @@ +package gmp + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + "github.com/cosmos/ibc-go/v10/modules/core/api" +) + +var _ api.IBCModule = (*IBCModule)(nil) + +// IBCModule implements the ICS26 interface for transfer given the transfer keeper. +type IBCModule struct { + keeper keeper.Keeper +} + +// NewIBCModule creates a new IBCModule given the keeper +func NewIBCModule(k keeper.Keeper) IBCModule { + return IBCModule{ + keeper: k, + } +} + +func (im *IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error { + // TODO: implement + panic("not implemented") +} + +func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult { + // TODO: implement + panic("not implemented") +} + +func (im *IBCModule) OnTimeoutPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) error { + // TODO: implement + panic("not implemented") +} + +func (im *IBCModule) OnAcknowledgementPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, acknowledgement []byte, payload channeltypesv2.Payload, relayer sdk.AccAddress) error { + // TODO: implement + panic("not implemented") +} diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index d6f81ad9d99..6ca7f1a4b39 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -30,9 +30,6 @@ var ( _ module.HasServices = (*AppModule)(nil) // _ module.HasProposalMsgs = (*AppModule)(nil) _ appmodule.AppModule = (*AppModule)(nil) - - // TODO: add IBCModule - // _ porttypes.IBCModule = (*IBCModule)(nil) ) // AppModuleBasic is the IBC Transfer AppModuleBasic From 7dfb3e6b6abb4a079ed6211dab77a80bc784f03c Mon Sep 17 00:00:00 2001 From: srdtrk Date: Mon, 5 May 2025 11:24:12 +0400 Subject: [PATCH 12/46] feat: add module to simapp --- modules/apps/27-gmp/ibc_module.go | 4 ++-- modules/apps/27-gmp/module.go | 4 ++-- modules/apps/27-gmp/types/keys.go | 5 ++++- testing/simapp/app.go | 23 ++++++++++++++++++++--- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index 533cd9a6db9..65918a28e8c 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -16,8 +16,8 @@ type IBCModule struct { } // NewIBCModule creates a new IBCModule given the keeper -func NewIBCModule(k keeper.Keeper) IBCModule { - return IBCModule{ +func NewIBCModule(k keeper.Keeper) *IBCModule { + return &IBCModule{ keeper: k, } } diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index 6ca7f1a4b39..ba8b8b3c166 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -80,11 +80,11 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // AppModule represents the AppModule for this module type AppModule struct { AppModuleBasic - keeper keeper.Keeper + keeper *keeper.Keeper } // NewAppModule creates a new 20-transfer module -func NewAppModule(k keeper.Keeper) AppModule { +func NewAppModule(k *keeper.Keeper) AppModule { return AppModule{ keeper: k, } diff --git a/modules/apps/27-gmp/types/keys.go b/modules/apps/27-gmp/types/keys.go index c15ff8535a4..ab44e86f3d4 100644 --- a/modules/apps/27-gmp/types/keys.go +++ b/modules/apps/27-gmp/types/keys.go @@ -3,9 +3,12 @@ package types import "cosmossdk.io/collections" const ( - // ModuleName defines the interchain accounts module name + // ModuleName defines the gmp module name ModuleName = "gmp" + // StoreKey is the primary storage key for the gmp module + StoreKey = ModuleName + // PortID is the default IBC port id that the gmp module PortID = "gmpport" diff --git a/testing/simapp/app.go b/testing/simapp/app.go index ae21ddb29ac..a3c278723cc 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -83,6 +83,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" + gmp "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp" + gmpkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + gmptypes "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" ica "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts" icacontroller "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/keeper" @@ -158,6 +161,7 @@ type SimApp struct { IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper + GMPKeeper gmpkeeper.Keeper TransferKeeper ibctransferkeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper @@ -252,7 +256,7 @@ func NewSimApp( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, group.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, - ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, + ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, gmptypes.StoreKey, authzkeeper.StoreKey, consensusparamtypes.StoreKey, ) @@ -360,6 +364,13 @@ func NewSimApp( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + // ICS-27 GMP keeper + app.GMPKeeper = gmpkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[gmptypes.ModuleName]), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + // Create IBC Router ibcRouter := porttypes.NewRouter() ibcRouterV2 := ibcapi.NewRouter() @@ -445,6 +456,9 @@ func NewSimApp( // register the transfer v2 module. ibcRouterV2.AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper)) + // Register the ICS-27 GMP module + ibcRouterV2.AddRoute(gmptypes.PortID, gmp.NewIBCModule(app.GMPKeeper)) + // Seal the IBC Router app.IBCKeeper.SetRouter(ibcRouter) app.IBCKeeper.SetRouterV2(ibcRouterV2) @@ -484,6 +498,7 @@ func NewSimApp( ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), + gmp.NewAppModule(&app.GMPKeeper), mockModule, // IBC light clients @@ -528,6 +543,7 @@ func NewSimApp( genutiltypes.ModuleName, authz.ModuleName, icatypes.ModuleName, + gmptypes.ModuleName, ibcmock.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( @@ -537,6 +553,7 @@ func NewSimApp( ibctransfertypes.ModuleName, genutiltypes.ModuleName, icatypes.ModuleName, + gmptypes.ModuleName, ibcmock.ModuleName, group.ModuleName, ) @@ -549,8 +566,8 @@ func NewSimApp( banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, ibcexported.ModuleName, genutiltypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName, - icatypes.ModuleName, ibcmock.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, - vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, + icatypes.ModuleName, gmptypes.ModuleName, ibcmock.ModuleName, paramstypes.ModuleName, + upgradetypes.ModuleName, vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...) From 5cd5bce3a474edcfb106eaf70803e9aa6bb5cc54 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Mon, 5 May 2025 17:38:58 +0400 Subject: [PATCH 13/46] imp: added account keeper --- modules/apps/27-gmp/keeper/keeper.go | 8 +++++++- modules/apps/27-gmp/types/codec.go | 4 ---- modules/apps/27-gmp/types/expected_keepers.go | 17 +++++++++++++++++ simapp/app.go | 4 +++- testing/simapp/app.go | 2 ++ 5 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 modules/apps/27-gmp/types/expected_keepers.go diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go index 38427112645..cac03569a6c 100644 --- a/modules/apps/27-gmp/keeper/keeper.go +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -20,6 +20,8 @@ type Keeper struct { ics4Wrapper porttypes.ICS4Wrapper msgRouter types.MessageRouter + accountKeeper types.AccountKeeper + // the address capable of executing a MsgUpdateParams message. Typically, this // should be the x/gov module account. authority string @@ -31,7 +33,11 @@ type Keeper struct { } // NewKeeper creates a new Keeper instance -func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService, authority string) Keeper { +func NewKeeper( + cdc codec.BinaryCodec, storeService storetypes.KVStoreService, + accountKeeper types.AccountKeeper, msgRouter types.MessageRouter, + authority string, +) Keeper { if strings.TrimSpace(authority) == "" { panic(errors.New("authority must be non-empty")) } diff --git a/modules/apps/27-gmp/types/codec.go b/modules/apps/27-gmp/types/codec.go index 0706cae43da..7ec8fae40ae 100644 --- a/modules/apps/27-gmp/types/codec.go +++ b/modules/apps/27-gmp/types/codec.go @@ -4,7 +4,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) // ModuleCdc references the global gmp module codec. Note, the codec @@ -17,8 +16,5 @@ var ModuleCdc = codec.NewProtoCodec(codectypes.NewInterfaceRegistry()) // RegisterInterfaces registers the gmp types and the concrete ICS27Account implementation // against the associated x/auth AccountI and GenesisAccount interfaces. func RegisterInterfaces(registry codectypes.InterfaceRegistry) { - registry.RegisterImplementations((*sdk.AccountI)(nil), &ICS27Account{}) - registry.RegisterImplementations((*authtypes.GenesisAccount)(nil), &ICS27Account{}) - registry.RegisterImplementations((*sdk.Msg)(nil), &MsgSendCall{}) } diff --git a/modules/apps/27-gmp/types/expected_keepers.go b/modules/apps/27-gmp/types/expected_keepers.go new file mode 100644 index 00000000000..3b04f77b43c --- /dev/null +++ b/modules/apps/27-gmp/types/expected_keepers.go @@ -0,0 +1,17 @@ +package types + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// AccountKeeper defines a subset of methods implemented by the cosmos-sdk account keeper +type AccountKeeper interface { + // Return a new account with the next account number and the specified address. Does not save the new account to the store. + NewAccountWithAddress(ctx context.Context, addr sdk.AccAddress) sdk.AccountI + // Retrieve an account from the store. + GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI + // Set an account in the store. + SetAccount(ctx context.Context, acc sdk.AccountI) +} diff --git a/simapp/app.go b/simapp/app.go index c7825e64815..beaf93a904e 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -102,6 +102,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" + gmp "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp" ica "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts" icacontroller "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/keeper" @@ -365,7 +366,7 @@ func NewSimApp( app.GovKeeper = *govKeeper.SetHooks( govtypes.NewMultiGovHooks( - // register the governance hooks + // register the governance hooks ), ) @@ -487,6 +488,7 @@ func NewSimApp( ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), + gmp.NewAppModule(nil), // IBC light clients ibctm.NewAppModule(tmLightClientModule), diff --git a/testing/simapp/app.go b/testing/simapp/app.go index a3c278723cc..85e295ecb17 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -368,6 +368,8 @@ func NewSimApp( app.GMPKeeper = gmpkeeper.NewKeeper( appCodec, runtime.NewKVStoreService(keys[gmptypes.ModuleName]), + app.AccountKeeper, + app.MsgServiceRouter(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) From d0a7742eb558959fb3ee9296f32de92e94668e8c Mon Sep 17 00:00:00 2001 From: srdtrk Date: Mon, 5 May 2025 17:41:38 +0400 Subject: [PATCH 14/46] imp: remoce ics4wrapper --- modules/apps/27-gmp/keeper/keeper.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go index cac03569a6c..7abccc44e83 100644 --- a/modules/apps/27-gmp/keeper/keeper.go +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -10,15 +10,13 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" - porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types" ) // Keeper defines the IBC fungible transfer keeper type Keeper struct { cdc codec.BinaryCodec - ics4Wrapper porttypes.ICS4Wrapper - msgRouter types.MessageRouter + msgRouter types.MessageRouter accountKeeper types.AccountKeeper From 918f808baac3b26a26732b6616b15904d294030b Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 6 May 2025 12:03:21 +0400 Subject: [PATCH 15/46] imp: implemented first message server --- modules/apps/27-gmp/keeper/keeper.go | 8 ++ modules/apps/27-gmp/keeper/msg_server.go | 74 ++++++++++++++- modules/apps/27-gmp/types/errors.go | 2 + modules/apps/27-gmp/types/packet.go | 101 +++++++++++++++++++++ modules/apps/27-gmp/types/solidity_abi.go | 104 ++++++++++++++++++++++ 5 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 modules/apps/27-gmp/types/solidity_abi.go diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go index 7abccc44e83..80f149f0dbd 100644 --- a/modules/apps/27-gmp/keeper/keeper.go +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -6,10 +6,13 @@ import ( "cosmossdk.io/collections" storetypes "cosmossdk.io/core/store" + "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + "github.com/cosmos/ibc-go/v10/modules/core/exported" ) // Keeper defines the IBC fungible transfer keeper @@ -61,3 +64,8 @@ func NewKeeper( func (k Keeper) GetAuthority() string { return k.authority } + +// Logger returns a module-specific logger. +func (Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName) +} diff --git a/modules/apps/27-gmp/keeper/msg_server.go b/modules/apps/27-gmp/keeper/msg_server.go index 7147e1d373f..147aee0c88e 100644 --- a/modules/apps/27-gmp/keeper/msg_server.go +++ b/modules/apps/27-gmp/keeper/msg_server.go @@ -3,13 +3,81 @@ package keeper import ( "context" + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" ) var _ types.MsgServer = (*Keeper)(nil) // SendCall defines the handler for the MsgSendCall message. -func (k Keeper) SendCall(ctx context.Context, msg *types.MsgSendCall) (*types.MsgSendCallResponse, error) { - // TODO: Add logic - panic("not implemented") +func (k Keeper) SendCall(goCtx context.Context, msg *types.MsgSendCall) (*types.MsgSendCallResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + _, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return nil, err + } + + packetData := types.NewGMPPacketData(msg.Sender, msg.Receiver, msg.Salt, msg.Payload, msg.Memo) + if err := packetData.ValidateBasic(); err != nil { + return nil, errorsmod.Wrapf(err, "failed to validate %s packet data", types.Version) + } + + sequence, err := k.sendPacket(ctx, msg.Encoding, msg.SourceClient, msg.TimeoutTimestamp, packetData) + if err != nil { + return nil, err + } + + k.Logger(ctx).Info("IBC send GMP packet", "sender", msg.Sender, "receiver", msg.Receiver) + + return &types.MsgSendCallResponse{Sequence: sequence}, nil +} + +func (k Keeper) sendPacket(ctx sdk.Context, encoding, sourceClient string, timeoutTimestamp uint64, packetData types.GMPPacketData) (uint64, error) { + if encoding == "" { + encoding = types.EncodingABI + } + + data, err := types.MarshalPacketData(&packetData, types.Version, encoding) + if err != nil { + return 0, err + } + + payload := channeltypesv2.NewPayload(types.PortID, types.PortID, types.Version, encoding, data) + msg := channeltypesv2.NewMsgSendPacket( + sourceClient, timeoutTimestamp, + packetData.Sender, payload, + ) + + handler := k.msgRouter.Handler(msg) + if handler == nil { + return 0, errorsmod.Wrapf(ibcerrors.ErrInvalidRequest, "unrecognized packet type: %T", msg) + } + res, err := handler(ctx, msg) + if err != nil { + return 0, err + } + + // NOTE: The sdk msg handler creates a new EventManager, so events must be correctly propagated back to the current context + ctx.EventManager().EmitEvents(res.GetEvents()) + + // Each individual sdk.Result has exactly one Msg response. We aggregate here. + msgResponse := res.MsgResponses[0] + if msgResponse == nil { + return 0, errorsmod.Wrapf(ibcerrors.ErrLogic, "got nil Msg response for msg %s", sdk.MsgTypeURL(msg)) + } + var sendResponse channeltypesv2.MsgSendPacketResponse + err = proto.Unmarshal(msgResponse.Value, &sendResponse) + if err != nil { + return 0, err + } + + return sendResponse.Sequence, nil } diff --git a/modules/apps/27-gmp/types/errors.go b/modules/apps/27-gmp/types/errors.go index d4018f56033..50947d8c33f 100644 --- a/modules/apps/27-gmp/types/errors.go +++ b/modules/apps/27-gmp/types/errors.go @@ -9,4 +9,6 @@ var ( ErrInvalidPayload = errorsmod.Register(ModuleName, 4, "invalid payload") ErrInvalidTimeoutTimestamp = errorsmod.Register(ModuleName, 5, "invalid timeout timestamp") ErrInvalidEncoding = errorsmod.Register(ModuleName, 6, "invalid encoding") + ErrAbiDecoding = errorsmod.Register(ModuleName, 7, "abi decoding error") + ErrAbiEncoding = errorsmod.Register(ModuleName, 8, "abi encoding error") ) diff --git a/modules/apps/27-gmp/types/packet.go b/modules/apps/27-gmp/types/packet.go index b192f0c6e80..beaf6213599 100644 --- a/modules/apps/27-gmp/types/packet.go +++ b/modules/apps/27-gmp/types/packet.go @@ -1,7 +1,108 @@ package types +import ( + "encoding/json" + "strings" + + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/cosmos-sdk/codec/unknownproto" + sdk "github.com/cosmos/cosmos-sdk/types" + + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + const ( EncodingJSON = "application/json" EncodingProtobuf = "application/x-protobuf" EncodingABI = "application/x-solidity-abi" ) + +// NewGMPPacketData creates a new GMPPacketData instance with the provided parameters. +func NewGMPPacketData( + sender, receiver string, salt, payload []byte, memo string, +) GMPPacketData { + return GMPPacketData{ + Sender: sender, + Receiver: receiver, + Salt: salt, + Payload: payload, + Memo: memo, + } +} + +func (p GMPPacketData) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(p.Sender); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + if strings.TrimSpace(p.Receiver) == "" { + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing recipient address") + } + if len(p.Receiver) > MaximumReceiverLength { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "recipient address must not exceed %d bytes", MaximumReceiverLength) + } + if len(p.Payload) > MaximumPayloadLength { + return errorsmod.Wrapf(ErrInvalidPayload, "payload must not exceed %d bytes", MaximumPayloadLength) + } + if len(p.Salt) > MaximumSaltLength { + return errorsmod.Wrapf(ErrInvalidSalt, "salt must not exceed %d bytes", MaximumSaltLength) + } + if len(p.Memo) > MaximumMemoLength { + return errorsmod.Wrapf(ErrInvalidMemo, "memo must not exceed %d bytes", MaximumMemoLength) + } + + return nil +} + +// MarshalPacketData attempts to marshal the provided GMPPacketData into bytes with the provided encoding. +func MarshalPacketData(data *GMPPacketData, ics27Version string, encoding string) ([]byte, error) { + if ics27Version != Version { + panic("unsupported ics27 version") + } + + switch encoding { + case EncodingJSON: + return json.Marshal(data) + case EncodingProtobuf: + return proto.Marshal(data) + case EncodingABI: + return EncodeABIGMPPacketData(data) + default: + return nil, errorsmod.Wrapf(ErrInvalidEncoding, "invalid encoding provided, must be either empty or one of [%q, %q, %q], got %s", EncodingJSON, EncodingProtobuf, EncodingABI, encoding) + } +} + +// UnmarshalPacketData attempts to unmarshal the provided bytes into a GMPPacketData with the provided encoding. +func UnmarshalPacketData(bz []byte, ics27Version string, encoding string) (*GMPPacketData, error) { + if ics27Version != Version { + panic("unsupported ics27 version") + } + + var data *GMPPacketData + switch encoding { + case EncodingJSON: + if err := json.Unmarshal(bz, &data); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal json packet data: %s", err) + } + case EncodingProtobuf: + if err := unknownproto.RejectUnknownFieldsStrict(bz, data, unknownproto.DefaultAnyResolver{}); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal protobuf packet data: %s", err) + } + + if err := proto.Unmarshal(bz, data); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal protobuf packet data: %s", err) + } + case EncodingABI: + var err error + data, err = DecodeABIGMPPacketData(bz) + if err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal ABI packet data: %s", err) + } + default: + return nil, errorsmod.Wrapf(ErrInvalidEncoding, "invalid encoding provided, must be either empty or one of [%q, %q, %q], got %s", EncodingJSON, EncodingProtobuf, EncodingABI, encoding) + } + + return data, nil +} diff --git a/modules/apps/27-gmp/types/solidity_abi.go b/modules/apps/27-gmp/types/solidity_abi.go new file mode 100644 index 00000000000..94438efbf86 --- /dev/null +++ b/modules/apps/27-gmp/types/solidity_abi.go @@ -0,0 +1,104 @@ +package types + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + + errorsmod "cosmossdk.io/errors" +) + +// getICS27ABI returns an abi.Arguments slice describing the Solidity types of the struct. +func getICS27ABI() abi.Arguments { + // Create the ABI types for each field. + // The Solidity types used are: + // - string for Sender, Receiver and Memo. + // - bytes for Salt and Payload. + tupleType, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + { + Name: "sender", + Type: "string", + }, + { + Name: "receiver", + Type: "string", + }, + { + Name: "salt", + Type: "bytes", + }, + { + Name: "payload", + Type: "bytes", + }, + { + Name: "memo", + Type: "string", + }, + }) + if err != nil { + panic(err) + } + + // Create an ABI argument representing our struct as a single tuple argument. + arguments := abi.Arguments{ + { + Type: tupleType, + }, + } + + return arguments +} + +// DecodeABIGMPPacketData decodes a solidity ABI encoded ics27lib.GMPPacketData and converts it into an ibc-go GMPPacketData. +func DecodeABIGMPPacketData(data []byte) (*GMPPacketData, error) { + arguments := getICS27ABI() + + packetDataI, err := arguments.Unpack(data) + if err != nil { + return nil, errorsmod.Wrapf(ErrAbiDecoding, "failed to unpack data: %s", err) + } + + packetData, ok := packetDataI[0].(struct { + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Salt []byte `json:"salt"` + Payload []byte `json:"payload"` + Memo string `json:"memo"` + }) + if !ok { + return nil, errorsmod.Wrapf(ErrAbiDecoding, "failed to parse packet data") + } + + return &GMPPacketData{ + Sender: packetData.Sender, + Receiver: packetData.Receiver, + Salt: packetData.Salt, + Payload: packetData.Payload, + Memo: packetData.Memo, + }, nil +} + +// EncodeABIGMPPacketData encodes a GMPPacketData into a solidity ABI encoded byte array. +func EncodeABIGMPPacketData(data *GMPPacketData) ([]byte, error) { + packetData := struct { + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Salt []byte `json:"salt"` + Payload []byte `json:"payload"` + Memo string `json:"memo"` + }{ + data.Sender, + data.Receiver, + data.Salt, + data.Payload, + data.Memo, + } + + arguments := getICS27ABI() + // Pack the values in the order defined in the ABI. + encodedData, err := arguments.Pack(packetData) + if err != nil { + return nil, errorsmod.Wrapf(ErrAbiEncoding, "failed to pack data: %s", err) + } + + return encodedData, nil +} From 23366e865021f68a2968d9d2cd3de803c67ca72d Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 6 May 2025 12:13:50 +0400 Subject: [PATCH 16/46] imp: verify autocli --- simapp/app.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/simapp/app.go b/simapp/app.go index beaf93a904e..54dabf15cb5 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -103,6 +103,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" gmp "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp" + gmptypes "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" ica "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts" icacontroller "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/keeper" @@ -554,7 +555,7 @@ func NewSimApp( banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName, ibcexported.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName, - icatypes.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, + icatypes.ModuleName, gmptypes.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, circuittypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) From 230ef6a2198bfe010d47f1f13a27be41fa702263 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 6 May 2025 12:22:44 +0400 Subject: [PATCH 17/46] imp: implemented OnSendPacket --- modules/apps/27-gmp/ibc_module.go | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index 65918a28e8c..61e8604a6a7 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -1,11 +1,16 @@ package gmp import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types" channeltypesv2 "github.com/cosmos/ibc-go/v10/modules/core/04-channel/v2/types" "github.com/cosmos/ibc-go/v10/modules/core/api" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" ) var _ api.IBCModule = (*IBCModule)(nil) @@ -23,8 +28,30 @@ func NewIBCModule(k keeper.Keeper) *IBCModule { } func (im *IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error { - // TODO: implement - panic("not implemented") + if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { + return errorsmod.Wrapf(channeltypesv2.ErrInvalidPacket, "payload port ID is invalid: expected %s, got sourcePort: %s destPort: %s", types.PortID, payload.SourcePort, payload.DestinationPort) + } + if !clienttypes.IsValidClientID(sourceChannel) || !clienttypes.IsValidClientID(destinationChannel) { + return errorsmod.Wrapf(channeltypesv2.ErrInvalidPacket, "client IDs must be in valid format: {string}-{number}") + } + + data, err := types.UnmarshalPacketData(payload.Value, payload.Version, payload.Encoding) + if err != nil { + return err + } + + sender, err := sdk.AccAddressFromBech32(data.Sender) + if err != nil { + return err + } + + if !signer.Equals(sender) { + return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "sender %s is different from signer %s", sender, signer) + } + + // TODO: emit event and telemetry + + return nil } func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult { From 032dd6382380e786e773228e71472d59278f5c00 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 6 May 2025 13:05:19 +0400 Subject: [PATCH 18/46] imp: implemented ack and timeout entry points --- modules/apps/27-gmp/ibc_module.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index 61e8604a6a7..69196da9c70 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -59,12 +59,10 @@ func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel string, destina panic("not implemented") } -func (im *IBCModule) OnTimeoutPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) error { - // TODO: implement - panic("not implemented") +func (im *IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { + return nil } -func (im *IBCModule) OnAcknowledgementPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, acknowledgement []byte, payload channeltypesv2.Payload, relayer sdk.AccAddress) error { - // TODO: implement - panic("not implemented") +func (im *IBCModule) OnAcknowledgementPacket(_ sdk.Context, _, _ string, _ uint64, _ []byte, _ channeltypesv2.Payload, _ sdk.AccAddress) error { + return nil } From 707fa5810d0bb7e918d9ab5a656b6a42f8587441 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 6 May 2025 13:39:35 +0400 Subject: [PATCH 19/46] imp: more boilerplate --- modules/apps/27-gmp/ibc_module.go | 41 +++++++++++++++++++++++++++-- modules/apps/27-gmp/keeper/relay.go | 24 +++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 modules/apps/27-gmp/keeper/relay.go diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index 69196da9c70..ef5a02f2f84 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -1,6 +1,8 @@ package gmp import ( + "fmt" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" @@ -55,8 +57,43 @@ func (im *IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destina } func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult { - // TODO: implement - panic("not implemented") + if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + if payload.Version != types.Version { + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + packetData, ackErr := types.UnmarshalPacketData(payload.Value, payload.Version, payload.Encoding) + if ackErr != nil { + im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + if ackErr = im.keeper.OnRecvPacket( + ctx, + packetData, + payload.SourcePort, + sourceChannel, + payload.DestinationPort, + destinationChannel, + ); ackErr != nil { + im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + im.keeper.Logger(ctx).Info("successfully handled ICS-27 GMP packet", "sequence", sequence) + + // TODO: implement telemetry + panic("implement telemetry") } func (im *IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { diff --git a/modules/apps/27-gmp/keeper/relay.go b/modules/apps/27-gmp/keeper/relay.go new file mode 100644 index 00000000000..54f220aeb5c --- /dev/null +++ b/modules/apps/27-gmp/keeper/relay.go @@ -0,0 +1,24 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" +) + +// OnRecvPacket processes a GMP packet. +// +// If the sender chain is the source of minted tokens then vouchers will be minted +// and sent to the receiving address. Otherwise if the sender chain is sending +// back tokens this chain originally transferred to it, the tokens are +// unescrowed and sent to the receiving address. +func (k Keeper) OnRecvPacket( + ctx sdk.Context, + data *types.GMPPacketData, + sourcePort, + sourceChannel, + destPort, + destChannel string, +) error { + panic("not implemented") // TODO: Implement +} From 06495a46b0d44924f143e513591db286d730c78b Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 6 May 2025 16:16:30 +0400 Subject: [PATCH 20/46] imp: added ack to proto --- modules/apps/27-gmp/types/packet.pb.go | 210 +++++++++++++++++++-- proto/ibc/applications/gmp/v1/packet.proto | 6 + 2 files changed, 199 insertions(+), 17 deletions(-) diff --git a/modules/apps/27-gmp/types/packet.pb.go b/modules/apps/27-gmp/types/packet.pb.go index f9c6538c03f..c7204389840 100644 --- a/modules/apps/27-gmp/types/packet.pb.go +++ b/modules/apps/27-gmp/types/packet.pb.go @@ -104,8 +104,55 @@ func (m *GMPPacketData) GetMemo() string { return "" } +// Acknowledgement defines a struct for the ICS27-2 acknowledgement +type Acknowledgement struct { + // The result of the call + Result []byte `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"` +} + +func (m *Acknowledgement) Reset() { *m = Acknowledgement{} } +func (m *Acknowledgement) String() string { return proto.CompactTextString(m) } +func (*Acknowledgement) ProtoMessage() {} +func (*Acknowledgement) Descriptor() ([]byte, []int) { + return fileDescriptor_2a0b0887619370c4, []int{1} +} +func (m *Acknowledgement) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Acknowledgement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Acknowledgement.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 *Acknowledgement) XXX_Merge(src proto.Message) { + xxx_messageInfo_Acknowledgement.Merge(m, src) +} +func (m *Acknowledgement) XXX_Size() int { + return m.Size() +} +func (m *Acknowledgement) XXX_DiscardUnknown() { + xxx_messageInfo_Acknowledgement.DiscardUnknown(m) +} + +var xxx_messageInfo_Acknowledgement proto.InternalMessageInfo + +func (m *Acknowledgement) GetResult() []byte { + if m != nil { + return m.Result + } + return nil +} + func init() { proto.RegisterType((*GMPPacketData)(nil), "ibc.applications.gmp.v1.GMPPacketData") + proto.RegisterType((*Acknowledgement)(nil), "ibc.applications.gmp.v1.Acknowledgement") } func init() { @@ -113,23 +160,25 @@ func init() { } var fileDescriptor_2a0b0887619370c4 = []byte{ - // 254 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xb1, 0x4a, 0x04, 0x31, - 0x10, 0x86, 0x37, 0x7a, 0x9e, 0x1a, 0xb4, 0x49, 0xa1, 0xc1, 0x22, 0x1c, 0x62, 0x71, 0xcd, 0x6d, - 0x5c, 0x05, 0xed, 0x45, 0xb0, 0x12, 0x96, 0x2b, 0xed, 0x92, 0xec, 0xb0, 0x06, 0x37, 0x37, 0x61, - 0x93, 0x5b, 0xb8, 0x07, 0xb0, 0xf7, 0xb1, 0x2c, 0xaf, 0xb4, 0x94, 0xdd, 0x17, 0x91, 0x0d, 0x2a, - 0xd7, 0xfd, 0xdf, 0xcc, 0xc7, 0xc0, 0x3f, 0xf4, 0xca, 0x6a, 0x23, 0x95, 0xf7, 0x8d, 0x35, 0x2a, - 0x5a, 0x5c, 0x05, 0x59, 0x3b, 0x2f, 0xbb, 0x42, 0x7a, 0x65, 0xde, 0x20, 0xe6, 0xbe, 0xc5, 0x88, - 0xec, 0xdc, 0x6a, 0x93, 0xef, 0x5a, 0x79, 0xed, 0x7c, 0xde, 0x15, 0x97, 0xef, 0x84, 0x9e, 0x3e, - 0x3d, 0x97, 0x65, 0x92, 0x1f, 0x55, 0x54, 0xec, 0x8c, 0x4e, 0x03, 0xac, 0x2a, 0x68, 0x39, 0x99, - 0x91, 0xf9, 0xf1, 0xf2, 0x97, 0xd8, 0x05, 0x3d, 0x6a, 0xc1, 0x80, 0xed, 0xa0, 0xe5, 0x7b, 0x69, - 0xf3, 0xcf, 0x8c, 0xd1, 0x49, 0x50, 0x4d, 0xe4, 0xfb, 0x33, 0x32, 0x3f, 0x59, 0xa6, 0xcc, 0x38, - 0x3d, 0xf4, 0x6a, 0xd3, 0xa0, 0xaa, 0xf8, 0x24, 0x8d, 0xff, 0x70, 0xb4, 0x1d, 0x38, 0xe4, 0x07, - 0xe9, 0x4a, 0xca, 0x0f, 0xe5, 0x67, 0x2f, 0xc8, 0xb6, 0x17, 0xe4, 0xbb, 0x17, 0xe4, 0x63, 0x10, - 0xd9, 0x76, 0x10, 0xd9, 0xd7, 0x20, 0xb2, 0x97, 0xbb, 0xda, 0xc6, 0xd7, 0xb5, 0xce, 0x0d, 0x3a, - 0x69, 0x30, 0x38, 0x0c, 0xd2, 0x6a, 0xb3, 0xa8, 0x51, 0x76, 0xc5, 0xb5, 0x74, 0x58, 0xad, 0x1b, - 0x08, 0xe3, 0x07, 0x82, 0xbc, 0xb9, 0x5f, 0x8c, 0xe5, 0xe3, 0xc6, 0x43, 0xd0, 0xd3, 0xd4, 0xfc, - 0xf6, 0x27, 0x00, 0x00, 0xff, 0xff, 0x92, 0x87, 0x05, 0xc8, 0x21, 0x01, 0x00, 0x00, + // 283 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0x31, 0x4b, 0x33, 0x31, + 0x1c, 0xc6, 0x9b, 0xf7, 0xad, 0x55, 0x43, 0x45, 0xc8, 0xa0, 0xc1, 0x21, 0x94, 0xe2, 0x50, 0x87, + 0x5e, 0xac, 0x82, 0xce, 0x8a, 0xe0, 0x24, 0x1c, 0x37, 0xba, 0xe5, 0x72, 0x7f, 0xce, 0xd0, 0xe4, + 0x12, 0x2e, 0xb9, 0x93, 0x7e, 0x00, 0x77, 0x3f, 0x96, 0x63, 0x47, 0x47, 0xb9, 0xfb, 0x22, 0x72, + 0xa1, 0x8a, 0xdb, 0xf3, 0x4b, 0x1e, 0xfe, 0x3c, 0xfc, 0xf0, 0xb9, 0xca, 0x25, 0x17, 0xce, 0x69, + 0x25, 0x45, 0x50, 0xb6, 0xf2, 0xbc, 0x34, 0x8e, 0xb7, 0x2b, 0xee, 0x84, 0x5c, 0x43, 0x48, 0x5c, + 0x6d, 0x83, 0x25, 0xa7, 0x2a, 0x97, 0xc9, 0xdf, 0x56, 0x52, 0x1a, 0x97, 0xb4, 0xab, 0xf9, 0x1b, + 0xc2, 0x47, 0x8f, 0x4f, 0x69, 0x1a, 0xcb, 0x0f, 0x22, 0x08, 0x72, 0x82, 0x27, 0x1e, 0xaa, 0x02, + 0x6a, 0x8a, 0x66, 0x68, 0x71, 0x98, 0xed, 0x88, 0x9c, 0xe1, 0x83, 0x1a, 0x24, 0xa8, 0x16, 0x6a, + 0xfa, 0x2f, 0xfe, 0xfc, 0x32, 0x21, 0x78, 0xec, 0x85, 0x0e, 0xf4, 0xff, 0x0c, 0x2d, 0xa6, 0x59, + 0xcc, 0x84, 0xe2, 0x7d, 0x27, 0x36, 0xda, 0x8a, 0x82, 0x8e, 0xe3, 0xf3, 0x0f, 0x0e, 0x6d, 0x03, + 0xc6, 0xd2, 0xbd, 0x78, 0x25, 0xe6, 0xf9, 0x05, 0x3e, 0xbe, 0x93, 0xeb, 0xca, 0xbe, 0x6a, 0x28, + 0x4a, 0x30, 0x50, 0x85, 0x61, 0x48, 0x0d, 0xbe, 0xd1, 0x21, 0x0e, 0x99, 0x66, 0x3b, 0xba, 0x4f, + 0x3f, 0x3a, 0x86, 0xb6, 0x1d, 0x43, 0x5f, 0x1d, 0x43, 0xef, 0x3d, 0x1b, 0x6d, 0x7b, 0x36, 0xfa, + 0xec, 0xd9, 0xe8, 0xf9, 0xa6, 0x54, 0xe1, 0xa5, 0xc9, 0x13, 0x69, 0x0d, 0x97, 0xd6, 0x1b, 0xeb, + 0xb9, 0xca, 0xe5, 0xb2, 0xb4, 0xbc, 0x5d, 0x5d, 0x72, 0x63, 0x8b, 0x46, 0x83, 0x1f, 0x64, 0x79, + 0x7e, 0x75, 0xbb, 0x1c, 0x3c, 0x85, 0x8d, 0x03, 0x9f, 0x4f, 0xa2, 0xa4, 0xeb, 0xef, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x3e, 0xa9, 0x52, 0x9d, 0x4c, 0x01, 0x00, 0x00, } func (m *GMPPacketData) Marshal() (dAtA []byte, err error) { @@ -190,6 +239,36 @@ func (m *GMPPacketData) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Acknowledgement) 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 *Acknowledgement) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Acknowledgement) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Result) > 0 { + i -= len(m.Result) + copy(dAtA[i:], m.Result) + i = encodeVarintPacket(dAtA, i, uint64(len(m.Result))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintPacket(dAtA []byte, offset int, v uint64) int { offset -= sovPacket(v) base := offset @@ -230,6 +309,19 @@ func (m *GMPPacketData) Size() (n int) { return n } +func (m *Acknowledgement) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Result) + if l > 0 { + n += 1 + l + sovPacket(uint64(l)) + } + return n +} + func sovPacket(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -450,6 +542,90 @@ func (m *GMPPacketData) Unmarshal(dAtA []byte) error { } return nil } +func (m *Acknowledgement) 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 ErrIntOverflowPacket + } + 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: Acknowledgement: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Acknowledgement: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPacket + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPacket + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPacket + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Result = append(m.Result[:0], dAtA[iNdEx:postIndex]...) + if m.Result == nil { + m.Result = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPacket(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPacket + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipPacket(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/proto/ibc/applications/gmp/v1/packet.proto b/proto/ibc/applications/gmp/v1/packet.proto index da295018e1d..43ede2a576f 100644 --- a/proto/ibc/applications/gmp/v1/packet.proto +++ b/proto/ibc/applications/gmp/v1/packet.proto @@ -17,3 +17,9 @@ message GMPPacketData { // optional memo string memo = 5; } + +// Acknowledgement defines a struct for the ICS27-2 acknowledgement +message Acknowledgement { + // The result of the call + bytes result = 1; +} From eceb5b14384293f231cc481cc75adbac6289c462 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 6 May 2025 16:51:19 +0400 Subject: [PATCH 21/46] imp: added ack helpers --- modules/apps/27-gmp/types/ack.go | 74 +++++++++++++++++++++++ modules/apps/27-gmp/types/solidity_abi.go | 72 ++++++++++++++++++++-- 2 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 modules/apps/27-gmp/types/ack.go diff --git a/modules/apps/27-gmp/types/ack.go b/modules/apps/27-gmp/types/ack.go new file mode 100644 index 00000000000..94135328a4d --- /dev/null +++ b/modules/apps/27-gmp/types/ack.go @@ -0,0 +1,74 @@ +package types + +import ( + "encoding/json" + + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/cosmos-sdk/codec/unknownproto" + + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// NewAcknowledgement creates a new Acknowledgement +func NewAcknowledgement(result []byte) Acknowledgement { + return Acknowledgement{ + Result: result, + } +} + +// ValidateBasic performs basic validation on the Acknowledgement +func (ack Acknowledgement) ValidateBasic() error { + return nil +} + +func MarshalAcknowledgement(data *Acknowledgement, ics27Version string, encoding string) ([]byte, error) { + if ics27Version != Version { + panic("unsupported ics27 version") + } + + switch encoding { + case EncodingJSON: + return json.Marshal(data) + case EncodingProtobuf: + return proto.Marshal(data) + case EncodingABI: + return EncodeABIAcknowledgement(data) + default: + return nil, errorsmod.Wrapf(ErrInvalidEncoding, "invalid encoding provided, must be either empty or one of [%q, %q, %q], got %s", EncodingJSON, EncodingProtobuf, EncodingABI, encoding) + } +} + +func UnmarshalAcknowledgement(bz []byte, ics27Version string, encoding string) (*Acknowledgement, error) { + if ics27Version != Version { + panic("unsupported ics27 version") + } + + var data *Acknowledgement + switch encoding { + case EncodingJSON: + if err := json.Unmarshal(bz, &data); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal json packet data: %s", err) + } + case EncodingProtobuf: + if err := unknownproto.RejectUnknownFieldsStrict(bz, data, unknownproto.DefaultAnyResolver{}); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal protobuf packet data: %s", err) + } + + if err := proto.Unmarshal(bz, data); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal protobuf packet data: %s", err) + } + case EncodingABI: + var err error + data, err = DecodeABIAcknowledgement(bz) + if err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal ABI packet data: %s", err) + } + default: + return nil, errorsmod.Wrapf(ErrInvalidEncoding, "invalid encoding provided, must be either empty or one of [%q, %q, %q], got %s", EncodingJSON, EncodingProtobuf, EncodingABI, encoding) + } + + return data, nil +} diff --git a/modules/apps/27-gmp/types/solidity_abi.go b/modules/apps/27-gmp/types/solidity_abi.go index 94438efbf86..7a78e27b6bb 100644 --- a/modules/apps/27-gmp/types/solidity_abi.go +++ b/modules/apps/27-gmp/types/solidity_abi.go @@ -6,8 +6,8 @@ import ( errorsmod "cosmossdk.io/errors" ) -// getICS27ABI returns an abi.Arguments slice describing the Solidity types of the struct. -func getICS27ABI() abi.Arguments { +// getICS27PacketABI returns an abi.Arguments slice describing the Solidity types of the struct. +func getICS27PacketABI() abi.Arguments { // Create the ABI types for each field. // The Solidity types used are: // - string for Sender, Receiver and Memo. @@ -48,9 +48,34 @@ func getICS27ABI() abi.Arguments { return arguments } +// getICS27AckABI returns an abi.Arguments slice describing the Solidity types of the struct. +func getICS27AckABI() abi.Arguments { + // Create the ABI types for each field. + // The Solidity types used are: + // - bytes for Result. + tupleType, err := abi.NewType("tuple", "", []abi.ArgumentMarshaling{ + { + Name: "result", + Type: "bytes", + }, + }) + if err != nil { + panic(err) + } + + // Create an ABI argument representing our struct as a single tuple argument. + arguments := abi.Arguments{ + { + Type: tupleType, + }, + } + + return arguments +} + // DecodeABIGMPPacketData decodes a solidity ABI encoded ics27lib.GMPPacketData and converts it into an ibc-go GMPPacketData. func DecodeABIGMPPacketData(data []byte) (*GMPPacketData, error) { - arguments := getICS27ABI() + arguments := getICS27PacketABI() packetDataI, err := arguments.Unpack(data) if err != nil { @@ -93,7 +118,7 @@ func EncodeABIGMPPacketData(data *GMPPacketData) ([]byte, error) { data.Memo, } - arguments := getICS27ABI() + arguments := getICS27PacketABI() // Pack the values in the order defined in the ABI. encodedData, err := arguments.Pack(packetData) if err != nil { @@ -102,3 +127,42 @@ func EncodeABIGMPPacketData(data *GMPPacketData) ([]byte, error) { return encodedData, nil } + +// DecodeABIAcknowledgement decodes a solidity ABI encoded ics27lib.Acknowledgement and converts it into an ibc-go Acknowledgement +func DecodeABIAcknowledgement(data []byte) (*Acknowledgement, error) { + arguments := getICS27AckABI() + + packetDataI, err := arguments.Unpack(data) + if err != nil { + return nil, errorsmod.Wrapf(ErrAbiDecoding, "failed to unpack data: %s", err) + } + + packetData, ok := packetDataI[0].(struct { + Result []byte `json:"result"` + }) + if !ok { + return nil, errorsmod.Wrapf(ErrAbiDecoding, "failed to parse packet data") + } + + return &Acknowledgement{ + Result: packetData.Result, + }, nil +} + +// EncodeABIAcknowledgement encodes an Acknowledgement into a solidity ABI encoded byte array +func EncodeABIAcknowledgement(data *Acknowledgement) ([]byte, error) { + ack := struct { + Result []byte `json:"result"` + }{ + Result: data.Result, + } + + arguments := getICS27AckABI() + // Pack the values in the order defined in the ABI. + encodedData, err := arguments.Pack(ack) + if err != nil { + return nil, errorsmod.Wrapf(ErrAbiEncoding, "failed to pack data: %s", err) + } + + return encodedData, nil +} From 2bd764dcb2f609fa83689fa5db67c19fdb95179e Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 6 May 2025 17:49:48 +0400 Subject: [PATCH 22/46] imp: more boilerplate --- modules/apps/27-gmp/ibc_module.go | 22 ++++++++++++++++++---- modules/apps/27-gmp/keeper/relay.go | 8 ++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index ef5a02f2f84..27fd714f6fc 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -56,7 +56,7 @@ func (im *IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destina return nil } -func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult { +func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, relayer sdk.AccAddress) channeltypesv2.RecvPacketResult { if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { return channeltypesv2.RecvPacketResult{ Status: channeltypesv2.PacketStatus_Failure, @@ -76,14 +76,24 @@ func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel string, destina } } - if ackErr = im.keeper.OnRecvPacket( + result, ackErr := im.keeper.OnRecvPacket( ctx, packetData, payload.SourcePort, sourceChannel, payload.DestinationPort, destinationChannel, - ); ackErr != nil { + ) + if ackErr != nil { + im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + + ack := types.NewAcknowledgement(result) + ackBz, ackErr := types.MarshalAcknowledgement(&ack, types.Version, payload.Encoding) + if ackErr != nil { im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) return channeltypesv2.RecvPacketResult{ Status: channeltypesv2.PacketStatus_Failure, @@ -93,7 +103,11 @@ func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel string, destina im.keeper.Logger(ctx).Info("successfully handled ICS-27 GMP packet", "sequence", sequence) // TODO: implement telemetry - panic("implement telemetry") + + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Success, + Acknowledgement: ackBz, + } } func (im *IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { diff --git a/modules/apps/27-gmp/keeper/relay.go b/modules/apps/27-gmp/keeper/relay.go index 54f220aeb5c..f56af2ff909 100644 --- a/modules/apps/27-gmp/keeper/relay.go +++ b/modules/apps/27-gmp/keeper/relay.go @@ -7,11 +7,7 @@ import ( ) // OnRecvPacket processes a GMP packet. -// -// If the sender chain is the source of minted tokens then vouchers will be minted -// and sent to the receiving address. Otherwise if the sender chain is sending -// back tokens this chain originally transferred to it, the tokens are -// unescrowed and sent to the receiving address. +// Returns the data result of the execution if successful. func (k Keeper) OnRecvPacket( ctx sdk.Context, data *types.GMPPacketData, @@ -19,6 +15,6 @@ func (k Keeper) OnRecvPacket( sourceChannel, destPort, destChannel string, -) error { +) ([]byte, error) { panic("not implemented") // TODO: Implement } From d3a9cd927a5c7b930d8931f96fad2024f3c9ed7e Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 12:46:06 +0400 Subject: [PATCH 23/46] feat: added account gen --- modules/apps/27-gmp/keeper/account.go | 61 ++++++++++++++++++++++++++ modules/apps/27-gmp/keeper/keeper.go | 5 ++- modules/apps/27-gmp/keeper/relay.go | 11 ++++- modules/apps/27-gmp/types/account.go | 62 +++++++++++++++++++++++++++ modules/apps/27-gmp/types/errors.go | 1 + modules/apps/27-gmp/types/keys.go | 3 ++ modules/apps/27-gmp/types/packet.go | 5 +-- 7 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 modules/apps/27-gmp/keeper/account.go create mode 100644 modules/apps/27-gmp/types/account.go diff --git a/modules/apps/27-gmp/keeper/account.go b/modules/apps/27-gmp/keeper/account.go new file mode 100644 index 00000000000..4e9273974e0 --- /dev/null +++ b/modules/apps/27-gmp/keeper/account.go @@ -0,0 +1,61 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/collections" + errorsmod "cosmossdk.io/errors" + + "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" +) + +// getOrCreateICS27Account retrieves an existing ICS27 account or creates a new one if it doesn't exist. +func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountId *types.AccountIdentifier) (*types.ICS27Account, error) { + existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountId.ClientId, accountId.Sender, accountId.Salt)) + if err == nil { + return &existingIcs27Account, nil + } else if !errorsmod.IsOf(err, collections.ErrNotFound) { + return nil, err + } + + // Create a new account + newAddr, err := types.BuildAddressPredictable(accountId) + if err != nil { + return nil, err + } + + existingAcc := k.accountKeeper.GetAccount(ctx, newAddr) + if existingAcc != nil { + // TODO: ensure this cannot be abused + return nil, errorsmod.Wrapf(types.ErrAccountAlreadyExists, "existing account for newly generated ICS27 account address %s", newAddr) + } + + newAcc := k.accountKeeper.NewAccountWithAddress(ctx, newAddr) + k.accountKeeper.SetAccount(ctx, newAcc) + + ics27Account := types.NewICS27Account(newAcc.GetAddress().String(), accountId) + if err := k.Accounts.Set(ctx, collections.Join3(accountId.ClientId, accountId.Sender, accountId.Salt), ics27Account); err != nil { + return nil, errorsmod.Wrapf(err, "failed to set account %s in store", ics27Account) + } + + k.Logger(ctx).Info("Created new ICS27 account", "account", ics27Account) + return &ics27Account, nil +} + +// getOrComputeICS27Adderss retrieves an existing ICS27 account address or computes it if it doesn't exist. This doesn't modify the store. +func (k Keeper) getOrComputeICS27Address(ctx context.Context, accountId *types.AccountIdentifier) (string, error) { + existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountId.ClientId, accountId.Sender, accountId.Salt)) + if err == nil { + return existingIcs27Account.Address, nil + } else if !errorsmod.IsOf(err, collections.ErrNotFound) { + return "", err + } + + // Compute a new address + newAddr, err := types.BuildAddressPredictable(accountId) + if err != nil { + return "", err + } + + return newAddr.String(), nil +} diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go index 80f149f0dbd..41b5569a9e7 100644 --- a/modules/apps/27-gmp/keeper/keeper.go +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -1,6 +1,7 @@ package keeper import ( + "context" "errors" "strings" @@ -66,6 +67,6 @@ func (k Keeper) GetAuthority() string { } // Logger returns a module-specific logger. -func (Keeper) Logger(ctx sdk.Context) log.Logger { - return ctx.Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName) +func (Keeper) Logger(goCtx context.Context) log.Logger { + return sdk.UnwrapSDKContext(goCtx).Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName) } diff --git a/modules/apps/27-gmp/keeper/relay.go b/modules/apps/27-gmp/keeper/relay.go index f56af2ff909..8e955315090 100644 --- a/modules/apps/27-gmp/keeper/relay.go +++ b/modules/apps/27-gmp/keeper/relay.go @@ -12,9 +12,16 @@ func (k Keeper) OnRecvPacket( ctx sdk.Context, data *types.GMPPacketData, sourcePort, - sourceChannel, + sourceClient, destPort, - destChannel string, + destClient string, ) ([]byte, error) { + accountId := types.NewAccountIdentifier(destClient, data.Sender, data.Salt) + + _, err := k.getOrCreateICS27Account(ctx, &accountId) + if err != nil { + return nil, err + } + panic("not implemented") // TODO: Implement } diff --git a/modules/apps/27-gmp/types/account.go b/modules/apps/27-gmp/types/account.go new file mode 100644 index 00000000000..369c3fe2444 --- /dev/null +++ b/modules/apps/27-gmp/types/account.go @@ -0,0 +1,62 @@ +package types + +import ( + "strings" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + + host "github.com/cosmos/ibc-go/v10/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" +) + +// NewAccountIdentifier creates a new AccountIdentifier with the given clientId, sender, and salt. +func NewAccountIdentifier(clientId, sender string, salt []byte) AccountIdentifier { + return AccountIdentifier{ + ClientId: clientId, + Sender: sender, + Salt: salt, + } +} + +// NewICS27Account creates a new ICS27Account with the given address and accountId. +func NewICS27Account(address string, accountId *AccountIdentifier) ICS27Account { + return ICS27Account{ + Address: address, + AccountId: accountId, + } +} + +// BuildAddressPredictable generates an account address for the gmp module with len = types.AccountAddrLen using the +// Cosmos SDK address.Module function. +// Internally a key is built containing: +// (len(clientId) | clientId | len(sender) | sender | len(salt) | salt). +// +// All method parameter values must be valid and not nil. +// +// This function was copied from wasmd and modified. +// +func BuildAddressPredictable(accountId *AccountIdentifier) (sdk.AccAddress, error) { + if err := host.ClientIdentifierValidator(accountId.ClientId); err != nil { + return nil, errorsmod.Wrapf(err, "invalid client ID %s", accountId.ClientId) + } + if strings.TrimSpace(accountId.Sender) == "" { + return nil, errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing sender address") + } + + clientIdBz := uint64LengthPrefix([]byte(accountId.ClientId)) + senderBz := uint64LengthPrefix([]byte(accountId.Sender)) + saltBz := uint64LengthPrefix(accountId.Salt) + key := make([]byte, len(clientIdBz)+len(senderBz)+len(saltBz)) + copy(key[0:], clientIdBz) + copy(key[len(clientIdBz):], senderBz) + copy(key[len(clientIdBz)+len(senderBz):], saltBz) + return address.Module(accountsKey, key)[:AccountAddrLen], nil +} + +// uint64LengthPrefix prepend big endian encoded byte length +func uint64LengthPrefix(bz []byte) []byte { + return append(sdk.Uint64ToBigEndian(uint64(len(bz))), bz...) +} diff --git a/modules/apps/27-gmp/types/errors.go b/modules/apps/27-gmp/types/errors.go index 50947d8c33f..6e0f8badfc7 100644 --- a/modules/apps/27-gmp/types/errors.go +++ b/modules/apps/27-gmp/types/errors.go @@ -11,4 +11,5 @@ var ( ErrInvalidEncoding = errorsmod.Register(ModuleName, 6, "invalid encoding") ErrAbiDecoding = errorsmod.Register(ModuleName, 7, "abi decoding error") ErrAbiEncoding = errorsmod.Register(ModuleName, 8, "abi encoding error") + ErrAccountAlreadyExists = errorsmod.Register(ModuleName, 9, "account already exists") ) diff --git a/modules/apps/27-gmp/types/keys.go b/modules/apps/27-gmp/types/keys.go index ab44e86f3d4..7613aaf9904 100644 --- a/modules/apps/27-gmp/types/keys.go +++ b/modules/apps/27-gmp/types/keys.go @@ -23,6 +23,9 @@ const ( // accountsKey is the key used when generating a module address for the gmp module accountsKey = "gmp-accounts" + + // AccountAddrLen is the length of the ICS27 account address + AccountAddrLen = 32 ) var ( diff --git a/modules/apps/27-gmp/types/packet.go b/modules/apps/27-gmp/types/packet.go index beaf6213599..6b3c06b59f9 100644 --- a/modules/apps/27-gmp/types/packet.go +++ b/modules/apps/27-gmp/types/packet.go @@ -9,7 +9,6 @@ import ( errorsmod "cosmossdk.io/errors" "github.com/cosmos/cosmos-sdk/codec/unknownproto" - sdk "github.com/cosmos/cosmos-sdk/types" ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" ) @@ -34,8 +33,8 @@ func NewGMPPacketData( } func (p GMPPacketData) ValidateBasic() error { - if _, err := sdk.AccAddressFromBech32(p.Sender); err != nil { - return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + if strings.TrimSpace(p.Sender) == "" { + return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing sender address") } if strings.TrimSpace(p.Receiver) == "" { return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing recipient address") From 0fab11f349c5dd772172dafe518e0b28f90273b3 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 15:02:56 +0400 Subject: [PATCH 24/46] imp: added cosmos tx --- proto/ibc/applications/gmp/v1/account.proto | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proto/ibc/applications/gmp/v1/account.proto b/proto/ibc/applications/gmp/v1/account.proto index a683470b737..ce1680f3d24 100644 --- a/proto/ibc/applications/gmp/v1/account.proto +++ b/proto/ibc/applications/gmp/v1/account.proto @@ -4,6 +4,7 @@ package ibc.applications.gmp.v1; option go_package = "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types"; +import "google/protobuf/any.proto"; import "cosmos_proto/cosmos.proto"; // AccountIdentifier is used to identify a ICS27 account. @@ -21,3 +22,8 @@ message ICS27Account { string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; AccountIdentifier account_id = 2; } + +// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. +message CosmosTx { + repeated google.protobuf.Any messages = 1; +} From 134b82a708de551b6f9045716a573b5d3fb1f5f0 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 15:46:25 +0400 Subject: [PATCH 25/46] imp: implemented receive --- modules/apps/27-gmp/ibc_module.go | 11 ++ modules/apps/27-gmp/keeper/keeper.go | 4 +- modules/apps/27-gmp/keeper/relay.go | 126 ++++++++++++- modules/apps/27-gmp/types/account.go | 55 ++++++ modules/apps/27-gmp/types/account.pb.go | 229 +++++++++++++++++++++--- modules/apps/27-gmp/types/errors.go | 2 + 6 files changed, 402 insertions(+), 25 deletions(-) diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index 27fd714f6fc..421273f8bfc 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -42,6 +42,10 @@ func (im *IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destina return err } + if err := data.ValidateBasic(); err != nil { + return errorsmod.Wrapf(err, "failed to validate %s packet data", types.Version) + } + sender, err := sdk.AccAddressFromBech32(data.Sender) if err != nil { return err @@ -76,6 +80,13 @@ func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel, destinationCha } } + if ackErr := packetData.ValidateBasic(); ackErr != nil { + im.keeper.Logger(ctx).Error(fmt.Sprintf("%s sequence %d", ackErr.Error(), sequence)) + return channeltypesv2.RecvPacketResult{ + Status: channeltypesv2.PacketStatus_Failure, + } + } + result, ackErr := im.keeper.OnRecvPacket( ctx, packetData, diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go index 41b5569a9e7..20e7db00ce2 100644 --- a/modules/apps/27-gmp/keeper/keeper.go +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -18,7 +18,7 @@ import ( // Keeper defines the IBC fungible transfer keeper type Keeper struct { - cdc codec.BinaryCodec + cdc codec.Codec msgRouter types.MessageRouter @@ -36,7 +36,7 @@ type Keeper struct { // NewKeeper creates a new Keeper instance func NewKeeper( - cdc codec.BinaryCodec, storeService storetypes.KVStoreService, + cdc codec.Codec, storeService storetypes.KVStoreService, accountKeeper types.AccountKeeper, msgRouter types.MessageRouter, authority string, ) Keeper { diff --git a/modules/apps/27-gmp/keeper/relay.go b/modules/apps/27-gmp/keeper/relay.go index 8e955315090..6e44935de9f 100644 --- a/modules/apps/27-gmp/keeper/relay.go +++ b/modules/apps/27-gmp/keeper/relay.go @@ -1,9 +1,17 @@ package keeper import ( + "bytes" + + "github.com/cosmos/gogoproto/proto" + + errorsmod "cosmossdk.io/errors" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" + ibcerrors "github.com/cosmos/ibc-go/v10/modules/core/errors" ) // OnRecvPacket processes a GMP packet. @@ -18,10 +26,124 @@ func (k Keeper) OnRecvPacket( ) ([]byte, error) { accountId := types.NewAccountIdentifier(destClient, data.Sender, data.Salt) - _, err := k.getOrCreateICS27Account(ctx, &accountId) + ics27Acc, err := k.getOrCreateICS27Account(ctx, &accountId) + if err != nil { + return nil, err + } + + ics27Addr, err := sdk.AccAddressFromBech32(ics27Acc.Address) + if err != nil { + return nil, err + } + + ics27SdkAcc := k.accountKeeper.GetAccount(ctx, ics27Addr) + if ics27SdkAcc == nil { + return nil, errorsmod.Wrapf(types.ErrAccountNotFound, "account %s not found", ics27Addr) + } + + txResponse, err := k.executeTx(ctx, ics27SdkAcc, data.Payload) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed to execute ICS27 account transaction") + } + + return txResponse, nil +} + +// executeTx attempts to execute the provided transaction. It begins by authenticating the transaction signer. +// If authentication succeeds, it does basic validation of the messages before attempting to deliver each message +// into state. The state changes will only be committed if all messages in the transaction succeed. Thus the +// execution of the transaction is atomic, all state changes are reverted if a single message fails. +func (k Keeper) executeTx(ctx sdk.Context, account sdk.AccountI, payload []byte) ([]byte, error) { + msgs, err := types.DeserializeCosmosTx(k.cdc, payload) + if err != nil { + return nil, errorsmod.Wrapf(err, "failed to deserialize ICS27 CosmosTx") + } + + if err := k.authenticateTx(ctx, account, msgs); err != nil { + return nil, err + } + + txMsgData := &sdk.TxMsgData{ + MsgResponses: make([]*codectypes.Any, len(msgs)), + } + + // CacheContext returns a new context with the multi-store branched into a cached storage object + // writeCache is called only if all msgs succeed, performing state transitions atomically + cacheCtx, writeCache := ctx.CacheContext() + for i, msg := range msgs { + if m, ok := msg.(sdk.HasValidateBasic); ok { + if err := m.ValidateBasic(); err != nil { + return nil, err + } + } + + protoAny, err := k.executeMsg(cacheCtx, msg) + if err != nil { + return nil, err + } + + txMsgData.MsgResponses[i] = protoAny + } + + writeCache() + + txResponse, err := proto.Marshal(txMsgData) + if err != nil { + return nil, errorsmod.Wrap(err, "failed to marshal tx data") + } + + return txResponse, nil +} + +// authenticateTx checks that the transaction is signed by the expected signer. +func (k Keeper) authenticateTx(ctx sdk.Context, account sdk.AccountI, msgs []sdk.Msg) error { + if len(msgs) == 0 { + return errorsmod.Wrapf(types.ErrInvalidPayload, "empty message list") + } + + accountAddr := account.GetAddress() + for _, msg := range msgs { + // obtain the message signers using the proto signer annotations + // the msgv2 return value is discarded as it is not used + signers, _, err := k.cdc.GetMsgV1Signers(msg) + if err != nil { + return errorsmod.Wrapf(err, "failed to obtain message signers for message type %s", sdk.MsgTypeURL(msg)) + } + + for _, signer := range signers { + // the interchain account address is stored as the string value of the sdk.AccAddress type + // thus we must cast the signer to a sdk.AccAddress to obtain the comparison value + // the stored interchain account address must match the signer for every message to be executed + if !bytes.Equal(signer, accountAddr.Bytes()) { + return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "unexpected signer address: expected %s, got %s", accountAddr, sdk.AccAddress(signer)) + } + } + } + + return nil +} + +// Attempts to get the message handler from the router and if found will then execute the message. +// If the message execution is successful, the proto marshaled message response will be returned. +func (k Keeper) executeMsg(ctx sdk.Context, msg sdk.Msg) (*codectypes.Any, error) { + handler := k.msgRouter.Handler(msg) + if handler == nil { + return nil, types.ErrInvalidMsgRoute + } + + res, err := handler(ctx, msg) if err != nil { return nil, err } - panic("not implemented") // TODO: Implement + // NOTE: The sdk msg handler creates a new EventManager, so events must be correctly propagated back to the current context + ctx.EventManager().EmitEvents(res.GetEvents()) + + // Each individual sdk.Result has exactly one Msg response. We aggregate here. + msgResponse := res.MsgResponses[0] + if msgResponse == nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrLogic, "got nil Msg response for msg %s", sdk.MsgTypeURL(msg)) + } + + return msgResponse, nil } diff --git a/modules/apps/27-gmp/types/account.go b/modules/apps/27-gmp/types/account.go index 369c3fe2444..86c0eb932c8 100644 --- a/modules/apps/27-gmp/types/account.go +++ b/modules/apps/27-gmp/types/account.go @@ -3,8 +3,12 @@ package types import ( "strings" + "github.com/cosmos/gogoproto/proto" + errorsmod "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" @@ -60,3 +64,54 @@ func BuildAddressPredictable(accountId *AccountIdentifier) (sdk.AccAddress, erro func uint64LengthPrefix(bz []byte) []byte { return append(sdk.Uint64ToBigEndian(uint64(len(bz))), bz...) } + +// DeserializeCosmosTx unmarshals and unpacks a slice of transaction bytes into a slice of sdk.Msg's. +// The transaction bytes are unmarshaled depending on the encoding type passed in. The sdk.Msg's are +// unpacked from Any's and returned. +func DeserializeCosmosTx(cdc codec.BinaryCodec, data []byte) ([]sdk.Msg, error) { + var cosmosTx CosmosTx + if err := cdc.Unmarshal(data, &cosmosTx); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "cannot unmarshal CosmosTx with protobuf: %v", err) + } + + msgs := make([]sdk.Msg, len(cosmosTx.Messages)) + + for i, protoAny := range cosmosTx.Messages { + var msg sdk.Msg + err := cdc.UnpackAny(protoAny, &msg) + if err != nil { + return nil, err + } + msgs[i] = msg + } + + return msgs, nil +} + +// SerializeCosmosTx serializes a slice of sdk.Msg's using the CosmosTx type. The sdk.Msg's are +// packed into Any's and inserted into the Messages field of a CosmosTx. The CosmosTx is marshaled +// depending on the encoding type passed in. The marshaled bytes are returned. +func SerializeCosmosTx(cdc codec.BinaryCodec, msgs []proto.Message) ([]byte, error) { + var ( + bz []byte + err error + ) + msgAnys := make([]*codectypes.Any, len(msgs)) + for i, msg := range msgs { + msgAnys[i], err = codectypes.NewAnyWithValue(msg) + if err != nil { + return nil, err + } + } + + cosmosTx := &CosmosTx{ + Messages: msgAnys, + } + + bz, err = cdc.Marshal(cosmosTx) + if err != nil { + return nil, errorsmod.Wrapf(err, "cannot marshal CosmosTx with protobuf") + } + + return bz, nil +} diff --git a/modules/apps/27-gmp/types/account.pb.go b/modules/apps/27-gmp/types/account.pb.go index 523ce488779..22288175f99 100644 --- a/modules/apps/27-gmp/types/account.pb.go +++ b/modules/apps/27-gmp/types/account.pb.go @@ -6,6 +6,7 @@ package types import ( fmt "fmt" _ "github.com/cosmos/cosmos-proto" + types "github.com/cosmos/cosmos-sdk/codec/types" proto "github.com/cosmos/gogoproto/proto" io "io" math "math" @@ -140,9 +141,55 @@ func (m *ICS27Account) GetAccountId() *AccountIdentifier { return nil } +// CosmosTx contains a list of sdk.Msg's. It should be used when sending transactions to an SDK host chain. +type CosmosTx struct { + Messages []*types.Any `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"` +} + +func (m *CosmosTx) Reset() { *m = CosmosTx{} } +func (m *CosmosTx) String() string { return proto.CompactTextString(m) } +func (*CosmosTx) ProtoMessage() {} +func (*CosmosTx) Descriptor() ([]byte, []int) { + return fileDescriptor_5d5b886ccdedc1db, []int{2} +} +func (m *CosmosTx) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CosmosTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CosmosTx.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 *CosmosTx) XXX_Merge(src proto.Message) { + xxx_messageInfo_CosmosTx.Merge(m, src) +} +func (m *CosmosTx) XXX_Size() int { + return m.Size() +} +func (m *CosmosTx) XXX_DiscardUnknown() { + xxx_messageInfo_CosmosTx.DiscardUnknown(m) +} + +var xxx_messageInfo_CosmosTx proto.InternalMessageInfo + +func (m *CosmosTx) GetMessages() []*types.Any { + if m != nil { + return m.Messages + } + return nil +} + func init() { proto.RegisterType((*AccountIdentifier)(nil), "ibc.applications.gmp.v1.AccountIdentifier") proto.RegisterType((*ICS27Account)(nil), "ibc.applications.gmp.v1.ICS27Account") + proto.RegisterType((*CosmosTx)(nil), "ibc.applications.gmp.v1.CosmosTx") } func init() { @@ -150,27 +197,31 @@ func init() { } var fileDescriptor_5d5b886ccdedc1db = []byte{ - // 314 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x51, 0x4f, 0x4b, 0xc3, 0x30, - 0x14, 0x5f, 0x54, 0xa6, 0x8b, 0xbb, 0x18, 0x44, 0xab, 0x42, 0x19, 0x03, 0x61, 0x08, 0x4b, 0x5c, - 0x05, 0x77, 0xde, 0x3c, 0xf5, 0x26, 0xdd, 0x4d, 0x84, 0x91, 0x26, 0xb1, 0x06, 0xda, 0x24, 0x34, - 0xd9, 0xc0, 0x0f, 0x21, 0xf8, 0x61, 0xfc, 0x10, 0x1e, 0x87, 0x27, 0x8f, 0xb2, 0x7d, 0x11, 0x69, - 0xd3, 0x81, 0x20, 0xde, 0xf2, 0xde, 0xfb, 0xe5, 0xfd, 0xfe, 0x3c, 0x78, 0x29, 0x53, 0x46, 0xa8, - 0x31, 0xb9, 0x64, 0xd4, 0x49, 0xad, 0x2c, 0xc9, 0x0a, 0x43, 0x96, 0x23, 0x42, 0x19, 0xd3, 0x0b, - 0xe5, 0xb0, 0x29, 0xb5, 0xd3, 0xe8, 0x54, 0xa6, 0x0c, 0xff, 0x86, 0xe1, 0xac, 0x30, 0x78, 0x39, - 0x3a, 0x3f, 0x63, 0xda, 0x16, 0xda, 0xce, 0x6b, 0x18, 0xf1, 0x85, 0xff, 0xd3, 0x7f, 0x84, 0x47, - 0x13, 0xbf, 0x24, 0xe6, 0x42, 0x39, 0xf9, 0x24, 0x45, 0x89, 0x2e, 0x60, 0x87, 0xe5, 0x52, 0x28, - 0x37, 0x97, 0x3c, 0x00, 0x3d, 0x30, 0xe8, 0x24, 0x07, 0xbe, 0x11, 0x73, 0x74, 0x02, 0xdb, 0x56, - 0x28, 0x2e, 0xca, 0x60, 0xa7, 0x9e, 0x34, 0x15, 0x42, 0x70, 0xcf, 0xd2, 0xdc, 0x05, 0xbb, 0x3d, - 0x30, 0xe8, 0x26, 0xf5, 0xbb, 0xff, 0x0a, 0x60, 0x37, 0xbe, 0x9b, 0x45, 0xe3, 0x86, 0x03, 0x45, - 0x70, 0x9f, 0x72, 0x5e, 0x0a, 0x6b, 0xfd, 0xde, 0x69, 0xf0, 0xf9, 0x3e, 0x3c, 0x6e, 0x14, 0x4d, - 0xfc, 0x64, 0xe6, 0x4a, 0xa9, 0xb2, 0x64, 0x0b, 0x44, 0x31, 0x84, 0x8d, 0xcf, 0x4a, 0x4e, 0x45, - 0x7a, 0x18, 0x5d, 0xe1, 0x7f, 0xbc, 0xe2, 0x3f, 0x6e, 0x92, 0x0e, 0xdd, 0xb6, 0xa6, 0xf7, 0x1f, - 0xeb, 0x10, 0xac, 0xd6, 0x21, 0xf8, 0x5e, 0x87, 0xe0, 0x6d, 0x13, 0xb6, 0x56, 0x9b, 0xb0, 0xf5, - 0xb5, 0x09, 0x5b, 0x0f, 0xb7, 0x99, 0x74, 0xcf, 0x8b, 0x14, 0x33, 0x5d, 0x34, 0x01, 0x11, 0x99, - 0xb2, 0x61, 0xa6, 0xc9, 0x72, 0x74, 0x4d, 0x0a, 0xcd, 0x17, 0xb9, 0xb0, 0xd5, 0x0d, 0x2c, 0x89, - 0xc6, 0xc3, 0x2a, 0x7e, 0xf7, 0x62, 0x84, 0x4d, 0xdb, 0x75, 0x8c, 0x37, 0x3f, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x9a, 0x1a, 0xd8, 0x45, 0xa3, 0x01, 0x00, 0x00, + // 370 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x51, 0x41, 0x8b, 0xda, 0x40, + 0x18, 0x35, 0xb5, 0x58, 0x1d, 0xbd, 0x74, 0x90, 0x36, 0x5a, 0x08, 0x22, 0x14, 0xa4, 0xe0, 0x8c, + 0xa6, 0x50, 0x2f, 0xbd, 0xa8, 0xa7, 0xdc, 0x4a, 0xec, 0xa9, 0x14, 0x64, 0x32, 0x19, 0x67, 0x07, + 0x92, 0x99, 0x90, 0x99, 0xc8, 0xfa, 0x23, 0x16, 0xf6, 0xc7, 0xec, 0x8f, 0xd8, 0xa3, 0xec, 0x69, + 0x8f, 0x8b, 0xfe, 0x91, 0x25, 0x99, 0xb8, 0x2c, 0x2c, 0x7b, 0xcb, 0xfb, 0xde, 0xcb, 0xf7, 0xde, + 0xbc, 0x0f, 0x7c, 0x17, 0x11, 0xc5, 0x24, 0xcb, 0x12, 0x41, 0x89, 0x11, 0x4a, 0x6a, 0xcc, 0xd3, + 0x0c, 0xef, 0xe7, 0x98, 0x50, 0xaa, 0x0a, 0x69, 0x50, 0x96, 0x2b, 0xa3, 0xe0, 0x57, 0x11, 0x51, + 0xf4, 0x5a, 0x86, 0x78, 0x9a, 0xa1, 0xfd, 0x7c, 0x38, 0xe0, 0x4a, 0xf1, 0x84, 0xe1, 0x4a, 0x16, + 0x15, 0x3b, 0x4c, 0xe4, 0xc1, 0xfe, 0x33, 0x1c, 0x50, 0xa5, 0x53, 0xa5, 0xb7, 0x15, 0xc2, 0x16, + 0x58, 0x6a, 0xfc, 0x1f, 0x7c, 0x5e, 0xda, 0xfd, 0x41, 0xcc, 0xa4, 0x11, 0x3b, 0xc1, 0x72, 0xf8, + 0x0d, 0x74, 0x68, 0x22, 0x98, 0x34, 0x5b, 0x11, 0xbb, 0xce, 0xc8, 0x99, 0x74, 0xc2, 0xb6, 0x1d, + 0x04, 0x31, 0xfc, 0x02, 0x5a, 0x9a, 0xc9, 0x98, 0xe5, 0xee, 0x87, 0x8a, 0xa9, 0x11, 0x84, 0xe0, + 0xa3, 0x26, 0x89, 0x71, 0x9b, 0x23, 0x67, 0xd2, 0x0b, 0xab, 0xef, 0xf1, 0x8d, 0x03, 0x7a, 0xc1, + 0x7a, 0xe3, 0x2f, 0x6a, 0x0f, 0xe8, 0x83, 0x4f, 0x24, 0x8e, 0x73, 0xa6, 0xb5, 0xdd, 0xbb, 0x72, + 0x1f, 0xee, 0xa6, 0xfd, 0x3a, 0xd1, 0xd2, 0x32, 0x1b, 0x93, 0x0b, 0xc9, 0xc3, 0x8b, 0x10, 0x06, + 0x00, 0xd4, 0x15, 0x94, 0x71, 0x4a, 0xd3, 0xae, 0xff, 0x03, 0xbd, 0x53, 0x03, 0x7a, 0xf3, 0x9a, + 0xb0, 0x43, 0x2e, 0xa3, 0xf1, 0x6f, 0xd0, 0x5e, 0x57, 0x5e, 0x7f, 0xaf, 0xe1, 0x0c, 0xb4, 0x53, + 0xa6, 0x35, 0xe1, 0xac, 0xcc, 0xd2, 0x9c, 0x74, 0xfd, 0x3e, 0xb2, 0x15, 0xa2, 0x4b, 0x85, 0x68, + 0x29, 0x0f, 0xe1, 0x8b, 0x6a, 0xf5, 0xe7, 0xfe, 0xe4, 0x39, 0xc7, 0x93, 0xe7, 0x3c, 0x9d, 0x3c, + 0xe7, 0xf6, 0xec, 0x35, 0x8e, 0x67, 0xaf, 0xf1, 0x78, 0xf6, 0x1a, 0xff, 0x7e, 0x71, 0x61, 0xae, + 0x8a, 0x08, 0x51, 0x95, 0xd6, 0xf5, 0x62, 0x11, 0xd1, 0x29, 0x57, 0x78, 0x3f, 0x9f, 0xe1, 0x54, + 0xc5, 0x45, 0xc2, 0x74, 0x79, 0x5c, 0x8d, 0xfd, 0xc5, 0xb4, 0xbc, 0xab, 0x39, 0x64, 0x4c, 0x47, + 0xad, 0xca, 0xe9, 0xe7, 0x73, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7c, 0x58, 0xaf, 0x6b, 0xfc, 0x01, + 0x00, 0x00, } func (m *AccountIdentifier) Marshal() (dAtA []byte, err error) { @@ -259,6 +310,43 @@ func (m *ICS27Account) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *CosmosTx) 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 *CosmosTx) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CosmosTx) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Messages) > 0 { + for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Messages[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAccount(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func encodeVarintAccount(dAtA []byte, offset int, v uint64) int { offset -= sovAccount(v) base := offset @@ -308,6 +396,21 @@ func (m *ICS27Account) Size() (n int) { return n } +func (m *CosmosTx) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Messages) > 0 { + for _, e := range m.Messages { + l = e.Size() + n += 1 + l + sovAccount(uint64(l)) + } + } + return n +} + func sovAccount(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -580,6 +683,90 @@ func (m *ICS27Account) Unmarshal(dAtA []byte) error { } return nil } +func (m *CosmosTx) 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 ErrIntOverflowAccount + } + 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: CosmosTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CosmosTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Messages", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAccount + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAccount + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAccount + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Messages = append(m.Messages, &types.Any{}) + if err := m.Messages[len(m.Messages)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAccount(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAccount + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipAccount(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/modules/apps/27-gmp/types/errors.go b/modules/apps/27-gmp/types/errors.go index 6e0f8badfc7..af78cee63de 100644 --- a/modules/apps/27-gmp/types/errors.go +++ b/modules/apps/27-gmp/types/errors.go @@ -12,4 +12,6 @@ var ( ErrAbiDecoding = errorsmod.Register(ModuleName, 7, "abi decoding error") ErrAbiEncoding = errorsmod.Register(ModuleName, 8, "abi encoding error") ErrAccountAlreadyExists = errorsmod.Register(ModuleName, 9, "account already exists") + ErrAccountNotFound = errorsmod.Register(ModuleName, 10, "account not found") + ErrInvalidMsgRoute = errorsmod.Register(ModuleName, 11, "invalid msg route") ) From ef9559aee6abda015b5a0e57706dbbeae24f9cd9 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 15:49:29 +0400 Subject: [PATCH 26/46] imp: implemented query --- modules/apps/27-gmp/keeper/query_server.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/modules/apps/27-gmp/keeper/query_server.go b/modules/apps/27-gmp/keeper/query_server.go index 5a4b7cff890..1f5a60f5eb9 100644 --- a/modules/apps/27-gmp/keeper/query_server.go +++ b/modules/apps/27-gmp/keeper/query_server.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "encoding/hex" "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" ) @@ -10,6 +11,18 @@ var _ types.QueryServer = (*Keeper)(nil) // AccountAddress defines the handler for the Query/AccountAddress RPC method. func (k Keeper) AccountAddress(ctx context.Context, req *types.QueryAccountAddressRequest) (*types.QueryAccountAddressResponse, error) { - // TODO: Add logic - panic("not implemented") + salt, err := hex.DecodeString(req.Salt) + if err != nil { + return nil, err + } + + accountId := types.NewAccountIdentifier(req.ClientId, req.Sender, salt) + address, err := k.getOrComputeICS27Address(ctx, &accountId) + if err != nil { + return nil, err + } + + return &types.QueryAccountAddressResponse{ + AccountAddress: address, + }, nil } From fa61151e0c39bb2f4db73e62c8fa2c5939df0f75 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 15:53:05 +0400 Subject: [PATCH 27/46] lint --- modules/apps/27-gmp/module.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index ba8b8b3c166..151db9bf0e3 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -106,7 +106,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - am.keeper.InitGenesis(ctx, &genesisState) + err := am.keeper.InitGenesis(ctx, &genesisState) + if err != nil { + panic(fmt.Errorf("failed to initialize %s genesis state: %w", types.ModuleName, err)) + } } // ExportGenesis returns the exported genesis state as raw bytes for the ibc-transfer From 0926c7d89ea902b596ea5ff779d4728ded1ad73d Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 16:01:18 +0400 Subject: [PATCH 28/46] imp: added gmp to wasm simapp --- .../08-wasm/testing/simapp/app.go | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/modules/light-clients/08-wasm/testing/simapp/app.go b/modules/light-clients/08-wasm/testing/simapp/app.go index 14588114ff9..eca7dc76a6d 100644 --- a/modules/light-clients/08-wasm/testing/simapp/app.go +++ b/modules/light-clients/08-wasm/testing/simapp/app.go @@ -111,6 +111,9 @@ import ( "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/blsverifier" ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/keeper" ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/v10/types" + gmp "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp" + gmpkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/keeper" + gmptypes "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" ica "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts" icacontroller "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/keeper" @@ -189,6 +192,7 @@ type SimApp struct { IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper + GMPKeeper gmpkeeper.Keeper EvidenceKeeper evidencekeeper.Keeper TransferKeeper ibctransferkeeper.Keeper WasmClientKeeper ibcwasmkeeper.Keeper @@ -312,7 +316,7 @@ func newSimApp( authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, govtypes.StoreKey, group.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, - evidencetypes.StoreKey, ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, + evidencetypes.StoreKey, ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey, gmptypes.StoreKey, authzkeeper.StoreKey, consensusparamtypes.StoreKey, circuittypes.StoreKey, ibcwasmtypes.StoreKey, ) @@ -486,6 +490,15 @@ func newSimApp( app.GRPCQueryRouter(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + // ICS-27 GMP keeper + app.GMPKeeper = gmpkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[gmptypes.ModuleName]), + app.AccountKeeper, + app.MsgServiceRouter(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + // Create IBC Router ibcRouter := porttypes.NewRouter() ibcRouterV2 := ibcapi.NewRouter() @@ -557,6 +570,9 @@ func newSimApp( // register the transfer v2 module. ibcRouterV2.AddRoute(ibctransfertypes.PortID, transferv2.NewIBCModule(app.TransferKeeper)) + // Register the ICS-27 GMP module + ibcRouterV2.AddRoute(gmptypes.PortID, gmp.NewIBCModule(app.GMPKeeper)) + // Seal the IBC Routers. app.IBCKeeper.SetRouter(ibcRouter) app.IBCKeeper.SetRouterV2(ibcRouterV2) @@ -615,6 +631,7 @@ func newSimApp( ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), + gmp.NewAppModule(&app.GMPKeeper), mockModule, // IBC light clients @@ -661,6 +678,7 @@ func newSimApp( genutiltypes.ModuleName, authz.ModuleName, icatypes.ModuleName, + gmptypes.ModuleName, ibcwasmtypes.ModuleName, ibcmock.ModuleName, ) @@ -673,6 +691,7 @@ func newSimApp( genutiltypes.ModuleName, feegrant.ModuleName, icatypes.ModuleName, + gmptypes.ModuleName, ibcwasmtypes.ModuleName, ibcmock.ModuleName, group.ModuleName, @@ -686,7 +705,7 @@ func newSimApp( banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName, ibcexported.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName, - icatypes.ModuleName, ibcmock.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, + icatypes.ModuleName, gmptypes.ModuleName, ibcmock.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, circuittypes.ModuleName, ibcwasmtypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) From c6203a97b68ce6c546bbce58edcccdbe73f11692 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 16:10:01 +0400 Subject: [PATCH 29/46] style: lint --- modules/apps/27-gmp/ibc_module.go | 6 ++--- modules/apps/27-gmp/keeper/account.go | 16 ++++++------- modules/apps/27-gmp/keeper/query_server.go | 4 ++-- modules/apps/27-gmp/keeper/relay.go | 6 ++--- modules/apps/27-gmp/module.go | 2 +- modules/apps/27-gmp/types/account.go | 28 +++++++++++----------- modules/apps/27-gmp/types/ack.go | 2 +- modules/apps/27-gmp/types/keys.go | 6 ++--- 8 files changed, 34 insertions(+), 36 deletions(-) diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index 421273f8bfc..fd2dc17c76f 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -29,7 +29,7 @@ func NewIBCModule(k keeper.Keeper) *IBCModule { } } -func (im *IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error { +func (_ *IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error { if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { return errorsmod.Wrapf(channeltypesv2.ErrInvalidPacket, "payload port ID is invalid: expected %s, got sourcePort: %s destPort: %s", types.PortID, payload.SourcePort, payload.DestinationPort) } @@ -121,10 +121,10 @@ func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel, destinationCha } } -func (im *IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { +func (_ *IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { return nil } -func (im *IBCModule) OnAcknowledgementPacket(_ sdk.Context, _, _ string, _ uint64, _ []byte, _ channeltypesv2.Payload, _ sdk.AccAddress) error { +func (_ *IBCModule) OnAcknowledgementPacket(_ sdk.Context, _, _ string, _ uint64, _ []byte, _ channeltypesv2.Payload, _ sdk.AccAddress) error { return nil } diff --git a/modules/apps/27-gmp/keeper/account.go b/modules/apps/27-gmp/keeper/account.go index 4e9273974e0..fbb50e5f933 100644 --- a/modules/apps/27-gmp/keeper/account.go +++ b/modules/apps/27-gmp/keeper/account.go @@ -10,8 +10,8 @@ import ( ) // getOrCreateICS27Account retrieves an existing ICS27 account or creates a new one if it doesn't exist. -func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountId *types.AccountIdentifier) (*types.ICS27Account, error) { - existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountId.ClientId, accountId.Sender, accountId.Salt)) +func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountID *types.AccountIdentifier) (*types.ICS27Account, error) { + existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt)) if err == nil { return &existingIcs27Account, nil } else if !errorsmod.IsOf(err, collections.ErrNotFound) { @@ -19,7 +19,7 @@ func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountId *types.Ac } // Create a new account - newAddr, err := types.BuildAddressPredictable(accountId) + newAddr, err := types.BuildAddressPredictable(accountID) if err != nil { return nil, err } @@ -33,8 +33,8 @@ func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountId *types.Ac newAcc := k.accountKeeper.NewAccountWithAddress(ctx, newAddr) k.accountKeeper.SetAccount(ctx, newAcc) - ics27Account := types.NewICS27Account(newAcc.GetAddress().String(), accountId) - if err := k.Accounts.Set(ctx, collections.Join3(accountId.ClientId, accountId.Sender, accountId.Salt), ics27Account); err != nil { + ics27Account := types.NewICS27Account(newAcc.GetAddress().String(), accountID) + if err := k.Accounts.Set(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt), ics27Account); err != nil { return nil, errorsmod.Wrapf(err, "failed to set account %s in store", ics27Account) } @@ -43,8 +43,8 @@ func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountId *types.Ac } // getOrComputeICS27Adderss retrieves an existing ICS27 account address or computes it if it doesn't exist. This doesn't modify the store. -func (k Keeper) getOrComputeICS27Address(ctx context.Context, accountId *types.AccountIdentifier) (string, error) { - existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountId.ClientId, accountId.Sender, accountId.Salt)) +func (k Keeper) getOrComputeICS27Address(ctx context.Context, accountID *types.AccountIdentifier) (string, error) { + existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt)) if err == nil { return existingIcs27Account.Address, nil } else if !errorsmod.IsOf(err, collections.ErrNotFound) { @@ -52,7 +52,7 @@ func (k Keeper) getOrComputeICS27Address(ctx context.Context, accountId *types.A } // Compute a new address - newAddr, err := types.BuildAddressPredictable(accountId) + newAddr, err := types.BuildAddressPredictable(accountID) if err != nil { return "", err } diff --git a/modules/apps/27-gmp/keeper/query_server.go b/modules/apps/27-gmp/keeper/query_server.go index 1f5a60f5eb9..89cdced698d 100644 --- a/modules/apps/27-gmp/keeper/query_server.go +++ b/modules/apps/27-gmp/keeper/query_server.go @@ -16,8 +16,8 @@ func (k Keeper) AccountAddress(ctx context.Context, req *types.QueryAccountAddre return nil, err } - accountId := types.NewAccountIdentifier(req.ClientId, req.Sender, salt) - address, err := k.getOrComputeICS27Address(ctx, &accountId) + accountID := types.NewAccountIdentifier(req.ClientId, req.Sender, salt) + address, err := k.getOrComputeICS27Address(ctx, &accountID) if err != nil { return nil, err } diff --git a/modules/apps/27-gmp/keeper/relay.go b/modules/apps/27-gmp/keeper/relay.go index 6e44935de9f..1030434e0f9 100644 --- a/modules/apps/27-gmp/keeper/relay.go +++ b/modules/apps/27-gmp/keeper/relay.go @@ -24,9 +24,9 @@ func (k Keeper) OnRecvPacket( destPort, destClient string, ) ([]byte, error) { - accountId := types.NewAccountIdentifier(destClient, data.Sender, data.Salt) + accountID := types.NewAccountIdentifier(destClient, data.Sender, data.Salt) - ics27Acc, err := k.getOrCreateICS27Account(ctx, &accountId) + ics27Acc, err := k.getOrCreateICS27Account(ctx, &accountID) if err != nil { return nil, err } @@ -96,7 +96,7 @@ func (k Keeper) executeTx(ctx sdk.Context, account sdk.AccountI, payload []byte) } // authenticateTx checks that the transaction is signed by the expected signer. -func (k Keeper) authenticateTx(ctx sdk.Context, account sdk.AccountI, msgs []sdk.Msg) error { +func (k Keeper) authenticateTx(_ sdk.Context, account sdk.AccountI, msgs []sdk.Msg) error { if len(msgs) == 0 { return errorsmod.Wrapf(types.ErrInvalidPayload, "empty message list") } diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index 151db9bf0e3..11be6c5fe43 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -91,7 +91,7 @@ func NewAppModule(k *keeper.Keeper) AppModule { } // AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. -func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { +func (_ AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { return types.AutoCLIOptions() } diff --git a/modules/apps/27-gmp/types/account.go b/modules/apps/27-gmp/types/account.go index 86c0eb932c8..7a333b47807 100644 --- a/modules/apps/27-gmp/types/account.go +++ b/modules/apps/27-gmp/types/account.go @@ -26,10 +26,10 @@ func NewAccountIdentifier(clientId, sender string, salt []byte) AccountIdentifie } // NewICS27Account creates a new ICS27Account with the given address and accountId. -func NewICS27Account(address string, accountId *AccountIdentifier) ICS27Account { +func NewICS27Account(addr string, accountID *AccountIdentifier) ICS27Account { return ICS27Account{ - Address: address, - AccountId: accountId, + Address: addr, + AccountId: accountID, } } @@ -42,21 +42,21 @@ func NewICS27Account(address string, accountId *AccountIdentifier) ICS27Account // // This function was copied from wasmd and modified. // -func BuildAddressPredictable(accountId *AccountIdentifier) (sdk.AccAddress, error) { - if err := host.ClientIdentifierValidator(accountId.ClientId); err != nil { - return nil, errorsmod.Wrapf(err, "invalid client ID %s", accountId.ClientId) +func BuildAddressPredictable(accountID *AccountIdentifier) (sdk.AccAddress, error) { + if err := host.ClientIdentifierValidator(accountID.ClientId); err != nil { + return nil, errorsmod.Wrapf(err, "invalid client ID %s", accountID.ClientId) } - if strings.TrimSpace(accountId.Sender) == "" { + if strings.TrimSpace(accountID.Sender) == "" { return nil, errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing sender address") } - clientIdBz := uint64LengthPrefix([]byte(accountId.ClientId)) - senderBz := uint64LengthPrefix([]byte(accountId.Sender)) - saltBz := uint64LengthPrefix(accountId.Salt) - key := make([]byte, len(clientIdBz)+len(senderBz)+len(saltBz)) - copy(key[0:], clientIdBz) - copy(key[len(clientIdBz):], senderBz) - copy(key[len(clientIdBz)+len(senderBz):], saltBz) + clientIDBz := uint64LengthPrefix([]byte(accountID.ClientId)) + senderBz := uint64LengthPrefix([]byte(accountID.Sender)) + saltBz := uint64LengthPrefix(accountID.Salt) + key := make([]byte, len(clientIDBz)+len(senderBz)+len(saltBz)) + copy(key[0:], clientIDBz) + copy(key[len(clientIDBz):], senderBz) + copy(key[len(clientIDBz)+len(senderBz):], saltBz) return address.Module(accountsKey, key)[:AccountAddrLen], nil } diff --git a/modules/apps/27-gmp/types/ack.go b/modules/apps/27-gmp/types/ack.go index 94135328a4d..d3664b99a54 100644 --- a/modules/apps/27-gmp/types/ack.go +++ b/modules/apps/27-gmp/types/ack.go @@ -20,7 +20,7 @@ func NewAcknowledgement(result []byte) Acknowledgement { } // ValidateBasic performs basic validation on the Acknowledgement -func (ack Acknowledgement) ValidateBasic() error { +func (_ Acknowledgement) ValidateBasic() error { return nil } diff --git a/modules/apps/27-gmp/types/keys.go b/modules/apps/27-gmp/types/keys.go index 7613aaf9904..c511cad377e 100644 --- a/modules/apps/27-gmp/types/keys.go +++ b/modules/apps/27-gmp/types/keys.go @@ -28,7 +28,5 @@ const ( AccountAddrLen = 32 ) -var ( - // AccountsKey is the key used to store the accounts in the keeper - AccountsKey = collections.NewPrefix(0) -) +// AccountsKey is the key used to store the accounts in the keeper +var AccountsKey = collections.NewPrefix(0) From 18c81574c8bbe1483b731fee4d0a3f98eba7929a Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 18:31:58 +0400 Subject: [PATCH 30/46] style: lint --- modules/apps/27-gmp/ibc_module.go | 6 +++--- modules/apps/27-gmp/module.go | 2 +- modules/apps/27-gmp/types/account.go | 4 ++-- modules/apps/27-gmp/types/ack.go | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index fd2dc17c76f..aa912c921f8 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -29,7 +29,7 @@ func NewIBCModule(k keeper.Keeper) *IBCModule { } } -func (_ *IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error { +func (*IBCModule) OnSendPacket(ctx sdk.Context, sourceChannel string, destinationChannel string, sequence uint64, payload channeltypesv2.Payload, signer sdk.AccAddress) error { if payload.SourcePort != types.PortID || payload.DestinationPort != types.PortID { return errorsmod.Wrapf(channeltypesv2.ErrInvalidPacket, "payload port ID is invalid: expected %s, got sourcePort: %s destPort: %s", types.PortID, payload.SourcePort, payload.DestinationPort) } @@ -121,10 +121,10 @@ func (im *IBCModule) OnRecvPacket(ctx sdk.Context, sourceChannel, destinationCha } } -func (_ *IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { +func (*IBCModule) OnTimeoutPacket(_ sdk.Context, _, _ string, _ uint64, _ channeltypesv2.Payload, _ sdk.AccAddress) error { return nil } -func (_ *IBCModule) OnAcknowledgementPacket(_ sdk.Context, _, _ string, _ uint64, _ []byte, _ channeltypesv2.Payload, _ sdk.AccAddress) error { +func (*IBCModule) OnAcknowledgementPacket(_ sdk.Context, _, _ string, _ uint64, _ []byte, _ channeltypesv2.Payload, _ sdk.AccAddress) error { return nil } diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index 11be6c5fe43..c6a74adc88b 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -91,7 +91,7 @@ func NewAppModule(k *keeper.Keeper) AppModule { } // AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. -func (_ AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { +func (AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { return types.AutoCLIOptions() } diff --git a/modules/apps/27-gmp/types/account.go b/modules/apps/27-gmp/types/account.go index 7a333b47807..b4c96b73340 100644 --- a/modules/apps/27-gmp/types/account.go +++ b/modules/apps/27-gmp/types/account.go @@ -17,9 +17,9 @@ import ( ) // NewAccountIdentifier creates a new AccountIdentifier with the given clientId, sender, and salt. -func NewAccountIdentifier(clientId, sender string, salt []byte) AccountIdentifier { +func NewAccountIdentifier(clientID, sender string, salt []byte) AccountIdentifier { return AccountIdentifier{ - ClientId: clientId, + ClientId: clientID, Sender: sender, Salt: salt, } diff --git a/modules/apps/27-gmp/types/ack.go b/modules/apps/27-gmp/types/ack.go index d3664b99a54..6f67c6da196 100644 --- a/modules/apps/27-gmp/types/ack.go +++ b/modules/apps/27-gmp/types/ack.go @@ -20,7 +20,7 @@ func NewAcknowledgement(result []byte) Acknowledgement { } // ValidateBasic performs basic validation on the Acknowledgement -func (_ Acknowledgement) ValidateBasic() error { +func (Acknowledgement) ValidateBasic() error { return nil } From be8367e07cfe6cd96681880643b5484eab1d4866 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 7 May 2025 18:34:28 +0400 Subject: [PATCH 31/46] chore: bump go version --- modules/light-clients/08-wasm/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/light-clients/08-wasm/Dockerfile b/modules/light-clients/08-wasm/Dockerfile index ce29c983b34..a7df9d51e9b 100644 --- a/modules/light-clients/08-wasm/Dockerfile +++ b/modules/light-clients/08-wasm/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.23.6-alpine AS builder-base +FROM golang:1.23.8-alpine AS builder-base ARG LIBWASM_VERSION ARG TARGETARCH From ee75f8b9d0e4aee0d84dad41d9ffba4a75842f68 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 8 May 2025 12:30:43 +0400 Subject: [PATCH 32/46] imp: attempt to improve module wiring --- modules/apps/27-gmp/module.go | 76 +++++++++---------- .../08-wasm/testing/simapp/app.go | 1 + testing/simapp/app.go | 1 + 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index c6a74adc88b..bdcc60a7ef2 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -22,7 +22,7 @@ import ( var ( _ module.AppModule = (*AppModule)(nil) - _ module.AppModuleBasic = (*AppModuleBasic)(nil) + _ module.AppModuleBasic = (*AppModule)(nil) // _ module.AppModuleSimulation = (*AppModule)(nil) _ module.HasGenesis = (*AppModule)(nil) _ module.HasName = (*AppModule)(nil) @@ -32,14 +32,25 @@ var ( _ appmodule.AppModule = (*AppModule)(nil) ) -// AppModuleBasic is the IBC Transfer AppModuleBasic -type AppModuleBasic struct{} +// AppModule represents the AppModule for this module +type AppModule struct { + keeper *keeper.Keeper +} -// Name implements AppModuleBasic interface -func (AppModuleBasic) Name() string { - return types.ModuleName +// NewAppModule creates a new 27-gmp module +func NewAppModule(k *keeper.Keeper) AppModule { + return AppModule{ + keeper: k, + } +} + +func NewAppModuleBasic(m AppModule) module.AppModuleBasic { + return module.CoreAppModuleBasicAdaptor(m.Name(), m) } +// Name implements AppModuleBasic interface +func (AppModule) Name() string { return types.ModuleName } + // IsOnePerModuleType implements the depinject.OnePerModuleType interface. func (AppModule) IsOnePerModuleType() {} @@ -47,21 +58,37 @@ func (AppModule) IsOnePerModuleType() {} func (AppModule) IsAppModule() {} // RegisterLegacyAminoCodec implements AppModuleBasic interface -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} +func (AppModule) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ics27 module. +func (AppModule) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } +} // RegisterInterfaces registers module concrete types into protobuf Any. -func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { +func (AppModule) RegisterInterfaces(registry codectypes.InterfaceRegistry) { types.RegisterInterfaces(registry) } +// ConsensusVersion implements AppModule/ConsensusVersion defining the current version of transfer. +func (AppModule) ConsensusVersion() uint64 { return 1 } + // DefaultGenesis returns default genesis state as raw bytes for the ibc // transfer module. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { +func (AppModule) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { return cdc.MustMarshalJSON(types.DefaultGenesisState()) } +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), am.keeper) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + // ValidateGenesis performs genesis state validation for the ibc transfer module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { +func (AppModule) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { var gs types.GenesisState if err := cdc.UnmarshalJSON(bz, &gs); err != nil { return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) @@ -70,37 +97,11 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod return gs.Validate() } -// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the ibc-transfer module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { - panic(err) - } -} - -// AppModule represents the AppModule for this module -type AppModule struct { - AppModuleBasic - keeper *keeper.Keeper -} - -// NewAppModule creates a new 20-transfer module -func NewAppModule(k *keeper.Keeper) AppModule { - return AppModule{ - keeper: k, - } -} - // AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. func (AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { return types.AutoCLIOptions() } -// RegisterServices registers module services. -func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterMsgServer(cfg.MsgServer(), am.keeper) - types.RegisterQueryServer(cfg.QueryServer(), am.keeper) -} - // InitGenesis performs genesis initialization for the ibc-transfer module. It returns // no validator updates. func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { @@ -123,9 +124,6 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw return cdc.MustMarshalJSON(gs) } -// ConsensusVersion implements AppModule/ConsensusVersion defining the current version of transfer. -func (AppModule) ConsensusVersion() uint64 { return 6 } - /* // AppModuleSimulation functions diff --git a/modules/light-clients/08-wasm/testing/simapp/app.go b/modules/light-clients/08-wasm/testing/simapp/app.go index eca7dc76a6d..dd93c9abf2b 100644 --- a/modules/light-clients/08-wasm/testing/simapp/app.go +++ b/modules/light-clients/08-wasm/testing/simapp/app.go @@ -154,6 +154,7 @@ var ( govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, icatypes.ModuleName: nil, + gmptypes.ModuleName: nil, ibcmock.ModuleName: nil, } ) diff --git a/testing/simapp/app.go b/testing/simapp/app.go index 85e295ecb17..198efbcae3a 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -127,6 +127,7 @@ var ( govtypes.ModuleName: {authtypes.Burner}, ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, icatypes.ModuleName: nil, + gmptypes.ModuleName: nil, ibcmock.ModuleName: nil, } ) From e6c856e653a56f2354d147765378e7eddd0567ed Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 8 May 2025 12:37:48 +0400 Subject: [PATCH 33/46] imp: fix attempt --- modules/apps/27-gmp/module.go | 4 ++-- modules/light-clients/08-wasm/testing/simapp/app.go | 2 +- testing/simapp/app.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index bdcc60a7ef2..4c45f85ffbd 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -34,11 +34,11 @@ var ( // AppModule represents the AppModule for this module type AppModule struct { - keeper *keeper.Keeper + keeper keeper.Keeper } // NewAppModule creates a new 27-gmp module -func NewAppModule(k *keeper.Keeper) AppModule { +func NewAppModule(k keeper.Keeper) AppModule { return AppModule{ keeper: k, } diff --git a/modules/light-clients/08-wasm/testing/simapp/app.go b/modules/light-clients/08-wasm/testing/simapp/app.go index dd93c9abf2b..7109f81796a 100644 --- a/modules/light-clients/08-wasm/testing/simapp/app.go +++ b/modules/light-clients/08-wasm/testing/simapp/app.go @@ -632,7 +632,7 @@ func newSimApp( ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), - gmp.NewAppModule(&app.GMPKeeper), + gmp.NewAppModule(app.GMPKeeper), mockModule, // IBC light clients diff --git a/testing/simapp/app.go b/testing/simapp/app.go index 198efbcae3a..8d91f9abcfb 100644 --- a/testing/simapp/app.go +++ b/testing/simapp/app.go @@ -501,7 +501,7 @@ func NewSimApp( ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), - gmp.NewAppModule(&app.GMPKeeper), + gmp.NewAppModule(app.GMPKeeper), mockModule, // IBC light clients From d84336d59b9ba3742f193b8be8c351917eb31d33 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 8 May 2025 12:41:20 +0400 Subject: [PATCH 34/46] imp: removed gmp from unused simapp --- simapp/app.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/simapp/app.go b/simapp/app.go index 54dabf15cb5..a38a0ca0ae0 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -102,8 +102,6 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - gmp "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp" - gmptypes "github.com/cosmos/ibc-go/v10/modules/apps/27-gmp/types" ica "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts" icacontroller "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller" icacontrollerkeeper "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/controller/keeper" @@ -489,7 +487,6 @@ func NewSimApp( ibc.NewAppModule(app.IBCKeeper), transfer.NewAppModule(app.TransferKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), - gmp.NewAppModule(nil), // IBC light clients ibctm.NewAppModule(tmLightClientModule), @@ -555,7 +552,7 @@ func NewSimApp( banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName, ibcexported.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, ibctransfertypes.ModuleName, - icatypes.ModuleName, gmptypes.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, + icatypes.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName, group.ModuleName, consensusparamtypes.ModuleName, circuittypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) From cc9968d0947a7f39eea6ce97dbdbf74a4c0cd6fd Mon Sep 17 00:00:00 2001 From: srdtrk Date: Thu, 8 May 2025 15:16:47 +0400 Subject: [PATCH 35/46] fix: keeper wiring --- modules/apps/27-gmp/keeper/keeper.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go index 20e7db00ce2..78118a5a2e8 100644 --- a/modules/apps/27-gmp/keeper/keeper.go +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -46,9 +46,11 @@ func NewKeeper( sb := collections.NewSchemaBuilder(storeService) k := Keeper{ - cdc: cdc, - authority: authority, - Accounts: collections.NewMap(sb, types.AccountsKey, "accounts", collections.TripleKeyCodec(collections.StringKey, collections.StringKey, collections.BytesKey), codec.CollValue[types.ICS27Account](cdc)), + cdc: cdc, + msgRouter: msgRouter, + accountKeeper: accountKeeper, + authority: authority, + Accounts: collections.NewMap(sb, types.AccountsKey, "accounts", collections.TripleKeyCodec(collections.StringKey, collections.StringKey, collections.BytesKey), codec.CollValue[types.ICS27Account](cdc)), } schema, err := sb.Build() From a841ca9e5941739d85f219856bcf60ad1e5eef56 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 9 May 2025 12:11:22 +0400 Subject: [PATCH 36/46] imp: allow receiver to be empty --- modules/apps/27-gmp/types/msgs.go | 6 +----- modules/apps/27-gmp/types/packet.go | 4 +--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/modules/apps/27-gmp/types/msgs.go b/modules/apps/27-gmp/types/msgs.go index c834b343697..6af21adb034 100644 --- a/modules/apps/27-gmp/types/msgs.go +++ b/modules/apps/27-gmp/types/msgs.go @@ -1,8 +1,6 @@ package types import ( - "strings" - errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" @@ -34,9 +32,7 @@ func (msg MsgSendCall) ValidateBasic() error { if _, err := sdk.AccAddressFromBech32(msg.Sender); err != nil { return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) } - if strings.TrimSpace(msg.Receiver) == "" { - return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing recipient address") - } + // receiver is allowed to be empty if len(msg.Receiver) > MaximumReceiverLength { return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "recipient address must not exceed %d bytes", MaximumReceiverLength) } diff --git a/modules/apps/27-gmp/types/packet.go b/modules/apps/27-gmp/types/packet.go index 6b3c06b59f9..35126cd290d 100644 --- a/modules/apps/27-gmp/types/packet.go +++ b/modules/apps/27-gmp/types/packet.go @@ -36,9 +36,7 @@ func (p GMPPacketData) ValidateBasic() error { if strings.TrimSpace(p.Sender) == "" { return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing sender address") } - if strings.TrimSpace(p.Receiver) == "" { - return errorsmod.Wrap(ibcerrors.ErrInvalidAddress, "missing recipient address") - } + // receiver is allowed to be empty if len(p.Receiver) > MaximumReceiverLength { return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "recipient address must not exceed %d bytes", MaximumReceiverLength) } From 62159d4495b2008abfd3210c40a0aba47a02233d Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 9 May 2025 12:47:23 +0400 Subject: [PATCH 37/46] imp: added logger --- modules/apps/27-gmp/keeper/relay.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/apps/27-gmp/keeper/relay.go b/modules/apps/27-gmp/keeper/relay.go index 1030434e0f9..78461f8fb04 100644 --- a/modules/apps/27-gmp/keeper/relay.go +++ b/modules/apps/27-gmp/keeper/relay.go @@ -79,6 +79,7 @@ func (k Keeper) executeTx(ctx sdk.Context, account sdk.AccountI, payload []byte) protoAny, err := k.executeMsg(cacheCtx, msg) if err != nil { + ctx.Logger().Error("failed to execute 27-gmp message", "msg", msg, "error", err) return nil, err } @@ -87,6 +88,8 @@ func (k Keeper) executeTx(ctx sdk.Context, account sdk.AccountI, payload []byte) writeCache() + ctx.Logger().Info("executed 27-gmp transaction", "account", account.GetAddress(), "msgs", msgs) + txResponse, err := proto.Marshal(txMsgData) if err != nil { return nil, errorsmod.Wrap(err, "failed to marshal tx data") From 6151f8fa49cee224b0bed85a0bc113245c39875f Mon Sep 17 00:00:00 2001 From: srdtrk Date: Fri, 9 May 2025 13:23:06 +0400 Subject: [PATCH 38/46] imp: no err if acc already exists --- modules/apps/27-gmp/keeper/account.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/apps/27-gmp/keeper/account.go b/modules/apps/27-gmp/keeper/account.go index fbb50e5f933..8c807f2acca 100644 --- a/modules/apps/27-gmp/keeper/account.go +++ b/modules/apps/27-gmp/keeper/account.go @@ -26,8 +26,13 @@ func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountID *types.Ac existingAcc := k.accountKeeper.GetAccount(ctx, newAddr) if existingAcc != nil { - // TODO: ensure this cannot be abused - return nil, errorsmod.Wrapf(types.ErrAccountAlreadyExists, "existing account for newly generated ICS27 account address %s", newAddr) + // TODO: ensure this cannot be abused (refactor after this is resolved) + ics27Account := types.NewICS27Account(existingAcc.GetAddress().String(), accountID) + if err := k.Accounts.Set(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt), ics27Account); err != nil { + return nil, errorsmod.Wrapf(err, "failed to set account %s in store", ics27Account) + } + + return &ics27Account, nil } newAcc := k.accountKeeper.NewAccountWithAddress(ctx, newAddr) From 09a7f9ab76d817d9ec5da30b4f4108870b9afb8e Mon Sep 17 00:00:00 2001 From: srdtrk Date: Mon, 25 Aug 2025 10:35:27 +0400 Subject: [PATCH 39/46] deps: go mod tidy --- go.mod | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2f015d8178f..5d3579580e4 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.2021 require ( cosmossdk.io/api v0.9.2 - cosmossdk.io/collections v1.2.0 + cosmossdk.io/collections v1.3.1 cosmossdk.io/core v0.11.3 cosmossdk.io/errors v1.0.2 cosmossdk.io/log v1.6.0 @@ -42,7 +42,6 @@ require ( cloud.google.com/go/iam v1.2.2 // indirect cloud.google.com/go/monitoring v1.21.2 // indirect cloud.google.com/go/storage v1.49.0 // indirect - cosmossdk.io/collections v1.3.1 // indirect cosmossdk.io/depinject v1.2.1 // indirect cosmossdk.io/schema v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect @@ -67,7 +66,6 @@ require ( github.com/chzyer/readline v1.5.1 // indirect github.com/cloudwego/base64x v0.1.5 // indirect github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect - github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.12.0 // indirect github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a // indirect github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect From 4dd15cfb63618ca0311fb5915233fb705626809e Mon Sep 17 00:00:00 2001 From: srdtrk Date: Mon, 25 Aug 2025 10:39:04 +0400 Subject: [PATCH 40/46] fix: compiler problems --- modules/apps/27-gmp/ibc_module.go | 4 ++-- modules/apps/27-gmp/keeper/keeper.go | 4 ++-- modules/apps/27-gmp/module.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/apps/27-gmp/ibc_module.go b/modules/apps/27-gmp/ibc_module.go index aa912c921f8..941e265b739 100644 --- a/modules/apps/27-gmp/ibc_module.go +++ b/modules/apps/27-gmp/ibc_module.go @@ -19,11 +19,11 @@ var _ api.IBCModule = (*IBCModule)(nil) // IBCModule implements the ICS26 interface for transfer given the transfer keeper. type IBCModule struct { - keeper keeper.Keeper + keeper *keeper.Keeper } // NewIBCModule creates a new IBCModule given the keeper -func NewIBCModule(k keeper.Keeper) *IBCModule { +func NewIBCModule(k *keeper.Keeper) *IBCModule { return &IBCModule{ keeper: k, } diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go index 78118a5a2e8..dc81f5d5c97 100644 --- a/modules/apps/27-gmp/keeper/keeper.go +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -39,7 +39,7 @@ func NewKeeper( cdc codec.Codec, storeService storetypes.KVStoreService, accountKeeper types.AccountKeeper, msgRouter types.MessageRouter, authority string, -) Keeper { +) *Keeper { if strings.TrimSpace(authority) == "" { panic(errors.New("authority must be non-empty")) } @@ -60,7 +60,7 @@ func NewKeeper( k.Schema = schema - return k + return &k } // GetAuthority returns the module's authority. diff --git a/modules/apps/27-gmp/module.go b/modules/apps/27-gmp/module.go index 4c45f85ffbd..bdcc60a7ef2 100644 --- a/modules/apps/27-gmp/module.go +++ b/modules/apps/27-gmp/module.go @@ -34,11 +34,11 @@ var ( // AppModule represents the AppModule for this module type AppModule struct { - keeper keeper.Keeper + keeper *keeper.Keeper } // NewAppModule creates a new 27-gmp module -func NewAppModule(k keeper.Keeper) AppModule { +func NewAppModule(k *keeper.Keeper) AppModule { return AppModule{ keeper: k, } From 12126c98ead7710a2d3419877eb2e7f971030b1b Mon Sep 17 00:00:00 2001 From: srdtrk Date: Tue, 26 Aug 2025 13:23:55 +0400 Subject: [PATCH 41/46] imp: allow protojson --- modules/apps/27-gmp/types/account.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/apps/27-gmp/types/account.go b/modules/apps/27-gmp/types/account.go index b4c96b73340..1c4c2aff55c 100644 --- a/modules/apps/27-gmp/types/account.go +++ b/modules/apps/27-gmp/types/account.go @@ -68,10 +68,19 @@ func uint64LengthPrefix(bz []byte) []byte { // DeserializeCosmosTx unmarshals and unpacks a slice of transaction bytes into a slice of sdk.Msg's. // The transaction bytes are unmarshaled depending on the encoding type passed in. The sdk.Msg's are // unpacked from Any's and returned. -func DeserializeCosmosTx(cdc codec.BinaryCodec, data []byte) ([]sdk.Msg, error) { +func DeserializeCosmosTx(cdc codec.Codec, data []byte) ([]sdk.Msg, error) { + // this is a defensive check to ensure only the ProtoCodec is used for message deserialization + if _, ok := cdc.(*codec.ProtoCodec); !ok { + return nil, errorsmod.Wrap(ErrInvalidCodec, "only the ProtoCodec may be used for receiving messages on the host chain") + } + var cosmosTx CosmosTx - if err := cdc.Unmarshal(data, &cosmosTx); err != nil { - return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "cannot unmarshal CosmosTx with protobuf: %v", err) + err := cdc.Unmarshal(data, &cosmosTx) + if err != nil { + // TODO: clean up after the demo + if err := cdc.UnmarshalJSON(data, &cosmosTx); err != nil { + return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "cannot unmarshal CosmosTx with protobuf or protojson: %v", err) + } } msgs := make([]sdk.Msg, len(cosmosTx.Messages)) From d389a668c1a08c4c54e64ec22c97fd9a34195249 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sat, 30 Aug 2025 14:13:55 +0400 Subject: [PATCH 42/46] imp: added NewMsgSendCall --- modules/apps/27-gmp/types/msgs.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/apps/27-gmp/types/msgs.go b/modules/apps/27-gmp/types/msgs.go index 6af21adb034..1b7bb900e68 100644 --- a/modules/apps/27-gmp/types/msgs.go +++ b/modules/apps/27-gmp/types/msgs.go @@ -21,6 +21,20 @@ var ( _ sdk.HasValidateBasic = (*MsgSendCall)(nil) ) +// NewMsgSendCall creates a new MsgSendCall instance +func NewMsgSendCall(sourceClient, sender, receiver string, payload, salt []byte, timeoutTimestamp uint64, encoding, memo string) *MsgSendCall { + return &MsgSendCall{ + SourceClient: sourceClient, + Sender: sender, + Receiver: receiver, + Payload: payload, + Salt: salt, + Memo: memo, + TimeoutTimestamp: timeoutTimestamp, + Encoding: encoding, + } +} + // ValidateBasic performs a basic check of the MsgSendCall fields. // NOTE: The recipient addresses format is not validated as the format defined by // the chain is not known to IBC. From 0c440fd8465589d4b5d3603e0feaef1d0bf941ec Mon Sep 17 00:00:00 2001 From: srdtrk Date: Sat, 30 Aug 2025 14:32:28 +0400 Subject: [PATCH 43/46] lint: issues --- modules/apps/27-gmp/keeper/account.go | 4 ++-- modules/apps/27-gmp/keeper/keeper.go | 4 ++-- modules/apps/27-gmp/keeper/msg_server.go | 4 ++-- modules/apps/27-gmp/keeper/query_server.go | 2 +- modules/apps/27-gmp/keeper/relay.go | 8 ++++---- modules/apps/27-gmp/types/msgs.go | 6 +----- modules/apps/transfer/types/msgs_test.go | 2 -- 7 files changed, 12 insertions(+), 18 deletions(-) diff --git a/modules/apps/27-gmp/keeper/account.go b/modules/apps/27-gmp/keeper/account.go index 8c807f2acca..f8d497fd594 100644 --- a/modules/apps/27-gmp/keeper/account.go +++ b/modules/apps/27-gmp/keeper/account.go @@ -10,7 +10,7 @@ import ( ) // getOrCreateICS27Account retrieves an existing ICS27 account or creates a new one if it doesn't exist. -func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountID *types.AccountIdentifier) (*types.ICS27Account, error) { +func (k *Keeper) getOrCreateICS27Account(ctx context.Context, accountID *types.AccountIdentifier) (*types.ICS27Account, error) { existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt)) if err == nil { return &existingIcs27Account, nil @@ -48,7 +48,7 @@ func (k Keeper) getOrCreateICS27Account(ctx context.Context, accountID *types.Ac } // getOrComputeICS27Adderss retrieves an existing ICS27 account address or computes it if it doesn't exist. This doesn't modify the store. -func (k Keeper) getOrComputeICS27Address(ctx context.Context, accountID *types.AccountIdentifier) (string, error) { +func (k *Keeper) getOrComputeICS27Address(ctx context.Context, accountID *types.AccountIdentifier) (string, error) { existingIcs27Account, err := k.Accounts.Get(ctx, collections.Join3(accountID.ClientId, accountID.Sender, accountID.Salt)) if err == nil { return existingIcs27Account.Address, nil diff --git a/modules/apps/27-gmp/keeper/keeper.go b/modules/apps/27-gmp/keeper/keeper.go index dc81f5d5c97..ab8e5f4fe5e 100644 --- a/modules/apps/27-gmp/keeper/keeper.go +++ b/modules/apps/27-gmp/keeper/keeper.go @@ -64,11 +64,11 @@ func NewKeeper( } // GetAuthority returns the module's authority. -func (k Keeper) GetAuthority() string { +func (k *Keeper) GetAuthority() string { return k.authority } // Logger returns a module-specific logger. -func (Keeper) Logger(goCtx context.Context) log.Logger { +func (*Keeper) Logger(goCtx context.Context) log.Logger { return sdk.UnwrapSDKContext(goCtx).Logger().With("module", "x/"+exported.ModuleName+"-"+types.ModuleName) } diff --git a/modules/apps/27-gmp/keeper/msg_server.go b/modules/apps/27-gmp/keeper/msg_server.go index 147aee0c88e..6972140e06e 100644 --- a/modules/apps/27-gmp/keeper/msg_server.go +++ b/modules/apps/27-gmp/keeper/msg_server.go @@ -17,7 +17,7 @@ import ( var _ types.MsgServer = (*Keeper)(nil) // SendCall defines the handler for the MsgSendCall message. -func (k Keeper) SendCall(goCtx context.Context, msg *types.MsgSendCall) (*types.MsgSendCallResponse, error) { +func (k *Keeper) SendCall(goCtx context.Context, msg *types.MsgSendCall) (*types.MsgSendCallResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) _, err := sdk.AccAddressFromBech32(msg.Sender) @@ -40,7 +40,7 @@ func (k Keeper) SendCall(goCtx context.Context, msg *types.MsgSendCall) (*types. return &types.MsgSendCallResponse{Sequence: sequence}, nil } -func (k Keeper) sendPacket(ctx sdk.Context, encoding, sourceClient string, timeoutTimestamp uint64, packetData types.GMPPacketData) (uint64, error) { +func (k *Keeper) sendPacket(ctx sdk.Context, encoding, sourceClient string, timeoutTimestamp uint64, packetData types.GMPPacketData) (uint64, error) { if encoding == "" { encoding = types.EncodingABI } diff --git a/modules/apps/27-gmp/keeper/query_server.go b/modules/apps/27-gmp/keeper/query_server.go index 89cdced698d..6ff2fac084b 100644 --- a/modules/apps/27-gmp/keeper/query_server.go +++ b/modules/apps/27-gmp/keeper/query_server.go @@ -10,7 +10,7 @@ import ( var _ types.QueryServer = (*Keeper)(nil) // AccountAddress defines the handler for the Query/AccountAddress RPC method. -func (k Keeper) AccountAddress(ctx context.Context, req *types.QueryAccountAddressRequest) (*types.QueryAccountAddressResponse, error) { +func (k *Keeper) AccountAddress(ctx context.Context, req *types.QueryAccountAddressRequest) (*types.QueryAccountAddressResponse, error) { salt, err := hex.DecodeString(req.Salt) if err != nil { return nil, err diff --git a/modules/apps/27-gmp/keeper/relay.go b/modules/apps/27-gmp/keeper/relay.go index 78461f8fb04..91a605cbb1b 100644 --- a/modules/apps/27-gmp/keeper/relay.go +++ b/modules/apps/27-gmp/keeper/relay.go @@ -16,7 +16,7 @@ import ( // OnRecvPacket processes a GMP packet. // Returns the data result of the execution if successful. -func (k Keeper) OnRecvPacket( +func (k *Keeper) OnRecvPacket( ctx sdk.Context, data *types.GMPPacketData, sourcePort, @@ -53,7 +53,7 @@ func (k Keeper) OnRecvPacket( // If authentication succeeds, it does basic validation of the messages before attempting to deliver each message // into state. The state changes will only be committed if all messages in the transaction succeed. Thus the // execution of the transaction is atomic, all state changes are reverted if a single message fails. -func (k Keeper) executeTx(ctx sdk.Context, account sdk.AccountI, payload []byte) ([]byte, error) { +func (k *Keeper) executeTx(ctx sdk.Context, account sdk.AccountI, payload []byte) ([]byte, error) { msgs, err := types.DeserializeCosmosTx(k.cdc, payload) if err != nil { return nil, errorsmod.Wrapf(err, "failed to deserialize ICS27 CosmosTx") @@ -99,7 +99,7 @@ func (k Keeper) executeTx(ctx sdk.Context, account sdk.AccountI, payload []byte) } // authenticateTx checks that the transaction is signed by the expected signer. -func (k Keeper) authenticateTx(_ sdk.Context, account sdk.AccountI, msgs []sdk.Msg) error { +func (k *Keeper) authenticateTx(_ sdk.Context, account sdk.AccountI, msgs []sdk.Msg) error { if len(msgs) == 0 { return errorsmod.Wrapf(types.ErrInvalidPayload, "empty message list") } @@ -128,7 +128,7 @@ func (k Keeper) authenticateTx(_ sdk.Context, account sdk.AccountI, msgs []sdk.M // Attempts to get the message handler from the router and if found will then execute the message. // If the message execution is successful, the proto marshaled message response will be returned. -func (k Keeper) executeMsg(ctx sdk.Context, msg sdk.Msg) (*codectypes.Any, error) { +func (k *Keeper) executeMsg(ctx sdk.Context, msg sdk.Msg) (*codectypes.Any, error) { handler := k.msgRouter.Handler(msg) if handler == nil { return nil, types.ErrInvalidMsgRoute diff --git a/modules/apps/27-gmp/types/msgs.go b/modules/apps/27-gmp/types/msgs.go index 1b7bb900e68..d43c6f5c6ca 100644 --- a/modules/apps/27-gmp/types/msgs.go +++ b/modules/apps/27-gmp/types/msgs.go @@ -62,11 +62,7 @@ func (msg MsgSendCall) ValidateBasic() error { if msg.TimeoutTimestamp == 0 { return errorsmod.Wrap(ErrInvalidTimeoutTimestamp, "timeout timestamp must be greater than 0") } - if err := validateEncoding(msg.Encoding); err != nil { - return err - } - - return nil + return validateEncoding(msg.Encoding) } // validateIdentifiers checks if the IBC identifiers are valid diff --git a/modules/apps/transfer/types/msgs_test.go b/modules/apps/transfer/types/msgs_test.go index ad81198047e..33619e4ad8c 100644 --- a/modules/apps/transfer/types/msgs_test.go +++ b/modules/apps/transfer/types/msgs_test.go @@ -32,8 +32,6 @@ const ( invalidChannel = "(invalidchannel1)" invalidShortChannel = "invalid" invalidLongChannel = "invalidlongchannelinvalidlongchannelinvalidlongchannelinvalidlongchannel" - - invalidAddress = "invalid" ) var ( From 908ecbe95f3630e45a2a7e2ad111929b63fd7e76 Mon Sep 17 00:00:00 2001 From: johnnylarner Date: Tue, 9 Sep 2025 10:17:32 +0200 Subject: [PATCH 44/46] docs: add PICKUP to gmp --- modules/apps/27-gmp/PICKUP.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 modules/apps/27-gmp/PICKUP.md diff --git a/modules/apps/27-gmp/PICKUP.md b/modules/apps/27-gmp/PICKUP.md new file mode 100644 index 00000000000..8953b79358d --- /dev/null +++ b/modules/apps/27-gmp/PICKUP.md @@ -0,0 +1,2 @@ +# GMP pickup document +Here we summarise the top features, fixes and refactors that need completing in the GMP stack to get it closer to production readiness. From c9a2f3cec3f664e6a13eee73e82e8c6d26670764 Mon Sep 17 00:00:00 2001 From: srdtrk Date: Wed, 10 Sep 2025 14:55:08 +0400 Subject: [PATCH 45/46] docs: added pickup doc --- modules/apps/27-gmp/PICKUP.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/apps/27-gmp/PICKUP.md b/modules/apps/27-gmp/PICKUP.md index 8953b79358d..d997f6fb1c1 100644 --- a/modules/apps/27-gmp/PICKUP.md +++ b/modules/apps/27-gmp/PICKUP.md @@ -1,2 +1,8 @@ # GMP pickup document -Here we summarise the top features, fixes and refactors that need completing in the GMP stack to get it closer to production readiness. + +`27-gmp` application is feature complete, however, it is not yet production ready. This document outlines the remaining tasks to make it production ready. + +- `BuildAddressPredictable` should be audited and tested for security. Specifcally, what happens if the address was created by sending the address some coins first? +- `DeserializeCosmosTx` supports both protobuf encoding and protojson encoding. However, the support for this is hacky since it tries to decode the tx using both methods and returns the one that works. It would be better to have a more robust way to determine the encoding of the tx. +- Add unit tests and integration tests for the `27-gmp` module. Right now, there are no tests for this module. +- End to end tests should be added to ensure the entire flow works as expected. End to end tests should be added to this repository if Cosmos to Cosmos calls are to be supported, otherwise, the end to end tests in the `solidity-ibc-go` repository should be sufficient. From 067e75b64dbca1bef3d2018adf79dcd730fe08c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20=C5=BBak?= Date: Fri, 10 Oct 2025 15:19:07 +0200 Subject: [PATCH 46/46] fix(gmp): fix keeper initialization and packet unmarshaling (#8660) Fix two critical bugs in ICS27-GMP module: 1. keeper: Initialize msgRouter and accountKeeper fields that were being passed to NewKeeper but not assigned to the keeper struct, causing nil pointer panics when routing messages 2. packet: Fix UnmarshalPacketData to use correct Go unmarshal pattern by initializing pointer before passing to json.Unmarshal instead of passing pointer-to-pointer --- modules/apps/27-gmp/types/packet.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/apps/27-gmp/types/packet.go b/modules/apps/27-gmp/types/packet.go index 35126cd290d..eca33f641b3 100644 --- a/modules/apps/27-gmp/types/packet.go +++ b/modules/apps/27-gmp/types/packet.go @@ -77,10 +77,10 @@ func UnmarshalPacketData(bz []byte, ics27Version string, encoding string) (*GMPP panic("unsupported ics27 version") } - var data *GMPPacketData + data := &GMPPacketData{} switch encoding { case EncodingJSON: - if err := json.Unmarshal(bz, &data); err != nil { + if err := json.Unmarshal(bz, data); err != nil { return nil, errorsmod.Wrapf(ibcerrors.ErrInvalidType, "failed to unmarshal json packet data: %s", err) } case EncodingProtobuf: