Skip to content

Commit

Permalink
feat(ica): allow unordered ica channels (#5633)
Browse files Browse the repository at this point in the history
* Remove order check for ICA host and controller upgrade callbacks (#5561)

* imp: remove the channel type = ordered checks from both host and controller (#5578)

* rm checks and tests, amend docustring

* rm unnecessary test

* When a channel reopens the ordering and metadata must not change (#5562)

* chore: require active channel be CLOSED before re-opening. (#5601)

* docs: Update ICA documentation with support for unordered channels (#5607)

* Allow specifying order when registering ICA account (#5608)

* proto: Add Order to MsgRegisterInterchainAccount.

* chore: apply proto changes to go files.

* Add ordering to cli tx for Register.

* Add documentation line for tx now accepting ordering.

* Address feedback review.

Co-authored-by: Carlos Rodriguez <carlos@interchain.io>

* Address Cian's feedback; spacing.

---------

Co-authored-by: Carlos Rodriguez <carlos@interchain.io>

* docs: ICA register CLI (#5625)

* imp(ica/host): removed previous version validation check (#5613)

* imp: removed validation check

* test: updated icahost test

* docs: added godocs

* docs: added godocs

* chore(ica/host): require active channel be CLOSED before re-opening (#5630)

* chore(ica/host): require active channel be CLOSED before re-opening

* Update modules/apps/27-interchain-accounts/host/keeper/handshake_test.go

Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>

---------

Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>

* e2e: ordered ica channel is upgraded to unordered (#5616)

* E2E test where unordered channel is used with ICA (#5566)

* test: add test to use an unordered ICA channel

* chore: add hard coded UNORDERED channel Order

* proto: Add Order to MsgRegisterInterchainAccount.

* chore: apply proto changes to go files.

* chore: apply proto changes to go files.

* chore: e2e test passing with hard coded ordered value

* Add ordering to cli tx for Register.

* Add documentation line for tx now accepting ordering.

* Address feedback review.

Co-authored-by: Carlos Rodriguez <carlos@interchain.io>

* Address Cian's feedback; spacing.

* Update e2e/tests/interchain_accounts/base_test.go

Co-authored-by: Charly <charly@interchain.io>

---------

Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>
Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
Co-authored-by: Charly <charly@interchain.io>

* fix: host chan open try test (#5632)

* chore: fix linter and merge main

* chore: doc lint issue fix

* docs: add extra information about ICA channel reopening (#5631)

* docs: add extra information about ICA channel reopening

* add link to active channels section

* Apply suggestions from code review

Co-authored-by: Damian Nolan <damiannolan@gmail.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>

* Update 01-overview.md

---------

Co-authored-by: Damian Nolan <damiannolan@gmail.com>
Co-authored-by: srdtrk <59252793+srdtrk@users.noreply.github.com>

* chore: rm order checks reintroduced after merge conflict.

* e2e: comment out failing e2e

* chore: lintertroubles

---------

Co-authored-by: Cian Hatton <cian@interchain.io>
Co-authored-by: Charly <charly@interchain.io>
Co-authored-by: DimitrisJim <d.f.hilliard@gmail.com>
Co-authored-by: Carlos Rodriguez <carlos@interchain.io>
Co-authored-by: Damian Nolan <damiannolan@gmail.com>
Co-authored-by: chatton <github.qpeyb@simplelogin.fr>
Co-authored-by: Colin Axnér <25233464+colin-axner@users.noreply.github.com>
(cherry picked from commit 6174822)

# Conflicts:
#	docs/apps/interchain-accounts/active-channels.md
#	docs/apps/interchain-accounts/overview.md
#	e2e/tests/core/04-channel/upgrades_test.go
#	e2e/tests/interchain_accounts/base_test.go
#	e2e/tests/interchain_accounts/gov_test.go
#	e2e/tests/interchain_accounts/groups_test.go
#	e2e/tests/interchain_accounts/incentivized_test.go
#	e2e/tests/interchain_accounts/localhost_test.go
#	e2e/tests/interchain_accounts/params_test.go
#	e2e/tests/upgrades/genesis_test.go
#	e2e/testsuite/testconfig.go
#	modules/apps/27-interchain-accounts/controller/client/cli/tx.go
#	modules/apps/27-interchain-accounts/controller/ibc_middleware_test.go
#	modules/apps/27-interchain-accounts/controller/keeper/handshake.go
#	modules/apps/27-interchain-accounts/controller/keeper/handshake_test.go
#	modules/apps/27-interchain-accounts/controller/keeper/msg_server_test.go
#	modules/apps/27-interchain-accounts/controller/types/msgs.go
#	modules/apps/27-interchain-accounts/controller/types/msgs_test.go
#	modules/apps/27-interchain-accounts/controller/types/tx.pb.go
#	modules/apps/27-interchain-accounts/host/keeper/handshake.go
#	modules/apps/27-interchain-accounts/host/keeper/handshake_test.go
#	modules/apps/callbacks/callbacks_test.go
#	proto/ibc/applications/interchain_accounts/controller/v1/tx.proto
  • Loading branch information
srdtrk authored and mergify[bot] committed Apr 25, 2024
1 parent 63d2e40 commit fa2a572
Show file tree
Hide file tree
Showing 28 changed files with 4,669 additions and 53 deletions.
10 changes: 10 additions & 0 deletions docs/apps/interchain-accounts/active-channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@ order: 9

# Understanding Active Channels

<<<<<<< HEAD:docs/apps/interchain-accounts/active-channels.md
The Interchain Accounts module uses [ORDERED channels](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#ordering) to maintain the order of transactions when sending packets from a controller to a host chain. A limitation when using ORDERED channels is that when a packet times out the channel will be closed.
=======
The Interchain Accounts module uses either [ORDERED or UNORDERED](https://github.com/cosmos/ibc/tree/master/spec/core/ics-004-channel-and-packet-semantics#ordering) channels.

When using `ORDERED` channels, the order of transactions when sending packets from a controller to a host chain is maintained.

When using `UNORDERED` channels, there is no guarantee that the order of transactions when sending packets from the controller to the host chain is maintained.

> A limitation when using ORDERED channels is that when a packet times out the channel will be closed.
>>>>>>> 61748221 (feat(ica): allow unordered ica channels (#5633)):docs/docs/02-apps/02-interchain-accounts/09-active-channels.md
In the case of a channel closing, a controller chain needs to be able to regain access to the interchain account registered on this channel. `Active Channels` enable this functionality.

Expand Down
19 changes: 19 additions & 0 deletions docs/apps/interchain-accounts/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ The `tx` commands allow users to interact with the controller submodule.
simd tx interchain-accounts controller --help
```

#### `register`

The `register` command allows users to register an interchain account on a host chain on the provided connection.

```shell
simd tx interchain-accounts controller register [connection-id] [flags]
```

During registration a new channel is set up between controller and host. There are two flags available that influence the channel that is created:

- `--version` to specify the (JSON-formatted) version string of the channel. For example: `{\"version\":\"ics27-1\",\"encoding\":\"proto3\",\"tx_type\":\"sdk_multi_msg\",\"controller_connection_id\":\"connection-0\",\"host_connection_id\":\"connection-0\"}`. Passing a custom version string is useful if you want to specify, for example, the encoding format of the interchain accounts packet data (either `proto3` or `proto3json`). If not specified the controller submodule will generate a default version string.
- `--ordering` to specify the ordering of the channel. Available options are `order_ordered` (default if not specified) and `order_unordered`.

Example:

```shell
simd tx interchain-accounts controller register connection-0 --ordering order_unordered --from cosmos1..
```

#### `send-tx`

The `send-tx` command allows users to send a transaction on the provided connection to be executed using an interchain account on the host chain.
Expand Down
1 change: 1 addition & 0 deletions docs/apps/interchain-accounts/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type MsgRegisterInterchainAccount struct {
Owner string
ConnectionID string
Version string
Order channeltypes.Order
}
```

Expand Down
13 changes: 13 additions & 0 deletions docs/apps/interchain-accounts/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,17 @@ SDK modules on a chain are assumed to be trustworthy. For example, there are no

The implementation of ICS-27 in ibc-go uses this assumption in its security considerations.

<<<<<<< HEAD:docs/apps/interchain-accounts/overview.md
The implementation assumes other IBC application modules will not bind to ports within the ICS-27 namespace.
=======
The implementation assumes other IBC application modules will not bind to ports within the ICS-27 namespace.

## Channel Closure

The provided interchain account host and controller implementations do not support `ChanCloseInit`. However, they do support `ChanCloseConfirm`.
This means that the host and controller modules cannot close channels, but they will confirm channel closures initiated by other implementations of ICS-27.

In the event of a channel closing (due to a packet timeout in an ordered channel, for example), the interchain account associated with that channel can become accessible again if a new channel is created with a (JSON-formatted) version string that encodes the exact same `Metadata` information of the previous channel. The channel can be reopened using either [`MsgRegisterInterchainAccount`](./05-messages.md#msgregisterinterchainaccount) or `MsgChannelOpenInit`. If `MsgRegisterInterchainAccount` is used, then it is possible to leave the `version` field of the message empty, since it will be filled in by the controller submodule. If `MsgChannelOpenInit` is used, then the `version` field must be provided with the correct JSON-encoded `Metadata` string. See section [Understanding Active Channels](./09-active-channels.md#understanding-active-channels) for more information.

When reopening a channel with the default controller submodule, the ordering of the channel cannot be changed. In order to change the ordering of the channel, the channel has to go through a [channel upgrade handshake](../../01-ibc/06-channel-upgrades.md) or reopen the channel with a custom controller implementation.
>>>>>>> 61748221 (feat(ica): allow unordered ica channels (#5633)):docs/docs/02-apps/02-interchain-accounts/01-overview.md
328 changes: 328 additions & 0 deletions e2e/tests/core/04-channel/upgrades_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,328 @@
//go:build !test_e2e

package channel

import (
"context"
"testing"

"github.com/strangelove-ventures/interchaintest/v8/ibc"
test "github.com/strangelove-ventures/interchaintest/v8/testutil"
testifysuite "github.com/stretchr/testify/suite"

sdkmath "cosmossdk.io/math"

govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"

"github.com/cosmos/ibc-go/e2e/testsuite"
"github.com/cosmos/ibc-go/e2e/testvalues"
feetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types"
transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"
channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types"
)

func TestChannelTestSuite(t *testing.T) {
testifysuite.Run(t, new(ChannelTestSuite))
}

type ChannelTestSuite struct {
testsuite.E2ETestSuite
}

// TestChannelUpgrade_WithFeeMiddleware_Succeeds tests upgrading a transfer channel to wire up fee middleware
func (s *ChannelTestSuite) TestChannelUpgrade_WithFeeMiddleware_Succeeds() {
t := s.T()
ctx := context.TODO()

relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions())
channelB := channelA.Counterparty
chainA, chainB := s.GetChains()

chainADenom := chainA.Config().Denom
chainBDenom := chainB.Config().Denom
chainAIBCToken := testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID)
chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelB.PortID, channelB.ChannelID)

chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount)
chainAAddress := chainAWallet.FormattedAddress()

chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount)
chainBAddress := chainBWallet.FormattedAddress()

var (
chainARelayerWallet, chainBRelayerWallet ibc.Wallet
relayerAStartingBalance int64
testFee = testvalues.DefaultFee(chainADenom)
)

s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks")

// trying to create some inflight packets, although they might get relayed before the upgrade starts
t.Run("create inflight transfer packets between chain A and chain B", func(t *testing.T) {
chainBWalletAmount := ibc.WalletAmount{
Address: chainBWallet.FormattedAddress(), // destination address
Denom: chainADenom,
Amount: sdkmath.NewInt(testvalues.IBCTransferAmount),
}

transferTxResp, err := chainA.SendIBCTransfer(ctx, channelA.ChannelID, chainAWallet.KeyName(), chainBWalletAmount, ibc.TransferOptions{})
s.Require().NoError(err)
s.Require().NoError(transferTxResp.Validate(), "chain-a ibc transfer tx is invalid")

chainAwalletAmount := ibc.WalletAmount{
Address: chainAWallet.FormattedAddress(), // destination address
Denom: chainBDenom,
Amount: sdkmath.NewInt(testvalues.IBCTransferAmount),
}

transferTxResp, err = chainB.SendIBCTransfer(ctx, channelB.ChannelID, chainBWallet.KeyName(), chainAwalletAmount, ibc.TransferOptions{})
s.Require().NoError(err)
s.Require().NoError(transferTxResp.Validate(), "chain-b ibc transfer tx is invalid")
})

t.Run("execute gov proposal to initiate channel upgrade", func(t *testing.T) {
chA, err := s.QueryChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)

s.initiateChannelUpgrade(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, s.createUpgradeFields(chA))
})

t.Run("start relayer", func(t *testing.T) {
s.StartRelayer(relayer)
})

s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks")

t.Run("packets are relayed between chain A and chain B", func(t *testing.T) {
// packet from chain A to chain B
s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1)
actualBalance, err := s.QueryBalance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom())
s.Require().NoError(err)
expected := testvalues.IBCTransferAmount
s.Require().Equal(expected, actualBalance.Int64())

// packet from chain B to chain A
s.AssertPacketRelayed(ctx, chainB, channelB.PortID, channelB.ChannelID, 1)
actualBalance, err = s.QueryBalance(ctx, chainA, chainAAddress, chainAIBCToken.IBCDenom())
s.Require().NoError(err)
expected = testvalues.IBCTransferAmount
s.Require().Equal(expected, actualBalance.Int64())
})

t.Run("verify channel A upgraded and is fee enabled", func(t *testing.T) {
channel, err := s.QueryChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)

// check the channel version include the fee version
version, err := feetypes.MetadataFromVersion(channel.Version)
s.Require().NoError(err)
s.Require().Equal(feetypes.Version, version.FeeVersion, "the channel version did not include ics29")

// extra check
feeEnabled, err := s.QueryFeeEnabledChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)
s.Require().Equal(true, feeEnabled)
})

t.Run("verify channel B upgraded and is fee enabled", func(t *testing.T) {
channel, err := s.QueryChannel(ctx, chainB, channelB.PortID, channelB.ChannelID)
s.Require().NoError(err)

// check the channel version include the fee version
version, err := feetypes.MetadataFromVersion(channel.Version)
s.Require().NoError(err)
s.Require().Equal(feetypes.Version, version.FeeVersion, "the channel version did not include ics29")

// extra check
feeEnabled, err := s.QueryFeeEnabledChannel(ctx, chainB, channelB.PortID, channelB.ChannelID)
s.Require().NoError(err)
s.Require().Equal(true, feeEnabled)
})

t.Run("prune packet acknowledgements", func(t *testing.T) {
// there should be one ack for the packet that we sent before the upgrade
acks, err := s.QueryPacketAcknowledgements(ctx, chainA, channelA.PortID, channelA.ChannelID, []uint64{})
s.Require().NoError(err)
s.Require().Len(acks, 1)
s.Require().Equal(uint64(1), acks[0].Sequence)

pruneAcksTxResponse := s.PruneAcknowledgements(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, uint64(1))
s.AssertTxSuccess(pruneAcksTxResponse)

// after pruning there should not be any acks
acks, err = s.QueryPacketAcknowledgements(ctx, chainA, channelA.PortID, channelA.ChannelID, []uint64{})
s.Require().NoError(err)
s.Require().Empty(acks)
})

t.Run("stop relayer", func(t *testing.T) {
s.StopRelayer(ctx, relayer)
})

t.Run("recover relayer wallets", func(t *testing.T) {
err := s.RecoverRelayerWallets(ctx, relayer)
s.Require().NoError(err)

chainARelayerWallet, chainBRelayerWallet, err = s.GetRelayerWallets(relayer)
s.Require().NoError(err)

relayerAStartingBalance, err = s.GetChainANativeBalance(ctx, chainARelayerWallet)
s.Require().NoError(err)
t.Logf("relayer A user starting with balance: %d", relayerAStartingBalance)
})

s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks")

t.Run("register and verify counterparty payee", func(t *testing.T) {
_, chainBRelayerUser := s.GetRelayerUsers(ctx)
resp := s.RegisterCounterPartyPayee(ctx, chainB, chainBRelayerUser, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, chainBRelayerWallet.FormattedAddress(), chainARelayerWallet.FormattedAddress())
s.AssertTxSuccess(resp)

address, err := s.QueryCounterPartyPayee(ctx, chainB, chainBRelayerWallet.FormattedAddress(), channelA.Counterparty.ChannelID)
s.Require().NoError(err)
s.Require().Equal(chainARelayerWallet.FormattedAddress(), address)
})

t.Run("start relayer", func(t *testing.T) {
s.StartRelayer(relayer)
})

t.Run("send incentivized transfer packet", func(t *testing.T) {
// before adding fees for the packet, there should not be incentivized packets
packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)
s.Require().Empty(packets)

transferAmount := testvalues.DefaultTransferAmount(chainA.Config().Denom)

msgPayPacketFee := feetypes.NewMsgPayPacketFee(testFee, channelA.PortID, channelA.ChannelID, chainAWallet.FormattedAddress(), nil)
msgTransfer := transfertypes.NewMsgTransfer(channelA.PortID, channelA.ChannelID, transferAmount, chainAWallet.FormattedAddress(), chainBWallet.FormattedAddress(), s.GetTimeoutHeight(ctx, chainB), 0, "")
resp := s.BroadcastMessages(ctx, chainA, chainAWallet, msgPayPacketFee, msgTransfer)
s.AssertTxSuccess(resp)
})

t.Run("packets are relayed", func(t *testing.T) {
packets, err := s.QueryIncentivizedPacketsForChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)
s.Require().Empty(packets)
})

t.Run("tokens are received by walletB", func(t *testing.T) {
actualBalance, err := s.QueryBalance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom())
s.Require().NoError(err)

// walletB has received two IBC transfers of value testvalues.IBCTransferAmount since the start of the test.
expected := 2 * testvalues.IBCTransferAmount
s.Require().Equal(expected, actualBalance.Int64())
})

t.Run("timeout fee is refunded", func(t *testing.T) {
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet)
s.Require().NoError(err)

// once the relayer has relayed the packets, the timeout fee should be refunded.
// walletA has done two IBC transfers of value testvalues.IBCTransferAmount since the start of the test.
expected := testvalues.StartingTokenAmount - (2 * testvalues.IBCTransferAmount) - testFee.AckFee.AmountOf(chainADenom).Int64() - testFee.RecvFee.AmountOf(chainADenom).Int64()
s.Require().Equal(expected, actualBalance)
})

t.Run("relayerA is paid ack and recv fee", func(t *testing.T) {
actualBalance, err := s.GetChainANativeBalance(ctx, chainARelayerWallet)
s.Require().NoError(err)

expected := relayerAStartingBalance + testFee.AckFee.AmountOf(chainADenom).Int64() + testFee.RecvFee.AmountOf(chainADenom).Int64()
s.Require().Equal(expected, actualBalance)
})
}

// TestChannelUpgrade_WithFeeMiddleware_FailsWithTimeoutOnAck tests upgrading a transfer channel to wire up fee middleware but fails on ACK because of timeout
func (s *ChannelTestSuite) TestChannelUpgrade_WithFeeMiddleware_FailsWithTimeoutOnAck() {
t := s.T()
ctx := context.TODO()

relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions())
channelB := channelA.Counterparty
chainA, chainB := s.GetChains()

chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount)
chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount)

s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks")

t.Run("execute gov proposal to set upgrade timeout", func(t *testing.T) {
s.setUpgradeTimeoutParam(ctx, chainB, chainBWallet)
})

t.Run("execute gov proposal to initiate channel upgrade", func(t *testing.T) {
chA, err := s.QueryChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)

s.initiateChannelUpgrade(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, s.createUpgradeFields(chA))
})

t.Run("start relayer", func(t *testing.T) {
s.StartRelayer(relayer)
})

s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks")

t.Run("verify channel A did not upgrade", func(t *testing.T) {
channel, err := s.QueryChannel(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)

s.Require().Equal(channeltypes.OPEN, channel.State, "the channel state is not OPEN")
s.Require().Equal(transfertypes.Version, channel.Version, "the channel version is not ics20-1")

errorReceipt, err := s.QueryUpgradeError(ctx, chainA, channelA.PortID, channelA.ChannelID)
s.Require().NoError(err)
s.Require().Equal(uint64(1), errorReceipt.Sequence)
s.Require().Contains(errorReceipt.Message, "restored channel to pre-upgrade state")
})

t.Run("verify channel B did not upgrade", func(t *testing.T) {
channel, err := s.QueryChannel(ctx, chainB, channelB.PortID, channelB.ChannelID)
s.Require().NoError(err)

s.Require().Equal(channeltypes.OPEN, channel.State, "the channel state is not OPEN")
s.Require().Equal(transfertypes.Version, channel.Version, "the channel version is not ics20-1")

errorReceipt, err := s.QueryUpgradeError(ctx, chainB, channelB.PortID, channelB.ChannelID)
s.Require().NoError(err)
s.Require().Equal(uint64(1), errorReceipt.Sequence)
s.Require().Contains(errorReceipt.Message, "restored channel to pre-upgrade state")
})
}

// createUpgradeFields created the upgrade fields for channel
func (s *ChannelTestSuite) createUpgradeFields(channel channeltypes.Channel) channeltypes.UpgradeFields {
versionMetadata := feetypes.Metadata{
FeeVersion: feetypes.Version,
AppVersion: transfertypes.Version,
}
versionBytes, err := feetypes.ModuleCdc.MarshalJSON(&versionMetadata)
s.Require().NoError(err)

return channeltypes.NewUpgradeFields(channel.Ordering, channel.ConnectionHops, string(versionBytes))
}

// setUpgradeTimeoutParam creates and submits a governance proposal to execute the message to update 04-channel params with a timeout of 1s
func (s *ChannelTestSuite) setUpgradeTimeoutParam(ctx context.Context, chain ibc.Chain, wallet ibc.Wallet) {
const timeoutDelta = 1000000000 // use 1 second as relative timeout to force upgrade timeout on the counterparty
govModuleAddress, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, chain)
s.Require().NoError(err)
s.Require().NotNil(govModuleAddress)

upgradeTimeout := channeltypes.NewTimeout(channeltypes.DefaultTimeout.Height, timeoutDelta)
msg := channeltypes.NewMsgUpdateChannelParams(govModuleAddress.String(), channeltypes.NewParams(upgradeTimeout))
s.ExecuteAndPassGovV1Proposal(ctx, msg, chain, wallet)
}

// initiateChannelUpgrade creates and submits a governance proposal to execute the message to initiate a channel upgrade
func (s *ChannelTestSuite) initiateChannelUpgrade(ctx context.Context, chain ibc.Chain, wallet ibc.Wallet, portID, channelID string, upgradeFields channeltypes.UpgradeFields) {
govModuleAddress, err := s.QueryModuleAccountAddress(ctx, govtypes.ModuleName, chain)
s.Require().NoError(err)
s.Require().NotNil(govModuleAddress)

msg := channeltypes.NewMsgChannelUpgradeInit(portID, channelID, upgradeFields, govModuleAddress.String())
s.ExecuteAndPassGovV1Proposal(ctx, msg, chain, wallet)
}
Loading

0 comments on commit fa2a572

Please sign in to comment.