diff --git a/e2e/tests/transfer/base_test.go b/e2e/tests/transfer/base_test.go index 72f3111ed14..8307d41e46d 100644 --- a/e2e/tests/transfer/base_test.go +++ b/e2e/tests/transfer/base_test.go @@ -2,14 +2,11 @@ package transfer import ( "context" - "fmt" "strconv" "testing" "time" - sdk "github.com/cosmos/cosmos-sdk/types" paramsproposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" - "github.com/strangelove-ventures/ibctest/chain/cosmos" "github.com/strangelove-ventures/ibctest/ibc" "github.com/strangelove-ventures/ibctest/test" "github.com/stretchr/testify/suite" @@ -17,7 +14,6 @@ import ( "github.com/cosmos/ibc-go/e2e/testsuite" "github.com/cosmos/ibc-go/e2e/testvalues" transfertypes "github.com/cosmos/ibc-go/v5/modules/apps/transfer/types" - clienttypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types" ibctesting "github.com/cosmos/ibc-go/v5/testing" ) @@ -29,14 +25,6 @@ type TransferTestSuite struct { testsuite.E2ETestSuite } -// Transfer broadcasts a MsgTransfer message. -func (s *TransferTestSuite) Transfer(ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, - portID, channelID string, token sdk.Coin, sender, receiver string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, -) (sdk.TxResponse, error) { - msg := transfertypes.NewMsgTransfer(portID, channelID, token, sender, receiver, timeoutHeight, timeoutTimestamp) - return s.BroadcastMessages(ctx, chain, user, msg) -} - // QueryTransferSendEnabledParam queries the on-chain send enabled param for the transfer module func (s *TransferTestSuite) QueryTransferSendEnabledParam(ctx context.Context, chain ibc.Chain) bool { queryClient := s.GetChainGRCPClients(chain).ParamsQueryClient @@ -105,7 +93,7 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { s.StartRelayer(relayer) }) - chainBIBCToken := s.getIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) + chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) t.Run("packets are relayed", func(t *testing.T) { s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) @@ -300,7 +288,7 @@ func (s *TransferTestSuite) TestReceiveEnabledParam() { var ( chainBDenom = chainB.Config().Denom - chainAIBCToken = s.getIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) // IBC token sent to chainA + chainAIBCToken = testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) // IBC token sent to chainA chainAAddress = chainAWallet.Bech32Address(chainA.Config().Bech32Prefix) chainBAddress = chainBWallet.Bech32Address(chainB.Config().Bech32Prefix) @@ -398,8 +386,3 @@ func transferChannelOptions() func(options *ibc.CreateChannelOptions) { opts.DestPortName = transfertypes.PortID } } - -// getIBCToken returns the denomination of the full token denom sent to the receiving channel -func (s *TransferTestSuite) getIBCToken(fullTokenDenom string, portID, channelID string) transfertypes.DenomTrace { - return transfertypes.ParseDenomTrace(fmt.Sprintf("%s/%s/%s", portID, channelID, fullTokenDenom)) -} diff --git a/e2e/tests/upgrades/upgrade_test.go b/e2e/tests/upgrades/upgrade_test.go index 38a45f61925..25033347fb3 100644 --- a/e2e/tests/upgrades/upgrade_test.go +++ b/e2e/tests/upgrades/upgrade_test.go @@ -19,8 +19,9 @@ import ( ) const ( - haltHeight = uint64(50) + haltHeight = uint64(100) blocksAfterUpgrade = uint64(10) + defaultUpgradeName = "normal upgrade" ) func TestUpgradeTestSuite(t *testing.T) { @@ -73,6 +74,7 @@ func (s *UpgradeTestSuite) UpgradeChain(ctx context.Context, chain *cosmos.Cosmo } func (s *UpgradeTestSuite) TestV4ToV5ChainUpgrade() { + t := s.T() // TODO: temporarily hard code the version upgrades. oldVersion := "v4.0.0" targetVersion := "pr-2144" // v5 version with upgrade handler, replace with v5.0.0-rc3 when it is cut. @@ -80,10 +82,103 @@ func (s *UpgradeTestSuite) TestV4ToV5ChainUpgrade() { s.Require().NoError(os.Setenv(testconfig.ChainBTagEnv, oldVersion)) ctx := context.Background() + relayer, channelA := s.SetupChainsRelayerAndChannel(ctx) + chainA, chainB := s.GetChains() - s.SetupChainsRelayerAndChannel(ctx) - chainA, _ := s.GetChains() + var ( + chainADenom = chainA.Config().Denom + chainBIBCToken = testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) // IBC token sent to chainB - chainAUser := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) - s.UpgradeChain(ctx, chainA, chainAUser, "normal upgrade", targetVersion) + chainBDenom = chainB.Config().Denom + chainAIBCToken = testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) // IBC token sent to chainA + ) + + // create separate user specifically for the upgrade proposal to more easily verify starting + // and end balances of the chainA users. + chainAUpgradeProposalWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + + chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) + chainAAddress := chainAWallet.Bech32Address(chainA.Config().Bech32Prefix) + + chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) + chainBAddress := chainBWallet.Bech32Address(chainB.Config().Bech32Prefix) + + s.Require().NoError(test.WaitForBlocks(ctx, 1, chainA, chainB), "failed to wait for blocks") + + t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0) + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + t.Run("tokens are escrowed", func(t *testing.T) { + actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) + s.Require().NoError(err) + + expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + t.Run("start relayer", func(t *testing.T) { + s.StartRelayer(relayer) + }) + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 1) + + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + t.Run("upgrade chainA", func(t *testing.T) { + s.UpgradeChain(ctx, chainA, chainAUpgradeProposalWallet, defaultUpgradeName, targetVersion) + }) + + t.Run("restart relayer", func(t *testing.T) { + s.StopRelayer(ctx, relayer) + s.StartRelayer(relayer) + }) + + t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, testvalues.DefaultTransferAmount(chainADenom), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0) + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.PortID, channelA.ChannelID, 2) + + actualBalance, err := chainB.GetBalance(ctx, chainBAddress, chainBIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount * 2 + s.Require().Equal(expected, actualBalance) + }) + + t.Run("ensure packets can be received, send from chainB to chainA", func(t *testing.T) { + t.Run("send from chainB to chainA", func(t *testing.T) { + transferTxResp, err := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, testvalues.DefaultTransferAmount(chainBDenom), chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0) + s.Require().NoError(err) + s.AssertValidTxResponse(transferTxResp) + }) + + s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") + + t.Run("packets are relayed", func(t *testing.T) { + s.AssertPacketRelayed(ctx, chainA, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) + + actualBalance, err := chainA.GetBalance(ctx, chainAAddress, chainAIBCToken.IBCDenom()) + s.Require().NoError(err) + + expected := testvalues.IBCTransferAmount + s.Require().Equal(expected, actualBalance) + }) + }) } diff --git a/e2e/testsuite/testsuite.go b/e2e/testsuite/testsuite.go index 0547210f095..5de38e505e7 100644 --- a/e2e/testsuite/testsuite.go +++ b/e2e/testsuite/testsuite.go @@ -25,6 +25,7 @@ import ( "github.com/cosmos/ibc-go/e2e/testconfig" "github.com/cosmos/ibc-go/e2e/testvalues" feetypes "github.com/cosmos/ibc-go/v5/modules/apps/29-fee/types" + transfertypes "github.com/cosmos/ibc-go/v5/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types" ) @@ -286,6 +287,14 @@ func (s *E2ETestSuite) RecoverRelayerWallets(ctx context.Context, relayer ibc.Re return nil } +// Transfer broadcasts a MsgTransfer message. +func (s *E2ETestSuite) Transfer(ctx context.Context, chain *cosmos.CosmosChain, user *ibc.Wallet, + portID, channelID string, token sdk.Coin, sender, receiver string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, +) (sdk.TxResponse, error) { + msg := transfertypes.NewMsgTransfer(portID, channelID, token, sender, receiver, timeoutHeight, timeoutTimestamp) + return s.BroadcastMessages(ctx, chain, user, msg) +} + // StartRelayer starts the given relayer. func (s *E2ETestSuite) StartRelayer(relayer ibc.Relayer) { if s.startRelayerFn == nil { @@ -457,3 +466,8 @@ func (s *E2ETestSuite) ExecuteGovProposal(ctx context.Context, chain *cosmos.Cos s.Require().NoError(err) s.Require().Equal(govtypes.StatusPassed, proposal.Status) } + +// GetIBCToken returns the denomination of the full token denom sent to the receiving channel +func GetIBCToken(fullTokenDenom string, portID, channelID string) transfertypes.DenomTrace { + return transfertypes.ParseDenomTrace(fmt.Sprintf("%s/%s/%s", portID, channelID, fullTokenDenom)) +}