-
Notifications
You must be signed in to change notification settings - Fork 620
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
tests(e2e): ics20 v2 multidenom #6290
Changes from 54 commits
c07bca9
e66bd89
034f472
4cc6a85
71f830c
28ff9b6
4e55137
ca056cf
147cf17
9bbfa1a
4f57916
b4244f9
b09f5d7
4c333c5
8b55295
0478cb9
f39d173
9b39944
06ca9a5
7897ef3
786a4f1
3a162ea
5747756
7e2e6df
a84b0e7
43877df
8eae033
dbcff45
bb69698
f19a145
8f86dda
d4b06c8
a9391a4
575403e
50ccd94
87eb32e
e8b9d5a
6d40bc6
c171059
a276219
d55c817
3319e42
0d0b5fc
a284934
2dafbd5
2485db0
6886e3b
14d17ff
3f12a8e
087d52f
feb2383
bdd4ab6
70f9b8c
7d42ff3
d4bd933
fbb6994
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,18 @@ | ||
{ | ||
"chain-a": [ | ||
"main" | ||
], | ||
"chain-b": [ | ||
"main" | ||
], | ||
"entrypoint": [ | ||
"TestTransferTestSuite" | ||
], | ||
"test": [ | ||
"TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom", | ||
"TestMsgTransfer_Fails_InvalidAddress_MultiDenom" | ||
], | ||
"relayer-type": [ | ||
"hermes" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"chain-a": [ | ||
"main" | ||
], | ||
"chain-b": [ | ||
"main" | ||
], | ||
"entrypoint": [ | ||
"TestTransferChannelUpgradesTestSuite" | ||
], | ||
"test": [ | ||
"TestChannelUpgrade_WithICS20v2_Succeeds", | ||
"TestChannelUpgrade_WithFeeMiddlewareAndICS20v2_Succeeds", | ||
"TestChannelDowngrade_WithICS20v1_Succeeds" | ||
], | ||
"relayer-type": [ | ||
"hermes" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"chain-a": [ | ||
"release-v9.0.x" | ||
], | ||
"chain-b": [ | ||
"release-v9.0.x" | ||
], | ||
"entrypoint": [ | ||
"TestTransferChannelUpgradesTestSuite" | ||
], | ||
"test": [ | ||
"TestChannelUpgrade_WithICS20v2_Succeeds", | ||
"TestChannelUpgrade_WithFeeMiddlewareAndICS20v2_Succeeds", | ||
"TestChannelDowngrade_WithICS20v1_Succeeds" | ||
], | ||
"relayer-type": [ | ||
"hermes" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"chain-a": [ | ||
"release-v9.0.x" | ||
], | ||
"chain-b": [ | ||
"release-v9.0.x" | ||
], | ||
"entrypoint": [ | ||
"TestTransferTestSuite" | ||
], | ||
"test": [ | ||
"TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom", | ||
"TestMsgTransfer_Fails_InvalidAddress_MultiDenom" | ||
], | ||
"relayer-type": [ | ||
"hermes" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -150,6 +150,227 @@ func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized() { | |
} | ||
} | ||
|
||
// TestMsgTransfer_Succeeds_MultiDenom will test sending successful IBC transfers from chainA to chainB. | ||
// A multidenom transfer with native chainB tokens and IBC tokens from chainA is executed from chainB to chainA. | ||
func (s *TransferTestSuite) TestMsgTransfer_Succeeds_Nonincentivized_MultiDenom() { | ||
t := s.T() | ||
ctx := context.TODO() | ||
|
||
relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, nil) | ||
chainA, chainB := s.GetChains() | ||
|
||
chainADenom := chainA.Config().Denom | ||
chainBDenom := chainB.Config().Denom | ||
|
||
chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) | ||
chainAAddress := chainAWallet.FormattedAddress() | ||
|
||
chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) | ||
chainBAddress := chainBWallet.FormattedAddress() | ||
|
||
chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) | ||
chainAIBCToken := testsuite.GetIBCToken(chainBDenom, channelA.PortID, channelA.ChannelID) | ||
|
||
t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { | ||
transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, sdk.NewCoins(testvalues.DefaultTransferAmount(chainADenom)), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") | ||
s.AssertTxSuccess(transferTxResp) | ||
}) | ||
|
||
s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") | ||
|
||
t.Run("native chainA tokens are escrowed", func(t *testing.T) { | ||
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) | ||
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. food for thought: I feel like there's a lot of repeated code in our e2e's. Would cut down review time on new pr's if we deduplicated this 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. On my list of ideas for a focus week 👀 |
||
s.Require().NoError(err) | ||
|
||
expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount | ||
s.Require().Equal(expected, actualBalance) | ||
|
||
actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) | ||
s.Require().NoError(err) | ||
|
||
expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) | ||
s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) | ||
}) | ||
|
||
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 := query.Balance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom()) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.IBCTransferAmount | ||
s.Require().Equal(expected, actualBalance.Int64()) | ||
}) | ||
|
||
t.Run("metadata for IBC denomination exists on chainB", func(t *testing.T) { | ||
s.AssertHumanReadableDenom(ctx, chainB, chainADenom, channelA) | ||
}) | ||
|
||
// send the native chainB denom and also the ibc token from chainA | ||
denoms := []string{chainBIBCToken.IBCDenom(), chainBDenom} | ||
var transferCoins []sdk.Coin | ||
for _, denom := range denoms { | ||
transferCoins = append(transferCoins, testvalues.DefaultTransferAmount(denom)) | ||
} | ||
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. [nit] with just two items it might be more readable to just do 2 appends instead of a for loop |
||
|
||
t.Run("native token from chain B and non-native IBC token from chainA, both to chainA", func(t *testing.T) { | ||
transferTxResp := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, transferCoins, chainBAddress, chainAAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") | ||
s.AssertTxSuccess(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, chainB, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) | ||
|
||
t.Run("chain A native denom", func(t *testing.T) { | ||
actualBalance, err := s.GetChainANativeBalance(ctx, chainAWallet) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.StartingTokenAmount | ||
s.Require().Equal(expected, actualBalance) | ||
}) | ||
|
||
t.Run("chain B IBC denom", func(t *testing.T) { | ||
actualBalance, err := query.Balance(ctx, chainA, chainAAddress, chainAIBCToken.IBCDenom()) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.IBCTransferAmount | ||
s.Require().Equal(expected, actualBalance.Int64()) | ||
}) | ||
}) | ||
|
||
t.Run("native chainA tokens are un-escrowed", func(t *testing.T) { | ||
actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) | ||
s.Require().NoError(err) | ||
s.Require().Equal(sdk.NewCoin(chainADenom, sdkmath.NewInt(0)), actualTotalEscrow) // total escrow is zero because tokens have come back | ||
}) | ||
} | ||
|
||
// TestMsgTransfer_Fails_InvalidAddress_MultiDenom attempts to send a multidenom IBC transfer | ||
// to an invalid address and ensures that the tokens on the sending chain are returned to the sender. | ||
func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress_MultiDenom() { | ||
t := s.T() | ||
ctx := context.TODO() | ||
|
||
relayer, channelA := s.SetupChainsRelayerAndChannel(ctx, nil) | ||
chainA, chainB := s.GetChains() | ||
|
||
chainADenom := chainA.Config().Denom | ||
chainBDenom := chainB.Config().Denom | ||
|
||
chainAWallet := s.CreateUserOnChainA(ctx, testvalues.StartingTokenAmount) | ||
chainAAddress := chainAWallet.FormattedAddress() | ||
|
||
chainBWallet := s.CreateUserOnChainB(ctx, testvalues.StartingTokenAmount) | ||
chainBAddress := chainBWallet.FormattedAddress() | ||
|
||
chainBIBCToken := testsuite.GetIBCToken(chainADenom, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID) | ||
|
||
t.Run("native IBC token transfer from chainA to chainB, sender is source of tokens", func(t *testing.T) { | ||
transferTxResp := s.Transfer(ctx, chainA, chainAWallet, channelA.PortID, channelA.ChannelID, sdk.NewCoins(testvalues.DefaultTransferAmount(chainADenom)), chainAAddress, chainBAddress, s.GetTimeoutHeight(ctx, chainB), 0, "") | ||
s.AssertTxSuccess(transferTxResp) | ||
}) | ||
|
||
s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") | ||
|
||
t.Run("native chainA 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) | ||
|
||
actualTotalEscrow, err := query.TotalEscrowForDenom(ctx, chainA, chainADenom) | ||
s.Require().NoError(err) | ||
|
||
expectedTotalEscrow := sdk.NewCoin(chainADenom, sdkmath.NewInt(testvalues.IBCTransferAmount)) | ||
s.Require().Equal(expectedTotalEscrow, actualTotalEscrow) | ||
}) | ||
|
||
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 := query.Balance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom()) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.IBCTransferAmount | ||
s.Require().Equal(expected, actualBalance.Int64()) | ||
}) | ||
|
||
t.Run("metadata for IBC denomination exists on chainB", func(t *testing.T) { | ||
s.AssertHumanReadableDenom(ctx, chainB, chainADenom, channelA) | ||
}) | ||
|
||
// send the native chainB denom and also the ibc token from chainA | ||
denoms := []string{chainBIBCToken.IBCDenom(), chainBDenom} | ||
var transferCoins []sdk.Coin | ||
for _, denom := range denoms { | ||
transferCoins = append(transferCoins, testvalues.DefaultTransferAmount(denom)) | ||
} | ||
|
||
t.Run("stop relayer", func(t *testing.T) { | ||
s.StopRelayer(ctx, relayer) | ||
}) | ||
|
||
t.Run("native token from chain B and non-native IBC token from chainA, both to chainA", func(t *testing.T) { | ||
transferTxResp := s.Transfer(ctx, chainB, chainBWallet, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, transferCoins, chainBAddress, testvalues.InvalidAddress, s.GetTimeoutHeight(ctx, chainA), 0, "") | ||
s.AssertTxSuccess(transferTxResp) | ||
}) | ||
|
||
s.Require().NoError(test.WaitForBlocks(ctx, 5, chainA, chainB), "failed to wait for blocks") | ||
|
||
t.Run("tokens are sent from chain B", func(t *testing.T) { | ||
t.Run("native chainB tokens are escrowed", func(t *testing.T) { | ||
actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.StartingTokenAmount - testvalues.IBCTransferAmount | ||
s.Require().Equal(expected, actualBalance) | ||
}) | ||
|
||
t.Run("non-native chainA IBC denom are burned", func(t *testing.T) { | ||
actualBalance, err := query.Balance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom()) | ||
s.Require().NoError(err) | ||
s.Require().Equal(int64(0), actualBalance.Int64()) | ||
}) | ||
}) | ||
|
||
t.Run("start relayer", func(t *testing.T) { | ||
s.StartRelayer(relayer) | ||
}) | ||
|
||
t.Run("packets are relayed", func(t *testing.T) { | ||
s.AssertPacketRelayed(ctx, chainB, channelA.Counterparty.PortID, channelA.Counterparty.ChannelID, 1) | ||
}) | ||
|
||
t.Run("tokens are returned to sender on chainB", func(t *testing.T) { | ||
t.Run("native chainB denom", func(t *testing.T) { | ||
actualBalance, err := s.GetChainBNativeBalance(ctx, chainBWallet) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.StartingTokenAmount | ||
s.Require().Equal(expected, actualBalance) | ||
}) | ||
|
||
t.Run("non-native chainA IBC denom", func(t *testing.T) { | ||
actualBalance, err := query.Balance(ctx, chainB, chainBAddress, chainBIBCToken.IBCDenom()) | ||
s.Require().NoError(err) | ||
|
||
expected := testvalues.IBCTransferAmount | ||
s.Require().Equal(expected, actualBalance.Int64()) | ||
}) | ||
}) | ||
} | ||
|
||
// TestMsgTransfer_Fails_InvalidAddress attempts to send an IBC transfer to an invalid address and ensures | ||
// that the tokens on the sending chain are unescrowed. | ||
func (s *TransferTestSuite) TestMsgTransfer_Fails_InvalidAddress() { | ||
|
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.
[nit] there is a
testvaluesDefaultTransferCoins
fn that does this sdk.NewCoins call to reduce boilerplate.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.
Happy to do this, but I prefer to do it in a separate PR, since there is already a bunch of places that could benefit from that.