Skip to content
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

test(e2e): failed receive after timeout test case #350

Merged
merged 23 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7ad6f52
add tests for failed receive
mconcat Feb 28, 2025
17c6006
add double spending prevention testing
mconcat Mar 3, 2025
c3233df
add relay packet construction after timeout
mconcat Mar 3, 2025
9416a3f
add notes on non-error result
mconcat Mar 4, 2025
70010aa
lint
mconcat Mar 4, 2025
f5a0e75
Merge branch 'main' into e2e-test-eth-timeout-no-effect
mconcat Mar 4, 2025
b321b2c
apply review
mconcat Mar 6, 2025
92d1182
Merge github.com:cosmos/solidity-ibc-eureka into e2e-test-eth-timeout…
mconcat Mar 6, 2025
1a9258a
Merge branch 'e2e-test-eth-timeout-no-effect' of github.com:cosmos/so…
mconcat Mar 6, 2025
936c07f
Merge branch 'main' into e2e-test-eth-timeout-no-effect
mconcat Mar 7, 2025
53d5a3e
Merge branch 'main' into e2e-test-eth-timeout-no-effect
gjermundgaraba Mar 12, 2025
b08ab7e
add no submission after timeout check to relayer_test
mconcat Mar 12, 2025
abf7c0c
Merge branch 'e2e-test-eth-timeout-no-effect' of github.com:cosmos/so…
mconcat Mar 12, 2025
88550c7
fix test
mconcat Mar 13, 2025
a3162ff
add error message for ICS20 timeout test
mconcat Mar 13, 2025
3f3308a
Merge branch 'main' into e2e-test-eth-timeout-no-effect
mconcat Mar 13, 2025
6ea9b46
add skipping timeout on non-pos chain
mconcat Mar 14, 2025
ceba678
Merge branch 'e2e-test-eth-timeout-no-effect' of github.com:cosmos/so…
mconcat Mar 14, 2025
263bb26
Merge branch 'main' into e2e-test-eth-timeout-no-effect
mconcat Mar 14, 2025
cb7e1d9
apply review: skip only the replay prevention test
mconcat Mar 17, 2025
a969dd6
Merge branch 'e2e-test-eth-timeout-no-effect' of github.com:cosmos/so…
mconcat Mar 17, 2025
151bba0
imp: review items
srdtrk Mar 17, 2025
e73e053
Merge branch 'main' into e2e-test-eth-timeout-no-effect
srdtrk Mar 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions e2e/interchaintestv8/cosmos_relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,17 @@ func (s *CosmosRelayerTestSuite) ICS20TimeoutPacketTest(ctx context.Context, num
transferAmount := big.NewInt(testvalues.TransferAmount)
totalTransferAmount := testvalues.TransferAmount * int64(numOfTransfers)

var originalBalance *sdk.Coin
s.Require().True(s.Run("Retrieve original balance on Chain B", func() {
resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, s.SimdB, &banktypes.QueryBalanceRequest{
Address: simdBUser.FormattedAddress(),
Denom: s.SimdB.Config().Denom,
})
s.Require().NoError(err)
s.Require().NotNil(resp.Balance)
originalBalance = resp.Balance
}))

var txHashes [][]byte
s.Require().True(s.Run("Send transfers on Chain A", func() {
for i := 0; i < numOfTransfers; i++ {
Expand Down Expand Up @@ -456,6 +467,22 @@ func (s *CosmosRelayerTestSuite) ICS20TimeoutPacketTest(ctx context.Context, num
}))
}))

// Prefetching the relay tx before the timeout
var txBodyBz []byte
s.Require().True(s.Run("Retrieve relay tx", func() {
resp, err := s.RelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{
SrcChain: s.SimdA.Config().ChainID,
DstChain: s.SimdB.Config().ChainID,
SourceTxIds: txHashes,
TargetClientId: ibctesting.FirstClientID,
})
s.Require().NoError(err)
s.Require().NotEmpty(resp.Tx)
s.Require().Empty(resp.Address)

txBodyBz = resp.Tx
}))

// Wait until timeout
time.Sleep(30 * time.Second)

Expand Down Expand Up @@ -488,5 +515,32 @@ func (s *CosmosRelayerTestSuite) ICS20TimeoutPacketTest(ctx context.Context, num
s.Require().NotNil(resp.Balance)
s.Require().Equal(testvalues.InitialBalance, resp.Balance.Amount.Int64())
}))

s.Require().True(s.Run("Verify balances on Chain B", func() {
resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, s.SimdB, &banktypes.QueryBalanceRequest{
Address: simdBUser.FormattedAddress(),
Denom: s.SimdB.Config().Denom,
})
s.Require().NoError(err)
s.Require().NotNil(resp.Balance)
s.Require().Equal(originalBalance, resp.Balance)
}))
}))

s.Require().True(s.Run("Constructing relay packet after timeout should fail", func() {
resp, err := s.RelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{
SrcChain: s.SimdA.Config().ChainID,
DstChain: s.SimdB.Config().ChainID,
TimeoutTxIds: txHashes,
TargetClientId: ibctesting.FirstClientID,
})
s.Require().Error(err)
s.Require().Nil(resp)
}))

s.Require().True(s.Run("Receiving packets on Chain B after timeout should fail", func() {
resp, err := s.BroadcastSdkTxBodyGetResult(ctx, s.SimdB, s.SimdBSubmitter, 2_000_000, txBodyBz)
s.Require().ErrorContains(err, "timeout elapsed")
s.Require().Nil(resp)
}))
}
12 changes: 8 additions & 4 deletions e2e/interchaintestv8/e2esuite/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,13 @@ func (s *TestSuite) FetchCosmosHeader(ctx context.Context, chain *cosmos.CosmosC
}

func (s *TestSuite) BroadcastSdkTxBody(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, gas uint64, txBodyBz []byte) *sdk.TxResponse {
resp, err := s.BroadcastSdkTxBodyGetResult(ctx, chain, user, gas, txBodyBz)
s.Require().NoError(err)

return resp
}

func (s *TestSuite) BroadcastSdkTxBodyGetResult(ctx context.Context, chain *cosmos.CosmosChain, user ibc.Wallet, gas uint64, txBodyBz []byte) (*sdk.TxResponse, error) {
var txBody txtypes.TxBody
err := proto.Unmarshal(txBodyBz, &txBody)
s.Require().NoError(err)
Expand All @@ -400,8 +407,5 @@ func (s *TestSuite) BroadcastSdkTxBody(ctx context.Context, chain *cosmos.Cosmos

s.Require().NotZero(len(msgs))

resp, err := s.BroadcastMessages(ctx, chain, user, gas, msgs...)
s.Require().NoError(err)

return resp
return s.BroadcastMessages(ctx, chain, user, gas, msgs...)
}
58 changes: 58 additions & 0 deletions e2e/interchaintestv8/ibc_eureka_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,19 @@ func (s *IbcEurekaTestSuite) ICS20TimeoutPacketFromEthereumTest(
cosmosUserWallet := s.CosmosUsers[0]
cosmosUserAddress := cosmosUserWallet.FormattedAddress()

var originalBalance *sdk.Coin
s.Require().True(s.Run("Retrieve original balance", func() {
denomOnCosmos := transfertypes.NewDenom(s.contractAddresses.Erc20, transfertypes.NewHop(transfertypes.PortID, testvalues.FirstWasmClientID))

resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, simd, &banktypes.QueryBalanceRequest{
Address: cosmosUserAddress,
Denom: denomOnCosmos.IBCDenom(),
})
s.Require().NoError(err)
s.Require().NotNil(resp.Balance)
originalBalance = resp.Balance
}))

s.Require().True(s.Run("Approve the ICS20Transfer.sol contract to spend the erc20 tokens", func() {
ics20Address := ethcommon.HexToAddress(s.contractAddresses.Ics20Transfer)
tx, err := s.erc20Contract.Approve(s.GetTransactOpts(s.key, eth), ics20Address, totalTransferAmount)
Expand Down Expand Up @@ -1207,6 +1220,21 @@ func (s *IbcEurekaTestSuite) ICS20TimeoutPacketFromEthereumTest(
}))
}))

var txBodyBz []byte
s.Require().True(s.Run("Prefetch relay tx", func() {
resp, err := s.RelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{
SrcChain: eth.ChainID.String(),
DstChain: simd.Config().ChainID,
SourceTxIds: ethSendTxHashes,
TargetClientId: testvalues.FirstWasmClientID,
})
s.Require().NoError(err)
s.Require().NotEmpty(resp.Tx)
s.Require().Empty(resp.Address)

txBodyBz = resp.Tx
}))

// sleep for 45 seconds to let the packet timeout
time.Sleep(45 * time.Second)

Expand Down Expand Up @@ -1251,6 +1279,36 @@ func (s *IbcEurekaTestSuite) ICS20TimeoutPacketFromEthereumTest(
s.Require().NoError(err)
s.Require().Zero(escrowBalance.Int64())
}))

s.Require().True(s.Run("Verify no balance on Cosmos chain", func() {
denomOnCosmos := transfertypes.NewDenom(s.contractAddresses.Erc20, transfertypes.NewHop(transfertypes.PortID, testvalues.FirstWasmClientID))

resp, err := e2esuite.GRPCQuery[banktypes.QueryBalanceResponse](ctx, simd, &banktypes.QueryBalanceRequest{
Address: cosmosUserAddress,
Denom: denomOnCosmos.IBCDenom(),
})
s.Require().NoError(err)
s.Require().Equal(originalBalance, resp.Balance)
}))
}))

s.Require().True(s.Run("Constructing relay packet after timeout should fail", func() {
resp, err := s.RelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{
SrcChain: eth.ChainID.String(),
DstChain: simd.Config().ChainID,
SourceTxIds: ethSendTxHashes,
TargetClientId: testvalues.FirstWasmClientID,
})
// TODO: https://github.com/cosmos/solidity-ibc-eureka/issues/363
// The following assertions should be Error and Nil, but the relayer returns a valid response currently.
s.Require().NoError(err)
s.Require().NotNil(resp)
}))

s.Require().True(s.Run("Receive packets on Cosmos chain after timeout", func() {
resp, err := s.BroadcastSdkTxBodyGetResult(ctx, simd, s.SimdRelayerSubmitter, 2_000_000, txBodyBz)
s.Require().Error(err)
s.Require().Nil(resp)
}))
}

Expand Down
36 changes: 36 additions & 0 deletions e2e/interchaintestv8/relayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/hex"
"fmt"
"math/big"
"os"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -960,6 +961,20 @@ func (s *RelayerTestSuite) ICS20TimeoutFromCosmosTimeoutTest(
}))
}))

var txBodyBz []byte
s.Require().True(s.Run("Prefetch relay tx", func() {
resp, err := s.RelayerClient.RelayByTx(context.Background(), &relayertypes.RelayByTxRequest{
SrcChain: simd.Config().ChainID,
DstChain: eth.ChainID.String(),
SourceTxIds: sendTxHashes,
TargetClientId: testvalues.CustomClientID,
})
s.Require().NoError(err)
s.Require().NotEmpty(resp.Tx)

txBodyBz = resp.Tx
}))

// sleep for 45 seconds to let the packet timeout
time.Sleep(45 * time.Second)

Expand Down Expand Up @@ -994,4 +1009,25 @@ func (s *RelayerTestSuite) ICS20TimeoutFromCosmosTimeoutTest(
s.Require().Equal(testvalues.InitialBalance, resp.Balance.Amount.Int64())
}))
}))

s.Require().True(s.Run("Verify no balance on Ethereum", func() {
denomOnEthereum := transfertypes.NewDenom(transferCoin.Denom, transfertypes.NewHop(transfertypes.PortID, testvalues.CustomClientID))

_, err := s.ics20Contract.IbcERC20Contract(nil, denomOnEthereum.Path())
// Ethereum side did not received the packet, ERC20 contract corresponding to the denom does not exist
s.Require().Error(err)
}))

// We are skipping the replay attack test on non-PoS mode
// In PoW mode, the test below will NOT fail as the mock light client accepts all proofs without verification.
if os.Getenv(testvalues.EnvKeyEthTestnetType) != testvalues.EthTestnetTypePoS {
s.T().Skip("Skipping replay attack test on non-PoS mode")
}

s.Require().True(s.Run("Receive packets on Ethereum after timeout should fail", func() {
ics26Address := ethcommon.HexToAddress(s.contractAddresses.Ics26Router)
receipt, err := eth.BroadcastTx(ctx, s.EthRelayerSubmitter, 5_000_000, ics26Address, txBodyBz)
s.Require().Error(err)
s.Require().Nil(receipt)
}))
}
Loading