diff --git a/e2e/tests/transfer/forwarding_test.go b/e2e/tests/transfer/forwarding_test.go index 4e8f9ea124a..5656e670a43 100644 --- a/e2e/tests/transfer/forwarding_test.go +++ b/e2e/tests/transfer/forwarding_test.go @@ -16,6 +16,7 @@ import ( "github.com/cosmos/ibc-go/e2e/testvalues" transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" + channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ) func TestTransferForwardingTestSuite(t *testing.T) { @@ -220,3 +221,96 @@ func (s *TransferForwardingTestSuite) TestForwardingWithUnwindSucceeds() { s.AssertPacketRelayed(ctx, chainB, channelBtoC.PortID, channelBtoC.ChannelID, 1) }) } + +func (s *TransferForwardingTestSuite) TestChannelUpgradeForwarding_Succeeds() { + ctx := context.TODO() + t := s.T() + testName := t.Name() + t.Parallel() + + relayer := s.CreateDefaultPaths(testName) + chains := s.GetAllChains() + + chainA, chainB, chainC := chains[0], chains[1], chains[2] + + opts := s.TransferChannelOptions() + opts.Version = transfertypes.V1 + + channelAtoB, _ := s.CreatePath(ctx, relayer, chains[0], chains[1], ibc.DefaultClientOpts(), opts, testName) + s.Require().Equal(transfertypes.V1, channelAtoB.Version, "the channel version is not ics20-1") + + channelBtoC, _ := s.CreatePath(ctx, relayer, chains[1], chains[2], ibc.DefaultClientOpts(), opts, testName) + s.Require().Equal(transfertypes.V1, channelBtoC.Version, "the channel version is not ics20-1") + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + chainADenom := chainA.Config().Denom + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + + chainCWallet := s.CreateUserOnChainC(ctx, testvalues.StartingTokenAmount) + chainCAddress := chainCWallet.FormattedAddress() + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer, testName) + }) + t.Run("execute gov proposal to initiate channel upgrade", func(t *testing.T) { + chA, err := query.Channel(ctx, chainA, channelAtoB.PortID, channelAtoB.ChannelID) + s.Require().NoError(err) + + upgradeFields := channeltypes.NewUpgradeFields(chA.Ordering, chA.ConnectionHops, transfertypes.V2) + s.InitiateChannelUpgrade(ctx, chainA, chainAWallet, channelAtoB.PortID, channelAtoB.ChannelID, upgradeFields) + + chB, err := query.Channel(ctx, chainB, channelBtoC.PortID, channelBtoC.ChannelID) + s.Require().NoError(err) + + upgradeFields = channeltypes.NewUpgradeFields(chB.Ordering, chB.ConnectionHops, transfertypes.V2) + s.InitiateChannelUpgrade(ctx, chainB, chainBWallet, channelBtoC.PortID, channelBtoC.ChannelID, upgradeFields) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB), "failed to wait for blocks") + + t.Run("verify channel A upgraded and transfer version is ics20-2", func(t *testing.T) { + channel, err := query.Channel(ctx, chainA, channelAtoB.PortID, channelAtoB.ChannelID) + s.Require().NoError(err) + s.Require().Equal(transfertypes.V2, channel.Version, "the channel version is not ics20-2") + }) + + t.Run("verify channel B upgraded and transfer version is ics20-2", func(t *testing.T) { + channel, err := query.Channel(ctx, chainB, channelBtoC.PortID, channelBtoC.ChannelID) + s.Require().NoError(err) + s.Require().Equal(transfertypes.V2, channel.Version, "the channel version is not ics20-2") + }) + + t.Run("IBC transfer from A to C with forwarding through B", func(t *testing.T) { + inFiveMinutes := time.Now().Add(5 * time.Minute).UnixNano() + forwarding := transfertypes.NewForwarding(false, transfertypes.NewHop(channelBtoC.PortID, channelBtoC.ChannelID)) + + msgTransfer := testsuite.GetMsgTransfer( + channelAtoB.PortID, + channelAtoB.ChannelID, + transfertypes.V2, + testvalues.DefaultTransferCoins(chainADenom), + chainAAddress, + chainCAddress, + clienttypes.ZeroHeight(), + uint64(inFiveMinutes), + "", + forwarding) + resp := s.BroadcastMessages(ctx, chainA, chainAWallet, msgTransfer) + s.AssertTxSuccess(resp) + }) + + t.Run("packets are relayed from A to B to C", func(t *testing.T) { + chainCDenom := transfertypes.NewDenom(chainADenom, + transfertypes.NewHop(channelBtoC.Counterparty.PortID, channelBtoC.Counterparty.ChannelID), + transfertypes.NewHop(channelAtoB.Counterparty.PortID, channelAtoB.Counterparty.ChannelID), + ) + + actualBalance, err := query.Balance(ctx, chainC, chainCAddress, chainCDenom.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance.Int64()) + }) +}