-
Notifications
You must be signed in to change notification settings - Fork 612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
E2E: Add ICA MsgSubmitTx tests (success + failure) #2021
Changes from all commits
8f44301
f470bcf
2297280
4c30485
cd6363c
d87a711
a9ceda1
2ec4c73
39eff2f
17d5840
1c79319
1db8103
57067fb
6890de3
d147af9
917a6a5
27cd4f8
4afd01e
f452e8b
e0e33f1
eb4bcb5
85370a8
d96c0d5
83eaa6f
5328362
289af25
0094b36
bd9ebc4
61a444e
50c9375
bb08d13
f9de6e6
e688082
cf8a8bc
609d93d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wdyt about renaming cc: @damiannolan There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i personally think that this change would be more confusing -- but that's just my opinion because of the language from the spec. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally like host/controller terminology |
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find it a little confusing that we use |
||
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) | ||
}) | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ive got the fail case /unhappy case below as well, so maybe we can keep this naming but break out the unhappy case into a separate test function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
separated out into 2 tests as you suggested!