From d7219fc72ed4aab0d9776fa7c55481d24ef3f82e Mon Sep 17 00:00:00 2001 From: Andrew Gouin Date: Mon, 3 Apr 2023 19:03:56 -0600 Subject: [PATCH] Make ICA waits more explicit (#1157) * Make ICA waits more explicit * poll for timeout * poll for channel close confirm * Comment out sqlite db file for scenarios tests --- interchaintest/ica_channel_close_test.go | 81 ++++++++++++------- interchaintest/interchain_accounts_test.go | 81 +++++++++++++------ interchaintest/relay_many_test.go | 9 ++- interchaintest/relayer_override_test.go | 9 ++- .../tendermint_v0.37_boundary_test.go | 11 +-- 5 files changed, 121 insertions(+), 70 deletions(-) diff --git a/interchaintest/ica_channel_close_test.go b/interchaintest/ica_channel_close_test.go index 30e4dcee0..b21a41c32 100644 --- a/interchaintest/ica_channel_close_test.go +++ b/interchaintest/ica_channel_close_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/crypto/keyring" + chantypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" relayerinterchaintest "github.com/cosmos/relayer/v2/interchaintest" interchaintest "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" @@ -61,7 +62,7 @@ func TestScenarioICAChannelClose(t *testing.T) { chains, err := cf.Chains(t.Name()) require.NoError(t, err) - chain1, chain2 := chains[0], chains[1] + chain1, chain2 := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) // Get a relayer instance r := relayerinterchaintest. @@ -84,11 +85,12 @@ func TestScenarioICAChannelClose(t *testing.T) { }) require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ - TestName: t.Name(), - Client: client, - NetworkID: network, - SkipPathCreation: true, - BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + TestName: t.Name(), + Client: client, + NetworkID: network, + SkipPathCreation: true, + // Uncomment this to load blocks, txs, msgs, and events into sqlite db as test runs + // BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), })) // Fund a user account on chain1 and chain2 @@ -105,14 +107,14 @@ func TestScenarioICAChannelClose(t *testing.T) { err = r.CreateClients(ctx, eRep, pathName, ibc.CreateClientOptions{TrustingPeriod: "330h"}) require.NoError(t, err) - err = testutil.WaitForBlocks(ctx, 5, chain1, chain2) + err = testutil.WaitForBlocks(ctx, 2, chain1, chain2) require.NoError(t, err) // Create a new connection err = r.CreateConnections(ctx, eRep, pathName) require.NoError(t, err) - err = testutil.WaitForBlocks(ctx, 5, chain1, chain2) + err = testutil.WaitForBlocks(ctx, 2, chain1, chain2) require.NoError(t, err) // Query for the newly created connection @@ -120,6 +122,19 @@ func TestScenarioICAChannelClose(t *testing.T) { require.NoError(t, err) require.Equal(t, 1, len(connections)) + // Start the relayer and set the cleanup function. + err = r.StartRelayer(ctx, eRep, pathName) + require.NoError(t, err) + + t.Cleanup( + func() { + err := r.StopRelayer(ctx, eRep) + if err != nil { + t.Logf("an error occurred while stopping the relayer: %s", err) + } + }, + ) + // Register a new interchain account on chain2, on behalf of the user acc on chain1 chain1Addr := chain1User.(*cosmos.CosmosWallet).FormattedAddressWithPrefix(chain1.Config().Bech32Prefix) @@ -136,21 +151,18 @@ func TestScenarioICAChannelClose(t *testing.T) { _, _, err = chain1.Exec(ctx, registerICA, nil) require.NoError(t, err) - // Start the relayer and set the cleanup function. - err = r.StartRelayer(ctx, eRep, pathName) + ir := cosmos.DefaultEncoding().InterfaceRegistry + + c2h, err := chain2.Height(ctx) require.NoError(t, err) - t.Cleanup( - func() { - err := r.StopRelayer(ctx, eRep) - if err != nil { - t.Logf("an error occured while stopping the relayer: %s", err) - } - }, - ) + channelFound := func(found *chantypes.MsgChannelOpenConfirm) bool { + return found.PortId == "icahost" + } - // Wait for relayer to start up and finish channel handshake - err = testutil.WaitForBlocks(ctx, 15, chain1, chain2) + // Wait for channel open confirm + _, err = cosmos.PollForMessage(ctx, chain2, ir, + c2h, c2h+30, channelFound) require.NoError(t, err) // Query for the newly registered interchain account @@ -185,10 +197,6 @@ func TestScenarioICAChannelClose(t *testing.T) { err = chain2.SendFunds(ctx, chain2User.KeyName(), transfer) require.NoError(t, err) - // Wait for transfer to be complete and assert balances - err = testutil.WaitForBlocks(ctx, 5, chain2) - require.NoError(t, err) - chain2Bal, err := chain2.GetBalance(ctx, chain2Addr, chain2.Config().Denom) require.NoError(t, err) require.Equal(t, chain2OrigBal-transferAmount, chain2Bal) @@ -225,8 +233,18 @@ func TestScenarioICAChannelClose(t *testing.T) { _, _, err = chain1.Exec(ctx, sendICATransfer, nil) require.NoError(t, err) - // Wait for tx to be relayed - err = testutil.WaitForBlocks(ctx, 10, chain2) + c1h, err := chain1.Height(ctx) + require.NoError(t, err) + + ackFound := func(found *chantypes.MsgAcknowledgement) bool { + return found.Packet.Sequence == 1 && + found.Packet.SourcePort == "icacontroller-"+chain1Addr && + found.Packet.DestinationPort == "icahost" + } + + // Wait for ack + _, err = cosmos.PollForMessage(ctx, chain1, ir, + c1h, c1h+10, ackFound) require.NoError(t, err) // Assert that the funds have been received by the user account on chain2 @@ -243,9 +261,6 @@ func TestScenarioICAChannelClose(t *testing.T) { err = r.StopRelayer(ctx, eRep) require.NoError(t, err) - err = testutil.WaitForBlocks(ctx, 5, chain1, chain2) - require.NoError(t, err) - // Send another bank transfer msg to ICA on chain2 from the user account on chain1. // This message should timeout and the channel will be closed when we re-start the relayer. _, _, err = chain1.Exec(ctx, sendICATransfer, nil) @@ -291,8 +306,12 @@ func TestScenarioICAChannelClose(t *testing.T) { _, _, err = chain1.Exec(ctx, registerICA, nil) require.NoError(t, err) - // Wait for channel handshake to finish - err = testutil.WaitForBlocks(ctx, 15, chain1, chain2) + c2h, err = chain2.Height(ctx) + require.NoError(t, err) + + // Wait for channel open confirm + _, err = cosmos.PollForMessage(ctx, chain2, ir, + c2h, c2h+30, channelFound) require.NoError(t, err) // Assert that a new channel has been opened and the same ICA is in use diff --git a/interchaintest/interchain_accounts_test.go b/interchaintest/interchain_accounts_test.go index 3da235746..0185b2bc2 100644 --- a/interchaintest/interchain_accounts_test.go +++ b/interchaintest/interchain_accounts_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/crypto/keyring" + chantypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" relayerinterchaintest "github.com/cosmos/relayer/v2/interchaintest" interchaintest "github.com/strangelove-ventures/interchaintest/v7" "github.com/strangelove-ventures/interchaintest/v7/chain/cosmos" @@ -62,7 +63,7 @@ func TestScenarioInterchainAccounts(t *testing.T) { chains, err := cf.Chains(t.Name()) require.NoError(t, err) - chain1, chain2 := chains[0], chains[1] + chain1, chain2 := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) // Get a relayer instance r := relayerinterchaintest. @@ -89,6 +90,8 @@ func TestScenarioInterchainAccounts(t *testing.T) { Client: client, NetworkID: network, SkipPathCreation: true, + // Uncomment this to load blocks, txs, msgs, and events into sqlite db as test runs + // BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), })) // Fund a user account on chain1 and chain2 @@ -105,14 +108,14 @@ func TestScenarioInterchainAccounts(t *testing.T) { err = r.CreateClients(ctx, eRep, pathName, ibc.CreateClientOptions{TrustingPeriod: "330h"}) require.NoError(t, err) - err = testutil.WaitForBlocks(ctx, 5, chain1, chain2) + err = testutil.WaitForBlocks(ctx, 2, chain1, chain2) require.NoError(t, err) // Create a new connection err = r.CreateConnections(ctx, eRep, pathName) require.NoError(t, err) - err = testutil.WaitForBlocks(ctx, 5, chain1, chain2) + err = testutil.WaitForBlocks(ctx, 2, chain1, chain2) require.NoError(t, err) // Query for the newly created connection @@ -120,6 +123,19 @@ func TestScenarioInterchainAccounts(t *testing.T) { require.NoError(t, err) require.Equal(t, 1, len(connections)) + // Start the relayer and set the cleanup function. + err = r.StartRelayer(ctx, eRep, pathName) + require.NoError(t, err) + + t.Cleanup( + func() { + err := r.StopRelayer(ctx, eRep) + if err != nil { + t.Logf("an error occured while stopping the relayer: %s", err) + } + }, + ) + // Register a new interchain account on chain2, on behalf of the user acc on chain1 chain1Addr := chain1User.(*cosmos.CosmosWallet).FormattedAddressWithPrefix(chain1.Config().Bech32Prefix) @@ -136,21 +152,18 @@ func TestScenarioInterchainAccounts(t *testing.T) { _, _, err = chain1.Exec(ctx, registerICA, nil) require.NoError(t, err) - // Start the relayer and set the cleanup function. - err = r.StartRelayer(ctx, eRep, pathName) + ir := cosmos.DefaultEncoding().InterfaceRegistry + + c2h, err := chain2.Height(ctx) require.NoError(t, err) - t.Cleanup( - func() { - err := r.StopRelayer(ctx, eRep) - if err != nil { - t.Logf("an error occured while stopping the relayer: %s", err) - } - }, - ) + channelFound := func(found *chantypes.MsgChannelOpenConfirm) bool { + return found.PortId == "icahost" + } - // Wait for relayer to start up and finish channel handshake - err = testutil.WaitForBlocks(ctx, 15, chain1, chain2) + // Wait for channel open confirm + _, err = cosmos.PollForMessage(ctx, chain2, ir, + c2h, c2h+30, channelFound) require.NoError(t, err) // Query for the newly registered interchain account @@ -185,10 +198,6 @@ func TestScenarioInterchainAccounts(t *testing.T) { err = chain2.SendFunds(ctx, chain2User.KeyName(), transfer) require.NoError(t, err) - // Wait for transfer to be complete and assert balances - err = testutil.WaitForBlocks(ctx, 5, chain2) - require.NoError(t, err) - chain2Bal, err := chain2.GetBalance(ctx, chain2Addr, chain2.Config().Denom) require.NoError(t, err) require.Equal(t, chain2OrigBal-transferAmount, chain2Bal) @@ -225,8 +234,18 @@ func TestScenarioInterchainAccounts(t *testing.T) { _, _, err = chain1.Exec(ctx, sendICATransfer, nil) require.NoError(t, err) - // Wait for tx to be relayed - err = testutil.WaitForBlocks(ctx, 10, chain2) + c1h, err := chain1.Height(ctx) + require.NoError(t, err) + + ackFound := func(found *chantypes.MsgAcknowledgement) bool { + return found.Packet.Sequence == 1 && + found.Packet.SourcePort == "icacontroller-"+chain1Addr && + found.Packet.DestinationPort == "icahost" + } + + // Wait for ack + _, err = cosmos.PollForMessage(ctx, chain1, ir, + c1h, c1h+10, ackFound) require.NoError(t, err) // Assert that the funds have been received by the user account on chain2 @@ -243,9 +262,6 @@ func TestScenarioInterchainAccounts(t *testing.T) { err = r.StopRelayer(ctx, eRep) require.NoError(t, err) - err = testutil.WaitForBlocks(ctx, 5, chain1, chain2) - require.NoError(t, err) - // Send another bank transfer msg to ICA on chain2 from the user account on chain1. // This message should timeout and the channel will be closed when we re-start the relayer. _, _, err = chain1.Exec(ctx, sendICATransfer, nil) @@ -258,7 +274,15 @@ func TestScenarioInterchainAccounts(t *testing.T) { err = r.StartRelayer(ctx, eRep, pathName) require.NoError(t, err) - err = testutil.WaitForBlocks(ctx, 15, chain1, chain2) + c2h, err = chain2.Height(ctx) + require.NoError(t, err) + + chanCloseFound := func(found *chantypes.MsgChannelCloseConfirm) bool { + return found.PortId == "icahost" + } + + // Wait for channel close confirm + _, err = cosmos.PollForMessage(ctx, chain2, ir, c2h, c2h+30, chanCloseFound) require.NoError(t, err) // Assert that the packet timed out and that the acc balances are correct @@ -286,7 +310,12 @@ func TestScenarioInterchainAccounts(t *testing.T) { require.NoError(t, err) // Wait for channel handshake to finish - err = testutil.WaitForBlocks(ctx, 15, chain1, chain2) + c2h, err = chain2.Height(ctx) + require.NoError(t, err) + + // Wait for channel open confirm + _, err = cosmos.PollForMessage(ctx, chain2, ir, + c2h, c2h+30, channelFound) require.NoError(t, err) // Assert that a new channel has been opened and the same ICA is in use diff --git a/interchaintest/relay_many_test.go b/interchaintest/relay_many_test.go index 49bb530ca..65859f487 100644 --- a/interchaintest/relay_many_test.go +++ b/interchaintest/relay_many_test.go @@ -86,10 +86,11 @@ func TestRelayerMultiplePathsSingleProcess(t *testing.T) { client, network := interchaintest.DockerSetup(t) require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ - TestName: t.Name(), - Client: client, - NetworkID: network, - BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + TestName: t.Name(), + Client: client, + NetworkID: network, + // Uncomment this to load blocks, txs, msgs, and events into sqlite db as test runs + // BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), SkipPathCreation: false, })) diff --git a/interchaintest/relayer_override_test.go b/interchaintest/relayer_override_test.go index 4774ce5a6..2885c21ff 100644 --- a/interchaintest/relayer_override_test.go +++ b/interchaintest/relayer_override_test.go @@ -73,10 +73,11 @@ func TestClientOverrideFlag(t *testing.T) { }) require.NoError(t, ic.Build(ctx, eRep, interchaintest.InterchainBuildOptions{ - TestName: t.Name(), - Client: client, - NetworkID: network, - BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + TestName: t.Name(), + Client: client, + NetworkID: network, + // Uncomment this to load blocks, txs, msgs, and events into sqlite db as test runs + // BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), SkipPathCreation: true, })) diff --git a/interchaintest/tendermint_v0.37_boundary_test.go b/interchaintest/tendermint_v0.37_boundary_test.go index 7833eb489..c7972c1ac 100644 --- a/interchaintest/tendermint_v0.37_boundary_test.go +++ b/interchaintest/tendermint_v0.37_boundary_test.go @@ -74,11 +74,12 @@ func TestScenarioTendermint37Boundary(t *testing.T) { rep := testreporter.NewNopReporter() require.NoError(t, ic.Build(ctx, rep.RelayerExecReporter(t), interchaintest.InterchainBuildOptions{ - TestName: t.Name(), - Client: client, - NetworkID: network, - BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), - SkipPathCreation: false, + TestName: t.Name(), + Client: client, + NetworkID: network, + // Uncomment this to load blocks, txs, msgs, and events into sqlite db as test runs + // BlockDatabaseFile: interchaintest.DefaultBlockDatabaseFilepath(), + SkipPathCreation: false, })) t.Cleanup(func() { _ = ic.Close()