From 8d10fed0f7bceac796cdfe2eba8d1fb60cb4a12c Mon Sep 17 00:00:00 2001 From: sangier <45793271+sangier@users.noreply.github.com> Date: Wed, 31 Jul 2024 12:05:15 +0200 Subject: [PATCH] Cherry-pick: Add MsgRegisterCounterparty Struct and Handler from ibc-lite (#6982) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(lite): counterparty client logic (#6307) * imp: added counterparty client store * imp: added provide counterparty to proto * imp: ran 'make proto-all' * imp: added logic to counterparty client * imp: fix proto * imp: fix proto * imp: ran 'make proto-all' * feat: finished counterparty client logic * change counterparty to include custom prefix * fix imports * import fixes, review suggestions * rm lite comment * applying review suggestions * add creator tests * addressing aditya review * Update proto/ibc/core/client/v1/client.proto Co-authored-by: DimitrisJim * Update modules/core/02-client/types/msgs.go Co-authored-by: DimitrisJim * Update modules/core/keeper/msg_server.go Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> * addressing jim review * refactor(proto): use counterparty type in MsgProvideCounterparty. Validate Counterparty type. * refactor(keys): move Counterparty key to 02-client keys.go * feat(core): delete creator after registering counterparty. * chore(core): make GetCreator return a boolean if not found. * tests(02-client): add tests for counterparty validation. * tests(02-client): add tests for msg_server provide counterparty handler. * nit(core): remove stale key for counterparty in host. * Update modules/core/02-client/keeper/keeper_test.go --------- Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com> Co-authored-by: Aditya Sripal <14364734+AdityaSripal@users.noreply.github.com> Co-authored-by: Stefano Angieri Co-authored-by: DimitrisJim Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com> --- modules/core/02-client/keeper/keeper.go | 39 ++ modules/core/02-client/keeper/keeper_test.go | 37 ++ modules/core/02-client/types/client.go | 22 + modules/core/02-client/types/client.pb.go | 300 +++++++++-- modules/core/02-client/types/client_test.go | 45 ++ modules/core/02-client/types/codec.go | 1 + modules/core/02-client/types/errors.go | 1 + modules/core/02-client/types/keys.go | 10 + modules/core/02-client/types/msgs.go | 31 ++ modules/core/02-client/types/tx.pb.go | 535 +++++++++++++++++-- modules/core/keeper/msg_server.go | 27 +- modules/core/keeper/msg_server_test.go | 74 +++ proto/ibc/core/client/v1/client.proto | 9 + proto/ibc/core/client/v1/tx.proto | 22 + 14 files changed, 1064 insertions(+), 89 deletions(-) diff --git a/modules/core/02-client/keeper/keeper.go b/modules/core/02-client/keeper/keeper.go index 02bc0e9e18f..568143526c2 100644 --- a/modules/core/02-client/keeper/keeper.go +++ b/modules/core/02-client/keeper/keeper.go @@ -322,6 +322,45 @@ func (k *Keeper) GetSelfConsensusState(ctx sdk.Context, height exported.Height) return k.consensusHost.GetSelfConsensusState(ctx, height) } +// SetCounterparty sets the Counterparty for a given client identifier. +func (k *Keeper) SetCounterparty(ctx sdk.Context, clientID string, counterparty types.Counterparty) { + bz := k.cdc.MustMarshal(&counterparty) + k.ClientStore(ctx, clientID).Set([]byte(types.CounterpartyKey), bz) +} + +// GetCounterparty gets the counterparty client's identifier for a given client identifier. +func (k *Keeper) GetCounterparty(ctx sdk.Context, clientID string) (types.Counterparty, bool) { + store := k.ClientStore(ctx, clientID) + bz := store.Get([]byte(types.CounterpartyKey)) + if len(bz) == 0 { + return types.Counterparty{}, false + } + + var counterparty types.Counterparty + k.cdc.MustUnmarshal(bz, &counterparty) + return counterparty, true +} + +// GetCreator returns the creator of the client. +func (k *Keeper) GetCreator(ctx sdk.Context, clientID string) (string, bool) { + bz := k.ClientStore(ctx, clientID).Get([]byte(types.CreatorKey)) + if len(bz) == 0 { + return "", false + } + + return string(bz), true +} + +// SetCreator sets the creator of the client. +func (k *Keeper) SetCreator(ctx sdk.Context, clientID, creator string) { + k.ClientStore(ctx, clientID).Set([]byte(types.CreatorKey), []byte(creator)) +} + +// DeleteCreator deletes the creator associated with the client. +func (k *Keeper) DeleteCreator(ctx sdk.Context, clientID string) { + k.ClientStore(ctx, clientID).Delete([]byte(types.CreatorKey)) +} + // ValidateSelfClient validates the client parameters for a client of the running chain. // This function is only used to validate the client state the counterparty stores for this chain. // NOTE: If the client type is not of type Tendermint then delegate to a custom client validator function. diff --git a/modules/core/02-client/keeper/keeper_test.go b/modules/core/02-client/keeper/keeper_test.go index 7e4005bda45..54b5698e1e6 100644 --- a/modules/core/02-client/keeper/keeper_test.go +++ b/modules/core/02-client/keeper/keeper_test.go @@ -129,6 +129,43 @@ func (suite *KeeperTestSuite) TestSetClientState() { suite.Require().Equal(clientState, retrievedState, "Client states are not equal") } +func (suite *KeeperTestSuite) TestSetCounterparty() { + merklePathPrefix := commitmenttypes.NewMerklePath([]byte("ibc"), []byte("")) + counterparty := types.Counterparty{ + ClientId: testClientID, + MerklePathPrefix: &merklePathPrefix, + } + suite.keeper.SetCounterparty(suite.ctx, testClientID, counterparty) + + retrievedCounterparty, found := suite.keeper.GetCounterparty(suite.ctx, testClientID) + suite.Require().True(found, "GetCounterparty does not return counterparty") + suite.Require().Equal(counterparty, retrievedCounterparty, "Counterparty retrieved not equal") + + retrievedCounterparty, found = suite.keeper.GetCounterparty(suite.ctx, "client-0") + suite.Require().False(found, "GetCounterparty unexpectedly returned a counterparty") + suite.Require().Equal(types.Counterparty{}, retrievedCounterparty, "Counterparty retrieved not empty") +} + +func (suite *KeeperTestSuite) TestSetCreator() { + clientID := "test-client" + expectedCreator := "test-creator" + + // Set the creator for the client + suite.keeper.SetCreator(suite.ctx, clientID, expectedCreator) + + // Retrieve the creator from the store + retrievedCreator, found := suite.keeper.GetCreator(suite.ctx, clientID) + + // Verify that the retrieved creator matches the expected creator + suite.Require().True(found, "GetCreator did not return stored creator") + suite.Require().Equal(expectedCreator, retrievedCreator, "Creator is not retrieved correctly") + + // Verify non stored creator is not found + retrievedCreator, found = suite.keeper.GetCreator(suite.ctx, "client-0") + suite.Require().False(found, "GetCreator unexpectedly returned a creator") + suite.Require().Equal(retrievedCreator, "", "Creator is not empty") +} + func (suite *KeeperTestSuite) TestSetClientConsensusState() { suite.keeper.SetClientConsensusState(suite.ctx, testClientID, testClientHeight, suite.consensusState) diff --git a/modules/core/02-client/types/client.go b/modules/core/02-client/types/client.go index 993f43d570a..e56e4517b34 100644 --- a/modules/core/02-client/types/client.go +++ b/modules/core/02-client/types/client.go @@ -13,6 +13,7 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2" host "github.com/cosmos/ibc-go/v9/modules/core/24-host" "github.com/cosmos/ibc-go/v9/modules/core/exported" ) @@ -71,6 +72,27 @@ func (ics IdentifiedClientStates) Sort() IdentifiedClientStates { return ics } +// NewCounterparty creates a new Counterparty instance +func NewCounterparty(clientID string, merklePathPrefix *commitmenttypes.MerklePath) Counterparty { + return Counterparty{ + ClientId: clientID, + MerklePathPrefix: merklePathPrefix, + } +} + +// Validate validates the Counterparty +func (c Counterparty) Validate() error { + if err := host.ClientIdentifierValidator(c.ClientId); err != nil { + return err + } + + if c.MerklePathPrefix.Empty() { + return errorsmod.Wrap(ErrInvalidCounterparty, "counterparty prefix cannot be empty") + } + + return nil +} + // NewConsensusStateWithHeight creates a new ConsensusStateWithHeight instance func NewConsensusStateWithHeight(height Height, consensusState exported.ConsensusState) ConsensusStateWithHeight { msg, ok := consensusState.(proto.Message) diff --git a/modules/core/02-client/types/client.pb.go b/modules/core/02-client/types/client.pb.go index 63653c7590a..df4d34a82b9 100644 --- a/modules/core/02-client/types/client.pb.go +++ b/modules/core/02-client/types/client.pb.go @@ -8,6 +8,7 @@ import ( types "github.com/cosmos/cosmos-sdk/codec/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" + v2 "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2" io "io" math "math" math_bits "math/bits" @@ -192,6 +193,61 @@ func (m *ClientConsensusStates) GetConsensusStates() []ConsensusStateWithHeight return nil } +// Counterparty defines the counterparty for a light client to implement IBC eureka protocol +type Counterparty struct { + // the client identifier of the counterparty chain + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // the merkle path that all ICS24 paths will be stored under + MerklePathPrefix *v2.MerklePath `protobuf:"bytes,2,opt,name=merkle_path_prefix,json=merklePathPrefix,proto3" json:"merkle_path_prefix,omitempty"` +} + +func (m *Counterparty) Reset() { *m = Counterparty{} } +func (m *Counterparty) String() string { return proto.CompactTextString(m) } +func (*Counterparty) ProtoMessage() {} +func (*Counterparty) Descriptor() ([]byte, []int) { + return fileDescriptor_b6bc4c8185546947, []int{3} +} +func (m *Counterparty) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Counterparty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Counterparty.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 *Counterparty) XXX_Merge(src proto.Message) { + xxx_messageInfo_Counterparty.Merge(m, src) +} +func (m *Counterparty) XXX_Size() int { + return m.Size() +} +func (m *Counterparty) XXX_DiscardUnknown() { + xxx_messageInfo_Counterparty.DiscardUnknown(m) +} + +var xxx_messageInfo_Counterparty proto.InternalMessageInfo + +func (m *Counterparty) GetClientId() string { + if m != nil { + return m.ClientId + } + return "" +} + +func (m *Counterparty) GetMerklePathPrefix() *v2.MerklePath { + if m != nil { + return m.MerklePathPrefix + } + return nil +} + // Height is a monotonically increasing data type // that can be compared against another Height for the purposes of updating and // freezing clients @@ -212,7 +268,7 @@ type Height struct { func (m *Height) Reset() { *m = Height{} } func (*Height) ProtoMessage() {} func (*Height) Descriptor() ([]byte, []int) { - return fileDescriptor_b6bc4c8185546947, []int{3} + return fileDescriptor_b6bc4c8185546947, []int{4} } func (m *Height) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -253,7 +309,7 @@ func (m *Params) Reset() { *m = Params{} } func (m *Params) String() string { return proto.CompactTextString(m) } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_b6bc4c8185546947, []int{4} + return fileDescriptor_b6bc4c8185546947, []int{5} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -293,6 +349,7 @@ func init() { proto.RegisterType((*IdentifiedClientState)(nil), "ibc.core.client.v1.IdentifiedClientState") proto.RegisterType((*ConsensusStateWithHeight)(nil), "ibc.core.client.v1.ConsensusStateWithHeight") proto.RegisterType((*ClientConsensusStates)(nil), "ibc.core.client.v1.ClientConsensusStates") + proto.RegisterType((*Counterparty)(nil), "ibc.core.client.v1.Counterparty") proto.RegisterType((*Height)(nil), "ibc.core.client.v1.Height") proto.RegisterType((*Params)(nil), "ibc.core.client.v1.Params") } @@ -300,35 +357,39 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/client.proto", fileDescriptor_b6bc4c8185546947) } var fileDescriptor_b6bc4c8185546947 = []byte{ - // 439 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xcf, 0x8b, 0xd3, 0x40, - 0x14, 0xce, 0x74, 0x97, 0xb2, 0x9d, 0x4a, 0x2b, 0x61, 0x17, 0x62, 0x85, 0xb4, 0xe4, 0x62, 0x0e, - 0xee, 0x8c, 0x8d, 0x07, 0x57, 0xc1, 0x83, 0xbb, 0x17, 0xf7, 0x22, 0x12, 0x0f, 0x82, 0x20, 0x25, - 0x99, 0xcc, 0x26, 0x03, 0xc9, 0xcc, 0x92, 0x99, 0x44, 0xfa, 0x1f, 0x78, 0x14, 0xbc, 0x78, 0xdc, - 0x3f, 0x67, 0x8f, 0x3d, 0x7a, 0x12, 0x69, 0xff, 0x11, 0xc9, 0xcc, 0x14, 0x89, 0xbf, 0xf0, 0xf6, - 0xf2, 0xbd, 0x2f, 0xdf, 0xfb, 0xde, 0x37, 0x0f, 0xce, 0x59, 0x4a, 0x30, 0x11, 0x35, 0xc5, 0xa4, - 0x64, 0x94, 0x2b, 0xdc, 0x2e, 0x6d, 0x85, 0xae, 0x6b, 0xa1, 0x84, 0xeb, 0xb2, 0x94, 0xa0, 0x8e, - 0x80, 0x2c, 0xdc, 0x2e, 0x67, 0xc7, 0xb9, 0xc8, 0x85, 0x6e, 0xe3, 0xae, 0x32, 0xcc, 0xd9, 0xbd, - 0x5c, 0x88, 0xbc, 0xa4, 0x58, 0x7f, 0xa5, 0xcd, 0x15, 0x4e, 0xf8, 0xda, 0xb4, 0x82, 0x0a, 0x9e, - 0x5c, 0x66, 0x94, 0x2b, 0x76, 0xc5, 0x68, 0x76, 0xa1, 0x75, 0xde, 0xa8, 0x44, 0x51, 0xf7, 0x3e, - 0x1c, 0x19, 0xd9, 0x15, 0xcb, 0x3c, 0xb0, 0x00, 0xe1, 0x28, 0x3e, 0x32, 0xc0, 0x65, 0xe6, 0x3e, - 0x81, 0x77, 0x6c, 0x53, 0x76, 0x64, 0x6f, 0xb0, 0x00, 0xe1, 0x38, 0x3a, 0x46, 0x66, 0x0e, 0xda, - 0xcf, 0x41, 0x2f, 0xf8, 0x3a, 0x1e, 0x93, 0x9f, 0xaa, 0xc1, 0x67, 0x00, 0xbd, 0x0b, 0xc1, 0x25, - 0xe5, 0xb2, 0x91, 0x1a, 0x7a, 0xcb, 0x54, 0xf1, 0x92, 0xb2, 0xbc, 0x50, 0xee, 0x19, 0x1c, 0x16, - 0xba, 0xd2, 0xf3, 0xc6, 0xd1, 0x0c, 0xfd, 0xbe, 0x21, 0x32, 0xdc, 0xf3, 0xc3, 0xdb, 0x6f, 0x73, - 0x27, 0xb6, 0x7c, 0xf7, 0x39, 0x9c, 0x92, 0xbd, 0xea, 0x7f, 0x58, 0x9a, 0x90, 0x9e, 0x85, 0xce, - 0xd5, 0x89, 0xd9, 0xbd, 0xef, 0x4d, 0xfe, 0x3b, 0x85, 0xf7, 0xf0, 0xee, 0x2f, 0x53, 0xa5, 0x37, - 0x58, 0x1c, 0x84, 0xe3, 0xe8, 0xe1, 0x9f, 0x9c, 0xff, 0x6d, 0x6f, 0xbb, 0xcb, 0xb4, 0x6f, 0x4a, - 0x06, 0x19, 0x1c, 0xda, 0x60, 0x1e, 0xc0, 0x69, 0x4d, 0x5b, 0x26, 0x99, 0xe0, 0x2b, 0xde, 0x54, - 0x29, 0xad, 0xb5, 0x97, 0xc3, 0x78, 0xb2, 0x87, 0x5f, 0x69, 0xb4, 0x47, 0xb4, 0x51, 0x0e, 0xfa, - 0x44, 0xa3, 0xf8, 0xec, 0xe8, 0xe3, 0xcd, 0xdc, 0xf9, 0x72, 0x33, 0x77, 0x82, 0x25, 0x1c, 0xbe, - 0x4e, 0xea, 0xa4, 0x92, 0xdd, 0xcf, 0x49, 0x59, 0x8a, 0x0f, 0x34, 0x5b, 0x19, 0xd3, 0xd2, 0x03, - 0x8b, 0x83, 0x70, 0x14, 0x4f, 0x2c, 0x6c, 0x22, 0x92, 0xe7, 0xf1, 0xed, 0xd6, 0x07, 0x9b, 0xad, - 0x0f, 0xbe, 0x6f, 0x7d, 0xf0, 0x69, 0xe7, 0x3b, 0x9b, 0x9d, 0xef, 0x7c, 0xdd, 0xf9, 0xce, 0xbb, - 0xb3, 0x9c, 0xa9, 0xa2, 0x49, 0x11, 0x11, 0x15, 0x26, 0x42, 0x56, 0x42, 0x62, 0x96, 0x92, 0xd3, - 0x5c, 0xe0, 0xf6, 0x29, 0xae, 0x44, 0xd6, 0x94, 0x54, 0x9a, 0x9b, 0x7e, 0x14, 0x9d, 0xda, 0xb3, - 0x56, 0xeb, 0x6b, 0x2a, 0xd3, 0xa1, 0x7e, 0xa0, 0xc7, 0x3f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf5, - 0xca, 0xb7, 0xeb, 0xf6, 0x02, 0x00, 0x00, + // 510 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x4f, 0x6f, 0xd3, 0x4e, + 0x10, 0xb5, 0xd3, 0x2a, 0x6a, 0x36, 0x55, 0x52, 0x59, 0xad, 0xe4, 0x5f, 0x7e, 0x92, 0x13, 0xf9, + 0xd2, 0x1c, 0xa8, 0x97, 0x98, 0x03, 0x05, 0x89, 0x03, 0xcd, 0x85, 0x1e, 0x40, 0x91, 0x39, 0x20, + 0x21, 0x21, 0xcb, 0x7f, 0x36, 0xf6, 0x0a, 0xaf, 0xd7, 0xf2, 0xae, 0x0d, 0x39, 0x70, 0xe7, 0x88, + 0xc4, 0x85, 0x63, 0x3f, 0x4e, 0x8f, 0x3d, 0x72, 0x42, 0x28, 0xf9, 0x22, 0xc8, 0xbb, 0x1b, 0x52, + 0xf3, 0xa7, 0xe2, 0x36, 0x7e, 0xf3, 0x66, 0xde, 0x9b, 0x19, 0x2f, 0x18, 0xe3, 0x30, 0x82, 0x11, + 0x2d, 0x11, 0x8c, 0x32, 0x8c, 0x72, 0x0e, 0xeb, 0x99, 0x8a, 0x9c, 0xa2, 0xa4, 0x9c, 0x1a, 0x06, + 0x0e, 0x23, 0xa7, 0x21, 0x38, 0x0a, 0xae, 0x67, 0xa3, 0xe3, 0x84, 0x26, 0x54, 0xa4, 0x61, 0x13, + 0x49, 0xe6, 0xe8, 0xbf, 0x84, 0xd2, 0x24, 0x43, 0x50, 0x7c, 0x85, 0xd5, 0x12, 0x06, 0xf9, 0x4a, + 0xa5, 0x4e, 0x77, 0x2a, 0x94, 0x10, 0xcc, 0x89, 0x50, 0x72, 0x6f, 0x7d, 0x49, 0xa2, 0x4d, 0xc0, + 0xc9, 0x65, 0x8c, 0x72, 0x8e, 0x97, 0x18, 0xc5, 0x73, 0x21, 0xf8, 0x92, 0x07, 0x1c, 0x19, 0xff, + 0x83, 0x9e, 0xd4, 0xf7, 0x71, 0x6c, 0xea, 0x13, 0x7d, 0xda, 0xf3, 0x0e, 0x24, 0x70, 0x19, 0x1b, + 0x0f, 0xc1, 0xa1, 0x4a, 0xb2, 0x86, 0x6c, 0x76, 0x26, 0xfa, 0xb4, 0xef, 0x1e, 0x3b, 0xd2, 0x90, + 0xb3, 0x35, 0xe4, 0x3c, 0xcd, 0x57, 0x5e, 0x3f, 0xda, 0x75, 0xb5, 0x3f, 0xeb, 0xc0, 0x9c, 0xd3, + 0x9c, 0xa1, 0x9c, 0x55, 0x4c, 0x40, 0xaf, 0x30, 0x4f, 0x9f, 0x21, 0x9c, 0xa4, 0xdc, 0x38, 0x07, + 0xdd, 0x54, 0x44, 0x42, 0xaf, 0xef, 0x8e, 0x9c, 0xdf, 0x57, 0xe1, 0x48, 0xee, 0xc5, 0xfe, 0xf5, + 0xb7, 0xb1, 0xe6, 0x29, 0xbe, 0xf1, 0x04, 0x0c, 0xa3, 0x6d, 0xd7, 0x7f, 0xb0, 0x34, 0x88, 0x5a, + 0x16, 0x1a, 0x57, 0x27, 0x72, 0xf6, 0xb6, 0x37, 0x76, 0xf7, 0x16, 0xde, 0x80, 0xa3, 0x5f, 0x54, + 0x99, 0xd9, 0x99, 0xec, 0x4d, 0xfb, 0xee, 0xbd, 0x3f, 0x39, 0xff, 0xdb, 0xdc, 0x6a, 0x96, 0x61, + 0xdb, 0x14, 0xb3, 0x3f, 0x80, 0xc3, 0x39, 0xad, 0x72, 0x8e, 0xca, 0x22, 0x28, 0xf9, 0xea, 0x6e, + 0x2f, 0x0b, 0x60, 0x10, 0x54, 0xbe, 0xcd, 0x90, 0x5f, 0x04, 0x3c, 0xf5, 0x8b, 0x12, 0x2d, 0xf1, + 0x7b, 0xb5, 0x04, 0xfb, 0x96, 0x9b, 0xdd, 0xfd, 0x6b, 0xd7, 0x79, 0x2e, 0x2a, 0x16, 0x01, 0x4f, + 0xbd, 0x23, 0xf2, 0x33, 0x5e, 0x88, 0x5a, 0x3b, 0x06, 0x5d, 0x75, 0x97, 0x53, 0x30, 0x2c, 0x51, + 0x8d, 0x19, 0xa6, 0xb9, 0x9f, 0x57, 0x24, 0x44, 0xa5, 0x90, 0xdf, 0xf7, 0x06, 0x5b, 0xf8, 0x85, + 0x40, 0x5b, 0x44, 0x75, 0xc9, 0x4e, 0x9b, 0x28, 0x3b, 0x3e, 0x3e, 0xf8, 0x78, 0x35, 0xd6, 0xbe, + 0x5c, 0x8d, 0x35, 0x7b, 0x06, 0xba, 0x8b, 0xa0, 0x0c, 0x08, 0x6b, 0x8a, 0x83, 0x2c, 0xa3, 0xef, + 0x50, 0xec, 0xcb, 0xa9, 0x98, 0xa9, 0x4f, 0xf6, 0xa6, 0x3d, 0x6f, 0xa0, 0x60, 0x79, 0x21, 0x76, + 0xe1, 0x5d, 0xaf, 0x2d, 0xfd, 0x66, 0x6d, 0xe9, 0xdf, 0xd7, 0x96, 0xfe, 0x69, 0x63, 0x69, 0x37, + 0x1b, 0x4b, 0xfb, 0xba, 0xb1, 0xb4, 0xd7, 0xe7, 0x09, 0xe6, 0x69, 0x15, 0x36, 0x53, 0xc2, 0x88, + 0x32, 0x42, 0x19, 0xc4, 0x61, 0x74, 0x96, 0x50, 0x58, 0x3f, 0x82, 0x84, 0xc6, 0x55, 0x86, 0x98, + 0x7c, 0x15, 0xf7, 0xdd, 0x33, 0xf5, 0xfc, 0xf8, 0xaa, 0x40, 0x2c, 0xec, 0x8a, 0xff, 0xe3, 0xc1, + 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x53, 0xb6, 0xa5, 0x5c, 0x9e, 0x03, 0x00, 0x00, } func (m *IdentifiedClientState) Marshal() (dAtA []byte, err error) { @@ -462,6 +523,48 @@ func (m *ClientConsensusStates) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *Counterparty) 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 *Counterparty) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Counterparty) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MerklePathPrefix != nil { + { + size, err := m.MerklePathPrefix.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintClient(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintClient(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Height) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -589,6 +692,23 @@ func (m *ClientConsensusStates) Size() (n int) { return n } +func (m *Counterparty) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovClient(uint64(l)) + } + if m.MerklePathPrefix != nil { + l = m.MerklePathPrefix.Size() + n += 1 + l + sovClient(uint64(l)) + } + return n +} + func (m *Height) Size() (n int) { if m == nil { return 0 @@ -978,6 +1098,124 @@ func (m *ClientConsensusStates) Unmarshal(dAtA []byte) error { } return nil } +func (m *Counterparty) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Counterparty: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Counterparty: 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 ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthClient + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthClient + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MerklePathPrefix", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowClient + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthClient + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthClient + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MerklePathPrefix == nil { + m.MerklePathPrefix = &v2.MerklePath{} + } + if err := m.MerklePathPrefix.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipClient(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthClient + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Height) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/modules/core/02-client/types/client_test.go b/modules/core/02-client/types/client_test.go index 43b5b1c7f58..21769232cb1 100644 --- a/modules/core/02-client/types/client_test.go +++ b/modules/core/02-client/types/client_test.go @@ -6,6 +6,8 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" + commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2" + host "github.com/cosmos/ibc-go/v9/modules/core/24-host" ibctesting "github.com/cosmos/ibc-go/v9/testing" ) @@ -86,3 +88,46 @@ func TestValidateClientType(t *testing.T) { } } } + +func TestValidateCounterparty(t *testing.T) { + testCases := []struct { + name string + clientID string + merklePathPrefix commitmenttypes.MerklePath + expError error + }{ + { + "success", + ibctesting.FirstClientID, + commitmenttypes.NewMerklePath([]byte("ibc")), + nil, + }, + { + "failure: invalid client id", + "", + commitmenttypes.NewMerklePath([]byte("ibc")), + host.ErrInvalidID, + }, + { + "failure: empty merkle path prefix", + ibctesting.FirstClientID, + commitmenttypes.NewMerklePath(), + types.ErrInvalidCounterparty, + }, + } + + for _, tc := range testCases { + tc := tc + + counterparty := types.NewCounterparty(tc.clientID, &tc.merklePathPrefix) + err := counterparty.Validate() + + expPass := tc.expError == nil + if expPass { + require.NoError(t, err, tc.name) + } else { + require.Error(t, err, tc.name) + require.ErrorIs(t, err, tc.expError) + } + } +} diff --git a/modules/core/02-client/types/codec.go b/modules/core/02-client/types/codec.go index 082970cd598..9e239c83564 100644 --- a/modules/core/02-client/types/codec.go +++ b/modules/core/02-client/types/codec.go @@ -45,6 +45,7 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) { &MsgRecoverClient{}, &MsgIBCSoftwareUpgrade{}, &MsgUpdateParams{}, + &MsgProvideCounterparty{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/modules/core/02-client/types/errors.go b/modules/core/02-client/types/errors.go index 62d906bc40c..b3771efdd8e 100644 --- a/modules/core/02-client/types/errors.go +++ b/modules/core/02-client/types/errors.go @@ -38,4 +38,5 @@ var ( ErrFailedNonMembershipVerification = errorsmod.Register(SubModuleName, 31, "non-membership verification failed") ErrRouteNotFound = errorsmod.Register(SubModuleName, 32, "light client module route not found") ErrClientTypeNotSupported = errorsmod.Register(SubModuleName, 33, "client type not supported") + ErrInvalidCounterparty = errorsmod.Register(SubModuleName, 34, "invalid counterparty identifier") ) diff --git a/modules/core/02-client/types/keys.go b/modules/core/02-client/types/keys.go index e0c23c96aaa..29604c2816e 100644 --- a/modules/core/02-client/types/keys.go +++ b/modules/core/02-client/types/keys.go @@ -32,6 +32,16 @@ const ( // AllowAllClients is the value that if set in AllowedClients param // would allow any wired up light client modules to be allowed AllowAllClients = "*" + + // CreatorKey is the key used to store the client creator in the client store + // the creator key is imported from types instead of host because + // the creator key is not a part of the ics-24 host specification + CreatorKey = "creator" + + // CounterpartyKey is the key used to store counterparty in the client store. + // the counterparty key is imported from types instead of host because + // the counterparty key is not a part of the ics-24 host specification + CounterpartyKey = "counterparty" ) // FormatClientIdentifier returns the client identifier with the sequence appended. diff --git a/modules/core/02-client/types/msgs.go b/modules/core/02-client/types/msgs.go index e35b7bbbaad..e8e0d100555 100644 --- a/modules/core/02-client/types/msgs.go +++ b/modules/core/02-client/types/msgs.go @@ -7,6 +7,7 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" + commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2" host "github.com/cosmos/ibc-go/v9/modules/core/24-host" ibcerrors "github.com/cosmos/ibc-go/v9/modules/core/errors" "github.com/cosmos/ibc-go/v9/modules/core/exported" @@ -20,6 +21,7 @@ var ( _ sdk.Msg = (*MsgUpdateParams)(nil) _ sdk.Msg = (*MsgIBCSoftwareUpgrade)(nil) _ sdk.Msg = (*MsgRecoverClient)(nil) + _ sdk.Msg = (*MsgProvideCounterparty)(nil) _ sdk.HasValidateBasic = (*MsgCreateClient)(nil) _ sdk.HasValidateBasic = (*MsgUpdateClient)(nil) @@ -28,6 +30,7 @@ var ( _ sdk.HasValidateBasic = (*MsgUpdateParams)(nil) _ sdk.HasValidateBasic = (*MsgIBCSoftwareUpgrade)(nil) _ sdk.HasValidateBasic = (*MsgRecoverClient)(nil) + _ sdk.HasValidateBasic = (*MsgProvideCounterparty)(nil) _ codectypes.UnpackInterfacesMessage = (*MsgCreateClient)(nil) _ codectypes.UnpackInterfacesMessage = (*MsgUpdateClient)(nil) @@ -265,6 +268,34 @@ func (msg *MsgRecoverClient) ValidateBasic() error { return nil } +// NewMsgProvideCounterparty creates a new MsgProvideCounterparty instance +func NewMsgProvideCounterparty(signer, clientID, counterpartyID string, merklePathPrefix *commitmenttypes.MerklePath) *MsgProvideCounterparty { + counterparty := NewCounterparty(counterpartyID, merklePathPrefix) + + return &MsgProvideCounterparty{ + Signer: signer, + ClientId: clientID, + Counterparty: counterparty, + } +} + +// ValidateBasic performs basic checks on a MsgProvideCounterparty. +func (msg *MsgProvideCounterparty) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(msg.Signer); err != nil { + return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) + } + + if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { + return err + } + + if err := msg.Counterparty.Validate(); err != nil { + return err + } + + return nil +} + // NewMsgIBCSoftwareUpgrade creates a new MsgIBCSoftwareUpgrade instance func NewMsgIBCSoftwareUpgrade(signer string, plan upgradetypes.Plan, upgradedClientState exported.ClientState) (*MsgIBCSoftwareUpgrade, error) { anyClient, err := PackClientState(upgradedClientState) diff --git a/modules/core/02-client/types/tx.pb.go b/modules/core/02-client/types/tx.pb.go index 5a22491005e..fdca53cd3c9 100644 --- a/modules/core/02-client/types/tx.pb.go +++ b/modules/core/02-client/types/tx.pb.go @@ -448,6 +448,88 @@ func (m *MsgRecoverClientResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgRecoverClientResponse proto.InternalMessageInfo +// MsgProvideCounterparty defines the message used to provide the counterparty client +// identifier. Can only be invoked one time by the signer of MsgCreateClient if the counterparty +// client identifier was not provided in the initial MsgCreateClient message. +type MsgProvideCounterparty struct { + // client unique identifier + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + // counterparty client + Counterparty Counterparty `protobuf:"bytes,2,opt,name=counterparty,proto3" json:"counterparty"` + // signer address + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` +} + +func (m *MsgProvideCounterparty) Reset() { *m = MsgProvideCounterparty{} } +func (m *MsgProvideCounterparty) String() string { return proto.CompactTextString(m) } +func (*MsgProvideCounterparty) ProtoMessage() {} +func (*MsgProvideCounterparty) Descriptor() ([]byte, []int) { + return fileDescriptor_cb5dc4651eb49a04, []int{10} +} +func (m *MsgProvideCounterparty) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgProvideCounterparty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgProvideCounterparty.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 *MsgProvideCounterparty) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgProvideCounterparty.Merge(m, src) +} +func (m *MsgProvideCounterparty) XXX_Size() int { + return m.Size() +} +func (m *MsgProvideCounterparty) XXX_DiscardUnknown() { + xxx_messageInfo_MsgProvideCounterparty.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgProvideCounterparty proto.InternalMessageInfo + +// MsgProvideCounterpartyResponse defines the Msg/ProvideCounterparty response type. +type MsgProvideCounterpartyResponse struct { +} + +func (m *MsgProvideCounterpartyResponse) Reset() { *m = MsgProvideCounterpartyResponse{} } +func (m *MsgProvideCounterpartyResponse) String() string { return proto.CompactTextString(m) } +func (*MsgProvideCounterpartyResponse) ProtoMessage() {} +func (*MsgProvideCounterpartyResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cb5dc4651eb49a04, []int{11} +} +func (m *MsgProvideCounterpartyResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgProvideCounterpartyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgProvideCounterpartyResponse.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 *MsgProvideCounterpartyResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgProvideCounterpartyResponse.Merge(m, src) +} +func (m *MsgProvideCounterpartyResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgProvideCounterpartyResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgProvideCounterpartyResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgProvideCounterpartyResponse proto.InternalMessageInfo + // MsgIBCSoftwareUpgrade defines the message used to schedule an upgrade of an IBC client using a v1 governance proposal type MsgIBCSoftwareUpgrade struct { Plan types1.Plan `protobuf:"bytes,1,opt,name=plan,proto3" json:"plan"` @@ -468,7 +550,7 @@ func (m *MsgIBCSoftwareUpgrade) Reset() { *m = MsgIBCSoftwareUpgrade{} } func (m *MsgIBCSoftwareUpgrade) String() string { return proto.CompactTextString(m) } func (*MsgIBCSoftwareUpgrade) ProtoMessage() {} func (*MsgIBCSoftwareUpgrade) Descriptor() ([]byte, []int) { - return fileDescriptor_cb5dc4651eb49a04, []int{10} + return fileDescriptor_cb5dc4651eb49a04, []int{12} } func (m *MsgIBCSoftwareUpgrade) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -526,7 +608,7 @@ func (m *MsgIBCSoftwareUpgradeResponse) Reset() { *m = MsgIBCSoftwareUpg func (m *MsgIBCSoftwareUpgradeResponse) String() string { return proto.CompactTextString(m) } func (*MsgIBCSoftwareUpgradeResponse) ProtoMessage() {} func (*MsgIBCSoftwareUpgradeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_cb5dc4651eb49a04, []int{11} + return fileDescriptor_cb5dc4651eb49a04, []int{13} } func (m *MsgIBCSoftwareUpgradeResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -569,7 +651,7 @@ func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParams) ProtoMessage() {} func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_cb5dc4651eb49a04, []int{12} + return fileDescriptor_cb5dc4651eb49a04, []int{14} } func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -606,7 +688,7 @@ func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParamsResponse) ProtoMessage() {} func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_cb5dc4651eb49a04, []int{13} + return fileDescriptor_cb5dc4651eb49a04, []int{15} } func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -646,6 +728,8 @@ func init() { proto.RegisterType((*MsgSubmitMisbehaviourResponse)(nil), "ibc.core.client.v1.MsgSubmitMisbehaviourResponse") proto.RegisterType((*MsgRecoverClient)(nil), "ibc.core.client.v1.MsgRecoverClient") proto.RegisterType((*MsgRecoverClientResponse)(nil), "ibc.core.client.v1.MsgRecoverClientResponse") + proto.RegisterType((*MsgProvideCounterparty)(nil), "ibc.core.client.v1.MsgProvideCounterparty") + proto.RegisterType((*MsgProvideCounterpartyResponse)(nil), "ibc.core.client.v1.MsgProvideCounterpartyResponse") proto.RegisterType((*MsgIBCSoftwareUpgrade)(nil), "ibc.core.client.v1.MsgIBCSoftwareUpgrade") proto.RegisterType((*MsgIBCSoftwareUpgradeResponse)(nil), "ibc.core.client.v1.MsgIBCSoftwareUpgradeResponse") proto.RegisterType((*MsgUpdateParams)(nil), "ibc.core.client.v1.MsgUpdateParams") @@ -655,59 +739,63 @@ func init() { func init() { proto.RegisterFile("ibc/core/client/v1/tx.proto", fileDescriptor_cb5dc4651eb49a04) } var fileDescriptor_cb5dc4651eb49a04 = []byte{ - // 819 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0x8e, 0xd3, 0x34, 0xa2, 0xd7, 0xb4, 0xa1, 0x47, 0x4a, 0x53, 0x97, 0x26, 0x55, 0xe8, 0x50, - 0x0a, 0xb5, 0x9b, 0x22, 0x41, 0x29, 0x30, 0xb4, 0x59, 0xe8, 0x10, 0xa9, 0x72, 0xc5, 0xc2, 0x92, - 0xda, 0xce, 0xc5, 0x35, 0x8a, 0x7d, 0x96, 0xef, 0x1c, 0xe8, 0x86, 0x98, 0x18, 0x19, 0x58, 0xd8, - 0xf8, 0x09, 0x15, 0x3f, 0x80, 0x0d, 0xa9, 0x63, 0x47, 0x26, 0x84, 0xda, 0xa1, 0x12, 0xbf, 0x02, - 0xd9, 0x77, 0x49, 0x6d, 0x27, 0x36, 0x41, 0x6c, 0xb1, 0xdf, 0xf7, 0xee, 0x7d, 0xdf, 0xbb, 0xf7, - 0xbe, 0x18, 0x2c, 0x99, 0x9a, 0x2e, 0xeb, 0xd8, 0x45, 0xb2, 0xde, 0x35, 0x91, 0x4d, 0xe5, 0x5e, - 0x5d, 0xa6, 0x6f, 0x25, 0xc7, 0xc5, 0x14, 0x43, 0x68, 0x6a, 0xba, 0xe4, 0x07, 0x25, 0x16, 0x94, - 0x7a, 0x75, 0x71, 0x41, 0xc7, 0xc4, 0xc2, 0x44, 0xb6, 0x88, 0xe1, 0x63, 0x2d, 0x62, 0x30, 0xb0, - 0xb8, 0xca, 0x03, 0x9e, 0x63, 0xb8, 0x6a, 0x1b, 0xc9, 0xbd, 0xba, 0x86, 0xa8, 0x5a, 0xef, 0x3f, - 0x73, 0x54, 0xc9, 0xc0, 0x06, 0x0e, 0x7e, 0xca, 0xfe, 0x2f, 0xfe, 0x76, 0xd1, 0xc0, 0xd8, 0xe8, - 0x22, 0x39, 0x78, 0xd2, 0xbc, 0x8e, 0xac, 0xda, 0x27, 0x3c, 0x54, 0x1d, 0x41, 0x90, 0xb3, 0x09, - 0x00, 0xb5, 0xaf, 0x02, 0x28, 0x36, 0x89, 0xd1, 0x70, 0x91, 0x4a, 0x51, 0x23, 0x88, 0xc0, 0xc7, - 0xa0, 0xc0, 0x30, 0x2d, 0x42, 0x55, 0x8a, 0xca, 0xc2, 0x8a, 0xb0, 0x36, 0xbd, 0x55, 0x92, 0x58, - 0x19, 0xa9, 0x5f, 0x46, 0xda, 0xb5, 0x4f, 0x94, 0x69, 0x86, 0x3c, 0xf4, 0x81, 0xf0, 0x39, 0x28, - 0xea, 0xd8, 0x26, 0xc8, 0x26, 0x1e, 0xe1, 0xb9, 0xd9, 0x94, 0xdc, 0xd9, 0x01, 0x98, 0xa5, 0xdf, - 0x06, 0x79, 0x62, 0x1a, 0x36, 0x72, 0xcb, 0x13, 0x2b, 0xc2, 0xda, 0x94, 0xc2, 0x9f, 0x76, 0x8a, - 0x1f, 0xbe, 0x54, 0x33, 0xef, 0xaf, 0x4e, 0xd7, 0xf9, 0x8b, 0xda, 0x33, 0xb0, 0x10, 0xe3, 0xac, - 0x20, 0xe2, 0xf8, 0x87, 0xc1, 0x25, 0x30, 0xc5, 0xb9, 0x9b, 0xed, 0x80, 0xf8, 0x94, 0x72, 0x83, - 0xbd, 0xd8, 0x6f, 0xef, 0xe4, 0xfc, 0x83, 0x6a, 0x9f, 0x98, 0xe4, 0x97, 0x4e, 0xfb, 0x5a, 0x72, - 0x5a, 0x1a, 0x7c, 0x0a, 0x66, 0x79, 0xd0, 0x42, 0x84, 0xa8, 0x46, 0xba, 0xaa, 0x19, 0x86, 0x6d, - 0x32, 0xe8, 0xf8, 0xa2, 0x16, 0x03, 0x51, 0x61, 0x56, 0x7d, 0x51, 0xb5, 0xef, 0x59, 0x70, 0x33, - 0x88, 0x05, 0xb3, 0x30, 0x0e, 0xe5, 0xf8, 0x15, 0x66, 0xff, 0xe3, 0x0a, 0x27, 0xfe, 0xe1, 0x0a, - 0x37, 0x41, 0xc9, 0x71, 0x31, 0xee, 0xb4, 0xf8, 0xdc, 0xb6, 0xd8, 0xd9, 0xe5, 0xdc, 0x8a, 0xb0, - 0x56, 0x50, 0x60, 0x10, 0x8b, 0xca, 0xd8, 0x05, 0xcb, 0xb1, 0x8c, 0x58, 0xf9, 0xc9, 0x20, 0x55, - 0x8c, 0xa4, 0x26, 0xcd, 0x4d, 0x3e, 0xbd, 0xc5, 0x22, 0x28, 0xc7, 0xdb, 0x38, 0xe8, 0xf1, 0x67, - 0x01, 0xcc, 0x37, 0x89, 0x71, 0xe8, 0x69, 0x96, 0x49, 0x9b, 0x26, 0xd1, 0xd0, 0xb1, 0xda, 0x33, - 0xb1, 0xe7, 0xa6, 0x37, 0x7a, 0x1b, 0x14, 0xac, 0x10, 0x38, 0xb5, 0xd1, 0x11, 0x64, 0xe2, 0x60, - 0xcc, 0xc5, 0x58, 0x97, 0x85, 0x5a, 0x15, 0x2c, 0x8f, 0xa4, 0x16, 0x26, 0xef, 0x0f, 0x88, 0x82, - 0x74, 0xdc, 0x43, 0x2e, 0xef, 0xec, 0x3a, 0x98, 0x23, 0x9e, 0xf6, 0x1a, 0xe9, 0xb4, 0x15, 0xe7, - 0x5f, 0xe4, 0x81, 0x46, 0x5f, 0xc6, 0x26, 0x28, 0x11, 0x4f, 0x23, 0xd4, 0xa4, 0x1e, 0x45, 0x21, - 0x78, 0x36, 0x80, 0xc3, 0xeb, 0xd8, 0x20, 0x63, 0xec, 0xb9, 0x66, 0x4d, 0x8f, 0x50, 0x1b, 0xf0, - 0xfe, 0xc6, 0x9a, 0xbe, 0xbf, 0xd7, 0x38, 0xc4, 0x1d, 0xfa, 0x46, 0x75, 0x11, 0xbf, 0x1c, 0xf8, - 0x08, 0xe4, 0x9c, 0xae, 0x6a, 0x73, 0xef, 0xb9, 0x23, 0x31, 0x7b, 0x94, 0xfa, 0x76, 0xc8, 0xed, - 0x51, 0x3a, 0xe8, 0xaa, 0xf6, 0x5e, 0xee, 0xec, 0x67, 0x35, 0xa3, 0x04, 0x78, 0xf8, 0x02, 0xcc, - 0x73, 0x4c, 0xbb, 0x35, 0xf6, 0x06, 0xdc, 0xea, 0xa7, 0x34, 0x42, 0x9b, 0x90, 0x24, 0x70, 0x3a, - 0x2c, 0x8e, 0xdd, 0xcc, 0x30, 0xff, 0x81, 0x42, 0x1a, 0xf2, 0x9a, 0x03, 0xd5, 0x55, 0x2d, 0x12, - 0x3a, 0x58, 0x08, 0x1f, 0x0c, 0xb7, 0x41, 0xde, 0x09, 0x10, 0x9c, 0xab, 0x28, 0x0d, 0xff, 0x81, - 0x48, 0xec, 0x0c, 0x2e, 0x99, 0xe3, 0xd3, 0xbd, 0x84, 0x65, 0xf4, 0x09, 0x6d, 0xfd, 0x9e, 0x04, - 0x13, 0x4d, 0x62, 0xc0, 0x23, 0x50, 0x88, 0x98, 0xfe, 0xdd, 0x51, 0xd5, 0x62, 0x2e, 0x2b, 0xde, - 0x1f, 0x03, 0x34, 0xb0, 0xe2, 0x23, 0x50, 0x88, 0x78, 0x6c, 0x52, 0x85, 0x30, 0x28, 0xb1, 0xc2, - 0x28, 0x5f, 0x84, 0x3a, 0x98, 0x89, 0x9a, 0xc9, 0x6a, 0x62, 0x76, 0x08, 0x25, 0x3e, 0x18, 0x07, - 0x35, 0x28, 0xe2, 0x02, 0x38, 0xc2, 0x14, 0xee, 0x25, 0x9c, 0x31, 0x0c, 0x15, 0xeb, 0x63, 0x43, - 0xc3, 0xc2, 0xa2, 0xbb, 0x9c, 0x24, 0x2c, 0x82, 0x4a, 0x14, 0x36, 0x72, 0xf9, 0x7c, 0x61, 0x23, - 0x16, 0x2f, 0x49, 0xd8, 0x30, 0x34, 0x51, 0x58, 0xf2, 0x3a, 0xc0, 0x0e, 0x80, 0xe1, 0x9b, 0xe4, - 0x1b, 0x91, 0x3e, 0x19, 0x0c, 0xf4, 0x97, 0xc9, 0x88, 0x4e, 0xb9, 0x38, 0xf9, 0xee, 0xea, 0x74, - 0x5d, 0xd8, 0x53, 0xce, 0x2e, 0x2a, 0xc2, 0xf9, 0x45, 0x45, 0xf8, 0x75, 0x51, 0x11, 0x3e, 0x5e, - 0x56, 0x32, 0xe7, 0x97, 0x95, 0xcc, 0x8f, 0xcb, 0x4a, 0xe6, 0xd5, 0xb6, 0x61, 0xd2, 0x63, 0x4f, - 0x93, 0x74, 0x6c, 0xc9, 0xfc, 0xd3, 0xcb, 0xd4, 0xf4, 0x0d, 0x03, 0xcb, 0xbd, 0x27, 0xb2, 0x85, - 0xdb, 0x5e, 0x17, 0x11, 0xf6, 0xe1, 0xb4, 0xb9, 0xb5, 0xc1, 0xbf, 0x9d, 0xe8, 0x89, 0x83, 0x88, - 0x96, 0x0f, 0xac, 0xe3, 0xe1, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4e, 0xa7, 0x07, 0xfb, 0xfc, - 0x09, 0x00, 0x00, + // 886 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x31, 0x73, 0xe3, 0x44, + 0x14, 0xb6, 0x1c, 0x9f, 0x87, 0x6c, 0x7c, 0x67, 0x6e, 0xcf, 0x77, 0xe7, 0xd3, 0x71, 0xb6, 0xc7, + 0x5c, 0x11, 0x0c, 0x91, 0x62, 0x33, 0x03, 0x21, 0x40, 0x91, 0xb8, 0x21, 0xcc, 0x78, 0x26, 0xa3, + 0x0c, 0x0d, 0x8d, 0x23, 0xc9, 0x6b, 0x45, 0x8c, 0xa5, 0xd5, 0x68, 0x57, 0x06, 0x77, 0x0c, 0x15, + 0x25, 0x05, 0x0d, 0x1d, 0x35, 0x55, 0x86, 0x1f, 0x40, 0xc7, 0x4c, 0xca, 0x94, 0x54, 0x0c, 0x24, + 0x45, 0xfe, 0x06, 0x23, 0xed, 0x5a, 0x59, 0xc9, 0x92, 0x10, 0x43, 0x27, 0xe9, 0x7d, 0xef, 0xed, + 0xf7, 0xbd, 0x7d, 0xfb, 0xad, 0xc0, 0x4b, 0xdb, 0x30, 0x55, 0x13, 0xfb, 0x48, 0x35, 0x17, 0x36, + 0x72, 0xa9, 0xba, 0x1c, 0xaa, 0xf4, 0x1b, 0xc5, 0xf3, 0x31, 0xc5, 0x10, 0xda, 0x86, 0xa9, 0x84, + 0x41, 0x85, 0x05, 0x95, 0xe5, 0x50, 0x7e, 0x6e, 0x62, 0xe2, 0x60, 0xa2, 0x3a, 0xc4, 0x0a, 0xb1, + 0x0e, 0xb1, 0x18, 0x58, 0x7e, 0xcd, 0x03, 0x81, 0x67, 0xf9, 0xfa, 0x0c, 0xa9, 0xcb, 0xa1, 0x81, + 0xa8, 0x3e, 0x5c, 0xbf, 0x73, 0x54, 0xcb, 0xc2, 0x16, 0x8e, 0x1e, 0xd5, 0xf0, 0x89, 0x7f, 0x7d, + 0x61, 0x61, 0x6c, 0x2d, 0x90, 0x1a, 0xbd, 0x19, 0xc1, 0x5c, 0xd5, 0xdd, 0x15, 0x0f, 0x75, 0x33, + 0x08, 0x72, 0x36, 0x11, 0xa0, 0xff, 0xab, 0x04, 0x9a, 0x13, 0x62, 0x8d, 0x7d, 0xa4, 0x53, 0x34, + 0x8e, 0x22, 0xf0, 0x43, 0xd0, 0x60, 0x98, 0x29, 0xa1, 0x3a, 0x45, 0x6d, 0xa9, 0x27, 0xed, 0xee, + 0x8c, 0x5a, 0x0a, 0x5b, 0x46, 0x59, 0x2f, 0xa3, 0x1c, 0xb9, 0x2b, 0x6d, 0x87, 0x21, 0xcf, 0x42, + 0x20, 0xfc, 0x14, 0x34, 0x4d, 0xec, 0x12, 0xe4, 0x92, 0x80, 0xf0, 0xdc, 0x6a, 0x41, 0xee, 0xa3, + 0x18, 0xcc, 0xd2, 0x9f, 0x81, 0x3a, 0xb1, 0x2d, 0x17, 0xf9, 0xed, 0xad, 0x9e, 0xb4, 0xbb, 0xad, + 0xf1, 0xb7, 0xc3, 0xe6, 0xf7, 0x3f, 0x77, 0x2b, 0xdf, 0xdd, 0x5d, 0x0e, 0xf8, 0x87, 0xfe, 0x27, + 0xe0, 0x79, 0x8a, 0xb3, 0x86, 0x88, 0x17, 0x16, 0x83, 0x2f, 0xc1, 0x36, 0xe7, 0x6e, 0xcf, 0x22, + 0xe2, 0xdb, 0xda, 0x1b, 0xec, 0xc3, 0xc9, 0xec, 0xb0, 0x16, 0x16, 0xea, 0xff, 0xc8, 0x24, 0x7f, + 0xe1, 0xcd, 0xee, 0x25, 0x17, 0xa5, 0xc1, 0x8f, 0xc1, 0x23, 0x1e, 0x74, 0x10, 0x21, 0xba, 0x55, + 0xac, 0xea, 0x21, 0xc3, 0x4e, 0x18, 0xb4, 0xbc, 0xa8, 0x17, 0x91, 0x28, 0x91, 0xd5, 0x5a, 0x54, + 0xff, 0xf7, 0x2a, 0x78, 0x33, 0x8a, 0x45, 0xb3, 0x50, 0x86, 0x72, 0x7a, 0x0b, 0xab, 0xff, 0x63, + 0x0b, 0xb7, 0xfe, 0xc3, 0x16, 0xee, 0x83, 0x96, 0xe7, 0x63, 0x3c, 0x9f, 0xf2, 0xb9, 0x9d, 0xb2, + 0xda, 0xed, 0x5a, 0x4f, 0xda, 0x6d, 0x68, 0x30, 0x8a, 0x25, 0x65, 0x1c, 0x81, 0x57, 0xa9, 0x8c, + 0xd4, 0xf2, 0x0f, 0xa2, 0x54, 0x39, 0x91, 0x9a, 0x37, 0x37, 0xf5, 0xe2, 0x16, 0xcb, 0xa0, 0x9d, + 0x6e, 0x63, 0xdc, 0xe3, 0x9f, 0x24, 0xf0, 0x74, 0x42, 0xac, 0xb3, 0xc0, 0x70, 0x6c, 0x3a, 0xb1, + 0x89, 0x81, 0x2e, 0xf4, 0xa5, 0x8d, 0x03, 0xbf, 0xb8, 0xd1, 0x07, 0xa0, 0xe1, 0x08, 0xe0, 0xc2, + 0x46, 0x27, 0x90, 0xb9, 0x83, 0xf1, 0x38, 0xc5, 0xba, 0x2d, 0xf5, 0xbb, 0xe0, 0x55, 0x26, 0x35, + 0x91, 0x7c, 0x38, 0x20, 0x1a, 0x32, 0xf1, 0x12, 0xf9, 0xbc, 0xb3, 0x03, 0xf0, 0x98, 0x04, 0xc6, + 0x57, 0xc8, 0xa4, 0xd3, 0x34, 0xff, 0x26, 0x0f, 0x8c, 0xd7, 0x32, 0xf6, 0x41, 0x8b, 0x04, 0x06, + 0xa1, 0x36, 0x0d, 0x28, 0x12, 0xe0, 0xd5, 0x08, 0x0e, 0xef, 0x63, 0x71, 0x46, 0xe9, 0xb9, 0x66, + 0x4d, 0x4f, 0x50, 0x8b, 0x79, 0xff, 0x22, 0x81, 0x67, 0x13, 0x62, 0x9d, 0xfa, 0x78, 0x69, 0x87, + 0xdb, 0x1a, 0xb8, 0x14, 0xf9, 0x9e, 0xee, 0xd3, 0x55, 0x71, 0xd7, 0x3f, 0x07, 0x0d, 0x53, 0x00, + 0xf3, 0xae, 0xf7, 0x94, 0x4d, 0xc7, 0x55, 0xc4, 0xa2, 0xc7, 0xb5, 0xab, 0x3f, 0xbb, 0x15, 0x2d, + 0x91, 0x5b, 0x5e, 0x48, 0x0f, 0x74, 0xb2, 0xb9, 0xc6, 0x72, 0x7e, 0x63, 0x33, 0x74, 0x72, 0x3c, + 0x3e, 0xc3, 0x73, 0xfa, 0xb5, 0xee, 0x23, 0x3e, 0x6b, 0xf0, 0x03, 0x50, 0xf3, 0x16, 0xba, 0xcb, + 0xad, 0xf4, 0x2d, 0x85, 0xb9, 0xbd, 0xb2, 0x76, 0x77, 0xee, 0xf6, 0xca, 0xe9, 0x42, 0x77, 0x39, + 0xc9, 0x08, 0x0f, 0x3f, 0x03, 0x4f, 0x39, 0x66, 0x36, 0x2d, 0x7d, 0xa0, 0x9f, 0xac, 0x53, 0xc6, + 0xc2, 0xc1, 0xce, 0x93, 0xb9, 0x23, 0x4a, 0x64, 0x83, 0xb6, 0xc9, 0x3f, 0x56, 0x48, 0x05, 0xeb, + 0x3c, 0xd5, 0x7d, 0xdd, 0x21, 0x42, 0x61, 0x49, 0x2c, 0x0c, 0x0f, 0x40, 0xdd, 0x8b, 0x10, 0x9c, + 0xab, 0x9c, 0xb5, 0x3b, 0xac, 0x06, 0x97, 0xcc, 0xf1, 0xc5, 0xd6, 0xc8, 0x32, 0xd6, 0x84, 0x46, + 0x7f, 0xd7, 0xc1, 0xd6, 0x84, 0x58, 0xf0, 0x1c, 0x34, 0x12, 0x77, 0xd8, 0xdb, 0x59, 0xab, 0xa5, + 0x2e, 0x0d, 0xf9, 0xdd, 0x12, 0xa0, 0xf8, 0x66, 0x39, 0x07, 0x8d, 0xc4, 0x95, 0x91, 0xb7, 0x82, + 0x08, 0xca, 0x5d, 0x21, 0xcb, 0xe6, 0xa1, 0x09, 0x1e, 0x26, 0xbd, 0xf1, 0x75, 0x6e, 0xb6, 0x80, + 0x92, 0xdf, 0x2b, 0x83, 0x8a, 0x17, 0xf1, 0x01, 0xcc, 0xf0, 0xb8, 0x77, 0x72, 0x6a, 0x6c, 0x42, + 0xe5, 0x61, 0x69, 0xa8, 0x28, 0x2c, 0x69, 0x4d, 0x79, 0xc2, 0x12, 0xa8, 0x5c, 0x61, 0x99, 0x5e, + 0x02, 0x03, 0xf0, 0x24, 0xcb, 0x47, 0x06, 0x39, 0x45, 0x32, 0xb0, 0xf2, 0xa8, 0x3c, 0x56, 0xec, + 0x67, 0xc6, 0x79, 0xcf, 0xeb, 0xe7, 0x26, 0x34, 0xb7, 0x9f, 0xf9, 0xa7, 0x10, 0xce, 0x01, 0x14, + 0x07, 0x88, 0x1f, 0xc4, 0xe2, 0x81, 0x64, 0xa0, 0x7f, 0x19, 0xc8, 0xe4, 0xe1, 0x92, 0x1f, 0x7c, + 0x7b, 0x77, 0x39, 0x90, 0x8e, 0xb5, 0xab, 0x9b, 0x8e, 0x74, 0x7d, 0xd3, 0x91, 0xfe, 0xba, 0xe9, + 0x48, 0x3f, 0xdc, 0x76, 0x2a, 0xd7, 0xb7, 0x9d, 0xca, 0x1f, 0xb7, 0x9d, 0xca, 0x97, 0x07, 0x96, + 0x4d, 0x2f, 0x02, 0x43, 0x31, 0xb1, 0xa3, 0xf2, 0x1f, 0x58, 0xdb, 0x30, 0xf7, 0x2c, 0xac, 0x2e, + 0x3f, 0x52, 0x1d, 0x3c, 0x0b, 0x16, 0x88, 0xb0, 0xdf, 0xcf, 0xfd, 0xd1, 0x1e, 0xff, 0x03, 0xa5, + 0x2b, 0x0f, 0x11, 0xa3, 0x1e, 0x39, 0xd6, 0xfb, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x4a, 0xa4, + 0xb8, 0x24, 0x42, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -732,6 +820,8 @@ type MsgClient interface { SubmitMisbehaviour(ctx context.Context, in *MsgSubmitMisbehaviour, opts ...grpc.CallOption) (*MsgSubmitMisbehaviourResponse, error) // RecoverClient defines a rpc handler method for MsgRecoverClient. RecoverClient(ctx context.Context, in *MsgRecoverClient, opts ...grpc.CallOption) (*MsgRecoverClientResponse, error) + // ProvideCounterparty defines a rpc handler method for MsgProvideCounterparty. + ProvideCounterparty(ctx context.Context, in *MsgProvideCounterparty, opts ...grpc.CallOption) (*MsgProvideCounterpartyResponse, error) // IBCSoftwareUpgrade defines a rpc handler method for MsgIBCSoftwareUpgrade. IBCSoftwareUpgrade(ctx context.Context, in *MsgIBCSoftwareUpgrade, opts ...grpc.CallOption) (*MsgIBCSoftwareUpgradeResponse, error) // UpdateClientParams defines a rpc handler method for MsgUpdateParams. @@ -791,6 +881,15 @@ func (c *msgClient) RecoverClient(ctx context.Context, in *MsgRecoverClient, opt return out, nil } +func (c *msgClient) ProvideCounterparty(ctx context.Context, in *MsgProvideCounterparty, opts ...grpc.CallOption) (*MsgProvideCounterpartyResponse, error) { + out := new(MsgProvideCounterpartyResponse) + err := c.cc.Invoke(ctx, "/ibc.core.client.v1.Msg/ProvideCounterparty", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *msgClient) IBCSoftwareUpgrade(ctx context.Context, in *MsgIBCSoftwareUpgrade, opts ...grpc.CallOption) (*MsgIBCSoftwareUpgradeResponse, error) { out := new(MsgIBCSoftwareUpgradeResponse) err := c.cc.Invoke(ctx, "/ibc.core.client.v1.Msg/IBCSoftwareUpgrade", in, out, opts...) @@ -821,6 +920,8 @@ type MsgServer interface { SubmitMisbehaviour(context.Context, *MsgSubmitMisbehaviour) (*MsgSubmitMisbehaviourResponse, error) // RecoverClient defines a rpc handler method for MsgRecoverClient. RecoverClient(context.Context, *MsgRecoverClient) (*MsgRecoverClientResponse, error) + // ProvideCounterparty defines a rpc handler method for MsgProvideCounterparty. + ProvideCounterparty(context.Context, *MsgProvideCounterparty) (*MsgProvideCounterpartyResponse, error) // IBCSoftwareUpgrade defines a rpc handler method for MsgIBCSoftwareUpgrade. IBCSoftwareUpgrade(context.Context, *MsgIBCSoftwareUpgrade) (*MsgIBCSoftwareUpgradeResponse, error) // UpdateClientParams defines a rpc handler method for MsgUpdateParams. @@ -846,6 +947,9 @@ func (*UnimplementedMsgServer) SubmitMisbehaviour(ctx context.Context, req *MsgS func (*UnimplementedMsgServer) RecoverClient(ctx context.Context, req *MsgRecoverClient) (*MsgRecoverClientResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RecoverClient not implemented") } +func (*UnimplementedMsgServer) ProvideCounterparty(ctx context.Context, req *MsgProvideCounterparty) (*MsgProvideCounterpartyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ProvideCounterparty not implemented") +} func (*UnimplementedMsgServer) IBCSoftwareUpgrade(ctx context.Context, req *MsgIBCSoftwareUpgrade) (*MsgIBCSoftwareUpgradeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method IBCSoftwareUpgrade not implemented") } @@ -947,6 +1051,24 @@ func _Msg_RecoverClient_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _Msg_ProvideCounterparty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgProvideCounterparty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ProvideCounterparty(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.core.client.v1.Msg/ProvideCounterparty", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ProvideCounterparty(ctx, req.(*MsgProvideCounterparty)) + } + return interceptor(ctx, in, info, handler) +} + func _Msg_IBCSoftwareUpgrade_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgIBCSoftwareUpgrade) if err := dec(in); err != nil { @@ -1007,6 +1129,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "RecoverClient", Handler: _Msg_RecoverClient_Handler, }, + { + MethodName: "ProvideCounterparty", + Handler: _Msg_ProvideCounterparty_Handler, + }, { MethodName: "IBCSoftwareUpgrade", Handler: _Msg_IBCSoftwareUpgrade_Handler, @@ -1413,6 +1539,76 @@ func (m *MsgRecoverClientResponse) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *MsgProvideCounterparty) 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 *MsgProvideCounterparty) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgProvideCounterparty) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x1a + } + { + size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.ClientId) > 0 { + i -= len(m.ClientId) + copy(dAtA[i:], m.ClientId) + i = encodeVarintTx(dAtA, i, uint64(len(m.ClientId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgProvideCounterpartyResponse) 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 *MsgProvideCounterpartyResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgProvideCounterpartyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func (m *MsgIBCSoftwareUpgrade) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1728,6 +1924,34 @@ func (m *MsgRecoverClientResponse) Size() (n int) { return n } +func (m *MsgProvideCounterparty) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ClientId) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Counterparty.Size() + n += 1 + l + sovTx(uint64(l)) + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgProvideCounterpartyResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func (m *MsgIBCSoftwareUpgrade) Size() (n int) { if m == nil { return 0 @@ -2922,6 +3146,203 @@ func (m *MsgRecoverClientResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgProvideCounterparty) 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: MsgProvideCounterparty: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgProvideCounterparty: 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 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.ClientId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Counterparty", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Counterparty.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", 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.Signer = 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 *MsgProvideCounterpartyResponse) 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: MsgProvideCounterpartyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgProvideCounterpartyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + 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 *MsgIBCSoftwareUpgrade) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/modules/core/keeper/msg_server.go b/modules/core/keeper/msg_server.go index 173706e4b21..848f65c2ddd 100644 --- a/modules/core/keeper/msg_server.go +++ b/modules/core/keeper/msg_server.go @@ -43,7 +43,9 @@ func (k *Keeper) CreateClient(goCtx context.Context, msg *clienttypes.MsgCreateC return nil, err } - return &clienttypes.MsgCreateClientResponse{ClientId: clientID}, nil + k.ClientKeeper.SetCreator(ctx, clientID, msg.Signer) + + return &clienttypes.MsgCreateClientResponse{}, nil } // UpdateClient defines a rpc handler method for MsgUpdateClient. @@ -135,6 +137,29 @@ func (k *Keeper) IBCSoftwareUpgrade(goCtx context.Context, msg *clienttypes.MsgI return &clienttypes.MsgIBCSoftwareUpgradeResponse{}, nil } +// ProvideCounterparty defines a rpc handler method for MsgProvideCounterparty. +func (k *Keeper) ProvideCounterparty(goCtx context.Context, msg *clienttypes.MsgProvideCounterparty) (*clienttypes.MsgProvideCounterpartyResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + creator, found := k.ClientKeeper.GetCreator(ctx, msg.ClientId) + if !found { + return nil, errorsmod.Wrap(ibcerrors.ErrUnauthorized, "expected client creator to have been set") + } + + if creator != msg.Signer { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected client creator %s to match signer %s", creator, msg.Signer) + } + + if _, ok := k.ClientKeeper.GetCounterparty(ctx, msg.ClientId); ok { + return nil, errorsmod.Wrapf(clienttypes.ErrInvalidCounterparty, "counterparty already exists for client %s", msg.ClientId) + } + k.ClientKeeper.SetCounterparty(ctx, msg.ClientId, msg.Counterparty) + // Delete client creator from state as it is not needed after this point. + k.ClientKeeper.DeleteCreator(ctx, msg.ClientId) + + return &clienttypes.MsgProvideCounterpartyResponse{}, nil +} + // ConnectionOpenInit defines a rpc handler method for MsgConnectionOpenInit. func (k *Keeper) ConnectionOpenInit(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenInit) (*connectiontypes.MsgConnectionOpenInitResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) diff --git a/modules/core/keeper/msg_server_test.go b/modules/core/keeper/msg_server_test.go index 68d354786d7..839e519414b 100644 --- a/modules/core/keeper/msg_server_test.go +++ b/modules/core/keeper/msg_server_test.go @@ -17,6 +17,7 @@ import ( channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v9/modules/core/05-port/types" commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types" + commitmenttypesv2 "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2" host "github.com/cosmos/ibc-go/v9/modules/core/24-host" ibcerrors "github.com/cosmos/ibc-go/v9/modules/core/errors" "github.com/cosmos/ibc-go/v9/modules/core/exported" @@ -777,6 +778,79 @@ func (suite *KeeperTestSuite) TestHandleTimeoutOnClosePacket() { } } +func (suite *KeeperTestSuite) TestProvideCounterparty() { + var ( + path *ibctesting.Path + msg *clienttypes.MsgProvideCounterparty + ) + cases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "failure: unknown client identifier", + func() { + msg.ClientId = ibctesting.InvalidID + }, + ibcerrors.ErrUnauthorized, + }, + { + "failure: signer does not match creator", + func() { + msg.Signer = ibctesting.TestAccAddress + }, + ibcerrors.ErrUnauthorized, + }, + { + "failure: counterparty already exists", + func() { + // set it before handler + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetCounterparty(suite.chainA.GetContext(), msg.ClientId, msg.Counterparty) + }, + clienttypes.ErrInvalidCounterparty, + }, + } + + for _, tc := range cases { + tc := tc + path = ibctesting.NewPath(suite.chainA, suite.chainB) + path.SetupClients() + + signer := path.EndpointA.Chain.SenderAccount.GetAddress().String() + merklePrefix := commitmenttypesv2.NewMerklePath([]byte("mock-key")) + msg = clienttypes.NewMsgProvideCounterparty(signer, path.EndpointA.ClientID, path.EndpointB.ClientID, &merklePrefix) + + tc.malleate() + + ctx := suite.chainA.GetContext() + resp, err := suite.chainA.App.GetIBCKeeper().ProvideCounterparty(ctx, msg) + + expPass := tc.expError == nil + if expPass { + suite.Require().NotNil(resp) + suite.Require().Nil(err) + + // Assert counterparty set and creator deleted + counterparty, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetCounterparty(suite.chainA.GetContext(), path.EndpointA.ClientID) + suite.Require().True(found) + suite.Require().Equal(counterparty, msg.Counterparty) + + _, found = suite.chainA.App.GetIBCKeeper().ClientKeeper.GetCreator(suite.chainA.GetContext(), path.EndpointA.ClientID) + suite.Require().False(found) + } else { + suite.Require().Nil(resp) + suite.Require().Error(err) + suite.Require().ErrorIs(err, tc.expError) + } + } +} + func (suite *KeeperTestSuite) TestUpgradeClient() { var ( path *ibctesting.Path diff --git a/proto/ibc/core/client/v1/client.proto b/proto/ibc/core/client/v1/client.proto index cc245a4f98f..5adbdde55c4 100644 --- a/proto/ibc/core/client/v1/client.proto +++ b/proto/ibc/core/client/v1/client.proto @@ -6,6 +6,7 @@ option go_package = "github.com/cosmos/ibc-go/v9/modules/core/02-client/types"; import "gogoproto/gogo.proto"; import "google/protobuf/any.proto"; +import "ibc/core/commitment/v2/commitment.proto"; // IdentifiedClientState defines a client state with an additional client // identifier field. @@ -34,6 +35,14 @@ message ClientConsensusStates { repeated ConsensusStateWithHeight consensus_states = 2 [(gogoproto.nullable) = false]; } +// Counterparty defines the counterparty for a light client to implement IBC eureka protocol +message Counterparty { + // the client identifier of the counterparty chain + string client_id = 1; + // the merkle path that all ICS24 paths will be stored under + ibc.core.commitment.v2.MerklePath merkle_path_prefix = 2; +} + // Height is a monotonically increasing data type // that can be compared against another Height for the purposes of updating and // freezing clients diff --git a/proto/ibc/core/client/v1/tx.proto b/proto/ibc/core/client/v1/tx.proto index 1e9e4f47ada..357c5a7d0a1 100644 --- a/proto/ibc/core/client/v1/tx.proto +++ b/proto/ibc/core/client/v1/tx.proto @@ -29,6 +29,9 @@ service Msg { // RecoverClient defines a rpc handler method for MsgRecoverClient. rpc RecoverClient(MsgRecoverClient) returns (MsgRecoverClientResponse); + // ProvideCounterparty defines a rpc handler method for MsgProvideCounterparty. + rpc ProvideCounterparty(MsgProvideCounterparty) returns (MsgProvideCounterpartyResponse); + // IBCSoftwareUpgrade defines a rpc handler method for MsgIBCSoftwareUpgrade. rpc IBCSoftwareUpgrade(MsgIBCSoftwareUpgrade) returns (MsgIBCSoftwareUpgradeResponse); @@ -140,6 +143,25 @@ message MsgRecoverClient { // MsgRecoverClientResponse defines the Msg/RecoverClient response type. message MsgRecoverClientResponse {} +// MsgProvideCounterparty defines the message used to provide the counterparty client +// identifier. Can only be invoked one time by the signer of MsgCreateClient if the counterparty +// client identifier was not provided in the initial MsgCreateClient message. +message MsgProvideCounterparty { + option (cosmos.msg.v1.signer) = "signer"; + + option (gogoproto.goproto_getters) = false; + + // client unique identifier + string client_id = 1; + // counterparty client + Counterparty counterparty = 2 [(gogoproto.nullable) = false]; + // signer address + string signer = 3; +} + +// MsgProvideCounterpartyResponse defines the Msg/ProvideCounterparty response type. +message MsgProvideCounterpartyResponse {} + // MsgIBCSoftwareUpgrade defines the message used to schedule an upgrade of an IBC client using a v1 governance proposal message MsgIBCSoftwareUpgrade { option (cosmos.msg.v1.signer) = "signer";