From 7a2b2354da20b1eaf423bec2bfd8f7994ca116f2 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Mon, 17 Jun 2024 23:50:47 +0200 Subject: [PATCH 1/4] test(transfer): last chain in forwarding being ICS20 v1 --- e2e/tests/core/02-client/client_test.go | 2 +- .../core/03-connection/connection_test.go | 2 +- e2e/tests/transfer/authz_test.go | 4 +- e2e/tests/transfer/base_test.go | 12 +-- e2e/tests/transfer/forwarding_test.go | 83 +++++++++++++++- e2e/tests/transfer/localhost_test.go | 2 +- e2e/tests/transfer/upgrades_test.go | 6 +- e2e/tests/upgrades/upgrade_test.go | 2 +- e2e/testsuite/testsuite.go | 94 ++++++++++--------- 9 files changed, 141 insertions(+), 66 deletions(-) diff --git a/e2e/tests/core/02-client/client_test.go b/e2e/tests/core/02-client/client_test.go index 34980045530..f5e192d49b4 100644 --- a/e2e/tests/core/02-client/client_test.go +++ b/e2e/tests/core/02-client/client_test.go @@ -437,7 +437,7 @@ func (s *ClientTestSuite) TestAllowedClientsParam() { t := s.T() ctx := context.TODO() - _, _ = s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + _, _ = s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version diff --git a/e2e/tests/core/03-connection/connection_test.go b/e2e/tests/core/03-connection/connection_test.go index c9283be5abb..d4317ad736a 100644 --- a/e2e/tests/core/03-connection/connection_test.go +++ b/e2e/tests/core/03-connection/connection_test.go @@ -61,7 +61,7 @@ func (s *ConnectionTestSuite) TestMaxExpectedTimePerBlockParam() { t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version diff --git a/e2e/tests/transfer/authz_test.go b/e2e/tests/transfer/authz_test.go index fc0d4586af0..595f2b975ce 100644 --- a/e2e/tests/transfer/authz_test.go +++ b/e2e/tests/transfer/authz_test.go @@ -48,7 +48,7 @@ func (suite *AuthzTransferTestSuite) TestAuthz_MsgTransfer_Succeeds() { t := suite.T() ctx := context.TODO() - relayer, channelA := suite.SetupChainsRelayerAndChannel(ctx, suite.TransferChannelOptions()) + relayer, channelA := suite.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := suite.GetChains() chainADenom := chainA.Config().Denom @@ -208,7 +208,7 @@ func (suite *AuthzTransferTestSuite) TestAuthz_InvalidTransferAuthorizations() { t := suite.T() ctx := context.TODO() - relayer, channelA := suite.SetupChainsRelayerAndChannel(ctx, suite.TransferChannelOptions()) + relayer, channelA := suite.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := suite.GetChains() chainADenom := chainA.Config().Denom chainAVersion := chainA.Config().Images[0].Version diff --git a/e2e/tests/transfer/base_test.go b/e2e/tests/transfer/base_test.go index fffe14d9228..4e756bf4474 100644 --- a/e2e/tests/transfer/base_test.go +++ b/e2e/tests/transfer/base_test.go @@ -47,7 +47,7 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -156,7 +156,7 @@ func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress() { t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := s.GetChains() chainADenom := chainA.Config().Denom @@ -200,7 +200,7 @@ func (s *TransferTestSuite) TestMsgTransfer_Timeout_Nonincentivized() { t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, _ := s.GetChains() chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) @@ -249,7 +249,7 @@ func (s *TransferTestSuite) TestSendEnabledParam() { t := s.T() ctx := context.TODO() - _, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + _, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -309,7 +309,7 @@ func (s *TransferTestSuite) TestReceiveEnabledParam() { t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := s.GetChains() chainAVersion := chainA.Config().Images[0].Version @@ -429,7 +429,7 @@ func (s *TransferTestSuite) TestMsgTransfer_WithMemo() { t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := s.GetChains() chainADenom := chainA.Config().Denom diff --git a/e2e/tests/transfer/forwarding_test.go b/e2e/tests/transfer/forwarding_test.go index dbebfab1e9c..af3aac6e9a7 100644 --- a/e2e/tests/transfer/forwarding_test.go +++ b/e2e/tests/transfer/forwarding_test.go @@ -6,11 +6,13 @@ import ( "context" "testing" + "github.com/strangelove-ventures/interchaintest/v8/ibc" testifysuite "github.com/stretchr/testify/suite" "github.com/cosmos/ibc-go/e2e/testsuite" "github.com/cosmos/ibc-go/e2e/testsuite/query" "github.com/cosmos/ibc-go/e2e/testvalues" + transfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" ) func TestTransferForwardingTestSuite(t *testing.T) { @@ -28,11 +30,7 @@ func (s *TransferForwardingTestSuite) TestThreeChainSetup() { ctx := context.TODO() t := s.T() - // TODO: note the ThreeChainSetup fn needs to be passed to TransferChannelOptions since it calls - // GetChains which will requires those settings. We should be able to update the function to accept - // the chain version rather than calling GetChains. - // https://github.com/cosmos/ibc-go/issues/6577 - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions(testsuite.ThreeChainSetup()), testsuite.ThreeChainSetup()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions(), testsuite.ThreeChainSetup()) chains := s.GetAllChains() chainA, chainB, chainC := chains[0], chains[1], chains[2] @@ -91,3 +89,78 @@ func (s *TransferForwardingTestSuite) TestThreeChainSetup() { s.Require().Equal(expected, actualBalance.Int64()) }) } + +func (s *TransferForwardingTestSuite) TestForwarding_WithLastChainBeingICS20v1_Succeeds() { + ctx := context.TODO() + t := s.T() + + threeChainSetup := testsuite.ThreeChainSetup() + chainCChainID := "chainC-1" // Setting manually to ensure chainID is set to chainC-1 + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, func(options *ibc.CreateChannelOptions, chain1 ibc.Chain, chain2 ibc.Chain) { + if chain1.Config().ChainID == chainCChainID || chain2.Config().ChainID == chainCChainID { + options.Version = transfertypes.V1 + } + }, func(options *testsuite.ChainOptions) { + threeChainSetup(options) + + options.ChainSpecs[2].ChainID = chainCChainID + }) + chains := s.GetAllChains() + + chainA, chainB, chainC := chains[0], chains[1], chains[2] + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.FormattedAddress() + chainADenom := chainA.Config().Denom + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.FormattedAddress() + chainBDenom := chainB.Config().Denom + + chainCWallet := s.CreateUserOnChainC(ctx, testvalues.StartingTokenAmount) + chainCAddress := chainCWallet.FormattedAddress() + + chainBChannels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainB.Config().ChainID) + s.Require().NoError(err) + // channel between A and B and channel between B and C + s.Require().Len(chainBChannels, 2) + + chainBtoCChannel := chainBChannels[0] + s.Require().Equal(transfertypes.V1, chainBtoCChannel.Version, "the channel version is not ics20-1") + + t.Run("IBC transfer from A to B", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferCoins(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") + s.AssertTxSuccess(transferTxResp) + }) + + t.Run("IBC transfer from B to C", func(t *testing.T) { + transferTxResp := s.Transfer(ctx, chainB, chainBWallet, chainBtoCChannel.PortID, chainBtoCChannel.ChannelID, testvalues.DefaultTransferCoins(chainBDenom), chainBAddress, chainCAddress, s.GetTimeoutHeight(ctx, chainC), 0, "") + s.AssertTxSuccess(transferTxResp) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) + t.Run("packets are relayed from A to B", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + + actualBalance, err := query.Balance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance.Int64()) + }) + + chainCIBCToken := testsuite.GetIBCToken(chainBDenom, chainBtoCChannel.Counterparty.PortID, chainBtoCChannel.Counterparty.ChannelID) + t.Run("packets are relayed from B to C", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainB, chainBtoCChannel.PortID, chainBtoCChannel.ChannelID, 1) + + actualBalance, err := query.Balance(ctx, chainC, chainCAddress, chainCIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance.Int64()) + }) +} diff --git a/e2e/tests/transfer/localhost_test.go b/e2e/tests/transfer/localhost_test.go index 8d3de8e2808..33580b2515e 100644 --- a/e2e/tests/transfer/localhost_test.go +++ b/e2e/tests/transfer/localhost_test.go @@ -35,7 +35,7 @@ func (s *LocalhostTransferTestSuite) TestMsgTransfer_Localhost() { t := s.T() ctx := context.TODO() - _, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + _, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, _ := s.GetChains() chainADenom := chainA.Config().Denom diff --git a/e2e/tests/transfer/upgrades_test.go b/e2e/tests/transfer/upgrades_test.go index 7eb9de1fb53..0b6469a4493 100644 --- a/e2e/tests/transfer/upgrades_test.go +++ b/e2e/tests/transfer/upgrades_test.go @@ -35,7 +35,7 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) channelB := channelA.Counterparty @@ -253,7 +253,7 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) channelB := channelA.Counterparty @@ -343,7 +343,7 @@ func (s *TransferChannelUpgradesTestSuite) TestChannelUpgrade_WithFeeMiddleware_ t := s.T() ctx := context.TODO() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) chainA, chainB := s.GetChains() channelB := channelA.Counterparty diff --git a/e2e/tests/upgrades/upgrade_test.go b/e2e/tests/upgrades/upgrade_test.go index 277157878c8..f0ae83b5e9e 100644 --- a/e2e/tests/upgrades/upgrade_test.go +++ b/e2e/tests/upgrades/upgrade_test.go @@ -747,7 +747,7 @@ func (s *UpgradeTestSuite) TestV8ToV8_1ChainUpgrade_ChannelUpgrades() { testCfg := testsuite.LoadConfig() ctx := context.Background() - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, s.TransferChannelOptions()) + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, testsuite.TransferChannelOptions()) channelB := channelA.Counterparty chainA, chainB := s.GetChains() diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index d62e3d3c603..94f7498d491 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -43,6 +43,8 @@ const ( DefaultGasValue = 500_000_0000 ) +type ChannelOptionsConfiguration func(*ibc.CreateChannelOptions, ibc.Chain, ibc.Chain) + // E2ETestSuite has methods and functionality which can be shared among all test suites. type E2ETestSuite struct { testifysuite.Suite @@ -130,7 +132,7 @@ func (s *E2ETestSuite) GetRelayerUsers(ctx context.Context, chainOpts ...ChainOp // using the given channel options. The relayer returned by this function has not yet started. It should be started // with E2ETestSuite.StartRelayer if needed. // This should be called at the start of every test, unless fine grained control is required. -func (s *E2ETestSuite) SetupChainsRelayerAndChannel(ctx context.Context, channelOpts func(*ibc.CreateChannelOptions), chainSpecOpts ...ChainOptionConfiguration) (ibc.Relayer, ibc.ChannelOutput) { +func (s *E2ETestSuite) SetupChainsRelayerAndChannel(ctx context.Context, channelOpts ChannelOptionsConfiguration, chainSpecOpts ...ChainOptionConfiguration) (ibc.Relayer, ibc.ChannelOutput) { chains := s.GetAllChains(chainSpecOpts...) r := relayer.New(s.T(), *LoadConfig().GetActiveRelayerConfig(), s.logger, s.DockerClient, s.network) @@ -151,12 +153,7 @@ func (s *E2ETestSuite) SetupChainsRelayerAndChannel(ctx context.Context, channel } // newInterchain constructs a new interchain instance that creates channels between the chains. -func (s *E2ETestSuite) newInterchain(ctx context.Context, r ibc.Relayer, chains []ibc.Chain, channelOpts func(*ibc.CreateChannelOptions)) *interchaintest.Interchain { - channelOptions := defaultChannelOpts(chains) - if channelOpts != nil { - channelOpts(&channelOptions) - } - +func (s *E2ETestSuite) newInterchain(ctx context.Context, r ibc.Relayer, chains []ibc.Chain, channelOpts ChannelOptionsConfiguration) *interchaintest.Interchain { ic := interchaintest.NewInterchain() for _, chain := range chains { ic.AddChain(chain) @@ -172,9 +169,17 @@ func (s *E2ETestSuite) newInterchain(ctx context.Context, r ibc.Relayer, chains for i := 0; i < len(chains)-1; i++ { pathName := s.generatePathName() pathNames = append(pathNames, pathName) + + chain1 := chains[i] + chain2 := chains[i+1] + channelOptions := defaultChannelOpts(chains) + if channelOpts != nil { + channelOpts(&channelOptions, chain1, chain2) + } + ic.AddLink(interchaintest.InterchainLink{ - Chain1: chains[i], - Chain2: chains[i+1], + Chain1: chain1, + Chain2: chain2, Relayer: r, Path: pathName, CreateChannelOpts: channelOptions, @@ -520,45 +525,24 @@ func (s *E2ETestSuite) GetRelayerExecReporter() *testreporter.RelayerExecReporte return rep.RelayerExecReporter(s.T()) } -// TransferChannelOptions configures both of the chains to have non-incentivized transfer channels. -func (s *E2ETestSuite) TransferChannelOptions(chainOpts ...ChainOptionConfiguration) func(options *ibc.CreateChannelOptions) { - chainA, chainB := s.GetChains(chainOpts...) - chainAVersion := chainA.Config().Images[0].Version - chainBVersion := chainB.Config().Images[0].Version - - // select the transfer version based on the chain versions - transferVersion := transfertypes.V1 - if testvalues.ICS20v2FeatureReleases.IsSupported(chainAVersion) && testvalues.ICS20v2FeatureReleases.IsSupported(chainBVersion) { - transferVersion = transfertypes.V2 - } - - return func(opts *ibc.CreateChannelOptions) { - opts.Version = transferVersion - opts.SourcePortName = transfertypes.PortID - opts.DestPortName = transfertypes.PortID - } -} - // FeeMiddlewareChannelOptions configures both of the chains to have fee middleware enabled. -func (s *E2ETestSuite) FeeMiddlewareChannelOptions() func(options *ibc.CreateChannelOptions) { - chainA, chainB := s.GetChains() - chainAVersion := chainA.Config().Images[0].Version - chainBVersion := chainB.Config().Images[0].Version - - // select the transfer version based on the chain versions - transferVersion := transfertypes.V1 - if testvalues.ICS20v2FeatureReleases.IsSupported(chainAVersion) && testvalues.ICS20v2FeatureReleases.IsSupported(chainBVersion) { - transferVersion = transfertypes.V2 - } - - versionMetadata := feetypes.Metadata{ - FeeVersion: feetypes.Version, - AppVersion: transferVersion, - } - versionBytes, err := feetypes.ModuleCdc.MarshalJSON(&versionMetadata) - s.Require().NoError(err) +func (s *E2ETestSuite) FeeMiddlewareChannelOptions() ChannelOptionsConfiguration { + return func(opts *ibc.CreateChannelOptions, chainA, chainB ibc.Chain) { + chainAVersion := chainA.Config().Images[0].Version + chainBVersion := chainB.Config().Images[0].Version + + // select the transfer version based on the chain versions + transferVersion := transfertypes.V1 + if testvalues.ICS20v2FeatureReleases.IsSupported(chainAVersion) && testvalues.ICS20v2FeatureReleases.IsSupported(chainBVersion) { + transferVersion = transfertypes.V2 + } - return func(opts *ibc.CreateChannelOptions) { + versionMetadata := feetypes.Metadata{ + FeeVersion: feetypes.Version, + AppVersion: transferVersion, + } + versionBytes, err := feetypes.ModuleCdc.MarshalJSON(&versionMetadata) + s.Require().NoError(err) opts.Version = string(versionBytes) opts.DestPortName = transfertypes.PortID opts.SourcePortName = transfertypes.PortID @@ -666,6 +650,24 @@ func ThreeChainSetup() ChainOptionConfiguration { } } +// TransferChannelOptions configures both of the chains to have non-incentivized transfer channels. +func TransferChannelOptions() ChannelOptionsConfiguration { + return func(opts *ibc.CreateChannelOptions, chainA, chainB ibc.Chain) { + chainAVersion := chainA.Config().Images[0].Version + chainBVersion := chainB.Config().Images[0].Version + + // select the transfer version based on the chain versions + transferVersion := transfertypes.V1 + if testvalues.ICS20v2FeatureReleases.IsSupported(chainAVersion) && testvalues.ICS20v2FeatureReleases.IsSupported(chainBVersion) { + transferVersion = transfertypes.V2 + } + + opts.Version = transferVersion + opts.SourcePortName = transfertypes.PortID + opts.DestPortName = transfertypes.PortID + } +} + // DefaultChainOptions returns the default chain options for the test suite based on the provided chains. func defaultChannelOpts(chains []ibc.Chain) ibc.CreateChannelOptions { channelOptions := ibc.DefaultChannelOpts() From 4326e6fbecad1d833e26a9fd7b9c351f69e1dcca Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Fri, 21 Jun 2024 13:15:39 +0200 Subject: [PATCH 2/4] Finish TestForwarding_WithLastChainBeingICS20v1_Succeeds --- e2e/tests/transfer/forwarding_test.go | 85 ++++++++++++--------------- e2e/testsuite/testsuite.go | 68 +++++++++++---------- 2 files changed, 77 insertions(+), 76 deletions(-) diff --git a/e2e/tests/transfer/forwarding_test.go b/e2e/tests/transfer/forwarding_test.go index d175b011524..8b4f6c0c461 100644 --- a/e2e/tests/transfer/forwarding_test.go +++ b/e2e/tests/transfer/forwarding_test.go @@ -5,6 +5,7 @@ package transfer import ( "context" "testing" + "time" "github.com/strangelove-ventures/interchaintest/v8/ibc" testifysuite "github.com/stretchr/testify/suite" @@ -13,6 +14,7 @@ import ( "github.com/cosmos/ibc-go/e2e/testsuite/query" "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" ) func TestTransferForwardingTestSuite(t *testing.T) { @@ -102,70 +104,61 @@ func (s *TransferForwardingTestSuite) TestForwarding_WithLastChainBeingICS20v1_S ctx := context.TODO() t := s.T() - threeChainSetup := testsuite.ThreeChainSetup() - chainCChainID := "chainC-1" // Setting manually to ensure chainID is set to chainC-1 - relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, func(options *ibc.CreateChannelOptions, chain1 ibc.Chain, chain2 ibc.Chain) { - if chain1.Config().ChainID == chainCChainID || chain2.Config().ChainID == chainCChainID { - options.Version = transfertypes.V1 - } - }, func(options *testsuite.ChainOptions) { - threeChainSetup(options) - - options.ChainSpecs[2].ChainID = chainCChainID - }) - chains := s.GetAllChains() + relayer, chains := s.GetRelayer(), s.GetAllChains() chainA, chainB, chainC := chains[0], chains[1], chains[2] + channelAtoB := s.GetChainAChannel() + + // Creating a new path between chain B and chain C with a ICS20-v1 channel + opts := s.TransferChannelOptions() + opts.Version = transfertypes.V1 + channelBtoC, _ := s.CreateNewPath(ctx, chainB, chainC, ibc.DefaultClientOpts(), opts) + 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) - chainBAddress := chainBWallet.FormattedAddress() - chainBDenom := chainB.Config().Denom - chainCWallet := s.CreateUserOnChainC(ctx, testvalues.StartingTokenAmount) chainCAddress := chainCWallet.FormattedAddress() - chainBChannels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainB.Config().ChainID) - s.Require().NoError(err) - // channel between A and B and channel between B and C - s.Require().Len(chainBChannels, 2) - - chainBtoCChannel := chainBChannels[0] - s.Require().Equal(transfertypes.V1, chainBtoCChannel.Version, "the channel version is not ics20-1") - - t.Run("IBC transfer from A to B", func(t *testing.T) { - transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferCoins(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") - s.AssertTxSuccess(transferTxResp) - }) - - t.Run("IBC transfer from B to C", func(t *testing.T) { - transferTxResp := s.Transfer(ctx, chainB, chainBWallet, chainBtoCChannel.PortID, chainBtoCChannel.ChannelID, testvalues.DefaultTransferCoins(chainBDenom), chainBAddress, chainCAddress, s.GetTimeoutHeight(ctx, chainC), 0, "") - s.AssertTxSuccess(transferTxResp) + 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.Hop{ + PortId: channelBtoC.PortID, + ChannelId: 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("start relayer", func(t *testing.T) { s.StartRelayer(relayer) }) - chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) - t.Run("packets are relayed from A to B", func(t *testing.T) { - s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + t.Run("packets are relayed from A to B to C", func(t *testing.T) { + chainCDenom := transfertypes.NewDenom(chainADenom, + transfertypes.NewTrace(channelBtoC.Counterparty.PortID, channelBtoC.Counterparty.ChannelID), + transfertypes.NewTrace(channelAtoB.Counterparty.PortID, channelAtoB.Counterparty.ChannelID), + ) - actualBalance, err := query.Balance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom()) - s.Require().NoError(err) + s.AssertPacketRelayed(ctx, chainA, channelAtoB.PortID, channelAtoB.ChannelID, 1) + s.AssertPacketRelayed(ctx, chainB, channelBtoC.PortID, channelBtoC.ChannelID, 1) - expected := testvalues.IBCTransferAmount - s.Require().Equal(expected, actualBalance.Int64()) - }) - - chainCIBCToken := testsuite.GetIBCToken(chainBDenom, chainBtoCChannel.Counterparty.PortID, chainBtoCChannel.Counterparty.ChannelID) - t.Run("packets are relayed from B to C", func(t *testing.T) { - s.AssertPacketRelayed(ctx, chainB, chainBtoCChannel.PortID, chainBtoCChannel.ChannelID, 1) - - actualBalance, err := query.Balance(ctx, chainC, chainCAddress, chainCIBCToken.IBCDenom()) + actualBalance, err := query.Balance(ctx, chainC, chainCAddress, chainCDenom.IBCDenom()) s.Require().NoError(err) expected := testvalues.IBCTransferAmount diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index 1a24eb2e142..f168bdf94e6 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -177,52 +177,60 @@ func (s *E2ETestSuite) SetupTest() { s.SetupPath(ibc.DefaultClientOpts(), defaultChannelOpts(s.GetAllChains())) } -// SetupPath creates a path between the chains using the provided client and channel options. +// SetupPath creates paths between the all chains using the provided client and channel options. func (s *E2ETestSuite) SetupPath(clientOpts ibc.CreateClientOptions, channelOpts ibc.CreateChannelOptions) { s.T().Logf("Setting up path for: %s", s.T().Name()) - r := s.relayer ctx := context.TODO() allChains := s.GetAllChains() for i := 0; i < len(allChains)-1; i++ { chainA, chainB := allChains[i], allChains[i+1] - pathName := s.generatePathName() - s.T().Logf("establishing path between %s and %s on path %s", chainA.Config().ChainID, chainB.Config().ChainID, pathName) + _, _ = s.CreateNewPath(ctx, chainA, chainB, clientOpts, channelOpts) + } +} + +func (s *E2ETestSuite) CreateNewPath(ctx context.Context, chainA ibc.Chain, chainB ibc.Chain, clientOpts ibc.CreateClientOptions, channelOpts ibc.CreateChannelOptions) (ibc.ChannelOutput, ibc.ChannelOutput) { + r := s.relayer - err := r.GeneratePath(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID, chainB.Config().ChainID, pathName) - s.Require().NoError(err) + pathName := s.generatePathName() + s.T().Logf("establishing path between %s and %s on path %s", chainA.Config().ChainID, chainB.Config().ChainID, pathName) - // Create new clients - err = r.CreateClients(ctx, s.GetRelayerExecReporter(), pathName, clientOpts) - s.Require().NoError(err) - err = test.WaitForBlocks(ctx, 1, chainA, chainB) - s.Require().NoError(err) + err := r.GeneratePath(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID, chainB.Config().ChainID, pathName) + s.Require().NoError(err) - err = r.CreateConnections(ctx, s.GetRelayerExecReporter(), pathName) - s.Require().NoError(err) - err = test.WaitForBlocks(ctx, 1, chainA, chainB) - s.Require().NoError(err) + // Create new clients + err = r.CreateClients(ctx, s.GetRelayerExecReporter(), pathName, clientOpts) + s.Require().NoError(err) + err = test.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) - err = r.CreateChannel(ctx, s.GetRelayerExecReporter(), pathName, channelOpts) - s.Require().NoError(err) - err = test.WaitForBlocks(ctx, 1, chainA, chainB) - s.Require().NoError(err) + err = r.CreateConnections(ctx, s.GetRelayerExecReporter(), pathName) + s.Require().NoError(err) + err = test.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) - channelsA, err := r.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) - s.Require().NoError(err) + err = r.CreateChannel(ctx, s.GetRelayerExecReporter(), pathName, channelOpts) + s.Require().NoError(err) + err = test.WaitForBlocks(ctx, 1, chainA, chainB) + s.Require().NoError(err) - channelsB, err := r.GetChannels(ctx, s.GetRelayerExecReporter(), chainB.Config().ChainID) - s.Require().NoError(err) + channelsA, err := r.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) + s.Require().NoError(err) - if s.channels[s.T().Name()] == nil { - s.channels[s.T().Name()] = make(map[ibc.Chain][]ibc.ChannelOutput) - } + channelsB, err := r.GetChannels(ctx, s.GetRelayerExecReporter(), chainB.Config().ChainID) + s.Require().NoError(err) - // keep track of channels associated with a given chain for access within the tests. - s.channels[s.T().Name()][chainA] = channelsA - s.channels[s.T().Name()][chainB] = channelsB - s.testPaths[s.T().Name()] = append(s.testPaths[s.T().Name()], pathName) + if s.channels[s.T().Name()] == nil { + s.channels[s.T().Name()] = make(map[ibc.Chain][]ibc.ChannelOutput) } + + // keep track of channels associated with a given chain for access within the tests. + s.channels[s.T().Name()][chainA] = channelsA + s.channels[s.T().Name()][chainB] = channelsB + + s.testPaths[s.T().Name()] = append(s.testPaths[s.T().Name()], pathName) + + return channelsA[len(channelsA)-1], channelsB[len(channelsB)-1] } // GetChainAChannel returns the ibc.ChannelOutput for the current test. From 1f19d338385dc4706494af8e1314de41dacb9906 Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Fri, 21 Jun 2024 14:42:25 +0200 Subject: [PATCH 3/4] Update CreateNewPath signature Co-authored-by: Nikolas De Giorgis --- e2e/testsuite/testsuite.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index f168bdf94e6..5d2612a35bc 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -189,7 +189,7 @@ func (s *E2ETestSuite) SetupPath(clientOpts ibc.CreateClientOptions, channelOpts } } -func (s *E2ETestSuite) CreateNewPath(ctx context.Context, chainA ibc.Chain, chainB ibc.Chain, clientOpts ibc.CreateClientOptions, channelOpts ibc.CreateChannelOptions) (ibc.ChannelOutput, ibc.ChannelOutput) { +func (s *E2ETestSuite) CreateNewPath(ctx context.Context, chainA, chainB ibc.Chain, clientOpts ibc.CreateClientOptions, channelOpts ibc.CreateChannelOptions) (ibc.ChannelOutput, ibc.ChannelOutput) { r := s.relayer pathName := s.generatePathName() From d1188115fc5ab7bf75061f7773146551c2f1d25f Mon Sep 17 00:00:00 2001 From: Gjermund Garaba Date: Fri, 21 Jun 2024 17:38:24 +0200 Subject: [PATCH 4/4] Fix PR review comments --- e2e/testsuite/testsuite.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index 5d2612a35bc..5ae47a5b8df 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -189,7 +189,13 @@ func (s *E2ETestSuite) SetupPath(clientOpts ibc.CreateClientOptions, channelOpts } } -func (s *E2ETestSuite) CreateNewPath(ctx context.Context, chainA, chainB ibc.Chain, clientOpts ibc.CreateClientOptions, channelOpts ibc.CreateChannelOptions) (ibc.ChannelOutput, ibc.ChannelOutput) { +func (s *E2ETestSuite) CreateNewPath( + ctx context.Context, + chainA ibc.Chain, + chainB ibc.Chain, + clientOpts ibc.CreateClientOptions, + channelOpts ibc.CreateChannelOptions, +) (chainAChannel ibc.ChannelOutput, chainBChannel ibc.ChannelOutput) { r := s.relayer pathName := s.generatePathName()