-
Notifications
You must be signed in to change notification settings - Fork 634
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
E2E: Add ICA MsgSubmitTx tests (success + failure) (#2021)
- Loading branch information
Showing
7 changed files
with
283 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,225 @@ | ||
package e2e | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
ibctest "github.com/strangelove-ventures/ibctest" | ||
"github.com/strangelove-ventures/ibctest/chain/cosmos" | ||
"github.com/strangelove-ventures/ibctest/ibc" | ||
"github.com/strangelove-ventures/ibctest/test" | ||
"github.com/stretchr/testify/suite" | ||
|
||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" | ||
intertxtypes "github.com/cosmos/interchain-accounts/x/inter-tx/types" | ||
|
||
"github.com/cosmos/ibc-go/e2e/testconfig" | ||
"github.com/cosmos/ibc-go/e2e/testsuite" | ||
"github.com/cosmos/ibc-go/e2e/testvalues" | ||
ibctesting "github.com/cosmos/ibc-go/v5/testing" | ||
) | ||
|
||
func TestInterchainAccountsTestSuite(t *testing.T) { | ||
// NOTE: this is a temporary mechanism to enable this test to run alongside the simd tests. | ||
// This will be removed in a follow up PR and properly parameterized in a github workflow. | ||
testconfig.SetChainBinaryVersions( | ||
"ghcr.io/cosmos/ibc-go-icad", "master", "icad", "ghcr.io/cosmos/ibc-go-icad", "master", | ||
) | ||
suite.Run(t, new(InterchainAccountsTestSuite)) | ||
} | ||
|
||
type InterchainAccountsTestSuite struct { | ||
testsuite.E2ETestSuite | ||
} | ||
|
||
// RegisterInterchainAccount will attempt to register an interchain account on the counterparty chain. | ||
func (s *InterchainAccountsTestSuite) RegisterInterchainAccount(ctx context.Context, chain *cosmos.CosmosChain, user *ibctest.User, msgRegisterAccount *intertxtypes.MsgRegisterAccount) error { | ||
txResp, err := s.BroadcastMessages(ctx, chain, user, msgRegisterAccount) | ||
s.AssertValidTxResponse(txResp) | ||
return err | ||
} | ||
|
||
func (s *InterchainAccountsTestSuite) TestMsgSubmitTx_SuccessfulTransfer() { | ||
t := s.T() | ||
ctx := context.TODO() | ||
|
||
// setup relayers and connection-0 between two chains | ||
// channel-0 is a transfer channel but it will not be used in this test case | ||
relayer, _ := s.SetupChainsRelayerAndChannel(ctx) | ||
chainA, chainB := s.GetChains() | ||
|
||
// setup 2 accounts: controller account on chain A, a second chain B account. | ||
// host account will be created when the ICA is registered | ||
controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) | ||
chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) | ||
var hostAccount string | ||
|
||
t.Run("register interchain account", func(t *testing.T) { | ||
version := "" // allow app to handle the version as appropriate. | ||
msgRegisterAccount := intertxtypes.NewMsgRegisterAccount(controllerAccount.Bech32Address(chainA.Config().Bech32Prefix), ibctesting.FirstConnectionID, version) | ||
err := s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterAccount) | ||
s.Require().NoError(err) | ||
}) | ||
|
||
t.Run("start relayer", func(t *testing.T) { | ||
s.StartRelayer(relayer) | ||
}) | ||
|
||
t.Run("verify interchain account", func(t *testing.T) { | ||
var err error | ||
hostAccount, err = s.QueryInterchainAccount(ctx, chainA, controllerAccount.Bech32Address(chainA.Config().Bech32Prefix), ibctesting.FirstConnectionID) | ||
s.Require().NoError(err) | ||
s.Require().NotZero(len(hostAccount)) | ||
|
||
channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) | ||
s.Require().NoError(err) | ||
s.Require().Equal(len(channels), 2) | ||
}) | ||
|
||
t.Run("interchain account executes a bank transfer on behalf of the corresponding owner account", func(t *testing.T) { | ||
|
||
t.Run("fund interchain account wallet", func(t *testing.T) { | ||
// fund the host account account so it has some $$ to send | ||
err := chainB.SendFunds(ctx, ibctest.FaucetAccountKeyName, ibc.WalletAmount{ | ||
Address: hostAccount, | ||
Amount: testvalues.StartingTokenAmount, | ||
Denom: chainB.Config().Denom, | ||
}) | ||
s.Require().NoError(err) | ||
}) | ||
|
||
t.Run("broadcast MsgSubmitTx", func(t *testing.T) { | ||
// assemble bank transfer message from host account to user account on host chain | ||
msgSend := &banktypes.MsgSend{ | ||
FromAddress: hostAccount, | ||
ToAddress: chainBAccount.Bech32Address(chainB.Config().Bech32Prefix), | ||
Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), | ||
} | ||
|
||
// assemble submitMessage tx for intertx | ||
msgSubmitTx, err := intertxtypes.NewMsgSubmitTx( | ||
msgSend, | ||
ibctesting.FirstConnectionID, | ||
controllerAccount.Bech32Address(chainA.Config().Bech32Prefix), | ||
) | ||
s.Require().NoError(err) | ||
|
||
// broadcast submitMessage tx from controller account on chain A | ||
// this message should trigger the sending of an ICA packet over channel-1 (channel created between controller and host) | ||
// this ICA packet contains the assembled bank transfer message from above, which will be executed by the host account on the host chain. | ||
resp, err := s.BroadcastMessages( | ||
ctx, | ||
chainA, | ||
controllerAccount, | ||
msgSubmitTx, | ||
) | ||
|
||
s.AssertValidTxResponse(resp) | ||
s.Require().NoError(err) | ||
|
||
s.Require().NoError(test.WaitForBlocks(ctx, 10, chainA, chainB)) | ||
}) | ||
|
||
t.Run("verify tokens transferred", func(t *testing.T) { | ||
balance, err := chainB.GetBalance(ctx, chainBAccount.Bech32Address(chainB.Config().Bech32Prefix), chainB.Config().Denom) | ||
s.Require().NoError(err) | ||
|
||
_, err = chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.IBCTransferAmount + testvalues.StartingTokenAmount | ||
s.Require().Equal(expected, balance) | ||
}) | ||
}) | ||
} | ||
|
||
func (s *InterchainAccountsTestSuite) TestMsgSubmitTx_FailedTransfer_InsufficientFunds() { | ||
t := s.T() | ||
ctx := context.TODO() | ||
|
||
// setup relayers and connection-0 between two chains | ||
// channel-0 is a transfer channel but it will not be used in this test case | ||
relayer, _ := s.SetupChainsRelayerAndChannel(ctx) | ||
chainA, chainB := s.GetChains() | ||
|
||
// setup 2 accounts: controller account on chain A, a second chain B account. | ||
// host account will be created when the ICA is registered | ||
controllerAccount := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) | ||
chainBAccount := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) | ||
var hostAccount string | ||
|
||
t.Run("register interchain account", func(t *testing.T) { | ||
version := "" // allow app to handle the version as appropriate. | ||
msgRegisterAccount := intertxtypes.NewMsgRegisterAccount(controllerAccount.Bech32Address(chainA.Config().Bech32Prefix), ibctesting.FirstConnectionID, version) | ||
err := s.RegisterInterchainAccount(ctx, chainA, controllerAccount, msgRegisterAccount) | ||
s.Require().NoError(err) | ||
}) | ||
|
||
t.Run("start relayer", func(t *testing.T) { | ||
s.StartRelayer(relayer) | ||
}) | ||
|
||
t.Run("verify interchain account", func(t *testing.T) { | ||
var err error | ||
hostAccount, err = s.QueryInterchainAccount(ctx, chainA, controllerAccount.Bech32Address(chainA.Config().Bech32Prefix), ibctesting.FirstConnectionID) | ||
s.Require().NoError(err) | ||
s.Require().NotZero(len(hostAccount)) | ||
|
||
channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) | ||
s.Require().NoError(err) | ||
s.Require().Equal(len(channels), 2) | ||
}) | ||
|
||
t.Run("fail to execute bank transfer over ICA", func(t *testing.T) { | ||
t.Run("verify empty host wallet", func(t *testing.T) { | ||
hostAccountBalance, err := chainB.GetBalance(ctx, hostAccount, chainB.Config().Denom) | ||
s.Require().NoError(err) | ||
s.Require().Zero(hostAccountBalance) | ||
}) | ||
|
||
t.Run("broadcast MsgSubmitTx", func(t *testing.T) { | ||
// assemble bank transfer message from host account to user account on host chain | ||
transferMsg := &banktypes.MsgSend{ | ||
FromAddress: hostAccount, | ||
ToAddress: chainBAccount.Bech32Address(chainB.Config().Bech32Prefix), | ||
Amount: sdk.NewCoins(testvalues.DefaultTransferAmount(chainB.Config().Denom)), | ||
} | ||
|
||
// assemble submitMessage tx for intertx | ||
submitMsg, err := intertxtypes.NewMsgSubmitTx( | ||
transferMsg, | ||
ibctesting.FirstConnectionID, | ||
controllerAccount.Bech32Address(chainA.Config().Bech32Prefix), | ||
) | ||
s.Require().NoError(err) | ||
|
||
// broadcast submitMessage tx from controller account on chain A | ||
// this message should trigger the sending of an ICA packet over channel-1 (channel created between controller and host) | ||
// this ICA packet contains the assembled bank transfer message from above, which will be executed by the host account on the host chain. | ||
resp, err := s.BroadcastMessages( | ||
ctx, | ||
chainA, | ||
controllerAccount, | ||
submitMsg, | ||
) | ||
|
||
s.AssertValidTxResponse(resp) | ||
s.Require().NoError(err) | ||
}) | ||
|
||
t.Run("packets are relayed", func(t *testing.T) { | ||
channels, err := relayer.GetChannels(ctx, s.GetRelayerExecReporter(), chainA.Config().ChainID) | ||
s.Require().NoError(err) | ||
s.AssertPacketRelayed(ctx, chainA, channels[1].PortID, channels[1].ChannelID, 1) | ||
}) | ||
|
||
t.Run("verify balance is the same", func(t *testing.T) { | ||
balance, err := chainB.GetBalance(ctx, chainBAccount.Bech32Address(chainB.Config().Bech32Prefix), chainB.Config().Denom) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.StartingTokenAmount | ||
s.Require().Equal(expected, balance) | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.