diff --git a/proto/ibc/core/channel/v1/genesis.proto b/proto/ibc/core/channel/v1/genesis.proto index a89e69c7dd5d..d3b2c0424eaa 100644 --- a/proto/ibc/core/channel/v1/genesis.proto +++ b/proto/ibc/core/channel/v1/genesis.proto @@ -18,6 +18,8 @@ message GenesisState { [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"recv_sequences\""]; repeated PacketSequence ack_sequences = 7 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"ack_sequences\""]; + // the sequence for the next generated channel identifier + uint64 next_channel_sequence = 8 [(gogoproto.moretags) = "yaml:\"next_channel_sequence\""]; } // PacketSequence defines the genesis type necessary to retrieve and store diff --git a/proto/ibc/core/channel/v1/tx.proto b/proto/ibc/core/channel/v1/tx.proto index c60ecc4363d2..5f8426412415 100644 --- a/proto/ibc/core/channel/v1/tx.proto +++ b/proto/ibc/core/channel/v1/tx.proto @@ -46,10 +46,9 @@ message MsgChannelOpenInit { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string channel_id = 2 [(gogoproto.moretags) = "yaml:\"channel_id\""]; - Channel channel = 3 [(gogoproto.nullable) = false]; - string signer = 4; + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + Channel channel = 2 [(gogoproto.nullable) = false]; + string signer = 3; } // MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type. @@ -61,15 +60,16 @@ message MsgChannelOpenTry { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; - string desired_channel_id = 2 [(gogoproto.moretags) = "yaml:\"desired_channel_id\""]; - string counterparty_chosen_channel_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_channel_id\""]; - Channel channel = 4 [(gogoproto.nullable) = false]; - string counterparty_version = 5 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; - bytes proof_init = 6 [(gogoproto.moretags) = "yaml:\"proof_init\""]; - ibc.core.client.v1.Height proof_height = 7 + string port_id = 1 [(gogoproto.moretags) = "yaml:\"port_id\""]; + // in the case of crossing hello's, when both chains call OpenInit, we need the channel identifier + // of the previous channel in state INIT + string previous_channel_id = 2 [(gogoproto.moretags) = "yaml:\"previous_channel_id\""]; + Channel channel = 3 [(gogoproto.nullable) = false]; + string counterparty_version = 4 [(gogoproto.moretags) = "yaml:\"counterparty_version\""]; + bytes proof_init = 5 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; - string signer = 8; + string signer = 7; } // MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type. @@ -147,9 +147,9 @@ message MsgRecvPacket { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; - ibc.core.client.v1.Height proof_height = 3 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_commitment = 2 [(gogoproto.moretags) = "yaml:\"proof_commitment\""]; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; string signer = 4; } @@ -162,9 +162,9 @@ message MsgTimeout { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - ibc.core.client.v1.Height proof_height = 3 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + ibc.core.client.v1.Height proof_height = 3 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; uint64 next_sequence_recv = 4 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; string signer = 5; @@ -178,10 +178,10 @@ message MsgTimeoutOnClose { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - Packet packet = 1 [(gogoproto.nullable) = false]; - bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; - bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; - ibc.core.client.v1.Height proof_height = 4 + Packet packet = 1 [(gogoproto.nullable) = false]; + bytes proof_unreceived = 2 [(gogoproto.moretags) = "yaml:\"proof_unreceived\""]; + bytes proof_close = 3 [(gogoproto.moretags) = "yaml:\"proof_close\""]; + ibc.core.client.v1.Height proof_height = 4 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; uint64 next_sequence_recv = 5 [(gogoproto.moretags) = "yaml:\"next_sequence_recv\""]; string signer = 6; @@ -197,7 +197,7 @@ message MsgAcknowledgement { Packet packet = 1 [(gogoproto.nullable) = false]; bytes acknowledgement = 2; - bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; + bytes proof_acked = 3 [(gogoproto.moretags) = "yaml:\"proof_acked\""]; ibc.core.client.v1.Height proof_height = 4 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; string signer = 5; diff --git a/proto/ibc/core/connection/v1/genesis.proto b/proto/ibc/core/connection/v1/genesis.proto index 4cc2ab7a5e1e..11df4ba1801f 100644 --- a/proto/ibc/core/connection/v1/genesis.proto +++ b/proto/ibc/core/connection/v1/genesis.proto @@ -11,4 +11,6 @@ message GenesisState { repeated IdentifiedConnection connections = 1 [(gogoproto.nullable) = false]; repeated ConnectionPaths client_connection_paths = 2 [(gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"client_connection_paths\""]; + // the sequence for the next generated connection identifier + uint64 next_connection_sequence = 3 [(gogoproto.moretags) = "yaml:\"next_connection_sequence\""]; } diff --git a/proto/ibc/core/connection/v1/tx.proto b/proto/ibc/core/connection/v1/tx.proto index 02a12b0e3106..21c283545d62 100644 --- a/proto/ibc/core/connection/v1/tx.proto +++ b/proto/ibc/core/connection/v1/tx.proto @@ -29,11 +29,10 @@ message MsgConnectionOpenInit { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - string connection_id = 2 [(gogoproto.moretags) = "yaml:\"connection_id\""]; - Counterparty counterparty = 3 [(gogoproto.nullable) = false]; - Version version = 4; - string signer = 5; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + Counterparty counterparty = 2 [(gogoproto.nullable) = false]; + Version version = 3; + string signer = 4; } // MsgConnectionOpenInitResponse defines the Msg/ConnectionOpenInit response type. @@ -45,24 +44,25 @@ message MsgConnectionOpenTry { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - string desired_connection_id = 2 [(gogoproto.moretags) = "yaml:\"desired_connection_id\""]; - string counterparty_chosen_connection_id = 3 [(gogoproto.moretags) = "yaml:\"counterparty_chosen_connection_id\""]; - google.protobuf.Any client_state = 4 [(gogoproto.moretags) = "yaml:\"client_state\""]; - Counterparty counterparty = 5 [(gogoproto.nullable) = false]; - repeated Version counterparty_versions = 6 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; - ibc.core.client.v1.Height proof_height = 7 + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + // in the case of crossing hello's, when both chains call OpenInit, we need the connection identifier + // of the previous connection in state INIT + string previous_connection_id = 2 [(gogoproto.moretags) = "yaml:\"previous_connection_id\""]; + google.protobuf.Any client_state = 3 [(gogoproto.moretags) = "yaml:\"client_state\""]; + Counterparty counterparty = 4 [(gogoproto.nullable) = false]; + repeated Version counterparty_versions = 5 [(gogoproto.moretags) = "yaml:\"counterparty_versions\""]; + ibc.core.client.v1.Height proof_height = 6 [(gogoproto.moretags) = "yaml:\"proof_height\"", (gogoproto.nullable) = false]; // proof of the initialization the connection on Chain A: `UNITIALIZED -> // INIT` - bytes proof_init = 8 [(gogoproto.moretags) = "yaml:\"proof_init\""]; + bytes proof_init = 7 [(gogoproto.moretags) = "yaml:\"proof_init\""]; // proof of client state included in message - bytes proof_client = 9 [(gogoproto.moretags) = "yaml:\"proof_client\""]; + bytes proof_client = 8 [(gogoproto.moretags) = "yaml:\"proof_client\""]; // proof of client consensus state - bytes proof_consensus = 10 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; - ibc.core.client.v1.Height consensus_height = 11 + bytes proof_consensus = 9 [(gogoproto.moretags) = "yaml:\"proof_consensus\""]; + ibc.core.client.v1.Height consensus_height = 10 [(gogoproto.moretags) = "yaml:\"consensus_height\"", (gogoproto.nullable) = false]; - string signer = 12; + string signer = 11; } // MsgConnectionOpenTryResponse defines the Msg/ConnectionOpenTry response type. diff --git a/proto/ibc/lightclients/solomachine/v1/solomachine.proto b/proto/ibc/lightclients/solomachine/v1/solomachine.proto index 738217fa6cbd..89686f3b7f5b 100644 --- a/proto/ibc/lightclients/solomachine/v1/solomachine.proto +++ b/proto/ibc/lightclients/solomachine/v1/solomachine.proto @@ -48,11 +48,11 @@ message Header { // Misbehaviour defines misbehaviour for a solo machine which consists // of a sequence and two signatures over different messages at that sequence. message Misbehaviour { - option (gogoproto.goproto_getters) = false; - string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; - uint64 sequence = 2; - SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; - SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; + option (gogoproto.goproto_getters) = false; + string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; + uint64 sequence = 2; + SignatureAndData signature_one = 3 [(gogoproto.moretags) = "yaml:\"signature_one\""]; + SignatureAndData signature_two = 4 [(gogoproto.moretags) = "yaml:\"signature_two\""]; } // SignatureAndData contains a signature and the data signed over to create that diff --git a/proto/ibc/lightclients/tendermint/v1/tendermint.proto b/proto/ibc/lightclients/tendermint/v1/tendermint.proto index 840bd97739f6..a6882bf432bd 100644 --- a/proto/ibc/lightclients/tendermint/v1/tendermint.proto +++ b/proto/ibc/lightclients/tendermint/v1/tendermint.proto @@ -75,7 +75,7 @@ message ConsensusState { // Misbehaviour is a wrapper over two conflicting Headers // that implements Misbehaviour interface expected by ICS-02 message Misbehaviour { - option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_getters) = false; string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; Header header_1 = 2 [(gogoproto.customname) = "Header1", (gogoproto.moretags) = "yaml:\"header_1\""]; diff --git a/x/auth/client/rest/rest_test.go b/x/auth/client/rest/rest_test.go index b03b615b6aa6..889067d852a3 100644 --- a/x/auth/client/rest/rest_test.go +++ b/x/auth/client/rest/rest_test.go @@ -307,8 +307,8 @@ func (s *IntegrationTestSuite) TestLegacyRestErrMessages() { val := s.network.Validators[0] args := []string{ - "121", // dummy port-id - "21212121212", // dummy channel-id + "121", // dummy port-id + "channel-0", // dummy channel-id fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), diff --git a/x/ibc/applications/transfer/keeper/relay_test.go b/x/ibc/applications/transfer/keeper/relay_test.go index 7878c5935715..9f303175175f 100644 --- a/x/ibc/applications/transfer/keeper/relay_test.go +++ b/x/ibc/applications/transfer/keeper/relay_test.go @@ -51,8 +51,8 @@ func (suite *KeeperTestSuite) TestSendTransfer() { {"next seq send not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA = connA.NextTestChannel(ibctesting.TransferPort) - channelB = connB.NextTestChannel(ibctesting.TransferPort) + channelA = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB = suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // manually create channel so next seq send is never set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainA.GetContext(), diff --git a/x/ibc/applications/transfer/module_test.go b/x/ibc/applications/transfer/module_test.go index b0d0fd10e4a4..b6ce1077c6a0 100644 --- a/x/ibc/applications/transfer/module_test.go +++ b/x/ibc/applications/transfer/module_test.go @@ -33,7 +33,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() { }, { "invalid port ID", func() { - testChannel = connA.NextTestChannel(ibctesting.MockPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.MockPort) }, false, }, { @@ -56,7 +56,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterparty := channeltypes.NewCounterparty(testChannel.PortID, testChannel.ID) channel = &channeltypes.Channel{ State: channeltypes.INIT, @@ -122,7 +122,7 @@ func (suite *TransferTestSuite) TestOnChanOpenTry() { }, { "invalid port ID", func() { - testChannel = connA.NextTestChannel(ibctesting.MockPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.MockPort) }, false, }, { @@ -144,7 +144,7 @@ func (suite *TransferTestSuite) TestOnChanOpenTry() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterparty := channeltypes.NewCounterparty(testChannel.PortID, testChannel.ID) channel = &channeltypes.Channel{ State: channeltypes.TRYOPEN, @@ -210,7 +210,7 @@ func (suite *TransferTestSuite) TestOnChanOpenAck() { suite.SetupTest() // reset _, _, connA, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - testChannel = connA.NextTestChannel(ibctesting.TransferPort) + testChannel = suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) counterpartyVersion = types.Version module, _, err := suite.chainA.App.IBCKeeper.PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.TransferPort) diff --git a/x/ibc/applications/transfer/types/msgs_test.go b/x/ibc/applications/transfer/types/msgs_test.go index 4c9eb80acdcf..89bd39524a51 100644 --- a/x/ibc/applications/transfer/types/msgs_test.go +++ b/x/ibc/applications/transfer/types/msgs_test.go @@ -19,7 +19,7 @@ const ( validChannel = "testchannel" invalidChannel = "(invalidchannel1)" - invalidShortChannel = "invalidch" + invalidShortChannel = "invalid" invalidLongChannel = "invalidlongchannelinvalidlongchannelinvalidlongchannelinvalidlongchannel" ) diff --git a/x/ibc/core/03-connection/client/cli/tx.go b/x/ibc/core/03-connection/client/cli/tx.go index 9526c5f8c010..bff4c5da9478 100644 --- a/x/ibc/core/03-connection/client/cli/tx.go +++ b/x/ibc/core/03-connection/client/cli/tx.go @@ -22,23 +22,22 @@ import ( const ( flagVersionIdentifier = "version-identifier" flagVersionFeatures = "version-features" - flagProvedID = "proved-id" ) // NewConnectionOpenInitCmd defines the command to initialize a connection on // chain A with a given counterparty chain B func NewConnectionOpenInitCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-init [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json]", + Use: "open-init [client-id] [counterparty-client-id] [path/to/counterparty_prefix.json]", Short: "Initialize connection on chain A", Long: `Initialize a connection on chain A with a given counterparty chain B. - 'version-identifier' flag can be a single pre-selected version identifier to be used in the handshake. - 'version-features' flag can be a list of features separated by commas to accompany the version identifier.`, Example: fmt.Sprintf( - "%s tx %s %s open-init [connection-id] [client-id] [counterparty-connection-id] [counterparty-client-id] [path/to/counterparty_prefix.json] --version-identifier=\"1.0\" --version-features=\"ORDER_UNORDERED\"", + "%s tx %s %s open-init [client-id] [counterparty-client-id] [path/to/counterparty_prefix.json] --version-identifier=\"1.0\" --version-features=\"ORDER_UNORDERED\"", version.AppName, host.ModuleName, types.SubModuleName, ), - Args: cobra.ExactArgs(5), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -46,12 +45,10 @@ func NewConnectionOpenInitCmd() *cobra.Command { return err } - connectionID := args[0] - clientID := args[1] - counterpartyConnectionID := args[2] - counterpartyClientID := args[3] + clientID := args[0] + counterpartyClientID := args[1] - counterpartyPrefix, err := utils.ParsePrefix(clientCtx.LegacyAmino, args[4]) + counterpartyPrefix, err := utils.ParsePrefix(clientCtx.LegacyAmino, args[2]) if err != nil { return err } @@ -71,7 +68,7 @@ func NewConnectionOpenInitCmd() *cobra.Command { } msg := types.NewMsgConnectionOpenInit( - connectionID, clientID, counterpartyConnectionID, counterpartyClientID, + clientID, counterpartyClientID, counterpartyPrefix, version, clientCtx.GetFromAddress(), ) @@ -116,7 +113,6 @@ func NewConnectionOpenTryCmd() *cobra.Command { } connectionID := args[0] - provedID, _ := cmd.Flags().GetString(flagProvedID) clientID := args[1] counterpartyConnectionID := args[2] counterpartyClientID := args[3] @@ -179,7 +175,7 @@ func NewConnectionOpenTryCmd() *cobra.Command { } msg := types.NewMsgConnectionOpenTry( - connectionID, provedID, clientID, counterpartyConnectionID, counterpartyClientID, + connectionID, clientID, counterpartyConnectionID, counterpartyClientID, counterpartyClient, counterpartyPrefix, counterpartyVersions, proofInit, proofClient, proofConsensus, proofHeight, consensusHeight, clientCtx.GetFromAddress(), @@ -193,7 +189,6 @@ func NewConnectionOpenTryCmd() *cobra.Command { }, } - cmd.Flags().String(flagProvedID, "", "identifier set by the counterparty chain") flags.AddTxFlagsToCmd(cmd) return cmd diff --git a/x/ibc/core/03-connection/genesis.go b/x/ibc/core/03-connection/genesis.go index da8ffcd50d53..4f97ed37ba96 100644 --- a/x/ibc/core/03-connection/genesis.go +++ b/x/ibc/core/03-connection/genesis.go @@ -16,6 +16,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { for _, connPaths := range gs.ClientConnectionPaths { k.SetClientConnectionPaths(ctx, connPaths.ClientId, connPaths.Paths) } + k.SetNextConnectionSequence(ctx, gs.NextConnectionSequence) } // ExportGenesis returns the ibc connection submodule's exported genesis. diff --git a/x/ibc/core/03-connection/keeper/grpc_query_test.go b/x/ibc/core/03-connection/keeper/grpc_query_test.go index 7e27b5af1015..e710b0d5477e 100644 --- a/x/ibc/core/03-connection/keeper/grpc_query_test.go +++ b/x/ibc/core/03-connection/keeper/grpc_query_test.go @@ -112,18 +112,18 @@ func (suite *KeeperTestSuite) TestQueryConnections() { "success", func() { clientA, clientB, connA0, connB0 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - connA1, connB1, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) + clientA1, clientB1, connA1, connB1 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) + connA2, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) - clientA1, clientB1, connA2, connB2 := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - counterparty1 := types.NewCounterparty(clientB, connB0.ID, suite.chainB.GetPrefix()) - counterparty2 := types.NewCounterparty(clientB, connB1.ID, suite.chainB.GetPrefix()) - counterparty3 := types.NewCounterparty(clientB1, connB2.ID, suite.chainB.GetPrefix()) + counterparty2 := types.NewCounterparty(clientB1, connB1.ID, suite.chainB.GetPrefix()) + // counterparty connection id is blank after open init + counterparty3 := types.NewCounterparty(clientB, "", suite.chainB.GetPrefix()) conn1 := types.NewConnectionEnd(types.OPEN, clientA, counterparty1, types.ExportedVersionsToProto(types.GetCompatibleVersions())) - conn2 := types.NewConnectionEnd(types.INIT, clientA, counterparty2, types.ExportedVersionsToProto(types.GetCompatibleVersions())) - conn3 := types.NewConnectionEnd(types.OPEN, clientA1, counterparty3, types.ExportedVersionsToProto(types.GetCompatibleVersions())) + conn2 := types.NewConnectionEnd(types.OPEN, clientA1, counterparty2, types.ExportedVersionsToProto(types.GetCompatibleVersions())) + conn3 := types.NewConnectionEnd(types.INIT, clientA, counterparty3, types.ExportedVersionsToProto(types.GetCompatibleVersions())) iconn1 := types.NewIdentifiedConnection(connA0.ID, conn1) iconn2 := types.NewIdentifiedConnection(connA1.ID, conn2) diff --git a/x/ibc/core/03-connection/keeper/handshake.go b/x/ibc/core/03-connection/keeper/handshake.go index 0fce7d90063f..7a7d700570e9 100644 --- a/x/ibc/core/03-connection/keeper/handshake.go +++ b/x/ibc/core/03-connection/keeper/handshake.go @@ -14,36 +14,33 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" ) -// ConnOpenInit initialises a connection attempt on chain A. +// ConnOpenInit initialises a connection attempt on chain A. The generated connection identifier +// is returned. // -// NOTE: Identifiers are checked on msg validation. +// NOTE: Msg validation verifies the supplied identifiers and ensures that the counterparty +// connection identifier is empty. func (k Keeper) ConnOpenInit( ctx sdk.Context, - connectionID, // identifier clientID string, - counterparty types.Counterparty, // desiredCounterpartyConnectionIdentifier, counterpartyPrefix, counterpartyClientIdentifier + counterparty types.Counterparty, // counterpartyPrefix, counterpartyClientIdentifier version *types.Version, -) error { - _, found := k.GetConnection(ctx, connectionID) - if found { - return sdkerrors.Wrap(types.ErrConnectionExists, connectionID) - } - +) (string, error) { versions := types.GetCompatibleVersions() if version != nil { if !types.IsSupportedVersion(version) { - return sdkerrors.Wrap(types.ErrInvalidVersion, "version is not supported") + return "", sdkerrors.Wrap(types.ErrInvalidVersion, "version is not supported") } versions = []exported.Version{version} } // connection defines chain A's ConnectionEnd + connectionID := k.GenerateConnectionIdentifier(ctx) connection := types.NewConnectionEnd(types.INIT, clientID, counterparty, types.ExportedVersionsToProto(versions)) k.SetConnection(ctx, connectionID, connection) if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { - return err + return "", err } k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", "NONE", "new-state", "INIT") @@ -52,7 +49,7 @@ func (k Keeper) ConnOpenInit( telemetry.IncrCounter(1, "ibc", "connection", "open-init") }() - return nil + return connectionID, nil } // ConnOpenTry relays notice of a connection attempt on chain A to chain B (this @@ -63,8 +60,7 @@ func (k Keeper) ConnOpenInit( // - Identifiers are checked on msg validation func (k Keeper) ConnOpenTry( ctx sdk.Context, - desiredConnectionID, // desiredIdentifier - counterpartyChosenConnectionID string, // counterparty used this identifier in proof + previousConnectionID string, // previousIdentifier counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier clientID string, // clientID of chainA clientState exported.ClientState, // clientState that chainA has for chainB @@ -74,10 +70,47 @@ func (k Keeper) ConnOpenTry( proofConsensus []byte, // proof that chainA stored chainB's consensus state at consensus height proofHeight exported.Height, // height at which relayer constructs proof of A storing connectionEnd in state consensusHeight exported.Height, // latest height of chain B which chain A has stored in its chain B client -) error { +) (string, error) { + var ( + connectionID string + previousConnection types.ConnectionEnd + found bool + ) + + // empty connection identifier indicates continuing a previous connection handshake + if previousConnectionID != "" { + // ensure that the previous connection exists + previousConnection, found = k.GetConnection(ctx, previousConnectionID) + if !found { + return "", sdkerrors.Wrapf(types.ErrConnectionNotFound, "previous connection does not exist for supplied previous connectionID %s", previousConnectionID) + } + + // ensure that the existing connection's + // counterparty is chainA and connection is on INIT stage. + // Check that existing connection versions for initialized connection is equal to compatible + // versions for this chain. + if !(previousConnection.Counterparty.ConnectionId == "" && + bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) && + previousConnection.ClientId == clientID && + previousConnection.Counterparty.ClientId == counterparty.ClientId) { + return "", sdkerrors.Wrap(types.ErrInvalidConnection, "connection fields mismatch previous connection fields") + } + + if !(previousConnection.State == types.INIT) { + return "", sdkerrors.Wrapf(types.ErrInvalidConnectionState, "previous connection state is in state %s, expected INIT", previousConnection.State) + } + + // continue with previous connection + connectionID = previousConnectionID + + } else { + // generate a new connection + connectionID = k.GenerateConnectionIdentifier(ctx) + } + selfHeight := clienttypes.GetSelfHeight(ctx) if consensusHeight.GTE(selfHeight) { - return sdkerrors.Wrapf( + return "", sdkerrors.Wrapf( sdkerrors.ErrInvalidHeight, "consensus height is greater than or equal to the current block height (%s >= %s)", consensusHeight, selfHeight, ) @@ -85,43 +118,20 @@ func (k Keeper) ConnOpenTry( // validate client parameters of a chainB client stored on chainA if err := k.clientKeeper.ValidateSelfClient(ctx, clientState); err != nil { - return err + return "", err } expectedConsensusState, found := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight) if !found { - return sdkerrors.Wrap(clienttypes.ErrSelfConsensusStateNotFound, consensusHeight.String()) - } - - // If the connection id chosen for this connection end by the counterparty is empty then - // flexible connection identifier selection is allowed by using the desired connection id. - // Otherwise the desiredConnectionID must match the counterpartyChosenConnectionID. - if counterpartyChosenConnectionID != "" && counterpartyChosenConnectionID != desiredConnectionID { - return sdkerrors.Wrapf( - types.ErrInvalidConnectionIdentifier, - "counterparty chosen connection ID (%s) must be empty or equal to the desired connection ID (%s)", counterpartyChosenConnectionID, desiredConnectionID, - ) + return "", sdkerrors.Wrap(clienttypes.ErrSelfConsensusStateNotFound, consensusHeight.String()) } // expectedConnection defines Chain A's ConnectionEnd // NOTE: chain A's counterparty is chain B (i.e where this code is executed) prefix := k.GetCommitmentPrefix() - expectedCounterparty := types.NewCounterparty(clientID, counterpartyChosenConnectionID, commitmenttypes.NewMerklePrefix(prefix.Bytes())) + expectedCounterparty := types.NewCounterparty(clientID, "", commitmenttypes.NewMerklePrefix(prefix.Bytes())) expectedConnection := types.NewConnectionEnd(types.INIT, counterparty.ClientId, expectedCounterparty, types.ExportedVersionsToProto(counterpartyVersions)) - // If connection already exists for desiredConnectionID, ensure that the existing connection's - // counterparty is chainA and connection is on INIT stage. - // Check that existing connection versions for initialized connection is equal to compatible - // versions for this chain. - previousConnection, found := k.GetConnection(ctx, desiredConnectionID) - if found && !(previousConnection.State == types.INIT && - previousConnection.Counterparty.ConnectionId == counterparty.ConnectionId && - bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) && - previousConnection.ClientId == clientID && - previousConnection.Counterparty.ClientId == counterparty.ClientId) { - return sdkerrors.Wrap(types.ErrInvalidConnection, "cannot relay connection attempt") - } - supportedVersions := types.GetCompatibleVersions() if len(previousConnection.Versions) != 0 { supportedVersions = previousConnection.GetVersions() @@ -132,7 +142,7 @@ func (k Keeper) ConnOpenTry( // of the supported versions and the counterparty versions. version, err := types.PickVersion(supportedVersions, counterpartyVersions) if err != nil { - return err + return "", err } // connection defines chain B's ConnectionEnd @@ -143,34 +153,34 @@ func (k Keeper) ConnOpenTry( ctx, connection, proofHeight, proofInit, counterparty.ConnectionId, expectedConnection, ); err != nil { - return err + return "", err } // Check that ChainA stored the clientState provided in the msg if err := k.VerifyClientState(ctx, connection, proofHeight, proofClient, clientState); err != nil { - return err + return "", err } // Check that ChainA stored the correct ConsensusState of chainB at the given consensusHeight if err := k.VerifyClientConsensusState( ctx, connection, proofHeight, consensusHeight, proofConsensus, expectedConsensusState, ); err != nil { - return err + return "", err } // store connection in chainB state - if err := k.addConnectionToClient(ctx, clientID, desiredConnectionID); err != nil { - return sdkerrors.Wrapf(err, "failed to add connection with ID %s to client with ID %s", desiredConnectionID, clientID) + if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil { + return "", sdkerrors.Wrapf(err, "failed to add connection with ID %s to client with ID %s", connectionID, clientID) } - k.SetConnection(ctx, desiredConnectionID, connection) - k.Logger(ctx).Info("connection state updated", "connection-id", desiredConnectionID, "previous-state", previousConnection.State.String(), "new-state", "TRYOPEN") + k.SetConnection(ctx, connectionID, connection) + k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", previousConnection.State.String(), "new-state", "TRYOPEN") defer func() { telemetry.IncrCounter(1, "ibc", "connection", "open-try") }() - return nil + return connectionID, nil } // ConnOpenAck relays acceptance of a connection open attempt from chain B back @@ -204,16 +214,6 @@ func (k Keeper) ConnOpenAck( return sdkerrors.Wrap(types.ErrConnectionNotFound, connectionID) } - // If the previously set connection end allowed for the counterparty to select its own - // connection identifier then we use the counterpartyConnectionID. Otherwise the - // counterpartyConnectionID must match the previously set counterparty connection ID. - if connection.Counterparty.ConnectionId != "" && counterpartyConnectionID != connection.Counterparty.ConnectionId { - return sdkerrors.Wrapf( - types.ErrInvalidConnectionIdentifier, - "counterparty connection identifier (%s) must be equal to stored connection ID for counterparty (%s)", counterpartyConnectionID, connection.Counterparty.ConnectionId, - ) - } - // Verify the provided version against the previously set connection state switch { // connection on ChainA must be in INIT or TRYOPEN diff --git a/x/ibc/core/03-connection/keeper/handshake_test.go b/x/ibc/core/03-connection/keeper/handshake_test.go index 2ece130ebba0..eb9ca5c401b5 100644 --- a/x/ibc/core/03-connection/keeper/handshake_test.go +++ b/x/ibc/core/03-connection/keeper/handshake_test.go @@ -36,9 +36,6 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] }, true}, - {"connection already exists", func() { - clientA, clientB, _, _ = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - }, false}, {"invalid version", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) version = &types.Version{} @@ -58,19 +55,20 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { tc.malleate() - connA := suite.chainA.GetFirstTestConnection(clientA, clientB) connB := suite.chainB.GetFirstTestConnection(clientB, clientA) if emptyConnBID { connB.ID = "" } counterparty := types.NewCounterparty(clientB, connB.ID, suite.chainB.GetPrefix()) - err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), connA.ID, clientA, counterparty, version) + connectionID, err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.chainA.GetContext(), clientA, counterparty, version) if tc.expPass { suite.Require().NoError(err) + suite.Require().Equal(types.FormatConnectionIdentifier(0), connectionID) } else { suite.Require().Error(err) + suite.Require().Equal("", connectionID) } }) } @@ -80,11 +78,12 @@ func (suite *KeeperTestSuite) TestConnOpenInit() { // connection on chainA is INIT func (suite *KeeperTestSuite) TestConnOpenTry() { var ( - clientA string - clientB string - versions []exported.Version - consensusHeight exported.Height - counterpartyClient exported.ClientState + clientA string + clientB string + previousConnectionID string + versions []exported.Version + consensusHeight exported.Height + counterpartyClient exported.ClientState ) testCases := []struct { @@ -100,50 +99,16 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) }, true}, - {"success with empty counterpartyChosenConnectionID", func() { + {"success with crossing hellos", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to empty string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - - connection.Counterparty.ConnectionId = "" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) + _, connB, err := suite.coordinator.ConnOpenInitOnBothChains(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) - }, true}, - {"counterpartyChosenConnectionID does not match desiredConnectionID", func() { - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to invalid identifier - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - connection.Counterparty.ConnectionId = "badidentifier" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - // retrieve client state of chainA to pass as counterpartyClient - counterpartyClient = suite.chainA.GetClientState(clientA) - }, false}, + previousConnectionID = connB.ID + }, true}, {"invalid counterparty client", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) _, _, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) @@ -255,6 +220,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) + + previousConnectionID = connB.ID }, false}, {"invalid previous connection has invalid versions", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) @@ -281,6 +248,8 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // retrieve client state of chainA to pass as counterpartyClient counterpartyClient = suite.chainA.GetClientState(clientA) + + previousConnectionID = connB.ID }, false}, } @@ -291,20 +260,13 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { suite.SetupTest() // reset consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate versions = types.GetCompatibleVersions() // must be explicitly changed in malleate + previousConnectionID = "" tc.malleate() connA := suite.chainA.GetFirstTestConnection(clientA, clientB) - connB := suite.chainB.GetFirstTestConnection(clientB, clientA) counterparty := types.NewCounterparty(clientA, connA.ID, suite.chainA.GetPrefix()) - // get counterpartyChosenConnectionID - var counterpartyChosenConnectionID string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - if found { - counterpartyChosenConnectionID = connection.Counterparty.ConnectionId - } - connectionKey := host.ConnectionKey(connA.ID) proofInit, proofHeight := suite.chainA.QueryProof(connectionKey) @@ -319,16 +281,18 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { clientKey := host.FullClientStateKey(clientA) proofClient, _ := suite.chainA.QueryProof(clientKey) - err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( - suite.chainB.GetContext(), connB.ID, counterpartyChosenConnectionID, counterparty, clientB, counterpartyClient, + connectionID, err := suite.chainB.App.IBCKeeper.ConnectionKeeper.ConnOpenTry( + suite.chainB.GetContext(), previousConnectionID, counterparty, clientB, counterpartyClient, versions, proofInit, proofClient, proofConsensus, proofHeight, consensusHeight, ) if tc.expPass { suite.Require().NoError(err) + suite.Require().Equal(types.FormatConnectionIdentifier(0), connectionID) } else { suite.Require().Error(err) + suite.Require().Equal("", connectionID) } }) } @@ -338,12 +302,11 @@ func (suite *KeeperTestSuite) TestConnOpenTry() { // the initialization (TRYINIT) of the connection on Chain B (ID #2). func (suite *KeeperTestSuite) TestConnOpenAck() { var ( - clientA string - clientB string - counterpartyConnectionID string - consensusHeight exported.Height - version *types.Version - counterpartyClient exported.ClientState + clientA string + clientB string + consensusHeight exported.Height + version *types.Version + counterpartyClient exported.ClientState ) testCases := []struct { @@ -362,33 +325,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // retrieve client state of chainB to pass as counterpartyClient counterpartyClient = suite.chainB.GetClientState(clientB) }, true}, - {"success with empty stored counterparty connection ID", func() { - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) - suite.Require().NoError(err) - - err = suite.coordinator.ConnOpenTry(suite.chainB, suite.chainA, connB, connA) - suite.Require().NoError(err) - - // modify connA to set counterparty connection identifier to empty string - connection, found := suite.chainA.App.IBCKeeper.ConnectionKeeper.GetConnection(suite.chainA.GetContext(), connA.ID) - suite.Require().True(found) - - connection.Counterparty.ConnectionId = "" - // use some other identifier - counterpartyConnectionID = connB.ID - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - suite.Require().NoError(err) - - // retrieve client state of chainB to pass as counterpartyClient - counterpartyClient = suite.chainB.GetClientState(clientB) - }, true}, {"success from tryopen", func() { // chainA is in TRYOPEN, chainB is in TRYOPEN clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) @@ -401,6 +337,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // set chainB to TRYOPEN connection := suite.chainB.GetConnection(connB) connection.State = types.TRYOPEN + connection.Counterparty.ConnectionId = connA.ID suite.chainB.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainB.GetContext(), connB.ID, connection) // update clientB so state change is committed suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) @@ -410,37 +347,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { // retrieve client state of chainB to pass as counterpartyClient counterpartyClient = suite.chainB.GetClientState(clientB) }, true}, - {"success from tryopen with empty stored connection id", func() { - // chainA is in TRYOPEN, chainB is in TRYOPEN - clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) - connB, connA, err := suite.coordinator.ConnOpenInit(suite.chainB, suite.chainA, clientB, clientA) - suite.Require().NoError(err) - - err = suite.coordinator.ConnOpenTry(suite.chainA, suite.chainB, connA, connB) - suite.Require().NoError(err) - - // set chainB to TRYOPEN - connection := suite.chainB.GetConnection(connB) - connection.State = types.TRYOPEN - - suite.chainB.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainB.GetContext(), connB.ID, connection) - - // set connA to use empty string - connection = suite.chainA.GetConnection(connA) - - // set counterparty connection identifier to empty string - connection.Counterparty.ConnectionId = "" - - suite.chainA.App.IBCKeeper.ConnectionKeeper.SetConnection(suite.chainA.GetContext(), connA.ID, connection) - - // update clientB so state change is committed - suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - - suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) - - // retrieve client state of chainB to pass as counterpartyClient - counterpartyClient = suite.chainB.GetClientState(clientB) - }, true}, {"invalid counterparty client", func() { clientA, clientB = suite.coordinator.SetupClients(suite.chainA, suite.chainB, exported.Tendermint) connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) @@ -663,17 +569,12 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { suite.SetupTest() // reset version = types.ExportedVersionsToProto(types.GetCompatibleVersions())[0] // must be explicitly changed in malleate consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate - counterpartyConnectionID = "" // must be explicitly changed in malleate tc.malleate() connA := suite.chainA.GetFirstTestConnection(clientA, clientB) connB := suite.chainB.GetFirstTestConnection(clientB, clientA) - if counterpartyConnectionID == "" { - counterpartyConnectionID = connB.ID - } - connectionKey := host.ConnectionKey(connB.ID) proofTry, proofHeight := suite.chainB.QueryProof(connectionKey) @@ -690,7 +591,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() { proofClient, _ := suite.chainB.QueryProof(clientKey) err := suite.chainA.App.IBCKeeper.ConnectionKeeper.ConnOpenAck( - suite.chainA.GetContext(), connA.ID, counterpartyClient, version, counterpartyConnectionID, + suite.chainA.GetContext(), connA.ID, counterpartyClient, version, connB.ID, proofTry, proofClient, proofConsensus, proofHeight, consensusHeight, ) diff --git a/x/ibc/core/03-connection/keeper/keeper.go b/x/ibc/core/03-connection/keeper/keeper.go index dda52958772b..05d110fec809 100644 --- a/x/ibc/core/03-connection/keeper/keeper.go +++ b/x/ibc/core/03-connection/keeper/keeper.go @@ -45,6 +45,16 @@ func (k Keeper) GetCommitmentPrefix() exported.Prefix { return commitmenttypes.NewMerklePrefix([]byte(k.storeKey.Name())) } +// GenerateConnectionIdentifier returns the next connection identifier. +func (k Keeper) GenerateConnectionIdentifier(ctx sdk.Context) string { + nextConnSeq := k.GetNextConnectionSequence(ctx) + connectionID := types.FormatConnectionIdentifier(nextConnSeq) + + nextConnSeq++ + k.SetNextConnectionSequence(ctx, nextConnSeq) + return connectionID +} + // GetConnection returns a connection with a particular identifier func (k Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) { store := ctx.KVStore(k.storeKey) @@ -105,6 +115,24 @@ func (k Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths store.Set(host.ClientConnectionsKey(clientID), bz) } +// GetNextConnectionSequence gets the next connection sequence from the store. +func (k Keeper) GetNextConnectionSequence(ctx sdk.Context) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get([]byte(types.KeyNextConnectionSequence)) + if bz == nil { + panic("next connection sequence is nil") + } + + return sdk.BigEndianToUint64(bz) +} + +// SetNextConnectionSequence sets the next connection sequence to the store. +func (k Keeper) SetNextConnectionSequence(ctx sdk.Context, sequence uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set([]byte(types.KeyNextConnectionSequence), bz) +} + // GetAllClientConnectionPaths returns all stored clients connection id paths. It // will ignore the clients that haven't initialized a connection handshake since // no paths are stored. diff --git a/x/ibc/core/03-connection/types/connection_test.go b/x/ibc/core/03-connection/types/connection_test.go index 93891cbea12e..133bb1e5c68d 100644 --- a/x/ibc/core/03-connection/types/connection_test.go +++ b/x/ibc/core/03-connection/types/connection_test.go @@ -13,7 +13,7 @@ import ( var ( chainID = "gaiamainnet" - connectionID = "connectionidone" + connectionID = "connection-0" clientID = "clientidone" connectionID2 = "connectionidtwo" clientID2 = "clientidtwo" diff --git a/x/ibc/core/03-connection/types/genesis.go b/x/ibc/core/03-connection/types/genesis.go index 58b21678c299..f5af9b8486b3 100644 --- a/x/ibc/core/03-connection/types/genesis.go +++ b/x/ibc/core/03-connection/types/genesis.go @@ -17,18 +17,21 @@ func NewConnectionPaths(id string, paths []string) ConnectionPaths { // NewGenesisState creates a GenesisState instance. func NewGenesisState( connections []IdentifiedConnection, connPaths []ConnectionPaths, + nextConnectionSequence uint64, ) GenesisState { return GenesisState{ - Connections: connections, - ClientConnectionPaths: connPaths, + Connections: connections, + ClientConnectionPaths: connPaths, + NextConnectionSequence: nextConnectionSequence, } } // DefaultGenesisState returns the ibc connection submodule's default genesis state. func DefaultGenesisState() GenesisState { return GenesisState{ - Connections: []IdentifiedConnection{}, - ClientConnectionPaths: []ConnectionPaths{}, + Connections: []IdentifiedConnection{}, + ClientConnectionPaths: []ConnectionPaths{}, + NextConnectionSequence: 0, } } diff --git a/x/ibc/core/03-connection/types/genesis.pb.go b/x/ibc/core/03-connection/types/genesis.pb.go index ba8b3bcd5be6..19c4e6aeb823 100644 --- a/x/ibc/core/03-connection/types/genesis.pb.go +++ b/x/ibc/core/03-connection/types/genesis.pb.go @@ -27,6 +27,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { Connections []IdentifiedConnection `protobuf:"bytes,1,rep,name=connections,proto3" json:"connections"` ClientConnectionPaths []ConnectionPaths `protobuf:"bytes,2,rep,name=client_connection_paths,json=clientConnectionPaths,proto3" json:"client_connection_paths" yaml:"client_connection_paths"` + // the sequence for the next generated connection identifier + NextConnectionSequence uint64 `protobuf:"varint,3,opt,name=next_connection_sequence,json=nextConnectionSequence,proto3" json:"next_connection_sequence,omitempty" yaml:"next_connection_sequence"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -76,6 +78,13 @@ func (m *GenesisState) GetClientConnectionPaths() []ConnectionPaths { return nil } +func (m *GenesisState) GetNextConnectionSequence() uint64 { + if m != nil { + return m.NextConnectionSequence + } + return 0 +} + func init() { proto.RegisterType((*GenesisState)(nil), "ibc.core.connection.v1.GenesisState") } @@ -85,25 +94,28 @@ func init() { } var fileDescriptor_1879d34bc6ac3cd7 = []byte{ - // 281 bytes of a gzipped FileDescriptorProto + // 326 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0xc9, 0x4c, 0x4a, 0xd6, 0x4f, 0xce, 0x2f, 0x4a, 0xd5, 0x4f, 0xce, 0xcf, 0xcb, 0x4b, 0x4d, 0x2e, 0xc9, 0xcc, 0xcf, 0xd3, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0xcb, 0x4c, 0x4a, 0xd6, 0x03, 0xa9, 0xd2, 0x43, 0xa8, 0xd2, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0xa5, 0xd4, 0x71, 0x98, 0x89, - 0xa4, 0x17, 0xac, 0x50, 0xe9, 0x1d, 0x23, 0x17, 0x8f, 0x3b, 0xc4, 0xa2, 0xe0, 0x92, 0xc4, 0x92, + 0xa4, 0x17, 0xac, 0x50, 0xe9, 0x2c, 0x13, 0x17, 0x8f, 0x3b, 0xc4, 0xa2, 0xe0, 0x92, 0xc4, 0x92, 0x54, 0xa1, 0x10, 0x2e, 0x6e, 0x84, 0xa2, 0x62, 0x09, 0x46, 0x05, 0x66, 0x0d, 0x6e, 0x23, 0x1d, 0x3d, 0xec, 0xb6, 0xeb, 0x79, 0xa6, 0xa4, 0xe6, 0x95, 0x64, 0xa6, 0x65, 0xa6, 0xa6, 0x38, 0xc3, 0xc5, 0x9d, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x42, 0x36, 0x46, 0xa8, 0x9d, 0x91, 0x4b, 0x3c, 0x39, 0x27, 0x33, 0x35, 0xaf, 0x24, 0x1e, 0x21, 0x1c, 0x5f, 0x90, 0x58, 0x92, 0x51, 0x2c, 0xc1, 0x04, 0xb6, 0x42, 0x1d, 0x97, 0x15, 0x08, 0x83, 0x03, 0x40, 0xca, 0x9d, 0xd4, 0x40, 0xa6, 0x7f, 0xba, 0x27, 0x2f, 0x57, 0x99, 0x98, 0x9b, 0x63, 0xa5, 0x84, 0xc3, 0x54, 0xa5, 0x20, 0x51, 0x88, - 0x0c, 0xba, 0xf6, 0xd0, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, - 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x4e, - 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, - 0x86, 0x52, 0xba, 0xc5, 0x29, 0xd9, 0xfa, 0x15, 0xfa, 0xf0, 0x20, 0x35, 0x30, 0xd6, 0x45, 0x0a, - 0xd5, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0x70, 0x70, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, - 0xff, 0xae, 0x12, 0xc8, 0x83, 0xcd, 0x01, 0x00, 0x00, + 0x0c, 0x9a, 0x76, 0xa1, 0x58, 0x2e, 0x89, 0xbc, 0xd4, 0x0a, 0x14, 0x0d, 0xc5, 0xa9, 0x85, 0xa5, + 0xa9, 0x79, 0xc9, 0xa9, 0x12, 0xcc, 0x0a, 0x8c, 0x1a, 0x2c, 0x4e, 0xca, 0x9f, 0xee, 0xc9, 0xcb, + 0x43, 0x0c, 0xc7, 0xa5, 0x52, 0x29, 0x48, 0x0c, 0x24, 0x85, 0x30, 0x3b, 0x18, 0x2a, 0xe1, 0x14, + 0x7a, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, + 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0xd6, 0xe9, 0x99, 0x25, 0x19, + 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xc9, 0xf9, 0xc5, 0xb9, 0xf9, 0xc5, 0x50, 0x4a, 0xb7, + 0x38, 0x25, 0x5b, 0xbf, 0x42, 0x1f, 0x1e, 0x63, 0x06, 0xc6, 0xba, 0x48, 0x91, 0x56, 0x52, 0x59, + 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x8e, 0x2d, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xad, + 0x14, 0x09, 0x2c, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -126,6 +138,11 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NextConnectionSequence != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.NextConnectionSequence)) + i-- + dAtA[i] = 0x18 + } if len(m.ClientConnectionPaths) > 0 { for iNdEx := len(m.ClientConnectionPaths) - 1; iNdEx >= 0; iNdEx-- { { @@ -186,6 +203,9 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if m.NextConnectionSequence != 0 { + n += 1 + sovGenesis(uint64(m.NextConnectionSequence)) + } return n } @@ -292,6 +312,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextConnectionSequence", wireType) + } + m.NextConnectionSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextConnectionSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/ibc/core/03-connection/types/genesis_test.go b/x/ibc/core/03-connection/types/genesis_test.go index 6290a98a9ff4..343d69b08e20 100644 --- a/x/ibc/core/03-connection/types/genesis_test.go +++ b/x/ibc/core/03-connection/types/genesis_test.go @@ -31,6 +31,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{connectionID}}, }, + 0, ), expPass: true, }, @@ -43,6 +44,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{connectionID}}, }, + 0, ), expPass: false, }, @@ -55,6 +57,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {"(CLIENTIDONE)", []string{connectionID}}, }, + 0, ), expPass: false, }, @@ -67,6 +70,7 @@ func TestValidateGenesis(t *testing.T) { []types.ConnectionPaths{ {clientID, []string{invalidConnectionID}}, }, + 0, ), expPass: false, }, diff --git a/x/ibc/core/03-connection/types/keys.go b/x/ibc/core/03-connection/types/keys.go index 23478ec7591a..c44602203e51 100644 --- a/x/ibc/core/03-connection/types/keys.go +++ b/x/ibc/core/03-connection/types/keys.go @@ -1,5 +1,13 @@ package types +import ( + "fmt" + "strconv" + "strings" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + const ( // SubModuleName defines the IBC connection name SubModuleName = "connection" @@ -12,4 +20,40 @@ const ( // QuerierRoute is the querier route for IBC connections QuerierRoute = SubModuleName + + // KeyNextConnectionSequence is the key used to store the next connection sequence in + // the keeper. + KeyNextConnectionSequence = "nextConnectionSequence" + + // ConnectionPrefix is the prefix used when creating a connection identifier + ConnectionPrefix = "connection-" ) + +// FormatConnectionIdentifier returns the connection identifier with the sequence appended. +func FormatConnectionIdentifier(sequence uint64) string { + return fmt.Sprintf("%s%d", ConnectionPrefix, sequence) +} + +// IsValidConnectionID return true if the connection identifier is valid. +func IsValidConnectionID(connectionID string) bool { + _, err := ParseConnectionSequence(connectionID) + return err == nil +} + +// ParseConnectionSequence parses the connection sequence from the connection identifier. +func ParseConnectionSequence(connectionID string) (uint64, error) { + if !strings.HasPrefix(connectionID, ConnectionPrefix) { + return 0, sdkerrors.Wrapf(ErrInvalidConnectionIdentifier, "doesn't contain prefix `%s`", ConnectionPrefix) + } + + splitStr := strings.Split(connectionID, ConnectionPrefix) + if len(splitStr) != 2 { + return 0, sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "connection identifier must be in format: `connection-{N}`") + } + + sequence, err := strconv.ParseUint(splitStr[1], 10, 64) + if err != nil { + return 0, sdkerrors.Wrap(err, "failed to parse connection identifier sequence") + } + return sequence, nil +} diff --git a/x/ibc/core/03-connection/types/keys_test.go b/x/ibc/core/03-connection/types/keys_test.go new file mode 100644 index 000000000000..261bd2895fbb --- /dev/null +++ b/x/ibc/core/03-connection/types/keys_test.go @@ -0,0 +1,44 @@ +package types_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/ibc/core/03-connection/types" + "github.com/stretchr/testify/require" +) + +// tests ParseConnectionSequence and IsValidConnectionID +func TestParseConnectionSequence(t *testing.T) { + testCases := []struct { + name string + connectionID string + expSeq uint64 + expPass bool + }{ + {"valid 0", "connection-0", 0, true}, + {"valid 1", "connection-1", 1, true}, + {"valid large sequence", "connection-234568219356718293", 234568219356718293, true}, + // uint64 == 20 characters + {"invalid large sequence", "connection-2345682193567182931243", 0, false}, + {"capital prefix", "Connection-0", 0, false}, + {"missing dash", "connection0", 0, false}, + {"blank id", " ", 0, false}, + {"empty id", "", 0, false}, + {"negative sequence", "connection--1", 0, false}, + } + + for _, tc := range testCases { + + seq, err := types.ParseConnectionSequence(tc.connectionID) + valid := types.IsValidConnectionID(tc.connectionID) + require.Equal(t, tc.expSeq, seq) + + if tc.expPass { + require.NoError(t, err, tc.name) + require.True(t, valid) + } else { + require.Error(t, err, tc.name) + require.False(t, valid) + } + } +} diff --git a/x/ibc/core/03-connection/types/msgs.go b/x/ibc/core/03-connection/types/msgs.go index a162fb589b10..a734f986081d 100644 --- a/x/ibc/core/03-connection/types/msgs.go +++ b/x/ibc/core/03-connection/types/msgs.go @@ -12,16 +12,16 @@ import ( var _ sdk.Msg = &MsgConnectionOpenInit{} -// NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance +// NewMsgConnectionOpenInit creates a new MsgConnectionOpenInit instance. It sets the +// counterparty connection identifier to be empty. //nolint:interfacer func NewMsgConnectionOpenInit( - connectionID, clientID, counterpartyConnectionID, - counterpartyClientID string, counterpartyPrefix commitmenttypes.MerklePrefix, + clientID, counterpartyClientID string, + counterpartyPrefix commitmenttypes.MerklePrefix, version *Version, signer sdk.AccAddress, ) *MsgConnectionOpenInit { - counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) + counterparty := NewCounterparty(counterpartyClientID, "", counterpartyPrefix) return &MsgConnectionOpenInit{ - ConnectionId: connectionID, ClientId: clientID, Counterparty: counterparty, Version: version, @@ -41,12 +41,13 @@ func (msg MsgConnectionOpenInit) Type() string { // ValidateBasic implements sdk.Msg. func (msg MsgConnectionOpenInit) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") - } if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { return sdkerrors.Wrap(err, "invalid client ID") } + if msg.Counterparty.ConnectionId != "" { + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty connection identifier must be empty") + } + // NOTE: Version can be nil on MsgConnectionOpenInit if msg.Version != nil { if err := ValidateVersion(msg.Version); err != nil { @@ -80,7 +81,7 @@ var _ sdk.Msg = &MsgConnectionOpenTry{} // NewMsgConnectionOpenTry creates a new MsgConnectionOpenTry instance //nolint:interfacer func NewMsgConnectionOpenTry( - desiredConnectionID, counterpartyChosenConnectionID, clientID, counterpartyConnectionID, + previousConnectionID, clientID, counterpartyConnectionID, counterpartyClientID string, counterpartyClient exported.ClientState, counterpartyPrefix commitmenttypes.MerklePrefix, counterpartyVersions []*Version, proofInit, proofClient, proofConsensus []byte, @@ -89,18 +90,17 @@ func NewMsgConnectionOpenTry( counterparty := NewCounterparty(counterpartyClientID, counterpartyConnectionID, counterpartyPrefix) csAny, _ := clienttypes.PackClientState(counterpartyClient) return &MsgConnectionOpenTry{ - DesiredConnectionId: desiredConnectionID, - CounterpartyChosenConnectionId: counterpartyChosenConnectionID, - ClientId: clientID, - ClientState: csAny, - Counterparty: counterparty, - CounterpartyVersions: counterpartyVersions, - ProofInit: proofInit, - ProofClient: proofClient, - ProofConsensus: proofConsensus, - ProofHeight: proofHeight, - ConsensusHeight: consensusHeight, - Signer: signer.String(), + PreviousConnectionId: previousConnectionID, + ClientId: clientID, + ClientState: csAny, + Counterparty: counterparty, + CounterpartyVersions: counterpartyVersions, + ProofInit: proofInit, + ProofClient: proofClient, + ProofConsensus: proofConsensus, + ProofHeight: proofHeight, + ConsensusHeight: consensusHeight, + Signer: signer.String(), } } @@ -116,15 +116,19 @@ func (msg MsgConnectionOpenTry) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenTry) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.DesiredConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid desired connection ID") - } - if msg.CounterpartyChosenConnectionId != "" && msg.CounterpartyChosenConnectionId != msg.DesiredConnectionId { - return sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "counterparty chosen connection identifier must be empty or equal to desired connection identifier") + // an empty connection identifier indicates that a connection identifier should be generated + if msg.PreviousConnectionId != "" { + if !IsValidConnectionID(msg.PreviousConnectionId) { + return sdkerrors.Wrap(ErrInvalidConnectionIdentifier, "invalid previous connection ID") + } } if err := host.ClientIdentifierValidator(msg.ClientId); err != nil { return sdkerrors.Wrap(err, "invalid client ID") } + // counterparty validate basic allows empty counterparty connection identifiers + if err := host.ConnectionIdentifierValidator(msg.Counterparty.ConnectionId); err != nil { + return sdkerrors.Wrap(err, "invalid counterparty connection ID") + } if msg.ClientState == nil { return sdkerrors.Wrap(clienttypes.ErrInvalidClient, "counterparty client is nil") } @@ -234,8 +238,8 @@ func (msg MsgConnectionOpenAck) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenAck) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") + if !IsValidConnectionID(msg.ConnectionId) { + return ErrInvalidConnectionIdentifier } if err := host.ConnectionIdentifierValidator(msg.CounterpartyConnectionId); err != nil { return sdkerrors.Wrap(err, "invalid counterparty connection ID") @@ -318,8 +322,8 @@ func (msg MsgConnectionOpenConfirm) Type() string { // ValidateBasic implements sdk.Msg func (msg MsgConnectionOpenConfirm) ValidateBasic() error { - if err := host.ConnectionIdentifierValidator(msg.ConnectionId); err != nil { - return sdkerrors.Wrap(err, "invalid connection ID") + if !IsValidConnectionID(msg.ConnectionId) { + return ErrInvalidConnectionIdentifier } if len(msg.ProofAck) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") diff --git a/x/ibc/core/03-connection/types/msgs_test.go b/x/ibc/core/03-connection/types/msgs_test.go index 675de9934719..9c09ec1f7b10 100644 --- a/x/ibc/core/03-connection/types/msgs_test.go +++ b/x/ibc/core/03-connection/types/msgs_test.go @@ -87,14 +87,13 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenInit() { msg *types.MsgConnectionOpenInit expPass bool }{ - {"invalid connection ID", types.NewMsgConnectionOpenInit("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", prefix, version, signer), false}, - {"invalid client ID", types.NewMsgConnectionOpenInit("ibcconntest", "test/iris", "connectiontotest", "clienttotest", prefix, version, signer), false}, - {"invalid counterparty client ID", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "test/conn1", "clienttotest", prefix, version, signer), false}, - {"invalid counterparty connection ID", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "test/conn1", prefix, version, signer), false}, - {"empty counterparty prefix", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", emptyPrefix, version, signer), false}, - {"supplied version fails basic validation", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, &types.Version{}, signer), false}, - {"empty singer", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, version, nil), false}, - {"success", types.NewMsgConnectionOpenInit("ibcconntest", "clienttotest", "connectiontotest", "clienttotest", prefix, version, signer), true}, + {"invalid client ID", types.NewMsgConnectionOpenInit("test/iris", "clienttotest", prefix, version, signer), false}, + {"invalid counterparty client ID", types.NewMsgConnectionOpenInit("clienttotest", "(clienttotest)", prefix, version, signer), false}, + {"invalid counterparty connection ID", &types.MsgConnectionOpenInit{connectionID, types.NewCounterparty("clienttotest", "connectiontotest", prefix), version, signer.String()}, false}, + {"empty counterparty prefix", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", emptyPrefix, version, signer), false}, + {"supplied version fails basic validation", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, &types.Version{}, signer), false}, + {"empty singer", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, nil), false}, + {"success", types.NewMsgConnectionOpenInit("clienttotest", "clienttotest", prefix, version, signer), true}, } for _, tc := range testCases { @@ -112,7 +111,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") clientState := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) // Pack consensus state into any to test unpacking error @@ -124,33 +123,32 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { // invalidClientState fails validateBasic invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) - provedID := "" var testCases = []struct { name string msg *types.MsgConnectionOpenTry expPass bool }{ - {"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid connection ID", types.NewMsgConnectionOpenTry("ibcconntest", "test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid client ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid counterparty client ID", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid nil counterparty client", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"invalid client unpacking", &types.MsgConnectionOpenTry{"ibcconntest", provedID, "clienttotesta", invalidAny, counterparty, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer.String()}, false}, - {"counterparty failed Validate", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty counterparty prefix", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty counterpartyVersions", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofInit", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofClient", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, - {"empty proofConsensus", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, - {"invalid proofHeight", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false}, - {"invalid consensusHeight", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, - {"empty singer", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, nil), false}, - {"success", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, - {"invalid version", types.NewMsgConnectionOpenTry("ibcconntest", provedID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid connection ID", types.NewMsgConnectionOpenTry("test/conn1", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid connection ID", types.NewMsgConnectionOpenTry("(invalidconnection)", "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid client ID", types.NewMsgConnectionOpenTry(connectionID, "test/iris", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid counterparty connection ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "ibc/test", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid counterparty client ID", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "test/conn1", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid nil counterparty client", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", nil, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"invalid client unpacking", &types.MsgConnectionOpenTry{connectionID, "clienttotesta", invalidAny, counterparty, []*types.Version{ibctesting.ConnectionVersion}, clientHeight, suite.proof, suite.proof, suite.proof, clientHeight, signer.String()}, false}, + {"counterparty failed Validate", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", invalidClient, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty counterparty prefix", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, emptyPrefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty counterpartyVersions", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofInit", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, emptyProof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofClient", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, emptyProof, suite.proof, clientHeight, clientHeight, signer), false}, + {"empty proofConsensus", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, emptyProof, clientHeight, clientHeight, signer), false}, + {"invalid proofHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clienttypes.ZeroHeight(), clientHeight, signer), false}, + {"invalid consensusHeight", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clienttypes.ZeroHeight(), signer), false}, + {"empty singer", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, nil), false}, + {"success", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{ibctesting.ConnectionVersion}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), true}, + {"invalid version", types.NewMsgConnectionOpenTry(connectionID, "clienttotesta", "connectiontotest", "clienttotest", clientState, prefix, []*types.Version{{}}, suite.proof, suite.proof, suite.proof, clientHeight, clientHeight, signer), false}, } for _, tc := range testCases { @@ -166,7 +164,7 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenTry() { func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { signer, _ := sdk.AccAddressFromBech32("cosmos1ckgw5d7jfj7wwxjzs9fdrdev9vc8dzcw3n2lht") clientState := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) // Pack consensus state into any to test unpacking error @@ -177,9 +175,9 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenAck() { // invalidClientState fails validateBasic invalidClient := ibctmtypes.NewClientState( - chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, + chainID, ibctmtypes.DefaultTrustLevel, ibctesting.TrustingPeriod, ibctesting.UnbondingPeriod, ibctesting.MaxClockDrift, clienttypes.ZeroHeight(), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false, ) - connectionID := "ibcconntest" + connectionID := "connection-0" var testCases = []struct { name string @@ -216,10 +214,10 @@ func (suite *MsgTestSuite) TestNewMsgConnectionOpenConfirm() { testMsgs := []*types.MsgConnectionOpenConfirm{ types.NewMsgConnectionOpenConfirm("test/conn1", suite.proof, clientHeight, signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", emptyProof, clientHeight, signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clienttypes.ZeroHeight(), signer), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clientHeight, nil), - types.NewMsgConnectionOpenConfirm("ibcconntest", suite.proof, clientHeight, signer), + types.NewMsgConnectionOpenConfirm(connectionID, emptyProof, clientHeight, signer), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clienttypes.ZeroHeight(), signer), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clientHeight, nil), + types.NewMsgConnectionOpenConfirm(connectionID, suite.proof, clientHeight, signer), } var testCases = []struct { diff --git a/x/ibc/core/03-connection/types/tx.pb.go b/x/ibc/core/03-connection/types/tx.pb.go index be78639db0a5..05e60cf3e1ff 100644 --- a/x/ibc/core/03-connection/types/tx.pb.go +++ b/x/ibc/core/03-connection/types/tx.pb.go @@ -34,10 +34,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // initialize a connection with Chain B. type MsgConnectionOpenInit struct { ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` - ConnectionId string `protobuf:"bytes,2,opt,name=connection_id,json=connectionId,proto3" json:"connection_id,omitempty" yaml:"connection_id"` - Counterparty Counterparty `protobuf:"bytes,3,opt,name=counterparty,proto3" json:"counterparty"` - Version *Version `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` - Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty"` + Counterparty Counterparty `protobuf:"bytes,2,opt,name=counterparty,proto3" json:"counterparty"` + Version *Version `protobuf:"bytes,3,opt,name=version,proto3" json:"version,omitempty"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgConnectionOpenInit) Reset() { *m = MsgConnectionOpenInit{} } @@ -113,22 +112,23 @@ var xxx_messageInfo_MsgConnectionOpenInitResponse proto.InternalMessageInfo // MsgConnectionOpenTry defines a msg sent by a Relayer to try to open a // connection on Chain B. type MsgConnectionOpenTry struct { - ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` - DesiredConnectionId string `protobuf:"bytes,2,opt,name=desired_connection_id,json=desiredConnectionId,proto3" json:"desired_connection_id,omitempty" yaml:"desired_connection_id"` - CounterpartyChosenConnectionId string `protobuf:"bytes,3,opt,name=counterparty_chosen_connection_id,json=counterpartyChosenConnectionId,proto3" json:"counterparty_chosen_connection_id,omitempty" yaml:"counterparty_chosen_connection_id"` - ClientState *types.Any `protobuf:"bytes,4,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` - Counterparty Counterparty `protobuf:"bytes,5,opt,name=counterparty,proto3" json:"counterparty"` - CounterpartyVersions []*Version `protobuf:"bytes,6,rep,name=counterparty_versions,json=counterpartyVersions,proto3" json:"counterparty_versions,omitempty" yaml:"counterparty_versions"` - ProofHeight types1.Height `protobuf:"bytes,7,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` + ClientId string `protobuf:"bytes,1,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty" yaml:"client_id"` + // in the case of crossing hello's, when both chains call OpenInit, we need the connection identifier + // of the previous connection in state INIT + PreviousConnectionId string `protobuf:"bytes,2,opt,name=previous_connection_id,json=previousConnectionId,proto3" json:"previous_connection_id,omitempty" yaml:"previous_connection_id"` + ClientState *types.Any `protobuf:"bytes,3,opt,name=client_state,json=clientState,proto3" json:"client_state,omitempty" yaml:"client_state"` + Counterparty Counterparty `protobuf:"bytes,4,opt,name=counterparty,proto3" json:"counterparty"` + CounterpartyVersions []*Version `protobuf:"bytes,5,rep,name=counterparty_versions,json=counterpartyVersions,proto3" json:"counterparty_versions,omitempty" yaml:"counterparty_versions"` + ProofHeight types1.Height `protobuf:"bytes,6,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` // proof of the initialization the connection on Chain A: `UNITIALIZED -> // INIT` - ProofInit []byte `protobuf:"bytes,8,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` + ProofInit []byte `protobuf:"bytes,7,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` // proof of client state included in message - ProofClient []byte `protobuf:"bytes,9,opt,name=proof_client,json=proofClient,proto3" json:"proof_client,omitempty" yaml:"proof_client"` + ProofClient []byte `protobuf:"bytes,8,opt,name=proof_client,json=proofClient,proto3" json:"proof_client,omitempty" yaml:"proof_client"` // proof of client consensus state - ProofConsensus []byte `protobuf:"bytes,10,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` - ConsensusHeight types1.Height `protobuf:"bytes,11,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` - Signer string `protobuf:"bytes,12,opt,name=signer,proto3" json:"signer,omitempty"` + ProofConsensus []byte `protobuf:"bytes,9,opt,name=proof_consensus,json=proofConsensus,proto3" json:"proof_consensus,omitempty" yaml:"proof_consensus"` + ConsensusHeight types1.Height `protobuf:"bytes,10,opt,name=consensus_height,json=consensusHeight,proto3" json:"consensus_height" yaml:"consensus_height"` + Signer string `protobuf:"bytes,11,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgConnectionOpenTry) Reset() { *m = MsgConnectionOpenTry{} } @@ -384,65 +384,62 @@ func init() { func init() { proto.RegisterFile("ibc/core/connection/v1/tx.proto", fileDescriptor_5d00fde5fc97399e) } var fileDescriptor_5d00fde5fc97399e = []byte{ - // 917 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x3f, 0x93, 0xdb, 0x44, - 0x14, 0xb7, 0xce, 0xf7, 0xc7, 0xde, 0x33, 0x24, 0x51, 0xec, 0x3b, 0x21, 0x82, 0xe4, 0xec, 0xc0, - 0x70, 0x45, 0x4e, 0x8a, 0x93, 0x30, 0x03, 0xc7, 0x50, 0xd8, 0x6e, 0xb8, 0x22, 0xc0, 0x88, 0x83, - 0x22, 0x8d, 0xc7, 0x96, 0xd7, 0xb2, 0xc6, 0xe7, 0x5d, 0x8f, 0x56, 0x76, 0x22, 0x5a, 0x1a, 0x86, - 0x8a, 0x8f, 0x90, 0x4f, 0xc1, 0x67, 0x48, 0x47, 0x4a, 0x2a, 0x0d, 0xdc, 0x35, 0xd4, 0xea, 0xe8, - 0x18, 0xad, 0xfe, 0x78, 0x65, 0xcb, 0x73, 0x36, 0xe7, 0x54, 0xd2, 0xdb, 0xf7, 0x7b, 0xef, 0xed, - 0xfe, 0xf6, 0xfd, 0xde, 0x2c, 0x50, 0xed, 0x9e, 0xa9, 0x9b, 0xc4, 0x41, 0xba, 0x49, 0x30, 0x46, - 0xa6, 0x6b, 0x13, 0xac, 0xcf, 0x1a, 0xba, 0xfb, 0x4a, 0x9b, 0x38, 0xc4, 0x25, 0xe2, 0x91, 0xdd, - 0x33, 0xb5, 0x10, 0xa0, 0xcd, 0x01, 0xda, 0xac, 0x21, 0x57, 0x2d, 0x62, 0x11, 0x06, 0xd1, 0xc3, - 0xbf, 0x08, 0x2d, 0x7f, 0x60, 0x11, 0x62, 0x5d, 0x22, 0x9d, 0x59, 0xbd, 0xe9, 0x40, 0xef, 0x62, - 0x2f, 0x76, 0x71, 0x95, 0x2e, 0x6d, 0x84, 0xdd, 0xb0, 0x4a, 0xf4, 0x17, 0x03, 0x3e, 0x5d, 0xb1, - 0x15, 0xae, 0x2e, 0x03, 0xc2, 0xdf, 0x77, 0x40, 0xed, 0x39, 0xb5, 0xda, 0xe9, 0xfa, 0xb7, 0x13, - 0x84, 0xcf, 0xb1, 0xed, 0x8a, 0x0d, 0x50, 0x8e, 0x52, 0x76, 0xec, 0xbe, 0x24, 0xd4, 0x85, 0x93, - 0x72, 0xab, 0x1a, 0xf8, 0xea, 0x5d, 0xaf, 0x3b, 0xbe, 0x3c, 0x83, 0xa9, 0x0b, 0x1a, 0xa5, 0xe8, - 0xff, 0xbc, 0x2f, 0x7e, 0x05, 0xde, 0x9b, 0x17, 0x08, 0xc3, 0x76, 0x58, 0x98, 0x14, 0xf8, 0x6a, - 0x35, 0x0e, 0xe3, 0xdd, 0xd0, 0xa8, 0xcc, 0xed, 0xf3, 0xbe, 0xf8, 0x0d, 0xa8, 0x98, 0x64, 0x8a, - 0x5d, 0xe4, 0x4c, 0xba, 0x8e, 0xeb, 0x49, 0xc5, 0xba, 0x70, 0x72, 0xf8, 0xe4, 0x63, 0x2d, 0x9f, - 0x35, 0xad, 0xcd, 0x61, 0x5b, 0xbb, 0x6f, 0x7c, 0xb5, 0x60, 0x64, 0xe2, 0xc5, 0x2f, 0xc0, 0xc1, - 0x0c, 0x39, 0xd4, 0x26, 0x58, 0xda, 0x65, 0xa9, 0xd4, 0x55, 0xa9, 0x7e, 0x8c, 0x60, 0x46, 0x82, - 0x17, 0x8f, 0xc0, 0x3e, 0xb5, 0x2d, 0x8c, 0x1c, 0x69, 0x2f, 0x3c, 0x82, 0x11, 0x5b, 0x67, 0xa5, - 0x5f, 0x5e, 0xab, 0x85, 0x7f, 0x5e, 0xab, 0x05, 0xa8, 0x82, 0x8f, 0x72, 0x79, 0x33, 0x10, 0x9d, - 0x10, 0x4c, 0x11, 0xfc, 0xe3, 0x00, 0x54, 0x97, 0x10, 0x17, 0x8e, 0xf7, 0x7f, 0x88, 0xbd, 0x00, - 0xb5, 0x3e, 0xa2, 0xb6, 0x83, 0xfa, 0x9d, 0x3c, 0x82, 0xeb, 0x81, 0xaf, 0x3e, 0x88, 0xc2, 0x73, - 0x61, 0xd0, 0xb8, 0x1f, 0xaf, 0xb7, 0x79, 0xbe, 0x5f, 0x82, 0x87, 0x3c, 0x5f, 0x1d, 0x73, 0x48, - 0x28, 0xc2, 0x0b, 0x15, 0x8a, 0xac, 0xc2, 0xa3, 0xc0, 0x57, 0x4f, 0x92, 0x2b, 0xbc, 0x21, 0x04, - 0x1a, 0x0a, 0x8f, 0x69, 0x33, 0x48, 0xa6, 0xf0, 0x77, 0xa0, 0x12, 0x1f, 0x93, 0xba, 0x5d, 0x17, - 0xc5, 0xb7, 0x53, 0xd5, 0xa2, 0x86, 0xd7, 0x92, 0x86, 0xd7, 0x9a, 0xd8, 0x6b, 0x1d, 0x07, 0xbe, - 0x7a, 0x3f, 0x43, 0x0d, 0x8b, 0x81, 0xc6, 0x61, 0x64, 0x7e, 0x1f, 0x5a, 0x4b, 0xad, 0xb3, 0x77, - 0xcb, 0xd6, 0x99, 0x81, 0x5a, 0xe6, 0x9c, 0x71, 0x5f, 0x50, 0x69, 0xbf, 0x5e, 0x5c, 0xa3, 0x91, - 0xf8, 0x1b, 0xc9, 0xcd, 0x03, 0x8d, 0x2a, 0xbf, 0x1e, 0x87, 0x51, 0xf1, 0x05, 0xa8, 0x4c, 0x1c, - 0x42, 0x06, 0x9d, 0x21, 0xb2, 0xad, 0xa1, 0x2b, 0x1d, 0xb0, 0x73, 0xc8, 0x5c, 0xb9, 0x48, 0xe5, - 0xb3, 0x86, 0xf6, 0x35, 0x43, 0xb4, 0x3e, 0x0c, 0x77, 0x3f, 0xe7, 0x88, 0x8f, 0x86, 0xc6, 0x21, - 0x33, 0x23, 0xa4, 0xf8, 0x0c, 0x80, 0xc8, 0x6b, 0x63, 0xdb, 0x95, 0x4a, 0x75, 0xe1, 0xa4, 0xd2, - 0xaa, 0x05, 0xbe, 0x7a, 0x8f, 0x8f, 0x0c, 0x7d, 0xd0, 0x28, 0x33, 0x83, 0x8d, 0x81, 0xb3, 0x64, - 0x47, 0x51, 0x65, 0xa9, 0xcc, 0xe2, 0x8e, 0x17, 0x2b, 0x46, 0xde, 0xa4, 0x62, 0x9b, 0x59, 0x62, - 0x1b, 0xdc, 0x89, 0xbd, 0xa1, 0x22, 0x30, 0x9d, 0x52, 0x09, 0xb0, 0x70, 0x39, 0xf0, 0xd5, 0xa3, - 0x4c, 0x78, 0x02, 0x80, 0xc6, 0xfb, 0x51, 0x86, 0x64, 0x41, 0x1c, 0x80, 0xbb, 0xa9, 0x37, 0xa1, - 0xe5, 0xf0, 0x46, 0x5a, 0xd4, 0x98, 0x96, 0xe3, 0x74, 0xee, 0x64, 0x32, 0x40, 0xe3, 0x4e, 0xba, - 0x14, 0xd3, 0x33, 0x97, 0x7c, 0x65, 0x85, 0xe4, 0x15, 0xf0, 0x20, 0x4f, 0xd0, 0xa9, 0xe2, 0xff, - 0xde, 0xcb, 0x51, 0x7c, 0xd3, 0x1c, 0x2d, 0xcf, 0x45, 0x61, 0xa3, 0xb9, 0x68, 0x02, 0x39, 0x2b, - 0xba, 0x9c, 0x11, 0xf0, 0x49, 0xe0, 0xab, 0x0f, 0xf3, 0x04, 0x9a, 0x4d, 0x2c, 0x65, 0x94, 0xc9, - 0x17, 0xe1, 0x86, 0x65, 0x71, 0xc3, 0x61, 0xb9, 0x7d, 0x39, 0x2f, 0xca, 0x60, 0x6f, 0x8b, 0x32, - 0x68, 0x80, 0xa8, 0xbb, 0x3b, 0xae, 0xe3, 0x49, 0xfb, 0xac, 0x1d, 0xb9, 0xf1, 0x9b, 0xba, 0xa0, - 0x51, 0x62, 0xff, 0xe1, 0xc4, 0x5e, 0xd4, 0xc0, 0xc1, 0xed, 0x34, 0x50, 0xda, 0x8a, 0x06, 0xca, - 0xef, 0x54, 0x03, 0x60, 0x03, 0x0d, 0x34, 0xcd, 0x51, 0xaa, 0x81, 0x5f, 0x77, 0x80, 0xb4, 0x04, - 0x68, 0x13, 0x3c, 0xb0, 0x9d, 0xf1, 0x6d, 0x75, 0x90, 0xde, 0x5c, 0xd7, 0x1c, 0xb1, 0xb6, 0xcf, - 0xb9, 0xb9, 0xae, 0x39, 0x4a, 0x6e, 0x2e, 0x54, 0xde, 0x62, 0x23, 0x15, 0xb7, 0xd8, 0x48, 0x73, - 0xb2, 0x76, 0x57, 0x90, 0x05, 0x41, 0x7d, 0x15, 0x17, 0x09, 0x61, 0x4f, 0xfe, 0x2d, 0x82, 0xe2, - 0x73, 0x6a, 0x89, 0x3f, 0x01, 0x31, 0xe7, 0x11, 0x76, 0xba, 0x4a, 0x84, 0xb9, 0x6f, 0x0f, 0xf9, - 0xb3, 0x8d, 0xe0, 0xc9, 0x1e, 0xc4, 0x97, 0xe0, 0xde, 0xf2, 0x33, 0xe5, 0xd1, 0xda, 0xb9, 0x2e, - 0x1c, 0x4f, 0x7e, 0xb6, 0x09, 0x7a, 0x75, 0xe1, 0xf0, 0xce, 0xd6, 0x2f, 0xdc, 0x34, 0x47, 0x1b, - 0x14, 0xe6, 0xda, 0x54, 0xfc, 0x59, 0x00, 0xb5, 0xfc, 0x1e, 0x7d, 0xbc, 0x76, 0xbe, 0x38, 0x42, - 0xfe, 0x7c, 0xd3, 0x88, 0x64, 0x17, 0xad, 0x1f, 0xde, 0x5c, 0x29, 0xc2, 0xdb, 0x2b, 0x45, 0xf8, - 0xeb, 0x4a, 0x11, 0x7e, 0xbb, 0x56, 0x0a, 0x6f, 0xaf, 0x95, 0xc2, 0x9f, 0xd7, 0x4a, 0xe1, 0xc5, - 0x97, 0x96, 0xed, 0x0e, 0xa7, 0x3d, 0xcd, 0x24, 0x63, 0xdd, 0x24, 0x74, 0x4c, 0x68, 0xfc, 0x39, - 0xa5, 0xfd, 0x91, 0xfe, 0x4a, 0x4f, 0x9f, 0xf7, 0x8f, 0x9f, 0x9e, 0x72, 0x2f, 0x7c, 0xd7, 0x9b, - 0x20, 0xda, 0xdb, 0x67, 0x13, 0xf7, 0xe9, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x86, 0xcf, 0x23, - 0x2c, 0x90, 0x0c, 0x00, 0x00, + // 880 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x31, 0x73, 0xda, 0x58, + 0x10, 0x46, 0x06, 0x63, 0x78, 0x70, 0x67, 0x5b, 0x07, 0x58, 0xa7, 0xb3, 0x11, 0xd6, 0xdc, 0xcd, + 0xb9, 0x38, 0x4b, 0xc6, 0xf6, 0xcd, 0xdc, 0xf9, 0xe6, 0x0a, 0xa0, 0x39, 0x17, 0xbe, 0x64, 0x14, + 0x27, 0x99, 0x71, 0xc3, 0x80, 0x10, 0xb2, 0x06, 0xa3, 0xc7, 0xe8, 0x09, 0x62, 0xa5, 0x4d, 0x93, + 0x49, 0x95, 0x9f, 0xe0, 0x9f, 0xe3, 0xd2, 0x65, 0xd2, 0x68, 0x12, 0xbb, 0x49, 0xad, 0x26, 0x93, + 0x2e, 0xa3, 0xf7, 0x24, 0x21, 0x40, 0x8c, 0x21, 0x38, 0x15, 0x5a, 0xed, 0xf7, 0xed, 0xae, 0x76, + 0xf7, 0x7b, 0x3c, 0xc0, 0x69, 0x4d, 0x59, 0x94, 0xa1, 0xa1, 0x88, 0x32, 0xd4, 0x75, 0x45, 0x36, + 0x35, 0xa8, 0x8b, 0x83, 0xb2, 0x68, 0x5e, 0x0a, 0x3d, 0x03, 0x9a, 0x90, 0x2e, 0x68, 0x4d, 0x59, + 0x70, 0x01, 0xc2, 0x10, 0x20, 0x0c, 0xca, 0x6c, 0x4e, 0x85, 0x2a, 0xc4, 0x10, 0xd1, 0x7d, 0x22, + 0x68, 0xf6, 0x67, 0x15, 0x42, 0xf5, 0x42, 0x11, 0xb1, 0xd5, 0xec, 0xb7, 0xc5, 0x86, 0x6e, 0x79, + 0xae, 0x50, 0xa6, 0x0b, 0x4d, 0xd1, 0x4d, 0x37, 0x0b, 0x79, 0xf2, 0x00, 0xbf, 0x4f, 0x29, 0x25, + 0x94, 0x17, 0x03, 0xf9, 0xcf, 0x14, 0xc8, 0x9f, 0x20, 0xb5, 0x16, 0xbc, 0x7f, 0xd4, 0x53, 0xf4, + 0x63, 0x5d, 0x33, 0xe9, 0x32, 0x48, 0x93, 0x90, 0x75, 0xad, 0xc5, 0x50, 0x25, 0x6a, 0x27, 0x5d, + 0xcd, 0x39, 0x36, 0xb7, 0x66, 0x35, 0xba, 0x17, 0x47, 0x7c, 0xe0, 0xe2, 0xa5, 0x14, 0x79, 0x3e, + 0x6e, 0xd1, 0xff, 0x83, 0xac, 0x0c, 0xfb, 0xba, 0xa9, 0x18, 0xbd, 0x86, 0x61, 0x5a, 0xcc, 0x52, + 0x89, 0xda, 0xc9, 0xec, 0xff, 0x2a, 0x44, 0x7f, 0xb6, 0x50, 0x0b, 0x61, 0xab, 0x89, 0x6b, 0x9b, + 0x8b, 0x49, 0x23, 0x7c, 0xfa, 0x6f, 0xb0, 0x32, 0x50, 0x0c, 0xa4, 0x41, 0x9d, 0x89, 0xe3, 0x50, + 0xdc, 0xb4, 0x50, 0xcf, 0x08, 0x4c, 0xf2, 0xf1, 0x74, 0x01, 0x24, 0x91, 0xa6, 0xea, 0x8a, 0xc1, + 0x24, 0xdc, 0xd2, 0x25, 0xcf, 0x3a, 0x4a, 0xbd, 0xbe, 0xe2, 0x62, 0x9f, 0xae, 0xb8, 0x18, 0xcf, + 0x81, 0xad, 0xc8, 0x0f, 0x97, 0x14, 0xd4, 0x83, 0x3a, 0x52, 0xf8, 0xf7, 0x49, 0x90, 0x9b, 0x40, + 0x9c, 0x1a, 0xd6, 0xb7, 0x74, 0xe6, 0x39, 0x28, 0xf4, 0x0c, 0x65, 0xa0, 0xc1, 0x3e, 0xaa, 0x0f, + 0x2b, 0x77, 0xf9, 0x4b, 0x98, 0xbf, 0xed, 0xd8, 0xdc, 0x16, 0xe1, 0x47, 0xe3, 0x78, 0x29, 0xe7, + 0x3b, 0x86, 0x05, 0x1d, 0xb7, 0xe8, 0xc7, 0x20, 0xeb, 0x25, 0x44, 0x66, 0xc3, 0x54, 0xbc, 0x3e, + 0xe5, 0x04, 0xb2, 0x3b, 0x82, 0xbf, 0x3b, 0x42, 0x45, 0xb7, 0xaa, 0x1b, 0x8e, 0xcd, 0xfd, 0x34, + 0x52, 0x24, 0xe6, 0xf0, 0x52, 0x86, 0x98, 0x4f, 0x5c, 0x6b, 0x62, 0x88, 0x89, 0x05, 0x87, 0x38, + 0x00, 0xf9, 0xb0, 0x5d, 0xf7, 0x26, 0x84, 0x98, 0xe5, 0x52, 0x7c, 0x86, 0x91, 0x56, 0x4b, 0x8e, + 0xcd, 0x6d, 0x7a, 0x55, 0x47, 0xc5, 0xe1, 0xa5, 0x5c, 0xf8, 0xbd, 0x47, 0x43, 0xf4, 0x19, 0xc8, + 0xf6, 0x0c, 0x08, 0xdb, 0xf5, 0x73, 0x45, 0x53, 0xcf, 0x4d, 0x26, 0x89, 0xbf, 0x83, 0x0d, 0xa5, + 0x23, 0x82, 0x19, 0x94, 0x85, 0xff, 0x30, 0xa2, 0xfa, 0x8b, 0x5b, 0xfd, 0xb0, 0x47, 0x61, 0x36, + 0x2f, 0x65, 0xb0, 0x49, 0x90, 0xf4, 0x21, 0x00, 0xc4, 0xab, 0xe9, 0x9a, 0xc9, 0xac, 0x94, 0xa8, + 0x9d, 0x6c, 0x35, 0xef, 0xd8, 0xdc, 0x7a, 0x98, 0xe9, 0xfa, 0x78, 0x29, 0x8d, 0x0d, 0xac, 0xa8, + 0x23, 0xbf, 0x22, 0x92, 0x99, 0x49, 0x61, 0xde, 0xc6, 0x78, 0x46, 0xe2, 0xf5, 0x33, 0xd6, 0xb0, + 0x45, 0xd7, 0xc0, 0xaa, 0xe7, 0x75, 0x77, 0x53, 0x47, 0x7d, 0xc4, 0xa4, 0x31, 0x9d, 0x75, 0x6c, + 0xae, 0x30, 0x42, 0xf7, 0x01, 0xbc, 0xf4, 0x23, 0x89, 0xe0, 0xbf, 0xa0, 0xdb, 0x60, 0x2d, 0xf0, + 0xfa, 0x6d, 0x01, 0xf7, 0xb6, 0x85, 0xf3, 0xda, 0xb2, 0xe1, 0x0f, 0x61, 0x34, 0x02, 0x2f, 0xad, + 0x06, 0xaf, 0xbc, 0xf6, 0x0c, 0xc5, 0x97, 0x99, 0x22, 0xbe, 0x22, 0xd8, 0x8c, 0x92, 0x56, 0xa0, + 0xbd, 0x8f, 0xcb, 0x11, 0xda, 0xab, 0xc8, 0x1d, 0xfa, 0x5f, 0xf0, 0xc3, 0xa8, 0x7e, 0x88, 0xfe, + 0x18, 0xc7, 0xe6, 0x72, 0x41, 0x7d, 0x61, 0xd9, 0x64, 0xe5, 0xb0, 0x5c, 0x64, 0xc0, 0x8e, 0x2c, + 0x51, 0x94, 0x16, 0x7f, 0x73, 0x6c, 0x6e, 0x3b, 0x62, 0xe1, 0xc6, 0x02, 0x33, 0x61, 0xe7, 0x88, + 0x26, 0x17, 0x38, 0xb6, 0xc6, 0xe5, 0x9c, 0x58, 0x58, 0xce, 0xe3, 0x32, 0x58, 0x7e, 0x40, 0x19, + 0x94, 0x01, 0xd9, 0xee, 0xba, 0x69, 0x58, 0x58, 0x5f, 0xd9, 0xf0, 0x41, 0x18, 0xb8, 0x78, 0x29, + 0x85, 0x9f, 0xdd, 0xb3, 0x73, 0x5c, 0x03, 0x2b, 0x8b, 0x69, 0x20, 0xf5, 0x20, 0x1a, 0x48, 0x7f, + 0x57, 0x0d, 0x80, 0x39, 0x34, 0x50, 0x91, 0x3b, 0x81, 0x06, 0xde, 0x2c, 0x01, 0x66, 0x02, 0x50, + 0x83, 0x7a, 0x5b, 0x33, 0xba, 0x8b, 0xea, 0x20, 0x98, 0x5c, 0x43, 0xee, 0xe0, 0xb5, 0x8f, 0x98, + 0x5c, 0x43, 0xee, 0xf8, 0x93, 0x73, 0x95, 0x37, 0xbe, 0x48, 0xf1, 0x07, 0x5c, 0xa4, 0xfb, 0xff, + 0xad, 0x79, 0x50, 0x9a, 0xd6, 0x0b, 0xbf, 0x61, 0xfb, 0x5f, 0xe2, 0x20, 0x7e, 0x82, 0x54, 0xfa, + 0x25, 0xa0, 0x23, 0xee, 0x33, 0xbb, 0xd3, 0x44, 0x18, 0x79, 0x0b, 0x60, 0xff, 0x9c, 0x0b, 0xee, + 0xd7, 0x40, 0xbf, 0x00, 0xeb, 0x93, 0x17, 0x86, 0x3f, 0x66, 0x8e, 0x75, 0x6a, 0x58, 0xec, 0xe1, + 0x3c, 0xe8, 0xe9, 0x89, 0xdd, 0x99, 0xcd, 0x9e, 0xb8, 0x22, 0x77, 0xe6, 0x48, 0x1c, 0x5a, 0x53, + 0xfa, 0x15, 0x05, 0xf2, 0xd1, 0x3b, 0xba, 0x37, 0x73, 0x3c, 0x8f, 0xc1, 0xfe, 0x35, 0x2f, 0xc3, + 0xaf, 0xa2, 0xfa, 0xf4, 0xfa, 0xb6, 0x48, 0xdd, 0xdc, 0x16, 0xa9, 0x0f, 0xb7, 0x45, 0xea, 0xed, + 0x5d, 0x31, 0x76, 0x73, 0x57, 0x8c, 0xbd, 0xbb, 0x2b, 0xc6, 0xce, 0xfe, 0x51, 0x35, 0xf3, 0xbc, + 0xdf, 0x14, 0x64, 0xd8, 0x15, 0x65, 0x88, 0xba, 0x10, 0x79, 0x3f, 0xbb, 0xa8, 0xd5, 0x11, 0x2f, + 0xc5, 0xe0, 0xa6, 0xbc, 0x77, 0xb0, 0x1b, 0xba, 0x2c, 0x9b, 0x56, 0x4f, 0x41, 0xcd, 0x24, 0x3e, + 0x71, 0x0f, 0xbe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x4a, 0xeb, 0x3e, 0xdb, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -666,7 +663,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } if m.Version != nil { { @@ -678,7 +675,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } { size, err := m.Counterparty.MarshalToSizedBuffer(dAtA[:i]) @@ -689,14 +686,7 @@ func (m *MsgConnectionOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - if len(m.ConnectionId) > 0 { - i -= len(m.ConnectionId) - copy(dAtA[i:], m.ConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.ConnectionId))) - i-- - dAtA[i] = 0x12 - } + dAtA[i] = 0x12 if len(m.ClientId) > 0 { i -= len(m.ClientId) copy(dAtA[i:], m.ClientId) @@ -755,7 +745,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x62 + dAtA[i] = 0x5a } { size, err := m.ConsensusHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -766,27 +756,27 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x5a + dAtA[i] = 0x52 if len(m.ProofConsensus) > 0 { i -= len(m.ProofConsensus) copy(dAtA[i:], m.ProofConsensus) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofConsensus))) i-- - dAtA[i] = 0x52 + dAtA[i] = 0x4a } if len(m.ProofClient) > 0 { i -= len(m.ProofClient) copy(dAtA[i:], m.ProofClient) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofClient))) i-- - dAtA[i] = 0x4a + dAtA[i] = 0x42 } if len(m.ProofInit) > 0 { i -= len(m.ProofInit) copy(dAtA[i:], m.ProofInit) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) i-- - dAtA[i] = 0x42 + dAtA[i] = 0x3a } { size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -797,7 +787,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 if len(m.CounterpartyVersions) > 0 { for iNdEx := len(m.CounterpartyVersions) - 1; iNdEx >= 0; iNdEx-- { { @@ -809,7 +799,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } } { @@ -821,7 +811,7 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 if m.ClientState != nil { { size, err := m.ClientState.MarshalToSizedBuffer(dAtA[:i]) @@ -832,19 +822,12 @@ func (m *MsgConnectionOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 - } - if len(m.CounterpartyChosenConnectionId) > 0 { - i -= len(m.CounterpartyChosenConnectionId) - copy(dAtA[i:], m.CounterpartyChosenConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyChosenConnectionId))) - i-- dAtA[i] = 0x1a } - if len(m.DesiredConnectionId) > 0 { - i -= len(m.DesiredConnectionId) - copy(dAtA[i:], m.DesiredConnectionId) - i = encodeVarintTx(dAtA, i, uint64(len(m.DesiredConnectionId))) + if len(m.PreviousConnectionId) > 0 { + i -= len(m.PreviousConnectionId) + copy(dAtA[i:], m.PreviousConnectionId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PreviousConnectionId))) i-- dAtA[i] = 0x12 } @@ -1111,10 +1094,6 @@ func (m *MsgConnectionOpenInit) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.ConnectionId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } l = m.Counterparty.Size() n += 1 + l + sovTx(uint64(l)) if m.Version != nil { @@ -1147,11 +1126,7 @@ func (m *MsgConnectionOpenTry) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.DesiredConnectionId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.CounterpartyChosenConnectionId) + l = len(m.PreviousConnectionId) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -1353,38 +1328,6 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { m.ClientId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ConnectionId", 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.ConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Counterparty", wireType) } @@ -1417,7 +1360,7 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } @@ -1453,7 +1396,7 @@ func (m *MsgConnectionOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -1625,7 +1568,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredConnectionId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreviousConnectionId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -1653,41 +1596,9 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DesiredConnectionId = string(dAtA[iNdEx:postIndex]) + m.PreviousConnectionId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChosenConnectionId", 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.CounterpartyChosenConnectionId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ClientState", wireType) } @@ -1723,7 +1634,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Counterparty", wireType) } @@ -1756,7 +1667,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersions", wireType) } @@ -1790,7 +1701,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -1823,7 +1734,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) } @@ -1857,7 +1768,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofInit = []byte{} } iNdEx = postIndex - case 9: + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofClient", wireType) } @@ -1891,7 +1802,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofClient = []byte{} } iNdEx = postIndex - case 10: + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofConsensus", wireType) } @@ -1925,7 +1836,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { m.ProofConsensus = []byte{} } iNdEx = postIndex - case 11: + case 10: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ConsensusHeight", wireType) } @@ -1958,7 +1869,7 @@ func (m *MsgConnectionOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 12: + case 11: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } diff --git a/x/ibc/core/04-channel/client/cli/tx.go b/x/ibc/core/04-channel/client/cli/tx.go index f4f417638331..d3150f2c9194 100644 --- a/x/ibc/core/04-channel/client/cli/tx.go +++ b/x/ibc/core/04-channel/client/cli/tx.go @@ -24,9 +24,9 @@ const ( // NewChannelOpenInitCmd returns the command to create a MsgChannelOpenInit transaction func NewChannelOpenInitCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-init [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops]", + Use: "open-init [port-id] [counterparty-port-id] [connection-hops]", Short: "Creates and sends a ChannelOpenInit message", - Args: cobra.ExactArgs(5), + Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -35,16 +35,14 @@ func NewChannelOpenInitCmd() *cobra.Command { } portID := args[0] - channelID := args[1] - counterpartyPortID := args[2] - counterpartyChannelID := args[3] - hops := strings.Split(args[4], "/") + counterpartyPortID := args[1] + hops := strings.Split(args[2], "/") order := channelOrder(cmd.Flags()) version, _ := cmd.Flags().GetString(FlagIBCVersion) msg := types.NewMsgChannelOpenInit( - portID, channelID, version, order, hops, - counterpartyPortID, counterpartyChannelID, clientCtx.GetFromAddress(), + portID, version, order, hops, + counterpartyPortID, clientCtx.GetFromAddress(), ) if err := msg.ValidateBasic(); err != nil { return err @@ -64,9 +62,9 @@ func NewChannelOpenInitCmd() *cobra.Command { // NewChannelOpenTryCmd returns the command to create a MsgChannelOpenTry transaction func NewChannelOpenTryCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "open-try [port-id] [channel-id] [proved-channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof_init.json] [proof-height]", + Use: "open-try [port-id] [channel-id] [counterparty-port-id] [counterparty-channel-id] [connection-hops] [/path/to/proof_init.json] [proof-height]", Short: "Creates and sends a ChannelOpenTry message", - Args: cobra.ExactArgs(8), + Args: cobra.ExactArgs(7), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) clientCtx, err := client.ReadTxCommandFlags(clientCtx, cmd.Flags()) @@ -76,27 +74,26 @@ func NewChannelOpenTryCmd() *cobra.Command { portID := args[0] channelID := args[1] - provedChannelID := args[2] - counterpartyPortID := args[3] - counterpartyChannelID := args[4] - hops := strings.Split(args[5], "/") + counterpartyPortID := args[2] + counterpartyChannelID := args[3] + hops := strings.Split(args[4], "/") order := channelOrder(cmd.Flags()) // TODO: Differentiate between channel and counterparty versions. version, _ := cmd.Flags().GetString(FlagIBCVersion) - proofInit, err := connectionutils.ParseProof(clientCtx.LegacyAmino, args[6]) + proofInit, err := connectionutils.ParseProof(clientCtx.LegacyAmino, args[5]) if err != nil { return err } - proofHeight, err := clienttypes.ParseHeight(args[7]) + proofHeight, err := clienttypes.ParseHeight(args[6]) if err != nil { return err } msg := types.NewMsgChannelOpenTry( - portID, channelID, provedChannelID, version, order, hops, + portID, channelID, version, order, hops, counterpartyPortID, counterpartyChannelID, version, proofInit, proofHeight, clientCtx.GetFromAddress(), ) diff --git a/x/ibc/core/04-channel/genesis.go b/x/ibc/core/04-channel/genesis.go index bd557bc5bfb6..07fad47d77b2 100644 --- a/x/ibc/core/04-channel/genesis.go +++ b/x/ibc/core/04-channel/genesis.go @@ -31,6 +31,7 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) { for _, as := range gs.AckSequences { k.SetNextSequenceAck(ctx, as.PortId, as.ChannelId, as.Sequence) } + k.SetNextChannelSequence(ctx, gs.NextChannelSequence) } // ExportGenesis returns the ibc channel submodule's exported genesis. diff --git a/x/ibc/core/04-channel/handler.go b/x/ibc/core/04-channel/handler.go index 2bf542cfdf95..375c35263ec1 100644 --- a/x/ibc/core/04-channel/handler.go +++ b/x/ibc/core/04-channel/handler.go @@ -9,20 +9,20 @@ import ( ) // HandleMsgChannelOpenInit defines the sdk.Handler for MsgChannelOpenInit -func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenInit) (*sdk.Result, *capabilitytypes.Capability, error) { - capKey, err := k.ChanOpenInit( - ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.ChannelId, +func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenInit) (*sdk.Result, string, *capabilitytypes.Capability, error) { + channelID, capKey, err := k.ChanOpenInit( + ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, portCap, msg.Channel.Counterparty, msg.Channel.Version, ) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "channel handshake open init failed") + return nil, "", nil, sdkerrors.Wrap(err, "channel handshake open init failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenInit, sdk.NewAttribute(types.AttributeKeyPortID, msg.PortId), - sdk.NewAttribute(types.AttributeKeyChannelID, msg.ChannelId), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), sdk.NewAttribute(types.AttributeCounterpartyPortID, msg.Channel.Counterparty.PortId), sdk.NewAttribute(types.AttributeCounterpartyChannelID, msg.Channel.Counterparty.ChannelId), sdk.NewAttribute(types.AttributeKeyConnectionID, msg.Channel.ConnectionHops[0]), @@ -35,23 +35,23 @@ func HandleMsgChannelOpenInit(ctx sdk.Context, k keeper.Keeper, portCap *capabil return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), - }, capKey, nil + }, channelID, capKey, nil } // HandleMsgChannelOpenTry defines the sdk.Handler for MsgChannelOpenTry -func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenTry) (*sdk.Result, *capabilitytypes.Capability, error) { - capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.DesiredChannelId, msg.CounterpartyChosenChannelId, +func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabilitytypes.Capability, msg *types.MsgChannelOpenTry) (*sdk.Result, string, *capabilitytypes.Capability, error) { + channelID, capKey, err := k.ChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.PreviousChannelId, portCap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion, msg.ProofInit, msg.ProofHeight, ) if err != nil { - return nil, nil, sdkerrors.Wrap(err, "channel handshake open try failed") + return nil, "", nil, sdkerrors.Wrap(err, "channel handshake open try failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeChannelOpenTry, sdk.NewAttribute(types.AttributeKeyPortID, msg.PortId), - sdk.NewAttribute(types.AttributeKeyChannelID, msg.DesiredChannelId), + sdk.NewAttribute(types.AttributeKeyChannelID, channelID), sdk.NewAttribute(types.AttributeCounterpartyPortID, msg.Channel.Counterparty.PortId), sdk.NewAttribute(types.AttributeCounterpartyChannelID, msg.Channel.Counterparty.ChannelId), sdk.NewAttribute(types.AttributeKeyConnectionID, msg.Channel.ConnectionHops[0]), @@ -64,7 +64,7 @@ func HandleMsgChannelOpenTry(ctx sdk.Context, k keeper.Keeper, portCap *capabili return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), - }, capKey, nil + }, channelID, capKey, nil } // HandleMsgChannelOpenAck defines the sdk.Handler for MsgChannelOpenAck diff --git a/x/ibc/core/04-channel/keeper/handshake.go b/x/ibc/core/04-channel/keeper/handshake.go index 75b0c1bd3def..2286deafec00 100644 --- a/x/ibc/core/04-channel/keeper/handshake.go +++ b/x/ibc/core/04-channel/keeper/handshake.go @@ -34,30 +34,25 @@ func (k Keeper) CounterpartyHops(ctx sdk.Context, ch types.Channel) ([]string, b } // ChanOpenInit is called by a module to initiate a channel opening handshake with -// a module on another chain. +// a module on another chain. The counterparty channel identifier is validated to be +// empty in msg validation. func (k Keeper) ChanOpenInit( ctx sdk.Context, order types.Order, connectionHops []string, - portID, - channelID string, + portID string, portCap *capabilitytypes.Capability, counterparty types.Counterparty, version string, -) (*capabilitytypes.Capability, error) { - // channel identifier and connection hop length checked on msg.ValidateBasic() - _, found := k.GetChannel(ctx, portID, channelID) - if found { - return nil, sdkerrors.Wrapf(types.ErrChannelExists, "port ID (%s) channel ID (%s)", portID, channelID) - } - +) (string, *capabilitytypes.Capability, error) { + // connection hop length checked on msg.ValidateBasic() connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) + return "", nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) } if len(connectionEnd.GetVersions()) != 1 { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "single version must be negotiated on connection before opening channel, got: %v", connectionEnd.GetVersions(), @@ -65,7 +60,7 @@ func (k Keeper) ChanOpenInit( } if !connectiontypes.VerifySupportedFeature(connectionEnd.GetVersions()[0], order.String()) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "connection version %s does not support channel ordering: %s", connectionEnd.GetVersions()[0], order.String(), @@ -73,15 +68,16 @@ func (k Keeper) ChanOpenInit( } if !k.portKeeper.Authenticate(ctx, portCap, portID) { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) + return "", nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) } + channelID := k.GenerateChannelIdentifier(ctx) channel := types.NewChannel(types.INIT, order, counterparty, connectionHops, version) k.SetChannel(ctx, portID, channelID, channel) capKey, err := k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if err != nil { - return nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) + return "", nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) } k.SetNextSequenceSend(ctx, portID, channelID, 1) @@ -94,7 +90,7 @@ func (k Keeper) ChanOpenInit( telemetry.IncrCounter(1, "ibc", "channel", "open-init") }() - return capKey, nil + return channelID, capKey, nil } // ChanOpenTry is called by a module to accept the first step of a channel opening @@ -104,44 +100,65 @@ func (k Keeper) ChanOpenTry( order types.Order, connectionHops []string, portID, - desiredChannelID, - counterpartyChosenChannelID string, + previousChannelID string, portCap *capabilitytypes.Capability, counterparty types.Counterparty, version, counterpartyVersion string, proofInit []byte, proofHeight exported.Height, -) (*capabilitytypes.Capability, error) { - // channel identifier and connection hop length checked on msg.ValidateBasic() - previousChannel, found := k.GetChannel(ctx, portID, desiredChannelID) - if found && !(previousChannel.State == types.INIT && - previousChannel.Ordering == order && - previousChannel.Counterparty.PortId == counterparty.PortId && - previousChannel.Counterparty.ChannelId == counterparty.ChannelId && - previousChannel.ConnectionHops[0] == connectionHops[0] && - previousChannel.Version == version) { - return nil, sdkerrors.Wrap(types.ErrInvalidChannel, "cannot relay connection attempt") +) (string, *capabilitytypes.Capability, error) { + var ( + previousChannel types.Channel + previousChannelFound bool + ) + + channelID := previousChannelID + + // empty channel identifier indicates continuing a previous channel handshake + if previousChannelID != "" { + // channel identifier and connection hop length checked on msg.ValidateBasic() + // ensure that the previous channel exists + previousChannel, previousChannelFound = k.GetChannel(ctx, portID, previousChannelID) + if !previousChannelFound { + return "", nil, sdkerrors.Wrapf(types.ErrInvalidChannel, "previous channel does not exist for supplied previous channelID %s", previousChannelID) + } + // previous channel must use the same fields + if !(previousChannel.Ordering == order && + previousChannel.Counterparty.PortId == counterparty.PortId && + previousChannel.Counterparty.ChannelId == "" && + previousChannel.ConnectionHops[0] == connectionHops[0] && + previousChannel.Version == version) { + return "", nil, sdkerrors.Wrap(types.ErrInvalidChannel, "channel fields mismatch previous channel fields") + } + + if previousChannel.State != types.INIT { + return "", nil, sdkerrors.Wrapf(types.ErrInvalidChannelState, "previous channel state is in %s, expected INIT", previousChannel.State) + } + + } else { + // generate a new channel + channelID = k.GenerateChannelIdentifier(ctx) } if !k.portKeeper.Authenticate(ctx, portCap, portID) { - return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) + return "", nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "caller does not own port capability for port ID %s", portID) } connectionEnd, found := k.connectionKeeper.GetConnection(ctx, connectionHops[0]) if !found { - return nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) + return "", nil, sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, connectionHops[0]) } if connectionEnd.GetState() != int32(connectiontypes.OPEN) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidConnectionState, "connection state is not OPEN (got %s)", connectiontypes.State(connectionEnd.GetState()).String(), ) } if len(connectionEnd.GetVersions()) != 1 { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "single version must be negotiated on connection before opening channel, got: %v", connectionEnd.GetVersions(), @@ -149,23 +166,13 @@ func (k Keeper) ChanOpenTry( } if !connectiontypes.VerifySupportedFeature(connectionEnd.GetVersions()[0], order.String()) { - return nil, sdkerrors.Wrapf( + return "", nil, sdkerrors.Wrapf( connectiontypes.ErrInvalidVersion, "connection version %s does not support channel ordering: %s", connectionEnd.GetVersions()[0], order.String(), ) } - // If the channel id chosen for this channel end by the counterparty is empty then - // flexible channel identifier selection is allowed by using the desired channel id. - // Otherwise the desiredChannelID must match the counterpartyChosenChannelID. - if counterpartyChosenChannelID != "" && counterpartyChosenChannelID != desiredChannelID { - return nil, sdkerrors.Wrapf( - types.ErrInvalidChannelIdentifier, - "counterparty chosen channel ID (%s) must be empty or equal to the desired channel ID (%s)", counterpartyChosenChannelID, desiredChannelID, - ) - } - // NOTE: this step has been switched with the one below to reverse the connection // hops channel := types.NewChannel(types.TRYOPEN, order, counterparty, connectionHops, version) @@ -178,7 +185,7 @@ func (k Keeper) ChanOpenTry( // expectedCounterpaty is the counterparty of the counterparty's channel end // (i.e self) - expectedCounterparty := types.NewCounterparty(portID, counterpartyChosenChannelID) + expectedCounterparty := types.NewCounterparty(portID, "") expectedChannel := types.NewChannel( types.INIT, channel.Ordering, expectedCounterparty, counterpartyHops, counterpartyVersion, @@ -188,7 +195,7 @@ func (k Keeper) ChanOpenTry( ctx, connectionEnd, proofHeight, proofInit, counterparty.PortId, counterparty.ChannelId, expectedChannel, ); err != nil { - return nil, err + return "", nil, err } var ( @@ -196,36 +203,34 @@ func (k Keeper) ChanOpenTry( err error ) - // Only create a capability and set the sequences if the previous channel does not exist - _, found = k.GetChannel(ctx, portID, desiredChannelID) - if !found { - capKey, err = k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, desiredChannelID)) + if !previousChannelFound { + capKey, err = k.scopedKeeper.NewCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if err != nil { - return nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, desiredChannelID) + return "", nil, sdkerrors.Wrapf(err, "could not create channel capability for port ID %s and channel ID %s", portID, channelID) } - k.SetNextSequenceSend(ctx, portID, desiredChannelID, 1) - k.SetNextSequenceRecv(ctx, portID, desiredChannelID, 1) - k.SetNextSequenceAck(ctx, portID, desiredChannelID, 1) + k.SetNextSequenceSend(ctx, portID, channelID, 1) + k.SetNextSequenceRecv(ctx, portID, channelID, 1) + k.SetNextSequenceAck(ctx, portID, channelID, 1) } else { // capability initialized in ChanOpenInit - capKey, found = k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, desiredChannelID)) + capKey, found = k.scopedKeeper.GetCapability(ctx, host.ChannelCapabilityPath(portID, channelID)) if !found { - return nil, sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, - "capability not found for existing channel, portID (%s) channelID (%s)", portID, desiredChannelID, + return "", nil, sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, + "capability not found for existing channel, portID (%s) channelID (%s)", portID, channelID, ) } } - k.SetChannel(ctx, portID, desiredChannelID, channel) + k.SetChannel(ctx, portID, channelID, channel) - k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", desiredChannelID, "previous-state", previousChannel.State.String(), "new-state", "TRYOPEN") + k.Logger(ctx).Info("channel state updated", "port-id", portID, "channel-id", channelID, "previous-state", previousChannel.State.String(), "new-state", "TRYOPEN") defer func() { telemetry.IncrCounter(1, "ibc", "channel", "open-try") }() - return capKey, nil + return channelID, capKey, nil } // ChanOpenAck is called by the handshake-originating module to acknowledge the @@ -256,16 +261,6 @@ func (k Keeper) ChanOpenAck( return sdkerrors.Wrapf(types.ErrChannelCapabilityNotFound, "caller does not own capability for channel, port ID (%s) channel ID (%s)", portID, channelID) } - // If the previously set channel end allowed for the counterparty to select its own - // channel identifier then we use the counterpartyChannelID. Otherwise the - // counterpartyChannelID must match the previously set counterparty channel ID. - if channel.Counterparty.ChannelId != "" && counterpartyChannelID != channel.Counterparty.ChannelId { - return sdkerrors.Wrapf( - types.ErrInvalidChannelIdentifier, - "counterparty channel identifier (%s) must be equal to stored channel ID for counterparty (%s)", counterpartyChannelID, channel.Counterparty.ChannelId, - ) - } - connectionEnd, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0]) if !found { return sdkerrors.Wrap(connectiontypes.ErrConnectionNotFound, channel.ConnectionHops[0]) diff --git a/x/ibc/core/04-channel/keeper/handshake_test.go b/x/ibc/core/04-channel/keeper/handshake_test.go index 857bba57d4ec..7aae08130c56 100644 --- a/x/ibc/core/04-channel/keeper/handshake_test.go +++ b/x/ibc/core/04-channel/keeper/handshake_test.go @@ -34,8 +34,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { {"success", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) features = []string{"ORDER_ORDERED", "ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, true}, {"channel already exists", func() { _, _, connA, connB, _, _ = suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED) @@ -64,8 +64,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { connA.ID, conn, ) features = []string{"ORDER_ORDERED", "ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, false}, {"connection does not support ORDERED channels", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -82,8 +82,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { ) // NOTE: Opening UNORDERED channels is still expected to pass but ORDERED channels should fail features = []string{"ORDER_UNORDERED"} - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, true}, } @@ -98,9 +98,9 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { counterparty := types.NewCounterparty(connB.FirstOrNextTestChannel(ibctesting.MockPort).PortID, connB.FirstOrNextTestChannel(ibctesting.MockPort).ID) channelA := connA.FirstOrNextTestChannel(ibctesting.MockPort) - cap, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( + channelID, cap, err := suite.chainA.App.IBCKeeper.ChannelKeeper.ChanOpenInit( suite.chainA.GetContext(), order, []string{connA.ID}, - channelA.PortID, channelA.ID, portCap, counterparty, channelA.Version, + channelA.PortID, portCap, counterparty, channelA.Version, ) // check if order is supported by channel to determine expected behaviour @@ -116,6 +116,7 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { if tc.expPass && orderSupported { suite.Require().NoError(err) suite.Require().NotNil(cap) + suite.Require().Equal(types.FormatChannelIdentifier(0), channelID) chanCap, ok := suite.chainA.App.ScopedIBCKeeper.GetCapability( suite.chainA.GetContext(), @@ -125,6 +126,8 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { suite.Require().Equal(chanCap.String(), cap.String(), "channel capability is not correct") } else { suite.Require().Error(err) + suite.Require().Nil(cap) + suite.Require().Equal("", channelID) } } }) @@ -137,10 +140,11 @@ func (suite *KeeperTestSuite) TestChanOpenInit() { // ChanOpenTry can succeed. func (suite *KeeperTestSuite) TestChanOpenTry() { var ( - connA *ibctesting.TestConnection - connB *ibctesting.TestConnection - portCap *capabilitytypes.Capability - heightDiff uint64 + connA *ibctesting.TestConnection + connB *ibctesting.TestConnection + previousChannelID string + portCap *capabilitytypes.Capability + heightDiff uint64 ) testCases := []testCase{ @@ -148,34 +152,16 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, true}, {"success with crossing hello", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - suite.coordinator.ChanOpenInitOnBothChains(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - }, true}, - {"success with empty counterparty chosen channel id", func() { - var clientA, clientB string - clientA, clientB, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.Require().NoError(err) - - // set the channel's counterparty channel identifier to empty string - channel := suite.chainA.GetChannel(channelA) - channel.Counterparty.ChannelId = "" - suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel) - - err = suite.coordinator.UpdateClient(suite.chainA, suite.chainB, clientA, exported.Tendermint) + _, channelB, err := suite.coordinator.ChanOpenInitOnBothChains(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) suite.Require().NoError(err) - err = suite.coordinator.UpdateClient(suite.chainB, suite.chainA, clientB, exported.Tendermint) - suite.Require().NoError(err) - - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + previousChannelID = channelB.ID + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, true}, {"previous channel with invalid state", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -206,28 +192,15 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) heightDiff = 3 // consensus state doesn't exist at this height }, false}, - {"counterparty chosen channel id does not match desired channel id", func() { - _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA, connB, ibctesting.MockPort, ibctesting.MockPort, types.ORDERED) - suite.Require().NoError(err) - - // set the channel's counterparty channel identifier to empty string - channel := suite.chainA.GetChannel(channelA) - channel.Counterparty.ChannelId = "otherchannel" - suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID, channel) - - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - }, false}, {"channel verification failed", func() { // not creating a channel on chainA will result in an invalid proof of existence _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, false}, {"port capability not found", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -249,8 +222,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.chainB.GetContext(), connB.ID, conn, ) - suite.chainB.CreatePortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainB.GetPortCapability(connB.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainB.CreatePortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) + portCap = suite.chainB.GetPortCapability(suite.chainB.NextTestChannel(connB, ibctesting.MockPort).PortID) }, false}, {"connection does not support ORDERED channels", func() { _, _, connA, connB = suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) @@ -266,8 +239,8 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.chainA.GetContext(), connA.ID, conn, ) - suite.chainA.CreatePortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) - portCap = suite.chainA.GetPortCapability(connA.NextTestChannel(ibctesting.MockPort).PortID) + suite.chainA.CreatePortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) + portCap = suite.chainA.GetPortCapability(suite.chainA.NextTestChannel(connA, ibctesting.MockPort).PortID) }, false}, } @@ -276,25 +249,19 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { suite.Run(fmt.Sprintf("Case %s", tc.msg), func() { suite.SetupTest() // reset heightDiff = 0 // must be explicitly changed in malleate + previousChannelID = "" tc.malleate() channelA := connA.FirstOrNextTestChannel(ibctesting.MockPort) channelB := connB.FirstOrNextTestChannel(ibctesting.MockPort) counterparty := types.NewCounterparty(channelA.PortID, channelA.ID) - // get counterpartyChosenChannelID - var counterpartyChosenChannelID string - channel, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) - if found { - counterpartyChosenChannelID = channel.Counterparty.ChannelId - } - channelKey := host.ChannelKey(counterparty.PortId, counterparty.ChannelId) proof, proofHeight := suite.chainA.QueryProof(channelKey) - cap, err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenTry( + channelID, cap, err := suite.chainB.App.IBCKeeper.ChannelKeeper.ChanOpenTry( suite.chainB.GetContext(), types.ORDERED, []string{connB.ID}, - channelB.PortID, channelB.ID, counterpartyChosenChannelID, portCap, counterparty, channelB.Version, connA.FirstOrNextTestChannel(ibctesting.MockPort).Version, + channelB.PortID, previousChannelID, portCap, counterparty, channelB.Version, connA.FirstOrNextTestChannel(ibctesting.MockPort).Version, proof, malleateHeight(proofHeight, heightDiff), ) @@ -304,7 +271,7 @@ func (suite *KeeperTestSuite) TestChanOpenTry() { chanCap, ok := suite.chainB.App.ScopedIBCKeeper.GetCapability( suite.chainB.GetContext(), - host.ChannelCapabilityPath(channelB.PortID, channelB.ID), + host.ChannelCapabilityPath(channelB.PortID, channelID), ) suite.Require().True(ok, "could not retrieve channel capapbility after successful ChanOpenTry") suite.Require().Equal(chanCap.String(), cap.String(), "channel capability is not correct") diff --git a/x/ibc/core/04-channel/keeper/keeper.go b/x/ibc/core/04-channel/keeper/keeper.go index 99aee2c6da5e..2390fb41cff5 100644 --- a/x/ibc/core/04-channel/keeper/keeper.go +++ b/x/ibc/core/04-channel/keeper/keeper.go @@ -55,6 +55,16 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", host.ModuleName, types.SubModuleName)) } +// GenerateChannelIdentifier returns the next channel identifier. +func (k Keeper) GenerateChannelIdentifier(ctx sdk.Context) string { + nextChannelSeq := k.GetNextChannelSequence(ctx) + channelID := types.FormatChannelIdentifier(nextChannelSeq) + + nextChannelSeq++ + k.SetNextChannelSequence(ctx, nextChannelSeq) + return channelID +} + // GetChannel returns a channel with a particular identifier binded to a specific port func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) { store := ctx.KVStore(k.storeKey) @@ -75,6 +85,24 @@ func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel ty store.Set(host.ChannelKey(portID, channelID), bz) } +// GetNextChannelSequence gets the next channel sequence from the store. +func (k Keeper) GetNextChannelSequence(ctx sdk.Context) uint64 { + store := ctx.KVStore(k.storeKey) + bz := store.Get([]byte(types.KeyNextChannelSequence)) + if bz == nil { + panic("next channel sequence is nil") + } + + return sdk.BigEndianToUint64(bz) +} + +// SetNextChannelSequence sets the next channel sequence to the store. +func (k Keeper) SetNextChannelSequence(ctx sdk.Context, sequence uint64) { + store := ctx.KVStore(k.storeKey) + bz := sdk.Uint64ToBigEndian(sequence) + store.Set([]byte(types.KeyNextChannelSequence), bz) +} + // GetNextSequenceSend gets a channel's next send sequence from the store func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) { store := ctx.KVStore(k.storeKey) diff --git a/x/ibc/core/04-channel/keeper/keeper_test.go b/x/ibc/core/04-channel/keeper/keeper_test.go index d1ea3de5da91..fa24a66b9c7a 100644 --- a/x/ibc/core/04-channel/keeper/keeper_test.go +++ b/x/ibc/core/04-channel/keeper/keeper_test.go @@ -42,8 +42,8 @@ func (suite *KeeperTestSuite) TestSetChannel() { // create client and connections on both chains _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - // check for channel to be created on chainB - channelA := connA.NextTestChannel(ibctesting.MockPort) + // check for channel to be created on chainA + channelA := suite.chainA.NextTestChannel(connA, ibctesting.MockPort) _, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) suite.False(found) @@ -52,7 +52,8 @@ func (suite *KeeperTestSuite) TestSetChannel() { suite.NoError(err) storedChannel, found := suite.chainA.App.IBCKeeper.ChannelKeeper.GetChannel(suite.chainA.GetContext(), channelA.PortID, channelA.ID) - expectedCounterparty := types.NewCounterparty(channelB.PortID, channelB.ID) + // counterparty channel id is empty after open init + expectedCounterparty := types.NewCounterparty(channelB.PortID, "") suite.True(found) suite.Equal(types.INIT, storedChannel.State) @@ -83,9 +84,10 @@ func (suite KeeperTestSuite) TestGetAllChannels() { testchannel2, _, err := suite.coordinator.ChanOpenInit(suite.chainA, suite.chainB, connA1, connB1, ibctesting.MockPort, ibctesting.MockPort, types.UNORDERED) suite.Require().NoError(err) + // counterparty channel id is empty after open init counterparty2 := types.Counterparty{ PortId: connB1.Channels[0].PortID, - ChannelId: connB1.Channels[0].ID, + ChannelId: "", } channel0 := types.NewChannel( diff --git a/x/ibc/core/04-channel/keeper/packet_test.go b/x/ibc/core/04-channel/keeper/packet_test.go index f53ed7947552..62c8336212e0 100644 --- a/x/ibc/core/04-channel/keeper/packet_test.go +++ b/x/ibc/core/04-channel/keeper/packet_test.go @@ -148,8 +148,8 @@ func (suite *KeeperTestSuite) TestSendPacket() { }, false}, {"next sequence send not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) // manually creating channel prevents next sequence from being set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( @@ -298,8 +298,8 @@ func (suite *KeeperTestSuite) TestRecvPacket() { connB, connA, err := suite.coordinator.ConnOpenInit(suite.chainB, suite.chainA, clientB, clientA) suite.Require().NoError(err) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // pass channel check suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainB.GetContext(), @@ -322,8 +322,8 @@ func (suite *KeeperTestSuite) TestRecvPacket() { }, false}, {"next receive sequence is not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // manually creating channel prevents next recv sequence from being set suite.chainB.App.IBCKeeper.ChannelKeeper.SetChannel( @@ -570,8 +570,8 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { connA, connB, err := suite.coordinator.ConnOpenInit(suite.chainA, suite.chainB, clientA, clientB) suite.Require().NoError(err) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) // pass channel check suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( suite.chainA.GetContext(), @@ -599,8 +599,8 @@ func (suite *KeeperTestSuite) TestAcknowledgePacket() { }, false}, {"next ack sequence not found", func() { _, _, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, exported.Tendermint) - channelA := connA.NextTestChannel(ibctesting.TransferPort) - channelB := connB.NextTestChannel(ibctesting.TransferPort) + channelA := suite.chainA.NextTestChannel(connA, ibctesting.TransferPort) + channelB := suite.chainB.NextTestChannel(connB, ibctesting.TransferPort) packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) // manually creating channel prevents next sequence acknowledgement from being set suite.chainA.App.IBCKeeper.ChannelKeeper.SetChannel( diff --git a/x/ibc/core/04-channel/types/genesis.go b/x/ibc/core/04-channel/types/genesis.go index 51de68127136..28ab32f21a5e 100644 --- a/x/ibc/core/04-channel/types/genesis.go +++ b/x/ibc/core/04-channel/types/genesis.go @@ -44,28 +44,30 @@ func (ps PacketSequence) Validate() error { // NewGenesisState creates a GenesisState instance. func NewGenesisState( channels []IdentifiedChannel, acks, receipts, commitments []PacketState, - sendSeqs, recvSeqs, ackSeqs []PacketSequence, + sendSeqs, recvSeqs, ackSeqs []PacketSequence, nextChannelSequence uint64, ) GenesisState { return GenesisState{ - Channels: channels, - Acknowledgements: acks, - Commitments: commitments, - SendSequences: sendSeqs, - RecvSequences: recvSeqs, - AckSequences: ackSeqs, + Channels: channels, + Acknowledgements: acks, + Commitments: commitments, + SendSequences: sendSeqs, + RecvSequences: recvSeqs, + AckSequences: ackSeqs, + NextChannelSequence: nextChannelSequence, } } // DefaultGenesisState returns the ibc channel submodule's default genesis state. func DefaultGenesisState() GenesisState { return GenesisState{ - Channels: []IdentifiedChannel{}, - Acknowledgements: []PacketState{}, - Receipts: []PacketState{}, - Commitments: []PacketState{}, - SendSequences: []PacketSequence{}, - RecvSequences: []PacketSequence{}, - AckSequences: []PacketSequence{}, + Channels: []IdentifiedChannel{}, + Acknowledgements: []PacketState{}, + Receipts: []PacketState{}, + Commitments: []PacketState{}, + SendSequences: []PacketSequence{}, + RecvSequences: []PacketSequence{}, + AckSequences: []PacketSequence{}, + NextChannelSequence: 0, } } diff --git a/x/ibc/core/04-channel/types/genesis.pb.go b/x/ibc/core/04-channel/types/genesis.pb.go index ca26a9bb5d15..51ff4e50771c 100644 --- a/x/ibc/core/04-channel/types/genesis.pb.go +++ b/x/ibc/core/04-channel/types/genesis.pb.go @@ -32,6 +32,8 @@ type GenesisState struct { SendSequences []PacketSequence `protobuf:"bytes,5,rep,name=send_sequences,json=sendSequences,proto3" json:"send_sequences" yaml:"send_sequences"` RecvSequences []PacketSequence `protobuf:"bytes,6,rep,name=recv_sequences,json=recvSequences,proto3" json:"recv_sequences" yaml:"recv_sequences"` AckSequences []PacketSequence `protobuf:"bytes,7,rep,name=ack_sequences,json=ackSequences,proto3" json:"ack_sequences" yaml:"ack_sequences"` + // the sequence for the next generated channel identifier + NextChannelSequence uint64 `protobuf:"varint,8,opt,name=next_channel_sequence,json=nextChannelSequence,proto3" json:"next_channel_sequence,omitempty" yaml:"next_channel_sequence"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -116,6 +118,13 @@ func (m *GenesisState) GetAckSequences() []PacketSequence { return nil } +func (m *GenesisState) GetNextChannelSequence() uint64 { + if m != nil { + return m.NextChannelSequence + } + return 0 +} + // PacketSequence defines the genesis type necessary to retrieve and store // next send and receive sequences. type PacketSequence struct { @@ -186,37 +195,39 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/genesis.proto", fileDescriptor_cb06ec201f452595) } var fileDescriptor_cb06ec201f452595 = []byte{ - // 471 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0xc7, 0xe3, 0x26, 0x4d, 0xd3, 0x6b, 0x13, 0xd1, 0xa3, 0x95, 0x4c, 0x04, 0x76, 0x30, 0x12, - 0x8a, 0x84, 0x6a, 0x53, 0xe8, 0x80, 0x18, 0xcd, 0x00, 0xd9, 0xd0, 0xb1, 0x21, 0xa1, 0xca, 0x39, - 0xbf, 0xba, 0x27, 0xc7, 0xbe, 0xe0, 0xbb, 0x06, 0xfa, 0x21, 0x10, 0x7c, 0xac, 0x8e, 0x1d, 0x99, - 0x2c, 0x94, 0x7c, 0x83, 0x8c, 0x4c, 0xc8, 0xe7, 0x8b, 0x9b, 0xa8, 0x11, 0x22, 0x4c, 0xf6, 0xbd, - 0xf7, 0x7f, 0xbf, 0xdf, 0x5b, 0x1e, 0x7a, 0xcc, 0x86, 0xd4, 0xa3, 0x3c, 0x03, 0x8f, 0x5e, 0x04, - 0x69, 0x0a, 0x23, 0x6f, 0x72, 0xe2, 0x45, 0x90, 0x82, 0x60, 0xc2, 0x1d, 0x67, 0x5c, 0x72, 0x7c, - 0x9f, 0x0d, 0xa9, 0x5b, 0x44, 0x5c, 0x1d, 0x71, 0x27, 0x27, 0xdd, 0xc3, 0x88, 0x47, 0x5c, 0xf5, - 0xbd, 0xe2, 0xaf, 0x8c, 0x76, 0xd7, 0xd2, 0x16, 0x53, 0x2a, 0xe2, 0x7c, 0xdb, 0x46, 0xfb, 0x6f, - 0x4b, 0xfe, 0x07, 0x19, 0x48, 0xc0, 0x9f, 0x50, 0x4b, 0x27, 0x84, 0x69, 0xf4, 0xea, 0xfd, 0xbd, - 0x17, 0x4f, 0xdd, 0x35, 0x46, 0x77, 0x10, 0x42, 0x2a, 0xd9, 0x39, 0x83, 0xf0, 0x4d, 0x59, 0xf4, - 0x1f, 0x5c, 0xe7, 0x76, 0xed, 0x77, 0x6e, 0x1f, 0xdc, 0x69, 0x91, 0x0a, 0x89, 0x09, 0xba, 0x17, - 0xd0, 0x38, 0xe5, 0x5f, 0x46, 0x10, 0x46, 0x90, 0x40, 0x2a, 0x85, 0xb9, 0xa5, 0x34, 0xbd, 0xb5, - 0x9a, 0xf7, 0x01, 0x8d, 0x41, 0xaa, 0xd5, 0xfc, 0x46, 0x21, 0x20, 0x77, 0xe6, 0xf1, 0x3b, 0xb4, - 0x47, 0x79, 0x92, 0x30, 0x59, 0xe2, 0xea, 0x1b, 0xe1, 0x96, 0x47, 0xb1, 0x8f, 0x5a, 0x19, 0x50, - 0x60, 0x63, 0x29, 0xcc, 0xc6, 0x46, 0x98, 0x6a, 0x0e, 0x33, 0xd4, 0x11, 0x90, 0x86, 0x67, 0x02, - 0x3e, 0x5f, 0x42, 0x4a, 0x41, 0x98, 0xdb, 0x8a, 0xf4, 0xe4, 0x6f, 0x24, 0x9d, 0xf5, 0x1f, 0x15, - 0xb0, 0x79, 0x6e, 0x1f, 0x5d, 0x05, 0xc9, 0xe8, 0xb5, 0xb3, 0x0a, 0x72, 0x48, 0xbb, 0x28, 0x2c, - 0xc2, 0x4a, 0x95, 0x01, 0x9d, 0x2c, 0xa9, 0x9a, 0xff, 0xad, 0x5a, 0x05, 0x39, 0xa4, 0x5d, 0x14, - 0x6e, 0x55, 0xe7, 0xa8, 0x1d, 0xd0, 0x78, 0xc9, 0xb4, 0xf3, 0xef, 0xa6, 0x87, 0xda, 0x74, 0x58, - 0x9a, 0x56, 0x38, 0x0e, 0xd9, 0x0f, 0x68, 0x5c, 0x79, 0x9c, 0xef, 0x06, 0xea, 0xac, 0x8e, 0xe3, - 0x67, 0x68, 0x67, 0xcc, 0x33, 0x79, 0xc6, 0x42, 0xd3, 0xe8, 0x19, 0xfd, 0x5d, 0x1f, 0xcf, 0x73, - 0xbb, 0x53, 0xb2, 0x74, 0xc3, 0x21, 0xcd, 0xe2, 0x6f, 0x10, 0xe2, 0x53, 0x84, 0xf4, 0x22, 0x45, - 0x7e, 0x4b, 0xe5, 0x8f, 0xe6, 0xb9, 0x7d, 0x50, 0xe6, 0x6f, 0x7b, 0x0e, 0xd9, 0xd5, 0x8f, 0x41, - 0x88, 0xbb, 0xa8, 0xb5, 0xd8, 0xc8, 0xac, 0xf7, 0x8c, 0x7e, 0x83, 0x54, 0x6f, 0x9f, 0x5c, 0x4f, - 0x2d, 0xe3, 0x66, 0x6a, 0x19, 0xbf, 0xa6, 0x96, 0xf1, 0x63, 0x66, 0xd5, 0x6e, 0x66, 0x56, 0xed, - 0xe7, 0xcc, 0xaa, 0x7d, 0x7c, 0x15, 0x31, 0x79, 0x71, 0x39, 0x74, 0x29, 0x4f, 0x3c, 0xca, 0x45, - 0xc2, 0x85, 0xfe, 0x1c, 0x8b, 0x30, 0xf6, 0xbe, 0x7a, 0xd5, 0xf5, 0x3d, 0x3f, 0x3d, 0x5e, 0x1c, - 0xa0, 0xbc, 0x1a, 0x83, 0x18, 0x36, 0xd5, 0xf1, 0xbd, 0xfc, 0x13, 0x00, 0x00, 0xff, 0xff, 0x70, - 0xac, 0x09, 0x09, 0xef, 0x03, 0x00, 0x00, + // 501 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0x87, 0xe3, 0x26, 0x4d, 0xd3, 0x6d, 0x13, 0xd1, 0x6d, 0x23, 0x99, 0xa8, 0xd8, 0xc6, 0x48, + 0x28, 0x12, 0xaa, 0x4d, 0xa1, 0x07, 0xc4, 0xd1, 0x1c, 0x20, 0x37, 0xb4, 0x70, 0x42, 0x42, 0x91, + 0xb3, 0x9e, 0xba, 0x2b, 0xc7, 0xde, 0xe0, 0xdd, 0x86, 0xf6, 0x29, 0xe0, 0xb1, 0x7a, 0xec, 0x91, + 0x93, 0x85, 0x92, 0x37, 0xc8, 0x91, 0x13, 0xf2, 0xdf, 0x24, 0x6a, 0x84, 0x68, 0x4f, 0xde, 0x9d, + 0xf9, 0xcd, 0xf7, 0xcd, 0xc1, 0x8b, 0x9e, 0xb2, 0x11, 0xb5, 0x29, 0x8f, 0xc1, 0xa6, 0x17, 0x6e, + 0x14, 0xc1, 0xd8, 0x9e, 0x9e, 0xda, 0x3e, 0x44, 0x20, 0x98, 0xb0, 0x26, 0x31, 0x97, 0x1c, 0x1f, + 0xb2, 0x11, 0xb5, 0xd2, 0x88, 0x55, 0x44, 0xac, 0xe9, 0x69, 0xef, 0xc8, 0xe7, 0x3e, 0xcf, 0xfa, + 0x76, 0x7a, 0xca, 0xa3, 0xbd, 0x8d, 0xb4, 0x72, 0x2a, 0x8b, 0x98, 0xf3, 0x6d, 0xb4, 0xff, 0x3e, + 0xe7, 0x7f, 0x92, 0xae, 0x04, 0xfc, 0x15, 0xb5, 0x8a, 0x84, 0x50, 0x15, 0xa3, 0xde, 0xdf, 0x7b, + 0xf5, 0xdc, 0xda, 0x60, 0xb4, 0x06, 0x1e, 0x44, 0x92, 0x9d, 0x33, 0xf0, 0xde, 0xe5, 0x45, 0xe7, + 0xf1, 0x4d, 0xa2, 0xd7, 0xfe, 0x24, 0xfa, 0xc1, 0x9d, 0x16, 0xa9, 0x90, 0x98, 0xa0, 0x47, 0x2e, + 0x0d, 0x22, 0xfe, 0x7d, 0x0c, 0x9e, 0x0f, 0x21, 0x44, 0x52, 0xa8, 0x5b, 0x99, 0xc6, 0xd8, 0xa8, + 0xf9, 0xe8, 0xd2, 0x00, 0x64, 0xb6, 0x9a, 0xd3, 0x48, 0x05, 0xe4, 0xce, 0x3c, 0xfe, 0x80, 0xf6, + 0x28, 0x0f, 0x43, 0x26, 0x73, 0x5c, 0xfd, 0x5e, 0xb8, 0xd5, 0x51, 0xec, 0xa0, 0x56, 0x0c, 0x14, + 0xd8, 0x44, 0x0a, 0xb5, 0x71, 0x2f, 0x4c, 0x35, 0x87, 0x19, 0xea, 0x08, 0x88, 0xbc, 0xa1, 0x80, + 0x6f, 0x97, 0x10, 0x51, 0x10, 0xea, 0x76, 0x46, 0x7a, 0xf6, 0x2f, 0x52, 0x91, 0x75, 0x9e, 0xa4, + 0xb0, 0x45, 0xa2, 0x77, 0xaf, 0xdd, 0x70, 0xfc, 0xd6, 0x5c, 0x07, 0x99, 0xa4, 0x9d, 0x16, 0xca, + 0x70, 0xa6, 0x8a, 0x81, 0x4e, 0x57, 0x54, 0xcd, 0x07, 0xab, 0xd6, 0x41, 0x26, 0x69, 0xa7, 0x85, + 0xa5, 0xea, 0x1c, 0xb5, 0x5d, 0x1a, 0xac, 0x98, 0x76, 0xfe, 0xdf, 0x74, 0x5c, 0x98, 0x8e, 0x72, + 0xd3, 0x1a, 0xc7, 0x24, 0xfb, 0x2e, 0x0d, 0x96, 0x9e, 0xcf, 0xa8, 0x1b, 0xc1, 0x95, 0x1c, 0x16, + 0xb4, 0x2a, 0xa8, 0xb6, 0x0c, 0xa5, 0xdf, 0x70, 0x8c, 0x45, 0xa2, 0x1f, 0xe7, 0x98, 0x8d, 0x31, + 0x93, 0x1c, 0xa6, 0xf5, 0xe2, 0xbf, 0x2b, 0xb1, 0xe6, 0x0f, 0x05, 0x75, 0xd6, 0x97, 0xc2, 0x2f, + 0xd0, 0xce, 0x84, 0xc7, 0x72, 0xc8, 0x3c, 0x55, 0x31, 0x94, 0xfe, 0xae, 0x83, 0x17, 0x89, 0xde, + 0xc9, 0xd1, 0x45, 0xc3, 0x24, 0xcd, 0xf4, 0x34, 0xf0, 0xf0, 0x19, 0x42, 0xa5, 0x89, 0x79, 0xea, + 0x56, 0x96, 0xef, 0x2e, 0x12, 0xfd, 0x20, 0xcf, 0x2f, 0x7b, 0x26, 0xd9, 0x2d, 0x2e, 0x03, 0x0f, + 0xf7, 0x50, 0xab, 0x5a, 0xbf, 0x9e, 0xae, 0x4f, 0xaa, 0xbb, 0x43, 0x6e, 0x66, 0x9a, 0x72, 0x3b, + 0xd3, 0x94, 0xdf, 0x33, 0x4d, 0xf9, 0x39, 0xd7, 0x6a, 0xb7, 0x73, 0xad, 0xf6, 0x6b, 0xae, 0xd5, + 0xbe, 0xbc, 0xf1, 0x99, 0xbc, 0xb8, 0x1c, 0x59, 0x94, 0x87, 0x36, 0xe5, 0x22, 0xe4, 0xa2, 0xf8, + 0x9c, 0x08, 0x2f, 0xb0, 0xaf, 0xec, 0xea, 0x4d, 0xbf, 0x3c, 0x3b, 0x29, 0x9f, 0xb5, 0xbc, 0x9e, + 0x80, 0x18, 0x35, 0xb3, 0x27, 0xfd, 0xfa, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3c, 0x42, 0xc2, + 0x18, 0x45, 0x04, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -239,6 +250,11 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.NextChannelSequence != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.NextChannelSequence)) + i-- + dAtA[i] = 0x40 + } if len(m.AckSequences) > 0 { for iNdEx := len(m.AckSequences) - 1; iNdEx >= 0; iNdEx-- { { @@ -441,6 +457,9 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if m.NextChannelSequence != 0 { + n += 1 + sovGenesis(uint64(m.NextChannelSequence)) + } return n } @@ -737,6 +756,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextChannelSequence", wireType) + } + m.NextChannelSequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextChannelSequence |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/ibc/core/04-channel/types/genesis_test.go b/x/ibc/core/04-channel/types/genesis_test.go index c1dbfd76e0c5..05e154296e68 100644 --- a/x/ibc/core/04-channel/types/genesis_test.go +++ b/x/ibc/core/04-channel/types/genesis_test.go @@ -66,6 +66,7 @@ func TestValidateGenesis(t *testing.T) { []types.PacketSequence{ types.NewPacketSequence(testPort2, testChannel2, 1), }, + 0, ), expPass: true, }, diff --git a/x/ibc/core/04-channel/types/keys.go b/x/ibc/core/04-channel/types/keys.go index 60f24d5e7468..b6c5745dda12 100644 --- a/x/ibc/core/04-channel/types/keys.go +++ b/x/ibc/core/04-channel/types/keys.go @@ -1,5 +1,13 @@ package types +import ( + "fmt" + "strconv" + "strings" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + const ( // SubModuleName defines the IBC channels name SubModuleName = "channel" @@ -12,4 +20,40 @@ const ( // QuerierRoute is the querier route for IBC channels QuerierRoute = SubModuleName + + // KeyNextChannelSequence is the key used to store the next channel sequence in + // the keeper. + KeyNextChannelSequence = "nextChannelSequence" + + // ChannelPrefix is the prefix used when creating a channel identifier + ChannelPrefix = "channel-" ) + +// FormatChannelIdentifier returns the channel identifier with the sequence appended. +func FormatChannelIdentifier(sequence uint64) string { + return fmt.Sprintf("%s%d", ChannelPrefix, sequence) +} + +// IsValidChannelID return true if the channel identifier is valid. +func IsValidChannelID(channelID string) bool { + _, err := ParseChannelSequence(channelID) + return err == nil +} + +// ParseChannelSequence parses the channel sequence from the channel identifier. +func ParseChannelSequence(channelID string) (uint64, error) { + if !strings.HasPrefix(channelID, ChannelPrefix) { + return 0, sdkerrors.Wrapf(ErrInvalidChannelIdentifier, "doesn't contain prefix `%s`", ChannelPrefix) + } + + splitStr := strings.Split(channelID, ChannelPrefix) + if len(splitStr) != 2 { + return 0, sdkerrors.Wrap(ErrInvalidChannelIdentifier, "channel identifier must be in format: `channel-{N}`") + } + + sequence, err := strconv.ParseUint(splitStr[1], 10, 64) + if err != nil { + return 0, sdkerrors.Wrap(err, "failed to parse channel identifier sequence") + } + return sequence, nil +} diff --git a/x/ibc/core/04-channel/types/keys_test.go b/x/ibc/core/04-channel/types/keys_test.go new file mode 100644 index 000000000000..418174cb0406 --- /dev/null +++ b/x/ibc/core/04-channel/types/keys_test.go @@ -0,0 +1,44 @@ +package types_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" + "github.com/stretchr/testify/require" +) + +// tests ParseChannelSequence and IsValidChannelID +func TestParseChannelSequence(t *testing.T) { + testCases := []struct { + name string + channelID string + expSeq uint64 + expPass bool + }{ + {"valid 0", "channel-0", 0, true}, + {"valid 1", "channel-1", 1, true}, + {"valid large sequence", "channel-234568219356718293", 234568219356718293, true}, + // uint64 == 20 characters + {"invalid large sequence", "channel-2345682193567182931243", 0, false}, + {"capital prefix", "Channel-0", 0, false}, + {"missing dash", "channel0", 0, false}, + {"blank id", " ", 0, false}, + {"empty id", "", 0, false}, + {"negative sequence", "channel--1", 0, false}, + } + + for _, tc := range testCases { + + seq, err := types.ParseChannelSequence(tc.channelID) + valid := types.IsValidChannelID(tc.channelID) + require.Equal(t, tc.expSeq, seq) + + if tc.expPass { + require.NoError(t, err, tc.name) + require.True(t, valid) + } else { + require.Error(t, err, tc.name) + require.False(t, valid) + } + } +} diff --git a/x/ibc/core/04-channel/types/msgs.go b/x/ibc/core/04-channel/types/msgs.go index 772a1204effc..da14a31030fa 100644 --- a/x/ibc/core/04-channel/types/msgs.go +++ b/x/ibc/core/04-channel/types/msgs.go @@ -12,19 +12,19 @@ import ( var _ sdk.Msg = &MsgChannelOpenInit{} -// NewMsgChannelOpenInit creates a new MsgChannelOpenInit +// NewMsgChannelOpenInit creates a new MsgChannelOpenInit. It sets the counterparty channel +// identifier to be empty. // nolint:interfacer func NewMsgChannelOpenInit( - portID, channelID string, version string, channelOrder Order, connectionHops []string, - counterpartyPortID, counterpartyChannelID string, signer sdk.AccAddress, + portID, version string, channelOrder Order, connectionHops []string, + counterpartyPortID string, signer sdk.AccAddress, ) *MsgChannelOpenInit { - counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) + counterparty := NewCounterparty(counterpartyPortID, "") channel := NewChannel(INIT, channelOrder, counterparty, connectionHops, version) return &MsgChannelOpenInit{ - PortId: portID, - ChannelId: channelID, - Channel: channel, - Signer: signer.String(), + PortId: portID, + Channel: channel, + Signer: signer.String(), } } @@ -43,15 +43,15 @@ func (msg MsgChannelOpenInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") - } if msg.Channel.State != INIT { return sdkerrors.Wrapf(ErrInvalidChannelState, "channel state must be INIT in MsgChannelOpenInit. expected: %s, got: %s", INIT, msg.Channel.State, ) } + if msg.Channel.Counterparty.ChannelId != "" { + return sdkerrors.Wrap(ErrInvalidCounterparty, "counterparty channel identifier must be empty") + } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) @@ -79,21 +79,20 @@ var _ sdk.Msg = &MsgChannelOpenTry{} // NewMsgChannelOpenTry creates a new MsgChannelOpenTry instance // nolint:interfacer func NewMsgChannelOpenTry( - portID, desiredChannelID, counterpartyChosenChannelID, version string, channelOrder Order, connectionHops []string, + portID, previousChannelID, version string, channelOrder Order, connectionHops []string, counterpartyPortID, counterpartyChannelID, counterpartyVersion string, proofInit []byte, proofHeight clienttypes.Height, signer sdk.AccAddress, ) *MsgChannelOpenTry { counterparty := NewCounterparty(counterpartyPortID, counterpartyChannelID) channel := NewChannel(TRYOPEN, channelOrder, counterparty, connectionHops, version) return &MsgChannelOpenTry{ - PortId: portID, - DesiredChannelId: desiredChannelID, - CounterpartyChosenChannelId: counterpartyChosenChannelID, - Channel: channel, - CounterpartyVersion: counterpartyVersion, - ProofInit: proofInit, - ProofHeight: proofHeight, - Signer: signer.String(), + PortId: portID, + PreviousChannelId: previousChannelID, + Channel: channel, + CounterpartyVersion: counterpartyVersion, + ProofInit: proofInit, + ProofHeight: proofHeight, + Signer: signer.String(), } } @@ -112,11 +111,10 @@ func (msg MsgChannelOpenTry) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.DesiredChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid desired channel ID") - } - if msg.CounterpartyChosenChannelId != "" && msg.CounterpartyChosenChannelId != msg.DesiredChannelId { - return sdkerrors.Wrap(ErrInvalidChannelIdentifier, "counterparty chosen channel ID must be empty or equal to desired channel ID") + if msg.PreviousChannelId != "" { + if !IsValidChannelID(msg.PreviousChannelId) { + return sdkerrors.Wrap(ErrInvalidChannelIdentifier, "invalid previous channel ID") + } } if len(msg.ProofInit) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") @@ -130,6 +128,11 @@ func (msg MsgChannelOpenTry) ValidateBasic() error { TRYOPEN, msg.Channel.State, ) } + // counterparty validate basic allows empty counterparty channel identifiers + if err := host.ChannelIdentifierValidator(msg.Channel.Counterparty.ChannelId); err != nil { + return sdkerrors.Wrap(err, "invalid counterparty channel ID") + } + _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "string could not be parsed as address: %v", err) @@ -186,8 +189,8 @@ func (msg MsgChannelOpenAck) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if err := host.ChannelIdentifierValidator(msg.CounterpartyChannelId); err != nil { return sdkerrors.Wrap(err, "invalid counterparty channel ID") @@ -252,8 +255,8 @@ func (msg MsgChannelOpenConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if len(msg.ProofAck) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof ack") @@ -312,8 +315,8 @@ func (msg MsgChannelCloseInit) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { @@ -369,8 +372,8 @@ func (msg MsgChannelCloseConfirm) ValidateBasic() error { if err := host.PortIdentifierValidator(msg.PortId); err != nil { return sdkerrors.Wrap(err, "invalid port ID") } - if err := host.ChannelIdentifierValidator(msg.ChannelId); err != nil { - return sdkerrors.Wrap(err, "invalid channel ID") + if !IsValidChannelID(msg.ChannelId) { + return ErrInvalidChannelIdentifier } if len(msg.ProofInit) == 0 { return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "cannot submit an empty proof init") diff --git a/x/ibc/core/04-channel/types/msgs_test.go b/x/ibc/core/04-channel/types/msgs_test.go index 3a666b31beef..9c27fd69efa8 100644 --- a/x/ibc/core/04-channel/types/msgs_test.go +++ b/x/ibc/core/04-channel/types/msgs_test.go @@ -23,7 +23,7 @@ import ( const ( // valid constatns used for testing portid = "testportid" - chanid = "testchannel" + chanid = "channel-0" cpportid = "testcpport" cpchanid = "testcpchannel" @@ -35,7 +35,7 @@ const ( invalidLongPort = "invalidlongportinvalidlongportinvalidlongportidinvalidlongportidinvalid" invalidChannel = "(invalidchannel1)" - invalidShortChannel = "invalidch" + invalidShortChannel = "invalid" invalidLongChannel = "invalidlongchannelinvalidlongchannelinvalidlongchannelinvalidlongchannel" invalidConnection = "(invalidconnection1)" @@ -114,22 +114,18 @@ func (suite *TypesTestSuite) TestMsgChannelOpenInitValidateBasic() { msg *types.MsgChannelOpenInit expPass bool }{ - {"", types.NewMsgChannelOpenInit(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), true}, - {"too short port id", types.NewMsgChannelOpenInit(invalidShortPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too long port id", types.NewMsgChannelOpenInit(invalidLongPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"port id contains non-alpha", types.NewMsgChannelOpenInit(invalidPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too short channel id", types.NewMsgChannelOpenInit(portid, invalidShortChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"too long channel id", types.NewMsgChannelOpenInit(portid, invalidLongChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"channel id contains non-alpha", types.NewMsgChannelOpenInit(portid, invalidChannel, version, types.ORDERED, connHops, cpportid, cpchanid, addr), false}, - {"invalid channel order", types.NewMsgChannelOpenInit(portid, chanid, version, types.Order(3), connHops, cpportid, cpchanid, addr), false}, - {"connection hops more than 1 ", types.NewMsgChannelOpenInit(portid, chanid, version, types.ORDERED, invalidConnHops, cpportid, cpchanid, addr), false}, - {"too short connection id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, addr), false}, - {"too long connection id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, addr), false}, - {"connection id contains non-alpha", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, addr), false}, - {"", types.NewMsgChannelOpenInit(portid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, addr), true}, - {"invalid counterparty port id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, addr), false}, - {"invalid counterparty channel id", types.NewMsgChannelOpenInit(portid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, addr), false}, - {"channel not in INIT state", &types.MsgChannelOpenInit{portid, chanid, tryOpenChannel, addr.String()}, false}, + {"", types.NewMsgChannelOpenInit(portid, version, types.ORDERED, connHops, cpportid, addr), true}, + {"too short port id", types.NewMsgChannelOpenInit(invalidShortPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"too long port id", types.NewMsgChannelOpenInit(invalidLongPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"port id contains non-alpha", types.NewMsgChannelOpenInit(invalidPort, version, types.ORDERED, connHops, cpportid, addr), false}, + {"invalid channel order", types.NewMsgChannelOpenInit(portid, version, types.Order(3), connHops, cpportid, addr), false}, + {"connection hops more than 1 ", types.NewMsgChannelOpenInit(portid, version, types.ORDERED, invalidConnHops, cpportid, addr), false}, + {"too short connection id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, invalidShortConnHops, cpportid, addr), false}, + {"too long connection id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, invalidLongConnHops, cpportid, addr), false}, + {"connection id contains non-alpha", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, []string{invalidConnection}, cpportid, addr), false}, + {"", types.NewMsgChannelOpenInit(portid, "", types.UNORDERED, connHops, cpportid, addr), true}, + {"invalid counterparty port id", types.NewMsgChannelOpenInit(portid, version, types.UNORDERED, connHops, invalidPort, addr), false}, + {"channel not in INIT state", &types.MsgChannelOpenInit{portid, tryOpenChannel, addr.String()}, false}, } for _, tc := range testCases { @@ -155,27 +151,25 @@ func (suite *TypesTestSuite) TestMsgChannelOpenTryValidateBasic() { msg *types.MsgChannelOpenTry expPass bool }{ - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"too short port id", types.NewMsgChannelOpenTry(invalidShortPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long port id", types.NewMsgChannelOpenTry(invalidLongPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"port id contains non-alpha", types.NewMsgChannelOpenTry(invalidPort, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too short channel id", types.NewMsgChannelOpenTry(portid, invalidShortChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long channel id", types.NewMsgChannelOpenTry(portid, invalidLongChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"channel id contains non-alpha", types.NewMsgChannelOpenTry(portid, invalidChannel, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, "", suite.proof, height, addr), true}, - {"proof height is zero", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, clienttypes.ZeroHeight(), addr), false}, - {"invalid channel order", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.Order(4), connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"connection hops more than 1 ", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too short connection id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"too long connection id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"connection id contains non-alpha", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"", types.NewMsgChannelOpenTry(portid, chanid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"invalid counterparty port id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, version, suite.proof, height, addr), false}, - {"invalid counterparty channel id", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, version, suite.proof, height, addr), false}, - {"empty proof", types.NewMsgChannelOpenTry(portid, chanid, chanid, version, types.UNORDERED, connHops, cpportid, cpchanid, version, emptyProof, height, addr), false}, - {"valid empty proved channel id", types.NewMsgChannelOpenTry(portid, chanid, "", version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, - {"invalid proved channel id, doesn't match channel id", types.NewMsgChannelOpenTry(portid, chanid, "differentchannel", version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, - {"channel not in TRYOPEN state", &types.MsgChannelOpenTry{portid, chanid, chanid, initChannel, version, suite.proof, height, addr.String()}, false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, + {"too short port id", types.NewMsgChannelOpenTry(invalidShortPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long port id", types.NewMsgChannelOpenTry(invalidLongPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"port id contains non-alpha", types.NewMsgChannelOpenTry(invalidPort, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too short channel id", types.NewMsgChannelOpenTry(portid, invalidShortChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long channel id", types.NewMsgChannelOpenTry(portid, invalidLongChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"channel id contains non-alpha", types.NewMsgChannelOpenTry(portid, invalidChannel, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, "", suite.proof, height, addr), true}, + {"proof height is zero", types.NewMsgChannelOpenTry(portid, chanid, version, types.ORDERED, connHops, cpportid, cpchanid, version, suite.proof, clienttypes.ZeroHeight(), addr), false}, + {"invalid channel order", types.NewMsgChannelOpenTry(portid, chanid, version, types.Order(4), connHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"connection hops more than 1 ", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too short connection id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidShortConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"too long connection id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, invalidLongConnHops, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"connection id contains non-alpha", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, []string{invalidConnection}, cpportid, cpchanid, version, suite.proof, height, addr), false}, + {"", types.NewMsgChannelOpenTry(portid, chanid, "", types.UNORDERED, connHops, cpportid, cpchanid, version, suite.proof, height, addr), true}, + {"invalid counterparty port id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, invalidPort, cpchanid, version, suite.proof, height, addr), false}, + {"invalid counterparty channel id", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, cpportid, invalidChannel, version, suite.proof, height, addr), false}, + {"empty proof", types.NewMsgChannelOpenTry(portid, chanid, version, types.UNORDERED, connHops, cpportid, cpchanid, version, emptyProof, height, addr), false}, + {"channel not in TRYOPEN state", &types.MsgChannelOpenTry{portid, chanid, initChannel, version, suite.proof, height, addr.String()}, false}, } for _, tc := range testCases { diff --git a/x/ibc/core/04-channel/types/tx.pb.go b/x/ibc/core/04-channel/types/tx.pb.go index 608f573a7754..9d2f3e221e98 100644 --- a/x/ibc/core/04-channel/types/tx.pb.go +++ b/x/ibc/core/04-channel/types/tx.pb.go @@ -32,10 +32,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgChannelOpenInit defines an sdk.Msg to initialize a channel handshake. It // is called by a relayer on Chain A. type MsgChannelOpenInit struct { - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` - ChannelId string `protobuf:"bytes,2,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"` - Channel Channel `protobuf:"bytes,3,opt,name=channel,proto3" json:"channel"` - Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty"` + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` + Channel Channel `protobuf:"bytes,2,opt,name=channel,proto3" json:"channel"` + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgChannelOpenInit) Reset() { *m = MsgChannelOpenInit{} } @@ -111,14 +110,15 @@ var xxx_messageInfo_MsgChannelOpenInitResponse proto.InternalMessageInfo // MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel // on Chain B. type MsgChannelOpenTry struct { - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` - DesiredChannelId string `protobuf:"bytes,2,opt,name=desired_channel_id,json=desiredChannelId,proto3" json:"desired_channel_id,omitempty" yaml:"desired_channel_id"` - CounterpartyChosenChannelId string `protobuf:"bytes,3,opt,name=counterparty_chosen_channel_id,json=counterpartyChosenChannelId,proto3" json:"counterparty_chosen_channel_id,omitempty" yaml:"counterparty_chosen_channel_id"` - Channel Channel `protobuf:"bytes,4,opt,name=channel,proto3" json:"channel"` - CounterpartyVersion string `protobuf:"bytes,5,opt,name=counterparty_version,json=counterpartyVersion,proto3" json:"counterparty_version,omitempty" yaml:"counterparty_version"` - ProofInit []byte `protobuf:"bytes,6,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` - ProofHeight types.Height `protobuf:"bytes,7,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` - Signer string `protobuf:"bytes,8,opt,name=signer,proto3" json:"signer,omitempty"` + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty" yaml:"port_id"` + // in the case of crossing hello's, when both chains call OpenInit, we need the channel identifier + // of the previous channel in state INIT + PreviousChannelId string `protobuf:"bytes,2,opt,name=previous_channel_id,json=previousChannelId,proto3" json:"previous_channel_id,omitempty" yaml:"previous_channel_id"` + Channel Channel `protobuf:"bytes,3,opt,name=channel,proto3" json:"channel"` + CounterpartyVersion string `protobuf:"bytes,4,opt,name=counterparty_version,json=counterpartyVersion,proto3" json:"counterparty_version,omitempty" yaml:"counterparty_version"` + ProofInit []byte `protobuf:"bytes,5,opt,name=proof_init,json=proofInit,proto3" json:"proof_init,omitempty" yaml:"proof_init"` + ProofHeight types.Height `protobuf:"bytes,6,opt,name=proof_height,json=proofHeight,proto3" json:"proof_height" yaml:"proof_height"` + Signer string `protobuf:"bytes,7,opt,name=signer,proto3" json:"signer,omitempty"` } func (m *MsgChannelOpenTry) Reset() { *m = MsgChannelOpenTry{} } @@ -853,80 +853,77 @@ func init() { func init() { proto.RegisterFile("ibc/core/channel/v1/tx.proto", fileDescriptor_bc4637e0ac3fc7b7) } var fileDescriptor_bc4637e0ac3fc7b7 = []byte{ - // 1158 bytes of a gzipped FileDescriptorProto + // 1120 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6e, 0xdb, 0x46, - 0x10, 0xd6, 0x9f, 0x65, 0x7b, 0xec, 0xc6, 0x0e, 0xfd, 0xa7, 0x50, 0xb6, 0xe8, 0x12, 0x68, 0xe2, - 0xa6, 0x88, 0x14, 0x3b, 0x01, 0xda, 0x06, 0xbd, 0x58, 0x02, 0x8a, 0x1a, 0x81, 0x91, 0x82, 0x71, - 0x7b, 0x30, 0x0a, 0x08, 0xf2, 0x6a, 0x43, 0x11, 0xb2, 0x76, 0x55, 0x92, 0x56, 0xac, 0x37, 0xe8, - 0x31, 0xe7, 0x9e, 0x72, 0xef, 0x21, 0x7d, 0x87, 0x5e, 0x72, 0xcc, 0x2d, 0x45, 0x0f, 0x44, 0x61, - 0x5f, 0x7a, 0xe6, 0x13, 0x14, 0x5c, 0x2e, 0x7f, 0x44, 0x91, 0x31, 0x5d, 0x57, 0x6a, 0x4f, 0x22, - 0x67, 0xbe, 0x9d, 0x9d, 0xfd, 0xe6, 0xdb, 0xd9, 0xa5, 0x60, 0x53, 0x3b, 0x41, 0x35, 0x44, 0x75, - 0x5c, 0x43, 0x9d, 0x16, 0x21, 0xf8, 0xb4, 0x36, 0xd8, 0xad, 0x99, 0xe7, 0xd5, 0xbe, 0x4e, 0x4d, - 0x2a, 0xac, 0x68, 0x27, 0xa8, 0xea, 0x78, 0xab, 0xdc, 0x5b, 0x1d, 0xec, 0x8a, 0xab, 0x2a, 0x55, - 0x29, 0xf3, 0xd7, 0x9c, 0x27, 0x17, 0x2a, 0x4a, 0x41, 0xa0, 0x53, 0x0d, 0x13, 0xd3, 0x89, 0xe3, - 0x3e, 0x71, 0xc0, 0xc7, 0x71, 0x33, 0x79, 0x61, 0x19, 0x44, 0x7e, 0x9f, 0x05, 0xe1, 0xd0, 0x50, - 0x1b, 0xae, 0xf1, 0x59, 0x1f, 0x93, 0x03, 0xa2, 0x99, 0xc2, 0x67, 0x30, 0xdb, 0xa7, 0xba, 0xd9, - 0xd4, 0xda, 0xa5, 0xec, 0x76, 0x76, 0x67, 0xbe, 0x2e, 0xd8, 0x96, 0x74, 0x6b, 0xd8, 0xea, 0x9d, - 0x3e, 0x91, 0xb9, 0x43, 0x56, 0x8a, 0xce, 0xd3, 0x41, 0x5b, 0x78, 0x0c, 0xc0, 0x83, 0x3a, 0xf8, - 0x1c, 0xc3, 0xaf, 0xd9, 0x96, 0x74, 0xdb, 0xc5, 0x07, 0x3e, 0x59, 0x99, 0xe7, 0x2f, 0x07, 0x6d, - 0xe1, 0x2b, 0x98, 0xe5, 0x2f, 0xa5, 0xfc, 0x76, 0x76, 0x67, 0x61, 0x6f, 0xb3, 0x1a, 0xb3, 0xf4, - 0x2a, 0xcf, 0xac, 0x5e, 0x78, 0x6b, 0x49, 0x19, 0xc5, 0x1b, 0x22, 0xac, 0x43, 0xd1, 0xd0, 0x54, - 0x82, 0xf5, 0x52, 0xc1, 0x99, 0x4f, 0xe1, 0x6f, 0x4f, 0xe6, 0x7e, 0x7a, 0x2d, 0x65, 0xfe, 0x7a, - 0x2d, 0x65, 0xe4, 0x4d, 0x10, 0xc7, 0x17, 0xa6, 0x60, 0xa3, 0x4f, 0x89, 0x81, 0xe5, 0xdf, 0x0a, - 0x70, 0x7b, 0xd4, 0x7d, 0xa4, 0x0f, 0xaf, 0xb7, 0xec, 0xa7, 0x20, 0xb4, 0xb1, 0xa1, 0xe9, 0xb8, - 0xdd, 0x1c, 0x5b, 0xfe, 0x96, 0x6d, 0x49, 0x77, 0xdc, 0x71, 0xe3, 0x18, 0x59, 0x59, 0xe6, 0xc6, - 0x86, 0xcf, 0x06, 0x81, 0x0a, 0xa2, 0x67, 0xc4, 0xc4, 0x7a, 0xbf, 0xa5, 0x9b, 0xc3, 0x26, 0xea, - 0x50, 0x03, 0x93, 0x70, 0xe0, 0x3c, 0x0b, 0xfc, 0xa9, 0x6d, 0x49, 0x9f, 0x70, 0x5e, 0x3f, 0x88, - 0x97, 0x95, 0x72, 0x18, 0xd0, 0x60, 0xfe, 0x46, 0x1c, 0xfb, 0x85, 0xeb, 0xb3, 0xaf, 0xc0, 0xea, - 0xc8, 0xec, 0x03, 0xac, 0x1b, 0x1a, 0x25, 0xa5, 0x19, 0x96, 0xa3, 0x64, 0x5b, 0x52, 0x39, 0x26, - 0x47, 0x8e, 0x92, 0x95, 0x95, 0xb0, 0xf9, 0x7b, 0xd7, 0xea, 0xa8, 0xa8, 0xaf, 0x53, 0xfa, 0xa2, - 0xa9, 0x11, 0xcd, 0x2c, 0x15, 0xb7, 0xb3, 0x3b, 0x8b, 0x61, 0x15, 0x05, 0x3e, 0x59, 0x99, 0x67, - 0x2f, 0x4c, 0xa8, 0xc7, 0xb0, 0xe8, 0x7a, 0x3a, 0x58, 0x53, 0x3b, 0x66, 0x69, 0x96, 0x2d, 0x46, - 0x0c, 0x2d, 0xc6, 0xdd, 0x10, 0x83, 0xdd, 0xea, 0x37, 0x0c, 0x51, 0x2f, 0x3b, 0x4b, 0xb1, 0x2d, - 0x69, 0x25, 0x1c, 0xd7, 0x1d, 0x2d, 0x2b, 0x0b, 0xec, 0xd5, 0x45, 0x86, 0x34, 0x36, 0x97, 0xa0, - 0xb1, 0x32, 0xdc, 0x19, 0x13, 0x91, 0x2f, 0xb1, 0xf7, 0xf9, 0xa8, 0xc4, 0xf6, 0x51, 0x77, 0x1a, - 0x3b, 0xeb, 0x18, 0x36, 0x22, 0xda, 0x88, 0x88, 0x48, 0xb6, 0x2d, 0xa9, 0x12, 0x2b, 0xa2, 0x20, - 0xde, 0xda, 0xa8, 0x7a, 0xbc, 0xd8, 0x49, 0x95, 0x2f, 0xdc, 0xa0, 0xf2, 0xbb, 0xe0, 0x16, 0xb4, - 0x69, 0xea, 0x43, 0x26, 0xa1, 0xc5, 0xfa, 0xaa, 0x6d, 0x49, 0xcb, 0xe1, 0x02, 0x99, 0xfa, 0x50, - 0x56, 0xe6, 0xd8, 0xb3, 0xb3, 0x51, 0xa3, 0x65, 0x2f, 0x4e, 0xa4, 0xec, 0xb3, 0x69, 0xcb, 0xbe, - 0x8f, 0xba, 0x7e, 0xd9, 0x7f, 0xc9, 0xc1, 0xda, 0xa8, 0xb7, 0x41, 0xc9, 0x0b, 0x4d, 0xef, 0x4d, - 0xa3, 0xf4, 0x3e, 0x95, 0x2d, 0xd4, 0x65, 0xc5, 0x8e, 0xa1, 0xb2, 0x85, 0xba, 0x1e, 0x95, 0x8e, - 0x20, 0xa3, 0x54, 0x16, 0x26, 0x42, 0xe5, 0x4c, 0x02, 0x95, 0x12, 0x6c, 0xc5, 0x92, 0xe5, 0xd3, - 0xf9, 0x73, 0x16, 0x56, 0x02, 0x44, 0xe3, 0x94, 0x1a, 0x78, 0x5a, 0x27, 0x54, 0x90, 0x7d, 0x3e, - 0x21, 0xfb, 0x2d, 0x28, 0xc7, 0xe4, 0xe6, 0xe7, 0xfe, 0x26, 0x07, 0xeb, 0x11, 0xff, 0x14, 0xb5, - 0x30, 0xda, 0x50, 0xf3, 0xff, 0xb0, 0xa1, 0x4e, 0x57, 0x0e, 0xdb, 0x50, 0x89, 0x27, 0xcc, 0xe7, - 0xf4, 0x55, 0x0e, 0x3e, 0x3a, 0x34, 0x54, 0x05, 0xa3, 0xc1, 0xb7, 0x2d, 0xd4, 0xc5, 0xa6, 0xf0, - 0x25, 0x14, 0xfb, 0xec, 0x89, 0x31, 0xb9, 0xb0, 0x57, 0x8e, 0x3d, 0xc9, 0x5c, 0x30, 0x3f, 0xc8, - 0xf8, 0x00, 0xe1, 0x6b, 0x58, 0x76, 0xd3, 0x45, 0xb4, 0xd7, 0xd3, 0xcc, 0x1e, 0x26, 0x26, 0xa3, - 0x77, 0xb1, 0x5e, 0xb6, 0x2d, 0x69, 0x23, 0xbc, 0xa0, 0x00, 0x21, 0x2b, 0x4b, 0xcc, 0xd4, 0xf0, - 0x2d, 0x63, 0xa4, 0xe5, 0x27, 0x42, 0x5a, 0xd2, 0x4d, 0x67, 0x83, 0x35, 0x9c, 0x80, 0x11, 0x9f, - 0xab, 0x3f, 0x72, 0x00, 0x87, 0x86, 0x7a, 0xa4, 0xf5, 0x30, 0x3d, 0xfb, 0x77, 0x88, 0x3a, 0x23, - 0x3a, 0x46, 0x58, 0x1b, 0xe0, 0x76, 0x12, 0x51, 0x01, 0xc2, 0x23, 0xea, 0x3b, 0xdf, 0x32, 0x51, - 0xa2, 0x9e, 0x82, 0x40, 0xf0, 0xb9, 0xd9, 0x34, 0xf0, 0x8f, 0x67, 0x98, 0x20, 0xdc, 0xd4, 0x31, - 0x1a, 0x30, 0xd2, 0x0a, 0xe1, 0xfb, 0xd8, 0x38, 0x46, 0x56, 0x96, 0x1d, 0xe3, 0x73, 0x6e, 0x73, - 0x88, 0x4c, 0x21, 0xd5, 0x55, 0x76, 0x71, 0xe6, 0xdc, 0x06, 0xed, 0xca, 0x3d, 0xf4, 0xb9, 0xf9, - 0x19, 0x61, 0x1a, 0xfe, 0x3f, 0x30, 0xff, 0x39, 0x2c, 0x70, 0x21, 0x3b, 0x19, 0xf1, 0x76, 0xb0, - 0x6e, 0x5b, 0x92, 0x30, 0xa2, 0x72, 0xc7, 0x29, 0x2b, 0x6e, 0xe3, 0x70, 0x73, 0x9f, 0x64, 0x43, - 0x88, 0x2f, 0xd9, 0xcc, 0x4d, 0x4b, 0x56, 0xfc, 0xe0, 0xb9, 0x3d, 0x5a, 0x1b, 0xbf, 0x72, 0xbf, - 0xe6, 0x58, 0x41, 0xf7, 0x51, 0x97, 0xd0, 0x97, 0xa7, 0xb8, 0xad, 0x62, 0xb6, 0xb5, 0x6f, 0x50, - 0xba, 0x1d, 0x58, 0x6a, 0x8d, 0x46, 0x73, 0x2b, 0xa7, 0x44, 0xcd, 0x41, 0x71, 0x9c, 0x81, 0xed, - 0xa4, 0xe2, 0x30, 0xa7, 0x57, 0x9c, 0x7d, 0xe7, 0xe5, 0x3f, 0xee, 0xd6, 0xee, 0x27, 0x56, 0x84, - 0x31, 0x8f, 0xd0, 0xbd, 0x37, 0x73, 0x90, 0x3f, 0x34, 0x54, 0xa1, 0x0b, 0x4b, 0xd1, 0xcf, 0xcb, - 0x7b, 0xb1, 0x24, 0x8e, 0x7f, 0xae, 0x89, 0xb5, 0x94, 0x40, 0x6f, 0x52, 0xa1, 0x03, 0xb7, 0x22, - 0xdf, 0x74, 0x77, 0x53, 0x84, 0x38, 0xd2, 0x87, 0x62, 0x35, 0x1d, 0x2e, 0x61, 0x26, 0xe7, 0x26, - 0x95, 0x66, 0xa6, 0x7d, 0xd4, 0x4d, 0x35, 0x53, 0xe8, 0x46, 0x29, 0x98, 0x20, 0xc4, 0xdc, 0x26, - 0xef, 0xa7, 0x88, 0xc2, 0xb1, 0xe2, 0x5e, 0x7a, 0xac, 0x3f, 0x2b, 0x81, 0xe5, 0xb1, 0x4b, 0xd7, - 0xce, 0x15, 0x71, 0x7c, 0xa4, 0xf8, 0x30, 0x2d, 0xd2, 0x9f, 0xef, 0x25, 0xac, 0xc4, 0x5e, 0x94, - 0xd2, 0x04, 0xf2, 0xd6, 0xf9, 0xe8, 0x1a, 0x60, 0x7f, 0xe2, 0x1f, 0x00, 0x42, 0xb7, 0x09, 0x39, - 0x29, 0x44, 0x80, 0x11, 0xef, 0x5f, 0x8d, 0xf1, 0xa3, 0x3f, 0x87, 0x59, 0xef, 0xfc, 0x95, 0x92, - 0x86, 0x71, 0x80, 0x78, 0xef, 0x0a, 0x40, 0x58, 0x7b, 0x91, 0x13, 0xe6, 0xee, 0x15, 0x43, 0x39, - 0x2e, 0x59, 0x7b, 0xf1, 0x5d, 0xd1, 0xd9, 0xbc, 0xd1, 0x8e, 0x98, 0x98, 0x65, 0x04, 0x98, 0xbc, - 0x79, 0x13, 0x3a, 0x46, 0x5d, 0x79, 0x7b, 0x51, 0xc9, 0xbe, 0xbb, 0xa8, 0x64, 0xff, 0xbc, 0xa8, - 0x64, 0x5f, 0x5d, 0x56, 0x32, 0xef, 0x2e, 0x2b, 0x99, 0xdf, 0x2f, 0x2b, 0x99, 0xe3, 0x2f, 0x54, - 0xcd, 0xec, 0x9c, 0x9d, 0x54, 0x11, 0xed, 0xd5, 0x10, 0x35, 0x7a, 0xd4, 0xe0, 0x3f, 0x0f, 0x8c, - 0x76, 0xb7, 0x76, 0x5e, 0xf3, 0xff, 0xe8, 0x7a, 0xf8, 0xf8, 0x81, 0xf7, 0x5f, 0x97, 0x39, 0xec, - 0x63, 0xe3, 0xa4, 0xc8, 0xfe, 0xe7, 0x7a, 0xf4, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x07, - 0x48, 0xeb, 0x76, 0x13, 0x00, 0x00, + 0x10, 0xd6, 0x8f, 0x2d, 0xdb, 0x63, 0x37, 0xb6, 0x29, 0xff, 0x28, 0x94, 0x2d, 0xba, 0x3c, 0x24, + 0x42, 0x8a, 0x48, 0xb1, 0x63, 0xa0, 0x6d, 0xd0, 0x8b, 0x64, 0xa0, 0x68, 0x50, 0xb8, 0x29, 0x18, + 0xb7, 0x07, 0xa3, 0x80, 0x20, 0xaf, 0x36, 0x14, 0x21, 0x89, 0xab, 0x92, 0x94, 0x62, 0xbd, 0x41, + 0x8f, 0x39, 0xf7, 0x94, 0x9e, 0x7b, 0x48, 0x1f, 0x23, 0xc7, 0x9c, 0xda, 0xa2, 0x07, 0xa2, 0xb0, + 0x2f, 0x3d, 0xf3, 0x09, 0x0a, 0xee, 0x2e, 0x29, 0x4a, 0x22, 0x2b, 0x2a, 0xa9, 0x9c, 0x9c, 0xb4, + 0x9c, 0xf9, 0x76, 0x76, 0xf6, 0xfb, 0x86, 0xb3, 0x4b, 0xc1, 0x9e, 0x76, 0x81, 0xca, 0x88, 0x18, + 0xb8, 0x8c, 0x9a, 0x75, 0x5d, 0xc7, 0xed, 0x72, 0xff, 0xb0, 0x6c, 0x5d, 0x96, 0xba, 0x06, 0xb1, + 0x88, 0x90, 0xd5, 0x2e, 0x50, 0xc9, 0xf5, 0x96, 0xb8, 0xb7, 0xd4, 0x3f, 0x14, 0xb7, 0x54, 0xa2, + 0x12, 0xea, 0x2f, 0xbb, 0x23, 0x06, 0x15, 0xa5, 0x61, 0xa0, 0xb6, 0x86, 0x75, 0xcb, 0x8d, 0xc3, + 0x46, 0x1c, 0xf0, 0x71, 0xd8, 0x4a, 0x5e, 0x58, 0x0a, 0x91, 0x7f, 0x49, 0x82, 0x70, 0x6a, 0xaa, + 0x27, 0xcc, 0xf8, 0xa4, 0x8b, 0xf5, 0xc7, 0xba, 0x66, 0x09, 0x9f, 0xc0, 0x52, 0x97, 0x18, 0x56, + 0x4d, 0x6b, 0xe4, 0x92, 0x07, 0xc9, 0xe2, 0x4a, 0x55, 0x70, 0x6c, 0xe9, 0xd6, 0xa0, 0xde, 0x69, + 0x3f, 0x92, 0xb9, 0x43, 0x56, 0x32, 0xee, 0xe8, 0x71, 0x43, 0xf8, 0x02, 0x96, 0x78, 0xd0, 0x5c, + 0xea, 0x20, 0x59, 0x5c, 0x3d, 0xda, 0x2b, 0x85, 0x6c, 0xa2, 0xc4, 0xd7, 0xa8, 0x2e, 0xbc, 0xb6, + 0xa5, 0x84, 0xe2, 0x4d, 0x11, 0x76, 0x20, 0x63, 0x6a, 0xaa, 0x8e, 0x8d, 0x5c, 0xda, 0x5d, 0x49, + 0xe1, 0x4f, 0x8f, 0x96, 0x7f, 0x7a, 0x29, 0x25, 0xfe, 0x79, 0x29, 0x25, 0xe4, 0x3d, 0x10, 0x27, + 0x53, 0x54, 0xb0, 0xd9, 0x25, 0xba, 0x89, 0xe5, 0xdf, 0xd3, 0xb0, 0x39, 0xea, 0x3e, 0x33, 0x06, + 0xb3, 0x6d, 0xe0, 0x1b, 0xc8, 0x76, 0x0d, 0xdc, 0xd7, 0x48, 0xcf, 0xac, 0xf1, 0xb4, 0xdc, 0x89, + 0x29, 0x3a, 0xb1, 0xe0, 0xd8, 0x92, 0xc8, 0x27, 0x4e, 0x82, 0x64, 0x65, 0xd3, 0xb3, 0xf2, 0x0c, + 0x46, 0x09, 0x49, 0xcf, 0x4e, 0x88, 0x02, 0x5b, 0x88, 0xf4, 0x74, 0x0b, 0x1b, 0xdd, 0xba, 0x61, + 0x0d, 0x6a, 0x7d, 0x6c, 0x98, 0x1a, 0xd1, 0x73, 0x0b, 0x34, 0x1d, 0xc9, 0xb1, 0xa5, 0x3c, 0x4b, + 0x27, 0x0c, 0x25, 0x2b, 0xd9, 0xa0, 0xf9, 0x7b, 0x66, 0x15, 0x8e, 0x01, 0xba, 0x06, 0x21, 0xcf, + 0x6a, 0x9a, 0xae, 0x59, 0xb9, 0xc5, 0x83, 0x64, 0x71, 0xad, 0xba, 0xed, 0xd8, 0xd2, 0xa6, 0xb7, + 0x31, 0xcf, 0x27, 0x2b, 0x2b, 0xf4, 0x81, 0x56, 0xc1, 0x39, 0xac, 0x31, 0x4f, 0x13, 0x6b, 0x6a, + 0xd3, 0xca, 0x65, 0xe8, 0x66, 0xc4, 0xc0, 0x66, 0x58, 0xb5, 0xf5, 0x0f, 0x4b, 0x5f, 0x51, 0x44, + 0x35, 0xef, 0x6e, 0xc5, 0xb1, 0xa5, 0x6c, 0x30, 0x2e, 0x9b, 0x2d, 0x2b, 0xab, 0xf4, 0x91, 0x21, + 0x03, 0xb2, 0x2f, 0x45, 0xc8, 0x9e, 0x87, 0xdb, 0x13, 0xba, 0xfa, 0xaa, 0xff, 0x31, 0xa1, 0x7a, + 0x05, 0xb5, 0x66, 0x53, 0xfd, 0x18, 0x60, 0x42, 0xec, 0x00, 0x27, 0x41, 0x8d, 0x57, 0x90, 0xaf, + 0xed, 0x39, 0xec, 0x8e, 0xf0, 0x1e, 0x08, 0x41, 0xeb, 0xb7, 0x2a, 0x3b, 0xb6, 0x54, 0x08, 0x11, + 0x28, 0x18, 0x6f, 0x3b, 0xe8, 0x19, 0xd6, 0xcd, 0x3c, 0x94, 0x3f, 0x04, 0x26, 0x68, 0xcd, 0x32, + 0x06, 0x5c, 0xf8, 0x2d, 0xc7, 0x96, 0x36, 0x82, 0x02, 0x59, 0xc6, 0x40, 0x56, 0x96, 0xe9, 0xd8, + 0x7d, 0x77, 0x3e, 0x30, 0xd9, 0x2b, 0xa8, 0xe5, 0xcb, 0xfe, 0x6b, 0x0a, 0xb6, 0x47, 0xbd, 0x27, + 0x44, 0x7f, 0xa6, 0x19, 0x9d, 0x9b, 0x90, 0xde, 0xa7, 0xb2, 0x8e, 0x5a, 0x54, 0xec, 0x10, 0x2a, + 0xeb, 0xa8, 0xe5, 0x51, 0xe9, 0x16, 0xe4, 0x38, 0x95, 0x0b, 0x73, 0xa1, 0x72, 0x31, 0x82, 0x4a, + 0x09, 0xf6, 0x43, 0xc9, 0xf2, 0xe9, 0xfc, 0x39, 0x09, 0xd9, 0x21, 0xe2, 0xa4, 0x4d, 0x4c, 0x3c, + 0x7b, 0xfb, 0x7f, 0x3b, 0x32, 0xa7, 0xb7, 0xfd, 0x7d, 0xc8, 0x87, 0xe4, 0xe6, 0xe7, 0xfe, 0x2a, + 0x05, 0x3b, 0x63, 0xfe, 0x1b, 0xac, 0x85, 0xd1, 0x86, 0x9a, 0x7e, 0xcb, 0x86, 0x7a, 0xb3, 0xe5, + 0x70, 0x00, 0x85, 0x70, 0xc2, 0x7c, 0x4e, 0x5f, 0xa4, 0xe0, 0xa3, 0x53, 0x53, 0x55, 0x30, 0xea, + 0x7f, 0x5b, 0x47, 0x2d, 0x6c, 0x09, 0x9f, 0x43, 0xa6, 0x4b, 0x47, 0x94, 0xc9, 0xd5, 0xa3, 0x7c, + 0xe8, 0x49, 0xc6, 0xc0, 0xfc, 0x20, 0xe3, 0x13, 0x84, 0x2f, 0x61, 0x83, 0xa5, 0x8b, 0x48, 0xa7, + 0xa3, 0x59, 0x1d, 0xac, 0x5b, 0x94, 0xde, 0xb5, 0x6a, 0xde, 0xb1, 0xa5, 0xdd, 0xe0, 0x86, 0x86, + 0x08, 0x59, 0x59, 0xa7, 0xa6, 0x13, 0xdf, 0x32, 0x41, 0x5a, 0x7a, 0x2e, 0xa4, 0x2d, 0x44, 0x90, + 0xb6, 0x4b, 0x1b, 0xce, 0x90, 0x11, 0x9f, 0xab, 0xbf, 0x52, 0x00, 0xa7, 0xa6, 0x7a, 0xa6, 0x75, + 0x30, 0xe9, 0xfd, 0x3f, 0x44, 0xf5, 0x74, 0x03, 0x23, 0xac, 0xf5, 0x71, 0x23, 0x8a, 0xa8, 0x21, + 0xc2, 0x23, 0xea, 0x3b, 0xdf, 0x32, 0x57, 0xa2, 0xbe, 0x06, 0x41, 0xc7, 0x97, 0x56, 0xcd, 0xc4, + 0x3f, 0xf6, 0xb0, 0x8e, 0x70, 0xcd, 0xc0, 0xa8, 0x4f, 0x49, 0x5b, 0xa8, 0xee, 0x3b, 0xb6, 0x74, + 0x9b, 0x45, 0x98, 0xc4, 0xc8, 0xca, 0x86, 0x6b, 0x7c, 0xca, 0x6d, 0x2e, 0x91, 0x31, 0x4a, 0x75, + 0x8b, 0xde, 0x4a, 0x39, 0xb7, 0xc3, 0x76, 0xc5, 0x0e, 0x7d, 0x6e, 0x7e, 0xa2, 0xd3, 0x1a, 0xfe, + 0x10, 0x98, 0xff, 0x14, 0x56, 0x79, 0x21, 0xbb, 0x19, 0xf1, 0x76, 0xb0, 0xe3, 0xd8, 0x92, 0x30, + 0x52, 0xe5, 0xae, 0x53, 0x56, 0x58, 0xe3, 0x60, 0xb9, 0xcf, 0xb3, 0x21, 0x84, 0x4b, 0xb6, 0xf8, + 0xae, 0x92, 0x65, 0xfe, 0xf3, 0xdc, 0x1e, 0xd5, 0xc6, 0x57, 0xee, 0xb7, 0x14, 0x15, 0xb4, 0x82, + 0x5a, 0x3a, 0x79, 0xde, 0xc6, 0x0d, 0x15, 0xd3, 0x57, 0xfb, 0x1d, 0xa4, 0x2b, 0xc2, 0x7a, 0x7d, + 0x34, 0x1a, 0x53, 0x4e, 0x19, 0x37, 0x0f, 0xc5, 0x71, 0x27, 0x36, 0xa2, 0xc4, 0xa1, 0x4e, 0x4f, + 0x9c, 0x8a, 0xfb, 0xf0, 0x9e, 0xbb, 0x35, 0xfb, 0xea, 0x19, 0x63, 0xcc, 0x23, 0xf4, 0xe8, 0xd5, + 0x32, 0xa4, 0x4f, 0x4d, 0x55, 0x68, 0xc1, 0xfa, 0xf8, 0xb7, 0xdb, 0xdd, 0x50, 0x12, 0x27, 0xbf, + 0xa0, 0xc4, 0x72, 0x4c, 0xa0, 0xb7, 0xa8, 0xd0, 0x84, 0x5b, 0x63, 0x9f, 0x59, 0x77, 0x62, 0x84, + 0x38, 0x33, 0x06, 0x62, 0x29, 0x1e, 0x2e, 0x62, 0x25, 0xf7, 0x26, 0x15, 0x67, 0xa5, 0x0a, 0x6a, + 0xc5, 0x5a, 0x29, 0x70, 0xa3, 0x14, 0x2c, 0x10, 0x42, 0x6e, 0x93, 0xf7, 0x62, 0x44, 0xe1, 0x58, + 0xf1, 0x28, 0x3e, 0xd6, 0x5f, 0x55, 0x87, 0x8d, 0x89, 0x4b, 0x57, 0x71, 0x4a, 0x1c, 0x1f, 0x29, + 0x3e, 0x88, 0x8b, 0xf4, 0xd7, 0x7b, 0x0e, 0xd9, 0xd0, 0x8b, 0x52, 0x9c, 0x40, 0xde, 0x3e, 0x1f, + 0xce, 0x00, 0xf6, 0x17, 0xfe, 0x01, 0x20, 0x70, 0x9b, 0x90, 0xa3, 0x42, 0x0c, 0x31, 0xe2, 0xbd, + 0xe9, 0x18, 0x3f, 0xfa, 0x53, 0x58, 0xf2, 0xce, 0x5f, 0x29, 0x6a, 0x1a, 0x07, 0x88, 0x77, 0xa7, + 0x00, 0x82, 0xb5, 0x37, 0x76, 0xc2, 0xdc, 0x99, 0x32, 0x95, 0xe3, 0xa2, 0x6b, 0x2f, 0xbc, 0x2b, + 0xba, 0x2f, 0xef, 0x78, 0x47, 0x8c, 0xcc, 0x72, 0x0c, 0x18, 0xfd, 0xf2, 0x46, 0x74, 0x8c, 0xaa, + 0xf2, 0xfa, 0xaa, 0x90, 0x7c, 0x73, 0x55, 0x48, 0xfe, 0x7d, 0x55, 0x48, 0xbe, 0xb8, 0x2e, 0x24, + 0xde, 0x5c, 0x17, 0x12, 0x7f, 0x5e, 0x17, 0x12, 0xe7, 0x9f, 0xa9, 0x9a, 0xd5, 0xec, 0x5d, 0x94, + 0x10, 0xe9, 0x94, 0x11, 0x31, 0x3b, 0xc4, 0xe4, 0x3f, 0xf7, 0xcd, 0x46, 0xab, 0x7c, 0x59, 0xf6, + 0xff, 0x45, 0x7a, 0x70, 0x7c, 0xdf, 0xfb, 0x23, 0xc9, 0x1a, 0x74, 0xb1, 0x79, 0x91, 0xa1, 0x7f, + 0x22, 0x3d, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0x38, 0xe9, 0x16, 0xfa, 0xd3, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1378,7 +1375,7 @@ func (m *MsgChannelOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } { size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) @@ -1389,14 +1386,7 @@ func (m *MsgChannelOpenInit) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - if len(m.ChannelId) > 0 { - i -= len(m.ChannelId) - copy(dAtA[i:], m.ChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.ChannelId))) - i-- - dAtA[i] = 0x12 - } + dAtA[i] = 0x12 if len(m.PortId) > 0 { i -= len(m.PortId) copy(dAtA[i:], m.PortId) @@ -1455,7 +1445,7 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x42 + dAtA[i] = 0x3a } { size, err := m.ProofHeight.MarshalToSizedBuffer(dAtA[:i]) @@ -1466,20 +1456,20 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 if len(m.ProofInit) > 0 { i -= len(m.ProofInit) copy(dAtA[i:], m.ProofInit) i = encodeVarintTx(dAtA, i, uint64(len(m.ProofInit))) i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } if len(m.CounterpartyVersion) > 0 { i -= len(m.CounterpartyVersion) copy(dAtA[i:], m.CounterpartyVersion) i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyVersion))) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } { size, err := m.Channel.MarshalToSizedBuffer(dAtA[:i]) @@ -1490,18 +1480,11 @@ func (m *MsgChannelOpenTry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 - if len(m.CounterpartyChosenChannelId) > 0 { - i -= len(m.CounterpartyChosenChannelId) - copy(dAtA[i:], m.CounterpartyChosenChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.CounterpartyChosenChannelId))) - i-- - dAtA[i] = 0x1a - } - if len(m.DesiredChannelId) > 0 { - i -= len(m.DesiredChannelId) - copy(dAtA[i:], m.DesiredChannelId) - i = encodeVarintTx(dAtA, i, uint64(len(m.DesiredChannelId))) + dAtA[i] = 0x1a + if len(m.PreviousChannelId) > 0 { + i -= len(m.PreviousChannelId) + copy(dAtA[i:], m.PreviousChannelId) + i = encodeVarintTx(dAtA, i, uint64(len(m.PreviousChannelId))) i-- dAtA[i] = 0x12 } @@ -2236,10 +2219,6 @@ func (m *MsgChannelOpenInit) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.ChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } l = m.Channel.Size() n += 1 + l + sovTx(uint64(l)) l = len(m.Signer) @@ -2268,11 +2247,7 @@ func (m *MsgChannelOpenTry) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } - l = len(m.DesiredChannelId) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - l = len(m.CounterpartyChosenChannelId) + l = len(m.PreviousChannelId) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -2652,38 +2627,6 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { m.PortId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChannelId", 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.ChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) } @@ -2716,7 +2659,7 @@ func (m *MsgChannelOpenInit) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -2888,7 +2831,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DesiredChannelId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PreviousChannelId", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2916,41 +2859,9 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DesiredChannelId = string(dAtA[iNdEx:postIndex]) + m.PreviousChannelId = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyChosenChannelId", 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.CounterpartyChosenChannelId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) } @@ -2983,7 +2894,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CounterpartyVersion", wireType) } @@ -3015,7 +2926,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { } m.CounterpartyVersion = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofInit", wireType) } @@ -3049,7 +2960,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { m.ProofInit = []byte{} } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ProofHeight", wireType) } @@ -3082,7 +2993,7 @@ func (m *MsgChannelOpenTry) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } diff --git a/x/ibc/core/24-host/validate.go b/x/ibc/core/24-host/validate.go index d589223f58da..10458e8d3a71 100644 --- a/x/ibc/core/24-host/validate.go +++ b/x/ibc/core/24-host/validate.go @@ -70,10 +70,10 @@ func ConnectionIdentifierValidator(id string) error { } // ChannelIdentifierValidator is the default validator function for Channel identifiers. -// A valid Identifier must be between 10-64 characters and only contain alphanumeric and some allowed +// A valid Identifier must be between 8-64 characters and only contain alphanumeric and some allowed // special characters (see IsValidID). func ChannelIdentifierValidator(id string) error { - return defaultIdentifierValidator(id, 10, DefaultMaxCharacterLength) + return defaultIdentifierValidator(id, 8, DefaultMaxCharacterLength) } // PortIdentifierValidator is the default validator function for Port identifiers. diff --git a/x/ibc/core/genesis_test.go b/x/ibc/core/genesis_test.go index d435cf85667a..29a26aad7402 100644 --- a/x/ibc/core/genesis_test.go +++ b/x/ibc/core/genesis_test.go @@ -105,6 +105,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), ChannelGenesis: channeltypes.NewGenesisState( []channeltypes.IdentifiedChannel{ @@ -133,6 +134,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []channeltypes.PacketSequence{ channeltypes.NewPacketSequence(port2, channel2, 1), }, + 0, ), }, expPass: true, @@ -168,6 +170,7 @@ func (suite *IBCTestSuite) TestValidateGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), }, expPass: false, @@ -244,6 +247,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { []connectiontypes.ConnectionPaths{ connectiontypes.NewConnectionPaths(clientID, []string{connectionID}), }, + 0, ), ChannelGenesis: channeltypes.NewGenesisState( []channeltypes.IdentifiedChannel{ @@ -272,6 +276,7 @@ func (suite *IBCTestSuite) TestInitGenesis() { []channeltypes.PacketSequence{ channeltypes.NewPacketSequence(port2, channel2, 1), }, + 0, ), }, }, diff --git a/x/ibc/core/keeper/msg_server.go b/x/ibc/core/keeper/msg_server.go index 9ca0697e1f7b..2b655ff9a2fc 100644 --- a/x/ibc/core/keeper/msg_server.go +++ b/x/ibc/core/keeper/msg_server.go @@ -132,16 +132,15 @@ func (k Keeper) SubmitMisbehaviour(goCtx context.Context, msg *clienttypes.MsgSu func (k Keeper) ConnectionOpenInit(goCtx context.Context, msg *connectiontypes.MsgConnectionOpenInit) (*connectiontypes.MsgConnectionOpenInitResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if err := k.ConnectionKeeper.ConnOpenInit( - ctx, msg.ConnectionId, msg.ClientId, msg.Counterparty, msg.Version, - ); err != nil { + connectionID, err := k.ConnectionKeeper.ConnOpenInit(ctx, msg.ClientId, msg.Counterparty, msg.Version) + if err != nil { return nil, sdkerrors.Wrap(err, "connection handshake open init failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( connectiontypes.EventTypeConnectionOpenInit, - sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.ConnectionId), + sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, connectionID), sdk.NewAttribute(connectiontypes.AttributeKeyClientID, msg.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, msg.Counterparty.ConnectionId), @@ -164,18 +163,19 @@ func (k Keeper) ConnectionOpenTry(goCtx context.Context, msg *connectiontypes.Ms return nil, sdkerrors.Wrapf(err, "client in msg is not exported.ClientState. invalid client: %v.", targetClient) } - if err := k.ConnectionKeeper.ConnOpenTry( - ctx, msg.DesiredConnectionId, msg.CounterpartyChosenConnectionId, msg.Counterparty, msg.ClientId, targetClient, + connectionID, err := k.ConnectionKeeper.ConnOpenTry( + ctx, msg.PreviousConnectionId, msg.Counterparty, msg.ClientId, targetClient, connectiontypes.ProtoVersionsToExported(msg.CounterpartyVersions), msg.ProofInit, msg.ProofClient, msg.ProofConsensus, msg.ProofHeight, msg.ConsensusHeight, - ); err != nil { + ) + if err != nil { return nil, sdkerrors.Wrap(err, "connection handshake open try failed") } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( connectiontypes.EventTypeConnectionOpenTry, - sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, msg.DesiredConnectionId), + sdk.NewAttribute(connectiontypes.AttributeKeyConnectionID, connectionID), sdk.NewAttribute(connectiontypes.AttributeKeyClientID, msg.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyClientID, msg.Counterparty.ClientId), sdk.NewAttribute(connectiontypes.AttributeKeyCounterpartyConnectionID, msg.Counterparty.ConnectionId), @@ -263,7 +263,7 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } - _, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg) + _, channelID, cap, err := channel.HandleMsgChannelOpenInit(ctx, k.ChannelKeeper, portCap, msg) if err != nil { return nil, err } @@ -274,7 +274,7 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.ChannelId, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil { + if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil { return nil, sdkerrors.Wrap(err, "channel open init callback failed") } @@ -290,7 +290,7 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } - _, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg) + _, channelID, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg) if err != nil { return nil, err } @@ -301,7 +301,7 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - if err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, msg.DesiredChannelId, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion); err != nil { + if err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion); err != nil { return nil, sdkerrors.Wrap(err, "channel open try callback failed") } diff --git a/x/ibc/core/spec/01_concepts.md b/x/ibc/core/spec/01_concepts.md index 079e6fa7023e..4b002458eb7d 100644 --- a/x/ibc/core/spec/01_concepts.md +++ b/x/ibc/core/spec/01_concepts.md @@ -131,16 +131,18 @@ The IBC interfaces expect an `ibcexported.Height` interface, however all clients The connection handshake occurs in 4 steps as defined in [ICS 03](https://github.com/cosmos/ics/tree/master/spec/ics-003-connection-semantics). `ConnOpenInit` is the first attempt to initialize a connection on the executing chain. -The handshake is expected to succeed if the connection identifier selected is not used and the -version selected is supported. The connection identifier for the counterparty connection may -be left empty indicating that the counterparty may select its own identifier. The connection -is set and stored in the INIT state upon success. +The handshake is expected to succeed if the version selected is supported. The connection +identifier for the counterparty connection must be left empty indicating that the counterparty +must select its own identifier. The connection identifier is auto derived in the format: +`connection{N}` where N is the next sequence to be used. The counter begins at 0 and increments +by 1. The connection is set and stored in the INIT state upon success. `ConnOpenTry` is a response to a chain executing `ConnOpenInit`. The executing chain will validate -the chain level parameters the counterparty has stored such as its chainID and consensus parameters. -The executing chain will also verify that if a previous connection exists for the specified -connection identifier that all the parameters match and its previous state was in INIT. This -may occur when both chains execute `ConnOpenInit` simultaneously. The executing chain will verify +the chain level parameters the counterparty has stored such as its chainID. The executing chain +will also verify that if a previous connection exists for the specified connection identifier +that all the parameters match and its previous state was in INIT. This may occur when both +chains execute `ConnOpenInit` simultaneously. If the connection does not exist then a connection +identifier is generated in the same format done in `ConnOpenInit`. The executing chain will verify that the counterparty created a connection in INIT state. The executing chain will also verify The `ClientState` and `ConsensusState` the counterparty stores for the executing chain. The executing chain will select a version from the intersection of its supported versions and the @@ -208,23 +210,25 @@ versions should have a unique version identifier. The channel handshake occurs in 4 steps as defined in [ICS 04](https://github.com/cosmos/ics/tree/master/spec/ics-004-channel-and-packet-semantics). `ChanOpenInit` is the first attempt to initialize a channel on top of an existing connection. -The handshake is expected to succeed if the channel identifier selected is not used and the -version selected for the existing connection is a supported IBC version. The portID must correspond -to a port already binded upon `InitChain`. The channel identifier for the counterparty channel -may be left empty indicating that the counterparty may select its own identifier. The channel is -set and stored in the INIT state upon success. The channel parameters `NextSequenceSend`, -`NextSequenceRecv`, and `NextSequenceAck` are all set to 1 and a channel capability is created -for the given portID and channelID path. +The handshake is expected to succeed if the version selected for the existing connection is a +supported IBC version. The portID must correspond to a port already binded upon `InitChain`. +The channel identifier for the counterparty channel must be left empty indicating that the +counterparty must select its own identifier. The channel identifier is auto derived in the +format: `channel{N}` where N is the next sequence to be used. The channel is set and stored +in the INIT state upon success. The channel parameters `NextSequenceSend`, `NextSequenceRecv`, +and `NextSequenceAck` are all set to 1 and a channel capability is created for the given +portID and channelID path. `ChanOpenTry` is a response to a chain executing `ChanOpenInit`. If the executing chain is calling `ChanOpenTry` after previously executing `ChanOpenInit` then the provided channel parameters must -match the previously selected parameters. The connection the channel is created on top of must be -an OPEN state and its IBC version must support the desired channel type being created (ORDERED, -UNORDERED, etc). The executing chain will verify that the channel state of the counterparty is -in INIT. The executing chain will set and store the channel state in TRYOPEN. The channel -parameters `NextSequenceSend`, `NextSequenceRecv`, and `NextSequenceAck` are all set to 1 and -a channel capability is created for the given portID and channelID path only if the channel -did not previously exist. +match the previously selected parameters. If the previous channel does not exist then a channel +identifier is generated in the same format as done in `ChanOpenInit`. The connection the channel +is created on top of must be an OPEN state and its IBC version must support the desired channel +type being created (ORDERED, UNORDERED, etc). The executing chain will verify that the channel +state of the counterparty is in INIT. The executing chain will set and store the channel state +in TRYOPEN. The channel parameters `NextSequenceSend`, `NextSequenceRecv`, and `NextSequenceAck` +are all set to 1 and a channel capability is created for the given portID and channelID path only +if the channel did not previously exist. `ChanOpenAck` may be called on a chain when the counterparty channel has entered TRYOPEN. A previous channel on the executing chain must exist be in either INIT or TRYOPEN state. If the diff --git a/x/ibc/core/spec/06_events.md b/x/ibc/core/spec/06_events.md index 9f96b089b39a..528a30cffa41 100644 --- a/x/ibc/core/spec/06_events.md +++ b/x/ibc/core/spec/06_events.md @@ -66,7 +66,6 @@ callbacks to IBC applications. | connection_open_init | connection_id | {connectionId} | | connection_open_init | client_id | {clientId} | | connection_open_init | counterparty_client_id | {counterparty.clientId} | -| connection_open_init | counterparty_connection_id | {counterparty.connectionId} | | message | action | connection_open_init | | message | module | ibc_connection | @@ -112,7 +111,6 @@ callbacks to IBC applications. | channel_open_init | port_id | {portId} | | channel_open_init | channel_id | {channelId} | | channel_open_init | counterparty_port_id | {channel.counterparty.portId} | -| channel_open_init | counterparty_channel_id | {channel.counterparty.channelId} | | channel_open_init | connection_id | {channel.connectionHops} | | message | action | channel_open_init | | message | module | ibc_channel | diff --git a/x/ibc/testing/chain.go b/x/ibc/testing/chain.go index 0c285a275caf..0ac3c51579b0 100644 --- a/x/ibc/testing/chain.go +++ b/x/ibc/testing/chain.go @@ -388,7 +388,7 @@ func (chain *TestChain) AddTestConnection(clientID, counterpartyClientID string) // created given a clientID and counterparty clientID. The connection id // format: -conn func (chain *TestChain) ConstructNextTestConnection(clientID, counterpartyClientID string) *TestConnection { - connectionID := fmt.Sprintf("%s-%s%d", chain.ChainID, ConnectionIDPrefix, len(chain.Connections)) + connectionID := connectiontypes.FormatConnectionIdentifier(uint64(len(chain.Connections))) return &TestConnection{ ID: connectionID, ClientID: clientID, @@ -407,6 +407,34 @@ func (chain *TestChain) GetFirstTestConnection(clientID, counterpartyClientID st return chain.ConstructNextTestConnection(clientID, counterpartyClientID) } +// AddTestChannel appends a new TestChannel which contains references to the port and channel ID +// used for channel creation and interaction. See 'NextTestChannel' for channel ID naming format. +func (chain *TestChain) AddTestChannel(conn *TestConnection, portID string) TestChannel { + channel := chain.NextTestChannel(conn, portID) + conn.Channels = append(conn.Channels, channel) + return channel +} + +// NextTestChannel returns the next test channel to be created on this connection, but does not +// add it to the list of created channels. This function is expected to be used when the caller +// has not created the associated channel in app state, but would still like to refer to the +// non-existent channel usually to test for its non-existence. +// +// channel ID format: -chan +// +// The port is passed in by the caller. +func (chain *TestChain) NextTestChannel(conn *TestConnection, portID string) TestChannel { + nextChanSeq := chain.App.IBCKeeper.ChannelKeeper.GetNextChannelSequence(chain.GetContext()) + channelID := channeltypes.FormatChannelIdentifier(nextChanSeq) + return TestChannel{ + PortID: portID, + ID: channelID, + ClientID: conn.ClientID, + CounterpartyClientID: conn.CounterpartyClientID, + Version: conn.NextChannelVersion, + } +} + // ConstructMsgCreateClient constructs a message to create a new client state (tendermint or solomachine). // NOTE: a solo machine client will be created with an empty diversifier. func (chain *TestChain) ConstructMsgCreateClient(counterparty *TestChain, clientID string, clientType string) *clienttypes.MsgCreateClient { @@ -613,8 +641,8 @@ func (chain *TestChain) ConnectionOpenInit( connection, counterpartyConnection *TestConnection, ) error { msg := connectiontypes.NewMsgConnectionOpenInit( - connection.ID, connection.ClientID, - counterpartyConnection.ID, connection.CounterpartyClientID, + connection.ClientID, + connection.CounterpartyClientID, counterparty.GetPrefix(), DefaultOpenInitVersion, chain.SenderAccount.GetAddress(), ) @@ -634,7 +662,7 @@ func (chain *TestChain) ConnectionOpenTry( proofConsensus, consensusHeight := counterparty.QueryConsensusStateProof(counterpartyConnection.ClientID) msg := connectiontypes.NewMsgConnectionOpenTry( - connection.ID, connection.ID, connection.ClientID, // testing doesn't use flexible selection + "", connection.ClientID, // does not support handshake continuation counterpartyConnection.ID, counterpartyConnection.ClientID, counterpartyClient, counterparty.GetPrefix(), []*connectiontypes.Version{ConnectionVersion}, proofInit, proofClient, proofConsensus, @@ -756,9 +784,9 @@ func (chain *TestChain) ChanOpenInit( connectionID string, ) error { msg := channeltypes.NewMsgChannelOpenInit( - ch.PortID, ch.ID, + ch.PortID, ch.Version, order, []string{connectionID}, - counterparty.PortID, counterparty.ID, + counterparty.PortID, chain.SenderAccount.GetAddress(), ) return chain.sendMsgs(msg) @@ -774,10 +802,9 @@ func (chain *TestChain) ChanOpenTry( proof, height := counterparty.QueryProof(host.ChannelKey(counterpartyCh.PortID, counterpartyCh.ID)) msg := channeltypes.NewMsgChannelOpenTry( - ch.PortID, ch.ID, ch.ID, // testing doesn't use flexible selection + ch.PortID, "", // does not support handshake continuation ch.Version, order, []string{connectionID}, - counterpartyCh.PortID, counterpartyCh.ID, - counterpartyCh.Version, + counterpartyCh.PortID, counterpartyCh.ID, counterpartyCh.Version, proof, height, chain.SenderAccount.GetAddress(), ) diff --git a/x/ibc/testing/coordinator.go b/x/ibc/testing/coordinator.go index b1c6e99d3f03..aecdcd4b704b 100644 --- a/x/ibc/testing/coordinator.go +++ b/x/ibc/testing/coordinator.go @@ -394,6 +394,46 @@ func (coord *Coordinator) ConnOpenInit( return sourceConnection, counterpartyConnection, nil } +// ConnOpenInitOnBothChains initializes a connection on the source chain with the state INIT +// using the OpenInit handshake call. +func (coord *Coordinator) ConnOpenInitOnBothChains( + source, counterparty *TestChain, + clientID, counterpartyClientID string, +) (*TestConnection, *TestConnection, error) { + sourceConnection := source.AddTestConnection(clientID, counterpartyClientID) + counterpartyConnection := counterparty.AddTestConnection(counterpartyClientID, clientID) + + // initialize connection on source + if err := source.ConnectionOpenInit(counterparty, sourceConnection, counterpartyConnection); err != nil { + return sourceConnection, counterpartyConnection, err + } + coord.IncrementTime() + + // initialize connection on counterparty + if err := counterparty.ConnectionOpenInit(source, counterpartyConnection, sourceConnection); err != nil { + return sourceConnection, counterpartyConnection, err + } + coord.IncrementTime() + + // update counterparty client on source connection + if err := coord.UpdateClient( + source, counterparty, + clientID, exported.Tendermint, + ); err != nil { + return sourceConnection, counterpartyConnection, err + } + + // update source client on counterparty connection + if err := coord.UpdateClient( + counterparty, source, + counterpartyClientID, exported.Tendermint, + ); err != nil { + return sourceConnection, counterpartyConnection, err + } + + return sourceConnection, counterpartyConnection, nil +} + // ConnOpenTry initializes a connection on the source chain with the state TRYOPEN // using the OpenTry handshake call. func (coord *Coordinator) ConnOpenTry( @@ -461,8 +501,8 @@ func (coord *Coordinator) ChanOpenInit( sourcePortID, counterpartyPortID string, order channeltypes.Order, ) (TestChannel, TestChannel, error) { - sourceChannel := connection.AddTestChannel(sourcePortID) - counterpartyChannel := counterpartyConnection.AddTestChannel(counterpartyPortID) + sourceChannel := source.AddTestChannel(connection, sourcePortID) + counterpartyChannel := counterparty.AddTestChannel(counterpartyConnection, counterpartyPortID) // NOTE: only creation of a capability for a transfer or mock port is supported // Other applications must bind to the port in InitGenesis or modify this code. @@ -494,8 +534,8 @@ func (coord *Coordinator) ChanOpenInitOnBothChains( sourcePortID, counterpartyPortID string, order channeltypes.Order, ) (TestChannel, TestChannel, error) { - sourceChannel := connection.AddTestChannel(sourcePortID) - counterpartyChannel := counterpartyConnection.AddTestChannel(counterpartyPortID) + sourceChannel := source.AddTestChannel(connection, sourcePortID) + counterpartyChannel := counterparty.AddTestChannel(counterpartyConnection, counterpartyPortID) // NOTE: only creation of a capability for a transfer or mock port is supported // Other applications must bind to the port in InitGenesis or modify this code. diff --git a/x/ibc/testing/types.go b/x/ibc/testing/types.go index c71b0ebd9786..16cda6216b19 100644 --- a/x/ibc/testing/types.go +++ b/x/ibc/testing/types.go @@ -1,7 +1,7 @@ package ibctesting import ( - "fmt" + channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" ) // TestConnection is a testing helper struct to keep track of the connectionID, source clientID, @@ -15,33 +15,6 @@ type TestConnection struct { Channels []TestChannel } -// AddTestChannel appends a new TestChannel which contains references to the port and channel ID -// used for channel creation and interaction. See 'NextTestChannel' for channel ID naming format. -func (conn *TestConnection) AddTestChannel(portID string) TestChannel { - channel := conn.NextTestChannel(portID) - conn.Channels = append(conn.Channels, channel) - return channel -} - -// NextTestChannel returns the next test channel to be created on this connection, but does not -// add it to the list of created channels. This function is expected to be used when the caller -// has not created the associated channel in app state, but would still like to refer to the -// non-existent channel usually to test for its non-existence. -// -// channel ID format: -chan -// -// The port is passed in by the caller. -func (conn *TestConnection) NextTestChannel(portID string) TestChannel { - channelID := fmt.Sprintf("%s-%s%d", conn.ID, ChannelIDPrefix, len(conn.Channels)) - return TestChannel{ - PortID: portID, - ID: channelID, - ClientID: conn.ClientID, - CounterpartyClientID: conn.CounterpartyClientID, - Version: conn.NextChannelVersion, - } -} - // FirstOrNextTestChannel returns the first test channel if it exists, otherwise it // returns the next test channel to be created. This function is expected to be used // when the caller does not know if the channel has or has not been created in app @@ -50,7 +23,13 @@ func (conn *TestConnection) FirstOrNextTestChannel(portID string) TestChannel { if len(conn.Channels) > 0 { return conn.Channels[0] } - return conn.NextTestChannel(portID) + return TestChannel{ + PortID: portID, + ID: channeltypes.FormatChannelIdentifier(0), + ClientID: conn.ClientID, + CounterpartyClientID: conn.CounterpartyClientID, + Version: conn.NextChannelVersion, + } } // TestChannel is a testing helper struct to keep track of the portID and channelID