Deterministic connection and channel identifiers (#7993)

* add generate identifier functions for connection and channel

* update proto types and begin open init changes

remove unnecessary field from open init msgs. Update connectionopeninit handshake, begin updating channel handshake

* finish connection handshake chanes and some channel handshake changes

Finish updating connection handshake changes, update genesis for connection and channel, some channel handshake changes, fix build for tests but still failing

* finish channel handshake changes

* fix more tests

* fix connection handshake tests

* fix more tests

* fix build

* changes from self review

* address @fedekunze review suggestions

* update spec

* fix build

* fix tests

* Update x/ibc/testing/chain.go

Co-authored-by: Aditya <adityasripal@gmail.com>

* Update x/ibc/core/03-connection/types/msgs.go

Co-authored-by: Aditya <adityasripal@gmail.com>

* address @AdityaSripal comments

* reflect spec changes

* address @AdityaSripal review suggestions

* nit

* add connection/channel identifier parsing and validation as per @AdityaSripal suggestion, cc @fedekunze

* Fix auth rest test

Change dummy channel id to a valid channel id given the updated stricter channel identifier checks cc @amaurymartiny

Co-authored-by: Aditya <adityasripal@gmail.com>
This commit is contained in:
colin axnér 2020-11-24 16:28:20 +01:00 committed by GitHub
parent ccd0d63f80
commit 88e03e4f40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 1153 additions and 1097 deletions

View File

@ -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

View File

@ -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;

View File

@ -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\""];
}

View File

@ -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.

View File

@ -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

View File

@ -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\""];

View File

@ -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()),

View File

@ -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(),

View File

@ -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)

View File

@ -19,7 +19,7 @@ const (
validChannel = "testchannel"
invalidChannel = "(invalidchannel1)"
invalidShortChannel = "invalidch"
invalidShortChannel = "invalid"
invalidLongChannel = "invalidlongchannelinvalidlongchannelinvalidlongchannelinvalidlongchannel"
)

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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)
previousConnectionID = connB.ID
}, 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},
{"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,
)

View File

@ -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.

View File

@ -13,7 +13,7 @@ import (
var (
chainID = "gaiamainnet"
connectionID = "connectionidone"
connectionID = "connection-0"
clientID = "clientidone"
connectionID2 = "connectionidtwo"
clientID2 = "clientidtwo"

View File

@ -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,
}
}

View File

@ -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:])

View File

@ -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,
},

View File

@ -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
}

View File

@ -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)
}
}
}

View File

@ -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")

View File

@ -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 {

View File

@ -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)
}

View File

@ -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(),
)

View File

@ -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.

View File

@ -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

View File

@ -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])

View File

@ -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)
_, channelB, err := suite.coordinator.ChanOpenInitOnBothChains(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)
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")

View File

@ -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)

View File

@ -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(

View File

@ -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(

View File

@ -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,
}
}

View File

@ -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:])

View File

@ -66,6 +66,7 @@ func TestValidateGenesis(t *testing.T) {
[]types.PacketSequence{
types.NewPacketSequence(testPort2, testChannel2, 1),
},
0,
),
expPass: true,
},

View File

@ -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
}

View File

@ -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)
}
}
}

View File

@ -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")

View File

@ -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 {

View File

@ -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)
}

View File

@ -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.

View File

@ -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,
),
},
},

View File

@ -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")
}

View File

@ -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

View File

@ -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 |

View File

@ -388,7 +388,7 @@ func (chain *TestChain) AddTestConnection(clientID, counterpartyClientID string)
// created given a clientID and counterparty clientID. The connection id
// format: <chainID>-conn<index>
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: <connectionid>-chan<channel-index>
//
// 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(),
)

View File

@ -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.

View File

@ -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: <connectionid>-chan<channel-index>
//
// 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