From 5b0bc507ef35fcd1ca82feb636a6dbd31426c6d2 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Thu, 21 Apr 2022 16:27:56 +0200
Subject: [PATCH 01/18] refactor: returning version from OnChanOpenInit

---
 .../controller/ibc_module.go                       |  6 +++---
 .../apps/27-interchain-accounts/host/ibc_module.go |  4 ++--
 modules/apps/29-fee/ibc_module.go                  | 10 ++++++++--
 modules/apps/transfer/ibc_module.go                | 14 +++++++++-----
 modules/core/05-port/types/module.go               |  2 +-
 modules/core/keeper/msg_server.go                  |  5 +++--
 testing/mock/ibc_app.go                            |  2 +-
 testing/mock/ibc_module.go                         |  7 +++----
 8 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/modules/apps/27-interchain-accounts/controller/ibc_module.go b/modules/apps/27-interchain-accounts/controller/ibc_module.go
index 325ec70959b..e701798c3be 100644
--- a/modules/apps/27-interchain-accounts/controller/ibc_module.go
+++ b/modules/apps/27-interchain-accounts/controller/ibc_module.go
@@ -42,13 +42,13 @@ func (im IBCModule) OnChanOpenInit(
 	chanCap *capabilitytypes.Capability,
 	counterparty channeltypes.Counterparty,
 	version string,
-) error {
+) (string, error) {
 	if !im.keeper.IsControllerEnabled(ctx) {
-		return types.ErrControllerSubModuleDisabled
+		return "", types.ErrControllerSubModuleDisabled
 	}
 
 	if err := im.keeper.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version); err != nil {
-		return err
+		return "", err
 	}
 
 	// call underlying app's OnChanOpenInit callback with the appVersion
diff --git a/modules/apps/27-interchain-accounts/host/ibc_module.go b/modules/apps/27-interchain-accounts/host/ibc_module.go
index fb403c71937..1598801601f 100644
--- a/modules/apps/27-interchain-accounts/host/ibc_module.go
+++ b/modules/apps/27-interchain-accounts/host/ibc_module.go
@@ -34,8 +34,8 @@ func (im IBCModule) OnChanOpenInit(
 	chanCap *capabilitytypes.Capability,
 	counterparty channeltypes.Counterparty,
 	version string,
-) error {
-	return sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain")
+) (string, error) {
+	return "", sdkerrors.Wrap(icatypes.ErrInvalidChannelFlow, "channel handshake must be initiated by controller chain")
 }
 
 // OnChanOpenTry implements the IBCModule interface
diff --git a/modules/apps/29-fee/ibc_module.go b/modules/apps/29-fee/ibc_module.go
index 6ed9faa1f34..b8971408eed 100644
--- a/modules/apps/29-fee/ibc_module.go
+++ b/modules/apps/29-fee/ibc_module.go
@@ -36,7 +36,7 @@ func (im IBCModule) OnChanOpenInit(
 	chanCap *capabilitytypes.Capability,
 	counterparty channeltypes.Counterparty,
 	version string,
-) error {
+) (string, error) {
 	var versionMetadata types.Metadata
 	if err := types.ModuleCdc.UnmarshalJSON([]byte(version), &versionMetadata); err != nil {
 		// Since it is valid for fee version to not be specified, the above middleware version may be for a middleware
@@ -46,8 +46,14 @@ func (im IBCModule) OnChanOpenInit(
 			chanCap, counterparty, version)
 	}
 
+	if versionMetadata.FeeVersion == "" {
+		// call underlying app's OnChanOpenInit callback with the appVersion
+		return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID,
+			chanCap, counterparty, versionMetadata.AppVersion)
+	}
+
 	if versionMetadata.FeeVersion != types.Version {
-		return sdkerrors.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion)
+		return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion)
 	}
 
 	im.keeper.SetFeeEnabled(ctx, portID, channelID)
diff --git a/modules/apps/transfer/ibc_module.go b/modules/apps/transfer/ibc_module.go
index f5ed807d8b2..653b0e38d36 100644
--- a/modules/apps/transfer/ibc_module.go
+++ b/modules/apps/transfer/ibc_module.go
@@ -70,21 +70,25 @@ func (im IBCModule) OnChanOpenInit(
 	chanCap *capabilitytypes.Capability,
 	counterparty channeltypes.Counterparty,
 	version string,
-) error {
+) (string, error) {
 	if err := ValidateTransferChannelParams(ctx, im.keeper, order, portID, channelID); err != nil {
-		return err
+		return "", err
+	}
+
+	if version == "" {
+		version = types.Version
 	}
 
 	if version != types.Version {
-		return sdkerrors.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version)
+		return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "got %s, expected %s", version, types.Version)
 	}
 
 	// Claim channel capability passed back by IBC module
 	if err := im.keeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil {
-		return err
+		return "", err
 	}
 
-	return nil
+	return version, nil
 }
 
 // OnChanOpenTry implements the IBCModule interface.
diff --git a/modules/core/05-port/types/module.go b/modules/core/05-port/types/module.go
index e6ba8f3449b..b73ffca239b 100644
--- a/modules/core/05-port/types/module.go
+++ b/modules/core/05-port/types/module.go
@@ -24,7 +24,7 @@ type IBCModule interface {
 		channelCap *capabilitytypes.Capability,
 		counterparty channeltypes.Counterparty,
 		version string,
-	) error
+	) (string, error)
 
 	// OnChanOpenTry will verify the relayer-chosen parameters along with the
 	// counterparty-chosen version string and perform custom TRY logic.
diff --git a/modules/core/keeper/msg_server.go b/modules/core/keeper/msg_server.go
index be18391c698..e03f9975b97 100644
--- a/modules/core/keeper/msg_server.go
+++ b/modules/core/keeper/msg_server.go
@@ -185,12 +185,13 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan
 	}
 
 	// Perform application logic callback
-	if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil {
+	version, err := cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortId, channelID, cap, msg.Channel.Counterparty, msg.Channel.Version)
+	if err != nil {
 		return nil, sdkerrors.Wrap(err, "channel open init callback failed")
 	}
 
 	// Write channel into state
-	k.ChannelKeeper.WriteOpenInitChannel(ctx, msg.PortId, channelID, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.Channel.Counterparty, msg.Channel.Version)
+	k.ChannelKeeper.WriteOpenInitChannel(ctx, msg.PortId, channelID, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.Channel.Counterparty, version)
 
 	return &channeltypes.MsgChannelOpenInitResponse{
 		ChannelId: channelID,
diff --git a/testing/mock/ibc_app.go b/testing/mock/ibc_app.go
index 77eb17b8c6f..0504c2df0de 100644
--- a/testing/mock/ibc_app.go
+++ b/testing/mock/ibc_app.go
@@ -23,7 +23,7 @@ type MockIBCApp struct {
 		channelCap *capabilitytypes.Capability,
 		counterparty channeltypes.Counterparty,
 		version string,
-	) error
+	) (string, error)
 
 	OnChanOpenTry func(
 		ctx sdk.Context,
diff --git a/testing/mock/ibc_module.go b/testing/mock/ibc_module.go
index e58f6ae7156..4c492872da0 100644
--- a/testing/mock/ibc_module.go
+++ b/testing/mock/ibc_module.go
@@ -32,18 +32,17 @@ func NewIBCModule(appModule *AppModule, app *MockIBCApp) IBCModule {
 func (im IBCModule) OnChanOpenInit(
 	ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string,
 	channelID string, chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string,
-) error {
+) (string, error) {
 	if im.IBCApp.OnChanOpenInit != nil {
 		return im.IBCApp.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version)
-
 	}
 
 	// Claim channel capability passed back by IBC module
 	if err := im.IBCApp.ScopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil {
-		return err
+		return "", err
 	}
 
-	return nil
+	return version, nil
 }
 
 // OnChanOpenTry implements the IBCModule interface.

From b7088f838cd30ecf727e026a7475108e35a9f83b Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Thu, 21 Apr 2022 16:43:07 +0200
Subject: [PATCH 02/18] refactor: update tests and add version to proto resp

---
 docs/ibc/proto-docs.md                        |   6 +
 .../controller/ibc_module_test.go             |   6 +-
 modules/apps/29-fee/ibc_module_test.go        |   8 +-
 modules/apps/transfer/ibc_module_test.go      |   2 +-
 modules/core/04-channel/types/tx.pb.go        | 265 ++++++++++++------
 proto/ibc/core/channel/v1/tx.proto            |   5 +-
 6 files changed, 202 insertions(+), 90 deletions(-)

diff --git a/docs/ibc/proto-docs.md b/docs/ibc/proto-docs.md
index 267feaeb581..5b93c9b8660 100644
--- a/docs/ibc/proto-docs.md
+++ b/docs/ibc/proto-docs.md
@@ -2809,6 +2809,7 @@ MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type.
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
 | `channel_id` | [string](#string) |  |  |
+| `version` | [string](#string) |  |  |
 
 
 
@@ -2844,6 +2845,11 @@ value will be ignored by core IBC.
 MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type.
 
 
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `version` | [string](#string) |  |  |
+
+
 
 
 
diff --git a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
index 608996515c1..e91c45726d7 100644
--- a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
+++ b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
@@ -147,8 +147,8 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() {
 				suite.chainA.GetSimApp().ICAAuthModule.IBCApp.OnChanOpenInit = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string,
 					portID, channelID string, chanCap *capabilitytypes.Capability,
 					counterparty channeltypes.Counterparty, version string,
-				) error {
-					return fmt.Errorf("mock ica auth fails")
+				) (string, error) {
+					return "", fmt.Errorf("mock ica auth fails")
 				}
 			}, false,
 		},
@@ -197,7 +197,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() {
 			cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module)
 			suite.Require().True(ok)
 
-			err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
+			_, err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
 				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.GetVersion(),
 			)
 
diff --git a/modules/apps/29-fee/ibc_module_test.go b/modules/apps/29-fee/ibc_module_test.go
index 3f5cf64635a..559692e16b6 100644
--- a/modules/apps/29-fee/ibc_module_test.go
+++ b/modules/apps/29-fee/ibc_module_test.go
@@ -68,11 +68,11 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() {
 			suite.chainA.GetSimApp().FeeMockModule.IBCApp.OnChanOpenInit = func(ctx sdk.Context, order channeltypes.Order, connectionHops []string,
 				portID, channelID string, chanCap *capabilitytypes.Capability,
 				counterparty channeltypes.Counterparty, version string,
-			) error {
+			) (string, error) {
 				if version != ibcmock.Version {
-					return fmt.Errorf("incorrect mock version")
+					return "", fmt.Errorf("incorrect mock version")
 				}
-				return nil
+				return ibcmock.Version, nil
 			}
 
 			suite.path.EndpointA.ChannelID = ibctesting.FirstChannelID
@@ -95,7 +95,7 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() {
 			cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module)
 			suite.Require().True(ok)
 
-			err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
+			_, err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
 				suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, chanCap, counterparty, channel.Version)
 
 			if tc.expPass {
diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go
index 3dcb5518cbb..5b68a3be1d4 100644
--- a/modules/apps/transfer/ibc_module_test.go
+++ b/modules/apps/transfer/ibc_module_test.go
@@ -85,7 +85,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() {
 
 			tc.malleate() // explicitly change fields in channel and testChannel
 
-			err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
+			_, err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
 				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, counterparty, channel.GetVersion(),
 			)
 
diff --git a/modules/core/04-channel/types/tx.pb.go b/modules/core/04-channel/types/tx.pb.go
index 8f9ebe6ec63..fe6f344384d 100644
--- a/modules/core/04-channel/types/tx.pb.go
+++ b/modules/core/04-channel/types/tx.pb.go
@@ -105,6 +105,7 @@ var xxx_messageInfo_MsgChannelOpenInit proto.InternalMessageInfo
 // MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type.
 type MsgChannelOpenInitResponse struct {
 	ChannelId string `protobuf:"bytes,1,opt,name=channel_id,json=channelId,proto3" json:"channel_id,omitempty" yaml:"channel_id"`
+	Version   string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
 }
 
 func (m *MsgChannelOpenInitResponse) Reset()         { *m = MsgChannelOpenInitResponse{} }
@@ -147,6 +148,13 @@ func (m *MsgChannelOpenInitResponse) GetChannelId() string {
 	return ""
 }
 
+func (m *MsgChannelOpenInitResponse) GetVersion() string {
+	if m != nil {
+		return m.Version
+	}
+	return ""
+}
+
 // MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel
 // on Chain B. The version field within the Channel field has been deprecated. Its
 // value will be ignored by core IBC.
@@ -198,6 +206,7 @@ var xxx_messageInfo_MsgChannelOpenTry proto.InternalMessageInfo
 
 // MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type.
 type MsgChannelOpenTryResponse struct {
+	Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
 }
 
 func (m *MsgChannelOpenTryResponse) Reset()         { *m = MsgChannelOpenTryResponse{} }
@@ -233,6 +242,13 @@ func (m *MsgChannelOpenTryResponse) XXX_DiscardUnknown() {
 
 var xxx_messageInfo_MsgChannelOpenTryResponse proto.InternalMessageInfo
 
+func (m *MsgChannelOpenTryResponse) GetVersion() string {
+	if m != nil {
+		return m.Version
+	}
+	return ""
+}
+
 // MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge
 // the change of channel state to TRYOPEN on Chain B.
 type MsgChannelOpenAck struct {
@@ -902,87 +918,88 @@ func init() {
 func init() { proto.RegisterFile("ibc/core/channel/v1/tx.proto", fileDescriptor_bc4637e0ac3fc7b7) }
 
 var fileDescriptor_bc4637e0ac3fc7b7 = []byte{
-	// 1275 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6e, 0xdb, 0x46,
-	0x10, 0xd6, 0x5f, 0x64, 0x67, 0xe4, 0xda, 0x32, 0x65, 0x3b, 0x32, 0x65, 0x8b, 0x2a, 0x0f, 0xb1,
-	0xe1, 0xc2, 0x52, 0x6c, 0xa7, 0x28, 0x62, 0x14, 0x28, 0x2c, 0x55, 0x41, 0x8d, 0xd6, 0x3f, 0xa0,
-	0xe4, 0x02, 0x75, 0x8b, 0x0a, 0x12, 0xb5, 0x91, 0x09, 0x49, 0x5c, 0x95, 0xa4, 0x94, 0xe8, 0x0d,
-	0x02, 0x9f, 0x72, 0x0e, 0x60, 0x20, 0x45, 0x4f, 0x45, 0x0f, 0xe9, 0x63, 0xe4, 0x98, 0x53, 0x5b,
-	0xf4, 0x20, 0x14, 0xf6, 0xa5, 0x67, 0x3d, 0x41, 0xc1, 0xe5, 0x92, 0xa2, 0x24, 0x12, 0xa6, 0x13,
-	0xdb, 0xcd, 0x6d, 0x77, 0xe6, 0xdb, 0xd9, 0xd9, 0xef, 0x1b, 0xee, 0x0f, 0x61, 0x49, 0xaa, 0x88,
-	0x19, 0x11, 0x2b, 0x28, 0x23, 0x9e, 0x94, 0x65, 0x19, 0x35, 0x32, 0x9d, 0x8d, 0x8c, 0xf6, 0x2c,
-	0xdd, 0x52, 0xb0, 0x86, 0x99, 0x98, 0x54, 0x11, 0xd3, 0xba, 0x37, 0x4d, 0xbd, 0xe9, 0xce, 0x06,
-	0x3b, 0x57, 0xc3, 0x35, 0x4c, 0xfc, 0x19, 0xbd, 0x65, 0x40, 0x59, 0x6e, 0x10, 0xa8, 0x21, 0x21,
-	0x59, 0xd3, 0xe3, 0x18, 0x2d, 0x0a, 0xf8, 0xd8, 0x69, 0x26, 0x33, 0x2c, 0x81, 0xf0, 0x3f, 0xfb,
-	0x81, 0xd9, 0x53, 0x6b, 0x39, 0xc3, 0x78, 0xd0, 0x42, 0xf2, 0xae, 0x2c, 0x69, 0xcc, 0x27, 0x30,
-	0xd1, 0xc2, 0x8a, 0x56, 0x92, 0xaa, 0x71, 0x7f, 0xca, 0xbf, 0x7a, 0x37, 0xcb, 0xf4, 0x7b, 0xdc,
-	0x74, 0xb7, 0xdc, 0x6c, 0x6c, 0xf3, 0xd4, 0xc1, 0x0b, 0x61, 0xbd, 0xb5, 0x5b, 0x65, 0x3e, 0x87,
-	0x09, 0x1a, 0x34, 0x1e, 0x48, 0xf9, 0x57, 0x23, 0x9b, 0x4b, 0x69, 0x87, 0x45, 0xa4, 0xe9, 0x1c,
-	0xd9, 0xd0, 0x9b, 0x1e, 0xe7, 0x13, 0xcc, 0x21, 0xcc, 0x02, 0x84, 0x55, 0xa9, 0x26, 0x23, 0x25,
-	0x1e, 0xd4, 0x67, 0x12, 0x68, 0x6f, 0x7b, 0xf2, 0xf9, 0x2b, 0xce, 0xf7, 0xef, 0x2b, 0xce, 0xc7,
-	0x0b, 0xc0, 0x8e, 0xa7, 0x28, 0x20, 0xb5, 0x85, 0x65, 0x15, 0x31, 0x0f, 0x01, 0x68, 0xa8, 0x41,
-	0xb6, 0xf3, 0xfd, 0x1e, 0x37, 0x6b, 0x64, 0x3b, 0xf0, 0xf1, 0xc2, 0x5d, 0xda, 0xd9, 0xad, 0xf2,
-	0x7f, 0x04, 0x61, 0x76, 0x38, 0x68, 0x51, 0xe9, 0x5e, 0x6d, 0xd9, 0xfb, 0x10, 0x6b, 0x29, 0xa8,
-	0x23, 0xe1, 0xb6, 0x5a, 0xb2, 0x65, 0x10, 0x20, 0x03, 0x93, 0xfd, 0x1e, 0xc7, 0xd2, 0x81, 0xe3,
-	0x20, 0x5e, 0x98, 0x35, 0xad, 0x39, 0x33, 0x25, 0x3b, 0x8d, 0xc1, 0xab, 0xd3, 0x28, 0xc0, 0x9c,
-	0x88, 0xdb, 0xb2, 0x86, 0x94, 0x56, 0x59, 0xd1, 0xba, 0xa5, 0x0e, 0x52, 0x54, 0x09, 0xcb, 0xf1,
-	0x10, 0x49, 0x87, 0xeb, 0xf7, 0xb8, 0x04, 0x25, 0xc4, 0x01, 0xc5, 0x0b, 0x31, 0xbb, 0xf9, 0x5b,
-	0xc3, 0xaa, 0x53, 0xdb, 0x52, 0x30, 0x7e, 0x52, 0x92, 0x64, 0x49, 0x8b, 0xdf, 0x49, 0xf9, 0x57,
-	0xa7, 0xec, 0xd4, 0x0e, 0x7c, 0xbc, 0x70, 0x97, 0x74, 0x48, 0xed, 0x1c, 0xc3, 0x94, 0xe1, 0x39,
-	0x41, 0x52, 0xed, 0x44, 0x8b, 0x87, 0xc9, 0x62, 0x58, 0xdb, 0x62, 0x8c, 0x1a, 0xed, 0x6c, 0xa4,
-	0xbf, 0x22, 0x88, 0x6c, 0x42, 0x5f, 0x4a, 0xbf, 0xc7, 0xc5, 0xec, 0x71, 0x8d, 0xd1, 0xbc, 0x10,
-	0x21, 0x5d, 0x03, 0x69, 0x2b, 0x96, 0x09, 0x97, 0x62, 0x49, 0xc0, 0xe2, 0x98, 0xae, 0x66, 0xad,
-	0xf0, 0x7f, 0x8e, 0xa9, 0xbe, 0x23, 0xd6, 0xaf, 0xa6, 0xfa, 0x70, 0xb9, 0x05, 0xbc, 0x95, 0x1b,
-	0x73, 0x0c, 0xf7, 0x86, 0x78, 0xb7, 0x85, 0x20, 0x55, 0x9f, 0xe5, 0xfb, 0x3d, 0x2e, 0xe9, 0x20,
-	0x90, 0x3d, 0xde, 0xbc, 0xdd, 0x33, 0xa8, 0x9b, 0x9b, 0x50, 0x7e, 0x03, 0x0c, 0x41, 0x4b, 0x9a,
-	0xd2, 0xa5, 0xc2, 0xcf, 0xf5, 0x7b, 0x5c, 0xd4, 0x2e, 0x90, 0xa6, 0x74, 0x79, 0x61, 0x92, 0xb4,
-	0xf5, 0x6f, 0xe7, 0x03, 0x93, 0x7d, 0x47, 0xac, 0x5b, 0xb2, 0xff, 0x16, 0x80, 0xf9, 0x61, 0x6f,
-	0x0e, 0xcb, 0x4f, 0x24, 0xa5, 0x79, 0x1b, 0xd2, 0x5b, 0x54, 0x96, 0xc5, 0x3a, 0x11, 0xdb, 0x81,
-	0xca, 0xb2, 0x58, 0x37, 0xa9, 0xd4, 0x0b, 0x72, 0x94, 0xca, 0xd0, 0x8d, 0x50, 0x79, 0xc7, 0x85,
-	0x4a, 0x0e, 0x96, 0x1d, 0xc9, 0xb2, 0xe8, 0x7c, 0xe9, 0x87, 0xd8, 0x00, 0x91, 0x6b, 0x60, 0x15,
-	0x5d, 0xfd, 0xd0, 0x78, 0x37, 0x32, 0x2f, 0x3f, 0x2c, 0x96, 0x21, 0xe1, 0x90, 0x9b, 0x95, 0xfb,
-	0xeb, 0x00, 0x2c, 0x8c, 0xf8, 0x6f, 0xb1, 0x16, 0x86, 0x37, 0xd4, 0xe0, 0x3b, 0x6e, 0xa8, 0xb7,
-	0x5b, 0x0e, 0x29, 0x48, 0x3a, 0x13, 0x66, 0x71, 0xfa, 0x22, 0x00, 0x1f, 0xed, 0xa9, 0x35, 0x01,
-	0x89, 0x9d, 0xc3, 0xb2, 0x58, 0x47, 0x1a, 0xf3, 0x08, 0xc2, 0x2d, 0xd2, 0x22, 0x4c, 0x46, 0x36,
-	0x13, 0x8e, 0x27, 0x99, 0x01, 0xa6, 0x07, 0x19, 0x1d, 0xc0, 0x3c, 0x86, 0xa8, 0x91, 0xae, 0x88,
-	0x9b, 0x4d, 0x49, 0x6b, 0x22, 0x59, 0x23, 0xf4, 0x4e, 0x65, 0x13, 0xfd, 0x1e, 0x77, 0xcf, 0xbe,
-	0xa0, 0x01, 0x82, 0x17, 0x66, 0x88, 0x29, 0x67, 0x59, 0xc6, 0x48, 0x0b, 0xde, 0x08, 0x69, 0x21,
-	0x17, 0xd2, 0x7e, 0x24, 0x1b, 0xce, 0x80, 0x11, 0xeb, 0xb6, 0xf2, 0x05, 0x84, 0x15, 0xa4, 0xb6,
-	0x1b, 0x06, 0x33, 0xd3, 0x9b, 0x2b, 0x8e, 0xcc, 0x98, 0x70, 0x81, 0x40, 0x8b, 0xdd, 0x16, 0x12,
-	0xe8, 0xb0, 0xed, 0x90, 0x3e, 0x07, 0xff, 0x77, 0x00, 0x60, 0x4f, 0xad, 0x15, 0xa5, 0x26, 0xc2,
-	0xed, 0xeb, 0xe1, 0xbb, 0x2d, 0x2b, 0x48, 0x44, 0x52, 0x07, 0x55, 0xdd, 0xf8, 0x1e, 0x20, 0x4c,
-	0xbe, 0x8f, 0x2c, 0xcb, 0x8d, 0xf2, 0xfd, 0x35, 0x30, 0x32, 0x7a, 0xa6, 0x95, 0x54, 0xf4, 0x53,
-	0x1b, 0xc9, 0x22, 0x2a, 0x29, 0x48, 0xec, 0x10, 0xee, 0x43, 0xd9, 0xe5, 0x7e, 0x8f, 0x5b, 0x34,
-	0x22, 0x8c, 0x63, 0x78, 0x21, 0xaa, 0x1b, 0x0b, 0xd4, 0xa6, 0xeb, 0xe1, 0xa1, 0xe2, 0xbf, 0x27,
-	0x57, 0x62, 0xca, 0xed, 0x75, 0x2b, 0xf7, 0xd2, 0xb8, 0x82, 0xd0, 0xe8, 0x07, 0x32, 0xf9, 0xa2,
-	0x3e, 0x04, 0x01, 0x3f, 0x83, 0x08, 0xfd, 0xac, 0xf4, 0x8c, 0xe8, 0xe6, 0xb4, 0xd0, 0xef, 0x71,
-	0xcc, 0xd0, 0x37, 0xa7, 0x3b, 0x79, 0xc1, 0xd8, 0xc6, 0x8c, 0xdc, 0x6f, 0x72, 0x7b, 0x72, 0x56,
-	0xfe, 0xce, 0xfb, 0x2a, 0x1f, 0x76, 0x51, 0xbe, 0x42, 0x6e, 0x11, 0xc3, 0xda, 0x5c, 0x77, 0x01,
-	0xfc, 0x1e, 0x20, 0xe5, 0xb5, 0x23, 0xd6, 0x65, 0xfc, 0xb4, 0x81, 0xaa, 0x35, 0x44, 0xf6, 0xab,
-	0xf7, 0xa8, 0x80, 0x55, 0x98, 0x29, 0x0f, 0x47, 0x33, 0x0a, 0x40, 0x18, 0x35, 0x0f, 0x34, 0xd6,
-	0x07, 0x56, 0xdd, 0x34, 0x26, 0x4e, 0x53, 0xe3, 0x1d, 0xbd, 0xf3, 0x3f, 0x1f, 0x41, 0x22, 0x79,
-	0x00, 0x8e, 0x30, 0x76, 0xcd, 0xba, 0xac, 0xfd, 0xea, 0x07, 0x66, 0x1c, 0xc4, 0x7c, 0x0a, 0x29,
-	0x21, 0x5f, 0x38, 0x3c, 0xd8, 0x2f, 0xe4, 0x4b, 0x42, 0xbe, 0x70, 0xf4, 0x4d, 0xb1, 0x54, 0xfc,
-	0xee, 0x30, 0x5f, 0x3a, 0xda, 0x2f, 0x1c, 0xe6, 0x73, 0xbb, 0x8f, 0x77, 0xf3, 0x5f, 0x46, 0x7d,
-	0xec, 0xcc, 0xe9, 0x59, 0x2a, 0x62, 0x33, 0x31, 0x2b, 0xb0, 0xe8, 0x38, 0x6c, 0xff, 0xe0, 0xe0,
-	0x30, 0xea, 0x67, 0x27, 0x4f, 0xcf, 0x52, 0x21, 0xbd, 0xcd, 0xac, 0xc3, 0x92, 0x23, 0xb0, 0x70,
-	0x94, 0xcb, 0xe5, 0x0b, 0x85, 0x68, 0x80, 0x8d, 0x9c, 0x9e, 0xa5, 0x26, 0x68, 0x97, 0x0d, 0x3d,
-	0xff, 0x25, 0xe9, 0xdb, 0x7c, 0x3d, 0x09, 0xc1, 0x3d, 0xb5, 0xc6, 0xd4, 0x61, 0x66, 0xf4, 0xe5,
-	0xee, 0xbc, 0xfa, 0xf1, 0xf7, 0x33, 0x9b, 0xf1, 0x08, 0xb4, 0x78, 0x3e, 0x81, 0xe9, 0x91, 0xe7,
-	0xf2, 0x7d, 0x0f, 0x21, 0x8a, 0x4a, 0x97, 0x4d, 0x7b, 0xc3, 0xb9, 0xcc, 0xa4, 0xdf, 0x88, 0xbd,
-	0xcc, 0xb4, 0x23, 0xd6, 0x3d, 0xcd, 0x64, 0x7b, 0x19, 0x30, 0x1a, 0x30, 0x0e, 0xaf, 0x82, 0x35,
-	0x0f, 0x51, 0x28, 0x96, 0xdd, 0xf4, 0x8e, 0xb5, 0x66, 0x95, 0x21, 0x3a, 0x76, 0x79, 0x5e, 0xbd,
-	0x24, 0x8e, 0x85, 0x64, 0x1f, 0x78, 0x45, 0x5a, 0xf3, 0x3d, 0x85, 0x98, 0xe3, 0x85, 0xd7, 0x4b,
-	0x20, 0x73, 0x9d, 0x5b, 0x57, 0x00, 0x5b, 0x13, 0xff, 0x00, 0x60, 0xbb, 0x15, 0xf2, 0x6e, 0x21,
-	0x06, 0x18, 0x76, 0xed, 0x72, 0x8c, 0x15, 0xbd, 0x00, 0x13, 0xe6, 0x05, 0x88, 0x73, 0x1b, 0x46,
-	0x01, 0xec, 0xca, 0x25, 0x00, 0x7b, 0xed, 0x8d, 0x9c, 0xcd, 0xf7, 0x2f, 0x19, 0x4a, 0x71, 0xee,
-	0xb5, 0xe7, 0x72, 0x9e, 0xd4, 0x61, 0x66, 0xf4, 0x10, 0x70, 0xcd, 0x72, 0x04, 0xe8, 0xfe, 0xf1,
-	0xba, 0x6c, 0x92, 0xd9, 0xc2, 0x9b, 0xf3, 0xa4, 0xff, 0xed, 0x79, 0xd2, 0xff, 0xcf, 0x79, 0xd2,
-	0xff, 0xe2, 0x22, 0xe9, 0x7b, 0x7b, 0x91, 0xf4, 0xfd, 0x75, 0x91, 0xf4, 0x1d, 0x3f, 0xaa, 0x49,
-	0xda, 0x49, 0xbb, 0x92, 0x16, 0x71, 0x33, 0x23, 0x62, 0xb5, 0x89, 0xd5, 0x8c, 0x54, 0x11, 0xd7,
-	0x6b, 0x38, 0xd3, 0xd9, 0xca, 0x34, 0x71, 0xb5, 0xdd, 0x40, 0xaa, 0xf1, 0x13, 0xf1, 0xc1, 0xc3,
-	0x75, 0xf3, 0x3f, 0xa2, 0xd6, 0x6d, 0x21, 0xb5, 0x12, 0x26, 0xff, 0x10, 0xb7, 0xfe, 0x0b, 0x00,
-	0x00, 0xff, 0xff, 0xec, 0xba, 0x10, 0x62, 0xd2, 0x14, 0x00, 0x00,
+	// 1294 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4d, 0x6f, 0xe2, 0x56,
+	0x17, 0xc6, 0x40, 0x20, 0x39, 0xe4, 0x4d, 0x88, 0x49, 0x32, 0xc4, 0x24, 0x98, 0xd7, 0x8b, 0x49,
+	0x94, 0x2a, 0x30, 0x49, 0x66, 0x54, 0x4d, 0x54, 0xa9, 0x0a, 0x94, 0x51, 0xa3, 0x36, 0x1f, 0x32,
+	0xa4, 0x52, 0xd3, 0xaa, 0x08, 0xcc, 0x1d, 0x62, 0x01, 0x36, 0xb5, 0x0d, 0x33, 0xfc, 0x83, 0x51,
+	0x56, 0xb3, 0x1e, 0x29, 0xd2, 0x54, 0x5d, 0x55, 0x5d, 0x4c, 0x7f, 0xc6, 0x2c, 0x67, 0xd5, 0x56,
+	0x5d, 0xa0, 0x2a, 0xd9, 0x74, 0xcd, 0x2f, 0xa8, 0x7c, 0x7d, 0x6d, 0x0c, 0xd8, 0x8a, 0x33, 0x93,
+	0x64, 0xba, 0xf3, 0xbd, 0xe7, 0xb9, 0xe7, 0x9c, 0xfb, 0x9c, 0xe7, 0x7e, 0x19, 0x96, 0xc5, 0x8a,
+	0x90, 0x11, 0x64, 0x05, 0x65, 0x84, 0xd3, 0xb2, 0x24, 0xa1, 0x46, 0xa6, 0xb3, 0x99, 0xd1, 0x9e,
+	0xa7, 0x5b, 0x8a, 0xac, 0xc9, 0x74, 0x4c, 0xac, 0x08, 0x69, 0xdd, 0x9a, 0x26, 0xd6, 0x74, 0x67,
+	0x93, 0x99, 0xaf, 0xc9, 0x35, 0x19, 0xdb, 0x33, 0xfa, 0x97, 0x01, 0x65, 0xd8, 0x81, 0xa3, 0x86,
+	0x88, 0x24, 0x4d, 0xf7, 0x63, 0x7c, 0x11, 0xc0, 0xff, 0x9d, 0x22, 0x99, 0x6e, 0x31, 0x84, 0xfb,
+	0x89, 0x02, 0x7a, 0x5f, 0xad, 0xe5, 0x8c, 0xce, 0xc3, 0x16, 0x92, 0xf6, 0x24, 0x51, 0xa3, 0x3f,
+	0x81, 0x70, 0x4b, 0x56, 0xb4, 0x92, 0x58, 0x8d, 0x53, 0x29, 0x6a, 0x6d, 0x2a, 0x4b, 0xf7, 0x7b,
+	0xec, 0x4c, 0xb7, 0xdc, 0x6c, 0xec, 0x70, 0xc4, 0xc0, 0xf1, 0x21, 0xfd, 0x6b, 0xaf, 0x4a, 0x7f,
+	0x06, 0x61, 0xe2, 0x34, 0xee, 0x4f, 0x51, 0x6b, 0x91, 0xad, 0xe5, 0xb4, 0xc3, 0x24, 0xd2, 0x24,
+	0x46, 0x36, 0xf8, 0xb6, 0xc7, 0xfa, 0x78, 0x73, 0x08, 0xbd, 0x08, 0x21, 0x55, 0xac, 0x49, 0x48,
+	0x89, 0x07, 0xf4, 0x48, 0x3c, 0x69, 0xed, 0x4c, 0xbe, 0x78, 0xcd, 0xfa, 0xfe, 0x79, 0xcd, 0xfa,
+	0xb8, 0x06, 0x30, 0xe3, 0x29, 0xf2, 0x48, 0x6d, 0xc9, 0x92, 0x8a, 0xe8, 0x87, 0x00, 0xc4, 0xd5,
+	0x20, 0xdb, 0x85, 0x7e, 0x8f, 0x9d, 0x33, 0xb2, 0x1d, 0xd8, 0x38, 0x7e, 0x8a, 0x34, 0xf6, 0xaa,
+	0x74, 0x1c, 0xc2, 0x1d, 0xa4, 0xa8, 0xa2, 0x2c, 0xe1, 0x9c, 0xa7, 0x78, 0xb3, 0xc9, 0xfd, 0x1e,
+	0x80, 0xb9, 0xe1, 0x70, 0x45, 0xa5, 0x7b, 0x3d, 0x42, 0x0e, 0x20, 0xd6, 0x52, 0x50, 0x47, 0x94,
+	0xdb, 0x6a, 0xc9, 0x96, 0x1b, 0x0e, 0x94, 0x4d, 0xf6, 0x7b, 0x2c, 0x43, 0x06, 0x8e, 0x83, 0x38,
+	0x7e, 0xce, 0xec, 0xcd, 0x59, 0xc9, 0xda, 0x08, 0x0e, 0x5c, 0x9f, 0x60, 0x1e, 0xe6, 0x05, 0xb9,
+	0x2d, 0x69, 0x48, 0x69, 0x95, 0x15, 0xad, 0x5b, 0x32, 0xe7, 0x1d, 0xc4, 0xe9, 0xb0, 0xfd, 0x1e,
+	0x9b, 0x20, 0x54, 0x39, 0xa0, 0x38, 0x3e, 0x66, 0xef, 0xfe, 0xc6, 0xe8, 0xd5, 0x49, 0x6f, 0x29,
+	0xb2, 0xfc, 0xb4, 0x24, 0x4a, 0xa2, 0x16, 0x9f, 0x48, 0x51, 0x6b, 0xd3, 0x76, 0xd2, 0x07, 0x36,
+	0x8e, 0x9f, 0xc2, 0x0d, 0xac, 0xaa, 0x13, 0x98, 0x36, 0x2c, 0xa7, 0x48, 0xac, 0x9d, 0x6a, 0xf1,
+	0x10, 0x9e, 0x0c, 0x63, 0x9b, 0x8c, 0xa1, 0xde, 0xce, 0x66, 0xfa, 0x4b, 0x8c, 0xc8, 0x26, 0xf4,
+	0xa9, 0xf4, 0x7b, 0x6c, 0xcc, 0xee, 0xd7, 0x18, 0xcd, 0xf1, 0x11, 0xdc, 0x34, 0x90, 0x36, 0x19,
+	0x85, 0x5d, 0x64, 0xf4, 0x08, 0x96, 0xc6, 0xea, 0x6a, 0xa9, 0xc8, 0xa6, 0x07, 0x6a, 0x58, 0x0f,
+	0x7f, 0x8c, 0xe9, 0x61, 0x57, 0xa8, 0x5f, 0x4f, 0x0f, 0xc3, 0x12, 0xf5, 0x7b, 0x94, 0xe8, 0x09,
+	0xdc, 0x1b, 0xaa, 0x88, 0xcd, 0x05, 0x5e, 0x29, 0x59, 0xae, 0xdf, 0x63, 0x93, 0x0e, 0xa5, 0xb3,
+	0xfb, 0x5b, 0xb0, 0x5b, 0x06, 0x8a, 0xba, 0x0d, 0x4d, 0x6c, 0x82, 0x51, 0xea, 0x92, 0xa6, 0x74,
+	0x89, 0x24, 0xe6, 0xfb, 0x3d, 0x36, 0x6a, 0x2f, 0x9d, 0xa6, 0x74, 0x39, 0x7e, 0x12, 0x7f, 0xeb,
+	0xab, 0xea, 0xe3, 0x0a, 0x22, 0x31, 0x2a, 0x88, 0x5d, 0xa1, 0x6e, 0x0a, 0x82, 0xfb, 0xd5, 0x0f,
+	0x0b, 0xc3, 0xd6, 0x9c, 0x2c, 0x3d, 0x15, 0x95, 0xe6, 0x5d, 0x94, 0xde, 0xa2, 0xb2, 0x2c, 0xd4,
+	0x71, 0xb1, 0x1d, 0xa8, 0x2c, 0x0b, 0x75, 0x93, 0x4a, 0x5d, 0x90, 0xa3, 0x54, 0x06, 0x6f, 0x85,
+	0xca, 0x09, 0x17, 0x2a, 0x59, 0x58, 0x71, 0x24, 0xcb, 0xa2, 0xf3, 0x15, 0x05, 0xb1, 0x01, 0x22,
+	0xd7, 0x90, 0x55, 0x74, 0xfd, 0x83, 0xe6, 0xfd, 0xc8, 0xbc, 0xfa, 0x80, 0x59, 0x81, 0x84, 0x43,
+	0x6e, 0x56, 0xee, 0x6f, 0xfc, 0xb0, 0x38, 0x62, 0xbf, 0x43, 0x2d, 0x0c, 0x6f, 0xb5, 0x81, 0xf7,
+	0xdc, 0x6a, 0xef, 0x56, 0x0e, 0x29, 0x48, 0x3a, 0x13, 0x66, 0x71, 0xfa, 0xd2, 0x0f, 0xff, 0xdb,
+	0x57, 0x6b, 0x3c, 0x12, 0x3a, 0x47, 0x65, 0xa1, 0x8e, 0x34, 0xfa, 0x31, 0x84, 0x5a, 0xf8, 0x0b,
+	0x33, 0x19, 0xd9, 0x4a, 0x38, 0x9e, 0x71, 0x06, 0x98, 0x1c, 0x71, 0x64, 0x00, 0xfd, 0x04, 0xa2,
+	0x46, 0xba, 0x82, 0xdc, 0x6c, 0x8a, 0x5a, 0x13, 0x49, 0x1a, 0xa6, 0x77, 0x3a, 0x9b, 0xe8, 0xf7,
+	0xd8, 0x7b, 0xf6, 0x09, 0x0d, 0x10, 0x1c, 0x3f, 0x8b, 0xbb, 0x72, 0x56, 0xcf, 0x18, 0x69, 0x81,
+	0x5b, 0x21, 0x2d, 0xe8, 0x42, 0xda, 0x0f, 0x78, 0xc3, 0x19, 0x30, 0x62, 0x9d, 0x4d, 0x9f, 0x43,
+	0x48, 0x41, 0x6a, 0xbb, 0x61, 0x30, 0x33, 0xb3, 0xb5, 0xea, 0xc8, 0x8c, 0x09, 0xe7, 0x31, 0xb4,
+	0xd8, 0x6d, 0x21, 0x9e, 0x0c, 0xdb, 0x09, 0xea, 0x31, 0xb8, 0xbf, 0xfc, 0x00, 0xfb, 0x6a, 0xad,
+	0x28, 0x36, 0x91, 0xdc, 0xbe, 0x19, 0xbe, 0xdb, 0x92, 0x82, 0x04, 0x24, 0x76, 0x50, 0xd5, 0x8d,
+	0xef, 0x01, 0xc2, 0xe4, 0xfb, 0xd8, 0xea, 0xb9, 0x55, 0xbe, 0xbf, 0x02, 0x5a, 0x42, 0xcf, 0xb5,
+	0x92, 0x8a, 0x7e, 0x6c, 0x23, 0x49, 0x40, 0x25, 0x05, 0x09, 0x1d, 0xcc, 0x7d, 0x30, 0xbb, 0xd2,
+	0xef, 0xb1, 0x4b, 0x86, 0x87, 0x71, 0x0c, 0xc7, 0x47, 0xf5, 0xce, 0x02, 0xe9, 0xd3, 0xeb, 0xe1,
+	0x41, 0xf1, 0xdf, 0xe1, 0x6b, 0x34, 0xe1, 0xf6, 0xa6, 0x2b, 0xf7, 0xca, 0xb8, 0x82, 0x10, 0xef,
+	0x87, 0x12, 0x5e, 0x51, 0xff, 0x85, 0x02, 0x7e, 0x0a, 0x11, 0xb2, 0xac, 0xf4, 0x8c, 0xc8, 0xe6,
+	0xb4, 0xd8, 0xef, 0xb1, 0xf4, 0xd0, 0x9a, 0xd3, 0x8d, 0x1c, 0x6f, 0x6c, 0x63, 0x46, 0xee, 0xb7,
+	0xb9, 0x3d, 0x39, 0x57, 0x7e, 0xe2, 0x43, 0x2b, 0x1f, 0x72, 0xa9, 0x7c, 0x05, 0xdf, 0x22, 0x86,
+	0x6b, 0x73, 0xd3, 0x02, 0xf8, 0xcd, 0x8f, 0xe5, 0xb5, 0x2b, 0xd4, 0x25, 0xf9, 0x59, 0x03, 0x55,
+	0x6b, 0x08, 0xef, 0x57, 0x1f, 0xa0, 0x80, 0x35, 0x98, 0x2d, 0x0f, 0x7b, 0x33, 0x04, 0xc0, 0x8f,
+	0x76, 0x0f, 0x6a, 0xac, 0x0f, 0xac, 0xba, 0xd5, 0x18, 0x1b, 0xcd, 0x1a, 0xef, 0xea, 0x8d, 0x8f,
+	0x7c, 0x04, 0x09, 0xf8, 0xd1, 0x38, 0xc2, 0xd8, 0x0d, 0xd7, 0x65, 0xfd, 0x17, 0x0a, 0xe8, 0x71,
+	0x10, 0xfd, 0x08, 0x52, 0x7c, 0xbe, 0x70, 0x74, 0x78, 0x50, 0xc8, 0x97, 0xf8, 0x7c, 0xe1, 0xf8,
+	0xeb, 0x62, 0xa9, 0xf8, 0xed, 0x51, 0xbe, 0x74, 0x7c, 0x50, 0x38, 0xca, 0xe7, 0xf6, 0x9e, 0xec,
+	0xe5, 0xbf, 0x88, 0xfa, 0x98, 0xd9, 0xb3, 0xf3, 0x54, 0xc4, 0xd6, 0x45, 0xaf, 0xc2, 0x92, 0xe3,
+	0xb0, 0x83, 0xc3, 0xc3, 0xa3, 0x28, 0xc5, 0x4c, 0x9e, 0x9d, 0xa7, 0x82, 0xfa, 0x37, 0xbd, 0x01,
+	0xcb, 0x8e, 0xc0, 0xc2, 0x71, 0x2e, 0x97, 0x2f, 0x14, 0xa2, 0x7e, 0x26, 0x72, 0x76, 0x9e, 0x0a,
+	0x93, 0x26, 0x13, 0x7c, 0xf1, 0x73, 0xd2, 0xb7, 0xf5, 0x66, 0x12, 0x02, 0xfb, 0x6a, 0x8d, 0xae,
+	0xc3, 0xec, 0xe8, 0x6b, 0xdf, 0x79, 0xf6, 0xe3, 0x6f, 0x6e, 0x26, 0xe3, 0x11, 0x68, 0xf1, 0x7c,
+	0x0a, 0x33, 0x23, 0x0f, 0xe9, 0xfb, 0x1e, 0x5c, 0x14, 0x95, 0x2e, 0x93, 0xf6, 0x86, 0x73, 0x89,
+	0xa4, 0xdf, 0x88, 0xbd, 0x44, 0xda, 0x15, 0xea, 0x9e, 0x22, 0xd9, 0x5e, 0x06, 0xb4, 0x06, 0xb4,
+	0xc3, 0xab, 0x60, 0xdd, 0x83, 0x17, 0x82, 0x65, 0xb6, 0xbc, 0x63, 0xad, 0xa8, 0x12, 0x44, 0xc7,
+	0x2e, 0xcf, 0x6b, 0x57, 0xf8, 0xb1, 0x90, 0xcc, 0x03, 0xaf, 0x48, 0x2b, 0xde, 0x33, 0x88, 0x39,
+	0x5e, 0x78, 0xbd, 0x38, 0x32, 0xe7, 0xb9, 0x7d, 0x0d, 0xb0, 0x15, 0xf8, 0x7b, 0x00, 0xdb, 0xad,
+	0x90, 0x73, 0x73, 0x31, 0xc0, 0x30, 0xeb, 0x57, 0x63, 0x2c, 0xef, 0x05, 0x08, 0x9b, 0x17, 0x20,
+	0xd6, 0x6d, 0x18, 0x01, 0x30, 0xab, 0x57, 0x00, 0xec, 0xda, 0x1b, 0x39, 0x9b, 0xef, 0x5f, 0x31,
+	0x94, 0xe0, 0xdc, 0xb5, 0xe7, 0x72, 0x9e, 0xd4, 0x61, 0x76, 0xf4, 0x10, 0x70, 0xcd, 0x72, 0x04,
+	0xe8, 0xbe, 0x78, 0x5d, 0x36, 0xc9, 0x6c, 0xe1, 0xed, 0x45, 0x92, 0x7a, 0x77, 0x91, 0xa4, 0xfe,
+	0xbe, 0x48, 0x52, 0x2f, 0x2f, 0x93, 0xbe, 0x77, 0x97, 0x49, 0xdf, 0x9f, 0x97, 0x49, 0xdf, 0xc9,
+	0xe3, 0x9a, 0xa8, 0x9d, 0xb6, 0x2b, 0x69, 0x41, 0x6e, 0x66, 0x04, 0x59, 0x6d, 0xca, 0x6a, 0x46,
+	0xac, 0x08, 0x1b, 0x35, 0x39, 0xd3, 0xd9, 0xce, 0x34, 0xe5, 0x6a, 0xbb, 0x81, 0x54, 0xe3, 0xc7,
+	0xe3, 0x83, 0x87, 0x1b, 0xe6, 0xbf, 0x47, 0xad, 0xdb, 0x42, 0x6a, 0x25, 0x84, 0xff, 0x3b, 0x6e,
+	0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x51, 0x2e, 0xf7, 0xe5, 0x06, 0x15, 0x00, 0x00,
 }
 
 // Reference imports to suppress errors if they are not otherwise used.
@@ -1478,6 +1495,13 @@ func (m *MsgChannelOpenInitResponse) MarshalToSizedBuffer(dAtA []byte) (int, err
 	_ = i
 	var l int
 	_ = l
+	if len(m.Version) > 0 {
+		i -= len(m.Version)
+		copy(dAtA[i:], m.Version)
+		i = encodeVarintTx(dAtA, i, uint64(len(m.Version)))
+		i--
+		dAtA[i] = 0x12
+	}
 	if len(m.ChannelId) > 0 {
 		i -= len(m.ChannelId)
 		copy(dAtA[i:], m.ChannelId)
@@ -1586,6 +1610,13 @@ func (m *MsgChannelOpenTryResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro
 	_ = i
 	var l int
 	_ = l
+	if len(m.Version) > 0 {
+		i -= len(m.Version)
+		copy(dAtA[i:], m.Version)
+		i = encodeVarintTx(dAtA, i, uint64(len(m.Version)))
+		i--
+		dAtA[i] = 0xa
+	}
 	return len(dAtA) - i, nil
 }
 
@@ -2326,6 +2357,10 @@ func (m *MsgChannelOpenInitResponse) Size() (n int) {
 	if l > 0 {
 		n += 1 + l + sovTx(uint64(l))
 	}
+	l = len(m.Version)
+	if l > 0 {
+		n += 1 + l + sovTx(uint64(l))
+	}
 	return n
 }
 
@@ -2368,6 +2403,10 @@ func (m *MsgChannelOpenTryResponse) Size() (n int) {
 	}
 	var l int
 	_ = l
+	l = len(m.Version)
+	if l > 0 {
+		n += 1 + l + sovTx(uint64(l))
+	}
 	return n
 }
 
@@ -2877,6 +2916,38 @@ func (m *MsgChannelOpenInitResponse) Unmarshal(dAtA []byte) error {
 			}
 			m.ChannelId = string(dAtA[iNdEx:postIndex])
 			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 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.Version = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipTx(dAtA[iNdEx:])
@@ -3205,6 +3276,38 @@ func (m *MsgChannelOpenTryResponse) Unmarshal(dAtA []byte) error {
 			return fmt.Errorf("proto: MsgChannelOpenTryResponse: illegal tag %d (wire type %d)", fieldNum, wire)
 		}
 		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType)
+			}
+			var stringLen uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 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.Version = string(dAtA[iNdEx:postIndex])
+			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
 			skippy, err := skipTx(dAtA[iNdEx:])
diff --git a/proto/ibc/core/channel/v1/tx.proto b/proto/ibc/core/channel/v1/tx.proto
index 15714173a1a..8ee57c42db3 100644
--- a/proto/ibc/core/channel/v1/tx.proto
+++ b/proto/ibc/core/channel/v1/tx.proto
@@ -68,6 +68,7 @@ message MsgChannelOpenInit {
 // MsgChannelOpenInitResponse defines the Msg/ChannelOpenInit response type.
 message MsgChannelOpenInitResponse {
   string channel_id = 1 [(gogoproto.moretags) = "yaml:\"channel_id\""];
+  string version = 2;
 }
 
 // MsgChannelOpenInit defines a msg sent by a Relayer to try to open a channel
@@ -91,7 +92,9 @@ message MsgChannelOpenTry {
 }
 
 // MsgChannelOpenTryResponse defines the Msg/ChannelOpenTry response type.
-message MsgChannelOpenTryResponse {}
+message MsgChannelOpenTryResponse {
+ string version = 1;
+}
 
 // MsgChannelOpenAck defines a msg sent by a Relayer to Chain A to acknowledge
 // the change of channel state to TRYOPEN on Chain B.

From 6f20ad9ebe3572a3a61190a97e807e386ece1f99 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Thu, 21 Apr 2022 17:23:03 +0200
Subject: [PATCH 03/18] refactor: adding version to msg server resp

---
 modules/core/keeper/msg_server.go | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/modules/core/keeper/msg_server.go b/modules/core/keeper/msg_server.go
index e03f9975b97..a4aeb496f6f 100644
--- a/modules/core/keeper/msg_server.go
+++ b/modules/core/keeper/msg_server.go
@@ -195,6 +195,7 @@ func (k Keeper) ChannelOpenInit(goCtx context.Context, msg *channeltypes.MsgChan
 
 	return &channeltypes.MsgChannelOpenInitResponse{
 		ChannelId: channelID,
+		Version:   version,
 	}, nil
 }
 
@@ -233,7 +234,9 @@ func (k Keeper) ChannelOpenTry(goCtx context.Context, msg *channeltypes.MsgChann
 	// Write channel into state
 	k.ChannelKeeper.WriteOpenTryChannel(ctx, msg.PortId, channelID, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.Channel.Counterparty, version)
 
-	return &channeltypes.MsgChannelOpenTryResponse{}, nil
+	return &channeltypes.MsgChannelOpenTryResponse{
+		Version: version,
+	}, nil
 }
 
 // ChannelOpenAck defines a rpc handler method for MsgChannelOpenAck.

From 31a28314589d574f283b48e1c166f56919e2887f Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Tue, 26 Apr 2022 12:17:52 +0200
Subject: [PATCH 04/18] refactor: remove unncessary if & update version on
 Endpoint.Ack

---
 modules/apps/29-fee/ibc_module.go | 8 +-------
 testing/endpoint.go               | 4 ++++
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/modules/apps/29-fee/ibc_module.go b/modules/apps/29-fee/ibc_module.go
index b8971408eed..ccaf9ecbf4a 100644
--- a/modules/apps/29-fee/ibc_module.go
+++ b/modules/apps/29-fee/ibc_module.go
@@ -46,12 +46,6 @@ func (im IBCModule) OnChanOpenInit(
 			chanCap, counterparty, version)
 	}
 
-	if versionMetadata.FeeVersion == "" {
-		// call underlying app's OnChanOpenInit callback with the appVersion
-		return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID,
-			chanCap, counterparty, versionMetadata.AppVersion)
-	}
-
 	if versionMetadata.FeeVersion != types.Version {
 		return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion)
 	}
@@ -119,7 +113,7 @@ func (im IBCModule) OnChanOpenAck(
 	if im.keeper.IsFeeEnabled(ctx, portID, channelID) {
 		var versionMetadata types.Metadata
 		if err := types.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &versionMetadata); err != nil {
-			return sdkerrors.Wrap(types.ErrInvalidVersion, "failed to unmarshal ICS29 counterparty version metadata")
+			return sdkerrors.Wrapf(types.ErrInvalidVersion, "failed to unmarshal ICS29 counterparty version metadata: %s", counterpartyVersion)
 		}
 
 		if versionMetadata.FeeVersion != types.Version {
diff --git a/testing/endpoint.go b/testing/endpoint.go
index 02c4e9aac39..94fa14f8b0d 100644
--- a/testing/endpoint.go
+++ b/testing/endpoint.go
@@ -279,6 +279,10 @@ func (endpoint *Endpoint) ChanOpenInit() error {
 	endpoint.ChannelID, err = ParseChannelIDFromEvents(res.GetEvents())
 	require.NoError(endpoint.Chain.T, err)
 
+	// update version to selected app version
+	// NOTE: this update must be performed after SendMsgs()
+	endpoint.ChannelConfig.Version = endpoint.GetChannel().Version
+
 	return nil
 }
 

From 0178c093a09265fa814491423cf3c9311e6ace1a Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Tue, 26 Apr 2022 12:50:48 +0200
Subject: [PATCH 05/18] fix: ics29 OnChanOpenInit remake versionMetaData before
 returning

---
 modules/apps/29-fee/ibc_module.go    | 14 ++++++++++++--
 modules/apps/29-fee/transfer_test.go |  1 -
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/modules/apps/29-fee/ibc_module.go b/modules/apps/29-fee/ibc_module.go
index ccaf9ecbf4a..36fe66948bc 100644
--- a/modules/apps/29-fee/ibc_module.go
+++ b/modules/apps/29-fee/ibc_module.go
@@ -50,11 +50,21 @@ func (im IBCModule) OnChanOpenInit(
 		return "", sdkerrors.Wrapf(types.ErrInvalidVersion, "expected %s, got %s", types.Version, versionMetadata.FeeVersion)
 	}
 
+	appVersion, err := im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, versionMetadata.AppVersion)
+	if err != nil {
+		return "", err
+	}
+
+	versionMetadata.AppVersion = appVersion
+	versionBytes, err := types.ModuleCdc.MarshalJSON(&versionMetadata)
+	if err != nil {
+		return "", err
+	}
+
 	im.keeper.SetFeeEnabled(ctx, portID, channelID)
 
 	// call underlying app's OnChanOpenInit callback with the appVersion
-	return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID,
-		chanCap, counterparty, versionMetadata.AppVersion)
+	return string(versionBytes), nil
 }
 
 // OnChanOpenTry implements the IBCModule interface
diff --git a/modules/apps/29-fee/transfer_test.go b/modules/apps/29-fee/transfer_test.go
index 9d7557fd6c4..ba1f505d9c0 100644
--- a/modules/apps/29-fee/transfer_test.go
+++ b/modules/apps/29-fee/transfer_test.go
@@ -68,5 +68,4 @@ func (suite *FeeTestSuite) TestFeeTransfer() {
 		fee.AckFee.Add(fee.TimeoutFee...), // ack fee paid, timeout fee refunded
 		sdk.NewCoins(suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), suite.chainA.SenderAccount.GetAddress(), ibctesting.TestCoin.Denom)).Sub(originalChainASenderAccountBalance),
 	)
-
 }

From 8f8ce7887edfceeca158bd078e4cf41ce9e10202 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Tue, 26 Apr 2022 13:00:12 +0200
Subject: [PATCH 06/18] chore: update godoc

---
 modules/apps/transfer/ibc_module.go  |  3 ++-
 modules/core/05-port/types/module.go | 14 ++++++++++----
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/modules/apps/transfer/ibc_module.go b/modules/apps/transfer/ibc_module.go
index 653b0e38d36..b9bfc2be189 100644
--- a/modules/apps/transfer/ibc_module.go
+++ b/modules/apps/transfer/ibc_module.go
@@ -3,6 +3,7 @@ package transfer
 import (
 	"fmt"
 	"math"
+	"strings"
 
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
@@ -75,7 +76,7 @@ func (im IBCModule) OnChanOpenInit(
 		return "", err
 	}
 
-	if version == "" {
+	if strings.TrimSpace(version) == "" {
 		version = types.Version
 	}
 
diff --git a/modules/core/05-port/types/module.go b/modules/core/05-port/types/module.go
index b73ffca239b..7ac57479dbd 100644
--- a/modules/core/05-port/types/module.go
+++ b/modules/core/05-port/types/module.go
@@ -11,10 +11,16 @@ import (
 // IBCModule defines an interface that implements all the callbacks
 // that modules must define as specified in ICS-26
 type IBCModule interface {
-	// OnChanOpenInit will verify that the relayer-chosen parameters are
-	// valid and perform any custom INIT logic.It may return an error if
-	// the chosen parameters are invalid in which case the handshake is aborted.
-	// OnChanOpenInit should return an error if the provided version is invalid.
+	// OnChanOpenInit will verify that the relayer-chosen parameters
+	// are valid and perform any custom INIT logic.
+	// It may return an error if the chosen parameters are invalid
+	// in which case the handshake is aborted.
+	// If the provided version string is non-empty, OnChanOpenInit should return
+	// the version string if valid or an error if the provided version is invalid.
+	// If the version string is empty, OnChanOpenInit is expected to
+	// return a default version string representing the version(s) it supports.
+	// If there is no default version string for the application,
+	// it should return an error if provided version is empty string.
 	OnChanOpenInit(
 		ctx sdk.Context,
 		order channeltypes.Order,

From 2b0cca4d2994e2c6a153d6e452656fcc0fc5a189 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Tue, 26 Apr 2022 19:21:46 +0200
Subject: [PATCH 07/18] test: adding check for expected version string

---
 .../controller/ibc_module_test.go             | 15 ++++++++++++++-
 modules/apps/29-fee/ibc_module_test.go        | 19 ++++++++++++++++++-
 modules/apps/transfer/ibc_module_test.go      |  3 ++-
 3 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
index e91c45726d7..f839d0914a1 100644
--- a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
+++ b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
@@ -197,11 +197,24 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() {
 			cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module)
 			suite.Require().True(ok)
 
-			_, err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
+			version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
 				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, channel.Counterparty, channel.GetVersion(),
 			)
 
 			if tc.expPass {
+				expMetaData := icatypes.NewMetadata(
+					icatypes.Version,
+					path.EndpointA.ConnectionID,
+					path.EndpointB.ConnectionID,
+					"",
+					icatypes.EncodingProtobuf,
+					icatypes.TxTypeSDKMultiMsg,
+				)
+
+				expBytes, err := icatypes.ModuleCdc.MarshalJSON(&expMetaData)
+				suite.Require().NoError(err)
+
+				suite.Require().Equal(version, string(expBytes))
 				suite.Require().NoError(err)
 			} else {
 				suite.Require().Error(err)
diff --git a/modules/apps/29-fee/ibc_module_test.go b/modules/apps/29-fee/ibc_module_test.go
index 559692e16b6..4db5730b057 100644
--- a/modules/apps/29-fee/ibc_module_test.go
+++ b/modules/apps/29-fee/ibc_module_test.go
@@ -95,10 +95,27 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() {
 			cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module)
 			suite.Require().True(ok)
 
-			_, err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
+			version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
 				suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, chanCap, counterparty, channel.Version)
 
 			if tc.expPass {
+
+				// check if the channel is fee enabled. If so version string should include metaData
+				isFeeEnabled := suite.chainA.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainA.GetContext(), suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID)
+				if isFeeEnabled {
+					versionMetadata := types.Metadata{
+						FeeVersion: types.Version,
+						AppVersion: ibcmock.Version,
+					}
+
+					versionBytes, err := types.ModuleCdc.MarshalJSON(&versionMetadata)
+					suite.Require().NoError(err)
+
+					suite.Require().Equal(version, string(versionBytes))
+				} else {
+					suite.Require().Equal(version, ibcmock.Version)
+				}
+
 				suite.Require().NoError(err, "unexpected error from version: %s", tc.version)
 			} else {
 				suite.Require().Error(err, "error not returned for version: %s", tc.version)
diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go
index 5b68a3be1d4..763e54e6b54 100644
--- a/modules/apps/transfer/ibc_module_test.go
+++ b/modules/apps/transfer/ibc_module_test.go
@@ -85,12 +85,13 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() {
 
 			tc.malleate() // explicitly change fields in channel and testChannel
 
-			_, err = cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
+			version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
 				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, counterparty, channel.GetVersion(),
 			)
 
 			if tc.expPass {
 				suite.Require().NoError(err)
+				suite.Require().Equal(types.Version, version)
 			} else {
 				suite.Require().Error(err)
 			}

From 2d7f0b862b24806f5fd493b2b117b88e85d95300 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Tue, 26 Apr 2022 19:25:33 +0200
Subject: [PATCH 08/18] test: adding test case for passing empty version string
 to ics20 onChanOpenInit

---
 modules/apps/transfer/ibc_module_test.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go
index 763e54e6b54..2f4a504fc68 100644
--- a/modules/apps/transfer/ibc_module_test.go
+++ b/modules/apps/transfer/ibc_module_test.go
@@ -28,6 +28,11 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() {
 		{
 			"success", func() {}, true,
 		},
+		{
+			"empty version string", func() {
+				channel.Version = ""
+			}, true,
+		},
 		{
 			"max channels reached", func() {
 				path.EndpointA.ChannelID = channeltypes.FormatChannelIdentifier(math.MaxUint32 + 1)

From 534e00c2f31a7dc081f83f88c86fd186bd1de8dd Mon Sep 17 00:00:00 2001
From: Sean King <seantking@users.noreply.github.com>
Date: Tue, 26 Apr 2022 19:27:13 +0200
Subject: [PATCH 09/18] Update modules/apps/29-fee/ibc_module.go
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: colin axnér <25233464+colin-axner@users.noreply.github.com>
---
 modules/apps/29-fee/ibc_module.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/apps/29-fee/ibc_module.go b/modules/apps/29-fee/ibc_module.go
index 36fe66948bc..687dbd86579 100644
--- a/modules/apps/29-fee/ibc_module.go
+++ b/modules/apps/29-fee/ibc_module.go
@@ -123,7 +123,7 @@ func (im IBCModule) OnChanOpenAck(
 	if im.keeper.IsFeeEnabled(ctx, portID, channelID) {
 		var versionMetadata types.Metadata
 		if err := types.ModuleCdc.UnmarshalJSON([]byte(counterpartyVersion), &versionMetadata); err != nil {
-			return sdkerrors.Wrapf(types.ErrInvalidVersion, "failed to unmarshal ICS29 counterparty version metadata: %s", counterpartyVersion)
+			return sdkerrors.Wrapf(err, "failed to unmarshal ICS29 counterparty version metadata: %s", counterpartyVersion)
 		}
 
 		if versionMetadata.FeeVersion != types.Version {

From 8f08760ccd1cc249cf7e5250306f402b92314100 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Tue, 26 Apr 2022 19:28:31 +0200
Subject: [PATCH 10/18] chore: comment

---
 modules/apps/27-interchain-accounts/controller/ibc_module.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/apps/27-interchain-accounts/controller/ibc_module.go b/modules/apps/27-interchain-accounts/controller/ibc_module.go
index e701798c3be..d5b29daa2b8 100644
--- a/modules/apps/27-interchain-accounts/controller/ibc_module.go
+++ b/modules/apps/27-interchain-accounts/controller/ibc_module.go
@@ -51,7 +51,7 @@ func (im IBCModule) OnChanOpenInit(
 		return "", err
 	}
 
-	// call underlying app's OnChanOpenInit callback with the appVersion
+	// call underlying app's OnChanOpenInit callback with the passed in version
 	return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID,
 		chanCap, counterparty, version)
 }

From a03916dff0aeb4f1d24e045be9b9dc663ffacfd8 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Wed, 27 Apr 2022 10:27:27 +0200
Subject: [PATCH 11/18] chore: changelog

---
 CHANGELOG.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6b84cecfd72..8626f816c88 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,6 +43,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
 ### API Breaking
 
 * (transfer) [\#1250](https://github.com/cosmos/ibc-go/pull/1250) Deprecate `GetTransferAccount` since the `transfer` module account is never used.
+* (channel) [\#1283](https://github.com/cosmos/ibc-go/pull/1283) `OnChanOpenInit` now returns a version string in line with the latest [spec changes](https://github.com/cosmos/ibc/pull/629).  
+
 
 ### State Machine Breaking
 

From ce656c4fe6dce20c5ab4e134dcfb414215e5798d Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Wed, 27 Apr 2022 17:54:02 +0200
Subject: [PATCH 12/18] fix: ica now discards auth module version

---
 .../apps/27-interchain-accounts/controller/ibc_module.go   | 7 +++++--
 .../27-interchain-accounts/controller/ibc_module_test.go   | 4 ++--
 modules/apps/29-fee/ibc_module.go                          | 1 -
 modules/apps/29-fee/ibc_module_test.go                     | 1 +
 modules/apps/transfer/ibc_module_test.go                   | 1 +
 5 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/modules/apps/27-interchain-accounts/controller/ibc_module.go b/modules/apps/27-interchain-accounts/controller/ibc_module.go
index d5b29daa2b8..5a45c87f146 100644
--- a/modules/apps/27-interchain-accounts/controller/ibc_module.go
+++ b/modules/apps/27-interchain-accounts/controller/ibc_module.go
@@ -52,8 +52,11 @@ func (im IBCModule) OnChanOpenInit(
 	}
 
 	// call underlying app's OnChanOpenInit callback with the passed in version
-	return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID,
-		chanCap, counterparty, version)
+	if _, err := im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version); err != nil {
+		return "", err
+	}
+
+	return version, nil
 }
 
 // OnChanOpenTry implements the IBCModule interface
diff --git a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
index f839d0914a1..3cf180c3fbb 100644
--- a/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
+++ b/modules/apps/27-interchain-accounts/controller/ibc_module_test.go
@@ -202,7 +202,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() {
 			)
 
 			if tc.expPass {
-				expMetaData := icatypes.NewMetadata(
+				expMetadata := icatypes.NewMetadata(
 					icatypes.Version,
 					path.EndpointA.ConnectionID,
 					path.EndpointB.ConnectionID,
@@ -211,7 +211,7 @@ func (suite *InterchainAccountsTestSuite) TestOnChanOpenInit() {
 					icatypes.TxTypeSDKMultiMsg,
 				)
 
-				expBytes, err := icatypes.ModuleCdc.MarshalJSON(&expMetaData)
+				expBytes, err := icatypes.ModuleCdc.MarshalJSON(&expMetadata)
 				suite.Require().NoError(err)
 
 				suite.Require().Equal(version, string(expBytes))
diff --git a/modules/apps/29-fee/ibc_module.go b/modules/apps/29-fee/ibc_module.go
index 687dbd86579..0767d310b41 100644
--- a/modules/apps/29-fee/ibc_module.go
+++ b/modules/apps/29-fee/ibc_module.go
@@ -101,7 +101,6 @@ func (im IBCModule) OnChanOpenTry(
 	}
 
 	versionMetadata.AppVersion = appVersion
-
 	versionBytes, err := types.ModuleCdc.MarshalJSON(&versionMetadata)
 	if err != nil {
 		return "", err
diff --git a/modules/apps/29-fee/ibc_module_test.go b/modules/apps/29-fee/ibc_module_test.go
index 4db5730b057..0bfb8a6b458 100644
--- a/modules/apps/29-fee/ibc_module_test.go
+++ b/modules/apps/29-fee/ibc_module_test.go
@@ -119,6 +119,7 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() {
 				suite.Require().NoError(err, "unexpected error from version: %s", tc.version)
 			} else {
 				suite.Require().Error(err, "error not returned for version: %s", tc.version)
+				suite.Require().Equal(version, "")
 			}
 		})
 	}
diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go
index 2f4a504fc68..1d8d825d8ed 100644
--- a/modules/apps/transfer/ibc_module_test.go
+++ b/modules/apps/transfer/ibc_module_test.go
@@ -99,6 +99,7 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() {
 				suite.Require().Equal(types.Version, version)
 			} else {
 				suite.Require().Error(err)
+				suite.Require().Equal(version, "")
 			}
 
 		})

From 092d3fe36392ef2747f568fe1f051200b48385a3 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Wed, 27 Apr 2022 17:57:20 +0200
Subject: [PATCH 13/18] chore: update changelog

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8626f816c88..690bf0fb791 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,7 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
 ### API Breaking
 
 * (transfer) [\#1250](https://github.com/cosmos/ibc-go/pull/1250) Deprecate `GetTransferAccount` since the `transfer` module account is never used.
-* (channel) [\#1283](https://github.com/cosmos/ibc-go/pull/1283) `OnChanOpenInit` now returns a version string in line with the latest [spec changes](https://github.com/cosmos/ibc/pull/629).  
+* (channel) [\#1283](https://github.com/cosmos/ibc-go/pull/1283) The `OnChanOpenInit` application callback now returns a version string in line with the latest [spec changes](https://github.com/cosmos/ibc/pull/629).  
 
 
 ### State Machine Breaking

From d30f887090049e4ae6493632332afe6ae18f8526 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Fri, 29 Apr 2022 18:41:56 +0200
Subject: [PATCH 14/18] adding default version for ics29

---
 modules/apps/29-fee/ibc_module.go      | 23 +++++++++++++++++------
 modules/apps/29-fee/ibc_module_test.go | 10 +++++++---
 testing/mock/ibc_module.go             |  5 +++++
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/modules/apps/29-fee/ibc_module.go b/modules/apps/29-fee/ibc_module.go
index 0767d310b41..00ea19b56f5 100644
--- a/modules/apps/29-fee/ibc_module.go
+++ b/modules/apps/29-fee/ibc_module.go
@@ -1,6 +1,8 @@
 package fee
 
 import (
+	"strings"
+
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
 	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
@@ -38,12 +40,21 @@ func (im IBCModule) OnChanOpenInit(
 	version string,
 ) (string, error) {
 	var versionMetadata types.Metadata
-	if err := types.ModuleCdc.UnmarshalJSON([]byte(version), &versionMetadata); err != nil {
-		// Since it is valid for fee version to not be specified, the above middleware version may be for a middleware
-		// lower down in the stack. Thus, if it is not a fee version we pass the entire version string onto the underlying
-		// application.
-		return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID,
-			chanCap, counterparty, version)
+
+	if strings.TrimSpace(version) == "" {
+		// default version
+		versionMetadata = types.Metadata{
+			FeeVersion: types.Version,
+			AppVersion: "",
+		}
+	} else {
+		if err := types.ModuleCdc.UnmarshalJSON([]byte(version), &versionMetadata); err != nil {
+			// Since it is valid for fee version to not be specified, the above middleware version may be for a middleware
+			// lower down in the stack. Thus, if it is not a fee version we pass the entire version string onto the underlying
+			// application.
+			return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID,
+				chanCap, counterparty, version)
+		}
 	}
 
 	if versionMetadata.FeeVersion != types.Version {
diff --git a/modules/apps/29-fee/ibc_module_test.go b/modules/apps/29-fee/ibc_module_test.go
index 0bfb8a6b458..025c765e42c 100644
--- a/modules/apps/29-fee/ibc_module_test.go
+++ b/modules/apps/29-fee/ibc_module_test.go
@@ -54,6 +54,11 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() {
 			types.Version,
 			false,
 		},
+		{
+			"passing an empty string returns default version",
+			"",
+			true,
+		},
 	}
 
 	for _, tc := range testCases {
@@ -99,7 +104,6 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() {
 				suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID, chanCap, counterparty, channel.Version)
 
 			if tc.expPass {
-
 				// check if the channel is fee enabled. If so version string should include metaData
 				isFeeEnabled := suite.chainA.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainA.GetContext(), suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID)
 				if isFeeEnabled {
@@ -113,13 +117,13 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() {
 
 					suite.Require().Equal(version, string(versionBytes))
 				} else {
-					suite.Require().Equal(version, ibcmock.Version)
+					suite.Require().Equal(ibcmock.Version, version)
 				}
 
 				suite.Require().NoError(err, "unexpected error from version: %s", tc.version)
 			} else {
 				suite.Require().Error(err, "error not returned for version: %s", tc.version)
-				suite.Require().Equal(version, "")
+				suite.Require().Equal("", version)
 			}
 		})
 	}
diff --git a/testing/mock/ibc_module.go b/testing/mock/ibc_module.go
index 4c492872da0..69f3c388a8a 100644
--- a/testing/mock/ibc_module.go
+++ b/testing/mock/ibc_module.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"fmt"
 	"strconv"
+	"strings"
 
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
@@ -33,6 +34,10 @@ func (im IBCModule) OnChanOpenInit(
 	ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string,
 	channelID string, chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string,
 ) (string, error) {
+	if strings.TrimSpace(version) == "" {
+		version = Version
+	}
+
 	if im.IBCApp.OnChanOpenInit != nil {
 		return im.IBCApp.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version)
 	}

From 1a44c0b4d983961902dc4749064bcb38efc44c07 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Wed, 4 May 2022 12:31:21 +0200
Subject: [PATCH 15/18] fix: using transfer module directly rather than calling
 full middleware stack

---
 modules/apps/transfer/ibc_module_test.go | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go
index 1d8d825d8ed..d757bacaec7 100644
--- a/modules/apps/transfer/ibc_module_test.go
+++ b/modules/apps/transfer/ibc_module_test.go
@@ -5,6 +5,7 @@ import (
 
 	capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
 
+	"github.com/cosmos/ibc-go/v3/modules/apps/transfer"
 	"github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
 	channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types"
 	host "github.com/cosmos/ibc-go/v3/modules/core/24-host"
@@ -79,18 +80,13 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() {
 				Version:        types.Version,
 			}
 
-			module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.TransferPort)
-			suite.Require().NoError(err)
-
-			chanCap, err = suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(ibctesting.TransferPort, path.EndpointA.ChannelID))
+			chanCap, err := suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(ibctesting.TransferPort, path.EndpointA.ChannelID))
 			suite.Require().NoError(err)
 
-			cbs, ok := suite.chainA.App.GetIBCKeeper().Router.GetRoute(module)
-			suite.Require().True(ok)
-
 			tc.malleate() // explicitly change fields in channel and testChannel
 
-			version, err := cbs.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
+			transferModule := transfer.NewIBCModule(suite.chainA.GetSimApp().TransferKeeper)
+			version, err := transferModule.OnChanOpenInit(suite.chainA.GetContext(), channel.Ordering, channel.GetConnectionHops(),
 				path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, chanCap, counterparty, channel.GetVersion(),
 			)
 

From 15d7092ba7b1b8dd522b674947dc610e98993ca2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?colin=20axn=C3=A9r?=
 <25233464+colin-axner@users.noreply.github.com>
Date: Wed, 4 May 2022 13:11:40 +0200
Subject: [PATCH 16/18] fix testing bug

---
 modules/apps/transfer/ibc_module_test.go | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go
index d757bacaec7..95779ad2e8e 100644
--- a/modules/apps/transfer/ibc_module_test.go
+++ b/modules/apps/transfer/ibc_module_test.go
@@ -80,7 +80,8 @@ func (suite *TransferTestSuite) TestOnChanOpenInit() {
 				Version:        types.Version,
 			}
 
-			chanCap, err := suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(ibctesting.TransferPort, path.EndpointA.ChannelID))
+			var err error
+			chanCap, err = suite.chainA.App.GetScopedIBCKeeper().NewCapability(suite.chainA.GetContext(), host.ChannelCapabilityPath(ibctesting.TransferPort, path.EndpointA.ChannelID))
 			suite.Require().NoError(err)
 
 			tc.malleate() // explicitly change fields in channel and testChannel

From 0b85196ec297e3cf0ab81e2bfa58f4ae1deb5a98 Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Wed, 4 May 2022 15:54:14 +0200
Subject: [PATCH 17/18] refactor: test now uses bool for isFeeEnabled rather
 than direct check

---
 modules/apps/29-fee/ibc_middleware_test.go | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/modules/apps/29-fee/ibc_middleware_test.go b/modules/apps/29-fee/ibc_middleware_test.go
index 45e5011dfd1..6a99d103cbb 100644
--- a/modules/apps/29-fee/ibc_middleware_test.go
+++ b/modules/apps/29-fee/ibc_middleware_test.go
@@ -25,39 +25,46 @@ var (
 // Tests OnChanOpenInit on ChainA
 func (suite *FeeTestSuite) TestOnChanOpenInit() {
 	testCases := []struct {
-		name    string
-		version string
-		expPass bool
+		name         string
+		version      string
+		expPass      bool
+		isFeeEnabled bool
 	}{
 		{
 			"success - valid fee middleware and mock version",
 			string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: ibcmock.Version})),
 			true,
+			true,
 		},
 		{
 			"success - fee version not included, only perform mock logic",
 			ibcmock.Version,
 			true,
+			false,
 		},
 		{
 			"invalid fee middleware version",
 			string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: "invalid-ics29-1", AppVersion: ibcmock.Version})),
 			false,
+			false,
 		},
 		{
 			"invalid mock version",
 			string(types.ModuleCdc.MustMarshalJSON(&types.Metadata{FeeVersion: types.Version, AppVersion: "invalid-mock-version"})),
 			false,
+			false,
 		},
 		{
 			"mock version not wrapped",
 			types.Version,
 			false,
+			false,
 		},
 		{
 			"passing an empty string returns default version",
 			"",
 			true,
+			true,
 		},
 	}
 
@@ -105,8 +112,7 @@ func (suite *FeeTestSuite) TestOnChanOpenInit() {
 
 			if tc.expPass {
 				// check if the channel is fee enabled. If so version string should include metaData
-				isFeeEnabled := suite.chainA.GetSimApp().IBCFeeKeeper.IsFeeEnabled(suite.chainA.GetContext(), suite.path.EndpointA.ChannelConfig.PortID, suite.path.EndpointA.ChannelID)
-				if isFeeEnabled {
+				if tc.isFeeEnabled {
 					versionMetadata := types.Metadata{
 						FeeVersion: types.Version,
 						AppVersion: ibcmock.Version,

From 0286c640ba31f5f66ab03ff188fc96a438b58dfd Mon Sep 17 00:00:00 2001
From: Sean King <sean@seking.dev>
Date: Wed, 4 May 2022 16:05:03 +0200
Subject: [PATCH 18/18] docs: updating comment and migration docs

---
 docs/migrations/v3-to-v4.md                                 | 6 +++++-
 .../27-interchain-accounts/controller/ibc_middleware.go     | 2 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/docs/migrations/v3-to-v4.md b/docs/migrations/v3-to-v4.md
index 90e9af256d2..5a3d61deaae 100644
--- a/docs/migrations/v3-to-v4.md
+++ b/docs/migrations/v3-to-v4.md
@@ -1,4 +1,4 @@
-# Migrating from ibc-go v2 to v3
+# Migrating from ibc-go v3 to v4
 
 This document is intended to highlight significant changes which may require more information than presented in the CHANGELOG.
 Any changes that must be done by a user of ibc-go should be documented here.
@@ -23,4 +23,8 @@ No genesis or in-place migrations required when upgrading from v1 or v2 of ibc-g
 The `WriteAcknowledgement` API now takes the `exported.Acknowledgement` type instead of passing in the acknowledgement byte array directly. 
 This is an API breaking change and as such IBC application developers will have to update any calls to `WriteAcknowledgement`. 
 
+The `OnChanOpenInit` application callback has been modified.
+The return signature now includes the application version as detailed in the latest IBC [spec changes](https://github.com/cosmos/ibc/pull/629).
+
+
 
diff --git a/modules/apps/27-interchain-accounts/controller/ibc_middleware.go b/modules/apps/27-interchain-accounts/controller/ibc_middleware.go
index 2755877a4b7..9bf874fa8eb 100644
--- a/modules/apps/27-interchain-accounts/controller/ibc_middleware.go
+++ b/modules/apps/27-interchain-accounts/controller/ibc_middleware.go
@@ -55,6 +55,8 @@ func (im IBCMiddleware) OnChanOpenInit(
 	}
 
 	// call underlying app's OnChanOpenInit callback with the passed in version
+	// the version returned is discarded as the ica-auth module does not have permission to edit the version string.
+	// ics27 will always return the version string containing the Metadata struct which is created during the `RegisterInterchainAccount` call.
 	if _, err := im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version); err != nil {
 		return "", err
 	}