From 267826a889d2cbc07d492afe5ea1779d0b17b1a9 Mon Sep 17 00:00:00 2001 From: jtieri Date: Mon, 17 Oct 2022 15:18:08 -0500 Subject: [PATCH 1/4] test: add multiple channels on one connection test case via ibctest --- ibctest/multi_channel_test.go | 188 ++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 ibctest/multi_channel_test.go diff --git a/ibctest/multi_channel_test.go b/ibctest/multi_channel_test.go new file mode 100644 index 000000000..6b2b4898c --- /dev/null +++ b/ibctest/multi_channel_test.go @@ -0,0 +1,188 @@ +package ibctest_test + +import ( + "context" + "testing" + + transfertypes "github.com/cosmos/ibc-go/v5/modules/apps/transfer/types" + relayeribctest "github.com/cosmos/relayer/v2/ibctest" + "github.com/strangelove-ventures/ibctest/v5" + "github.com/strangelove-ventures/ibctest/v5/chain/cosmos" + "github.com/strangelove-ventures/ibctest/v5/ibc" + ibctestrelayer "github.com/strangelove-ventures/ibctest/v5/relayer" + ibctestrly "github.com/strangelove-ventures/ibctest/v5/relayer/rly" + "github.com/strangelove-ventures/ibctest/v5/test" + "github.com/strangelove-ventures/ibctest/v5/testreporter" + "github.com/stretchr/testify/require" + "go.uber.org/zap/zaptest" +) + +func TestMultipleChannelsOneConnection(t *testing.T) { + relayeribctest.BuildRelayerImage(t) + + client, network := ibctest.DockerSetup(t) + r := ibctest.NewBuiltinRelayerFactory( + ibc.CosmosRly, + zaptest.NewLogger(t), + ibctestrelayer.CustomDockerImage(relayeribctest.RelayerImageName, "latest", "100:1000"), + ibctestrelayer.ImagePull(false), + ).Build(t, client, network) + + // Define chains involved in test + cf := ibctest.NewBuiltinChainFactory(zaptest.NewLogger(t), []*ibctest.ChainSpec{ + { + Name: "gaia", + ChainName: "gaia", + Version: "v7.0.3", + ChainConfig: ibc.ChainConfig{GasPrices: "0.00atom"}, + }, + { + Name: "osmosis", + ChainName: "osmosis", + Version: "v11.0.1", + ChainConfig: ibc.ChainConfig{GasPrices: "0.00osmo"}, + }, + }) + + chains, err := cf.Chains(t.Name()) + require.NoError(t, err) + + gaia, osmosis := chains[0].(*cosmos.CosmosChain), chains[1].(*cosmos.CosmosChain) + + // Build the network; spin up the chains and configure the relayer + const pathGaiaOsmosis = "gaia-osmosis" + const relayerName = "relayer" + + ic := ibctest.NewInterchain(). + AddChain(gaia). + AddChain(osmosis). + AddRelayer(r, relayerName). + AddLink(ibctest.InterchainLink{ + Chain1: gaia, + Chain2: osmosis, + Relayer: r, + Path: pathGaiaOsmosis, + }) + + rep := testreporter.NewNopReporter() + eRep := rep.RelayerExecReporter(t) + + ctx := context.Background() + + require.NoError(t, ic.Build(ctx, eRep, ibctest.InterchainBuildOptions{ + TestName: t.Name(), + Client: client, + NetworkID: network, + })) + t.Cleanup(func() { + _ = ic.Close() + }) + + // Create user accounts on both chains + const initFunds = int64(10_000_000) + users := ibctest.GetAndFundTestUsers(t, ctx, "user-key", initFunds, gaia, osmosis) + + gaiaUser, osmosisUser := users[0], users[1] + + // Create the second and third channels on the same connection as the first channel + rly := r.(*ibctestrly.CosmosRelayer) + + creatChanCmd := []string{ + "rly", "tx", "channel", pathGaiaOsmosis, + "--override", + "--home", rly.HomeDir(), + } + + for i := 0; i < 2; i++ { + res := r.Exec(ctx, eRep, creatChanCmd, nil) + require.NotEmpty(t, res) + require.NoError(t, res.Err) + } + + // Start the relayer + err = r.StartRelayer(ctx, eRep, pathGaiaOsmosis) + 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) + } + }, + ) + + // Wait a few blocks for the relayer to start + err = test.WaitForBlocks(ctx, 5, gaia, osmosis) + require.NoError(t, err) + + // Assert that all three channels were successfully initialized + channels, err := r.GetChannels(ctx, eRep, gaia.Config().ChainID) + require.NoError(t, err) + require.Equal(t, 3, len(channels)) + + // Send an IBC transfer across all three channels + const transferAmount = int64(1000) + transfer := ibc.WalletAmount{ + Address: osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix), + Denom: gaia.Config().Denom, + Amount: transferAmount, + } + + for _, channel := range channels { + _, err = gaia.SendIBCTransfer(ctx, channel.ChannelID, gaiaUser.KeyName, transfer, nil) + require.NoError(t, err) + } + + // Wait a few blocks for the transfers to be successfully relayed + err = test.WaitForBlocks(ctx, 5, gaia, osmosis) + require.NoError(t, err) + + // Compose IBC denoms for each channel + ibcDenoms := make([]transfertypes.DenomTrace, 3) + + ibcDenoms[0] = transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom(channels[0].Counterparty.PortID, channels[0].Counterparty.ChannelID, gaia.Config().Denom)) + ibcDenoms[1] = transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom(channels[1].Counterparty.PortID, channels[1].Counterparty.ChannelID, gaia.Config().Denom)) + ibcDenoms[2] = transfertypes.ParseDenomTrace(transfertypes.GetPrefixedDenom(channels[2].Counterparty.PortID, channels[2].Counterparty.ChannelID, gaia.Config().Denom)) + + // Assert that the transfers are all successful out of the src chain account + nativeGaiaBal, err := gaia.GetBalance(ctx, gaiaUser.Bech32Address(gaia.Config().Bech32Prefix), gaia.Config().Denom) + require.NoError(t, err) + require.Equal(t, initFunds-transferAmount*3, nativeGaiaBal) + + // Assert that the transfers are all successful on the dst chain account + for _, denom := range ibcDenoms { + balance, err := osmosis.GetBalance(ctx, osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix), denom.IBCDenom()) + require.NoError(t, err) + require.Equal(t, transferAmount, balance) + } + + // Send the funds back to the original source chain + for i, channel := range channels { + transfer := ibc.WalletAmount{ + Address: gaiaUser.Bech32Address(gaia.Config().Bech32Prefix), + Denom: ibcDenoms[i].IBCDenom(), + Amount: transferAmount, + } + + _, err = osmosis.SendIBCTransfer(ctx, channel.Counterparty.ChannelID, osmosisUser.KeyName, transfer, nil) + require.NoError(t, err) + } + + // Wait a few blocks for the transfers to be successfully relayed + err = test.WaitForBlocks(ctx, 5, gaia, osmosis) + require.NoError(t, err) + + // Assert that the transfers are all successful back on the original src chain account + nativeGaiaBal, err = gaia.GetBalance(ctx, gaiaUser.Bech32Address(gaia.Config().Bech32Prefix), gaia.Config().Denom) + require.NoError(t, err) + require.Equal(t, initFunds, nativeGaiaBal) + + // Assert that the transfers are all successfully sent back to the original src chain account + for _, denom := range ibcDenoms { + balance, err := osmosis.GetBalance(ctx, osmosisUser.Bech32Address(osmosis.Config().Bech32Prefix), denom.IBCDenom()) + require.NoError(t, err) + require.Equal(t, int64(0), balance) + } + +} From ac96b992ebb601a905f30104a187543d1bc855b4 Mon Sep 17 00:00:00 2001 From: jtieri Date: Mon, 17 Oct 2022 15:18:39 -0500 Subject: [PATCH 2/4] chore: remove old docker integration test make cmds --- Makefile | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Makefile b/Makefile index 8280e09ab..3ef81f863 100644 --- a/Makefile +++ b/Makefile @@ -54,18 +54,6 @@ build-osmosis-docker: test: @go test -mod=readonly -race ./... -test-integration: - @go test -mod=readonly -v -timeout 20m ./_test/ - -test-gaia: - @go test -mod=readonly -v -run 'TestGaiaToGaiaRelaying|TestGaiaToGaiaRelaying|TestUnorderedChannelBlockHeightTimeout|TestUnorderedChannelTimestampTimeout' ./_test - -test-akash: - @go test -mod=readonly -v -run TestAkashToGaiaRelaying ./_test/ - -test-short: - @go test -mod=readonly -v -run TestOsmoToGaiaRelaying ./_test/ - ibctest: cd ibctest && go test -race -v -run TestRelayerInProcess . From 903eede13d5231016e4e3869b8220e22449abc54 Mon Sep 17 00:00:00 2001 From: jtieri Date: Mon, 17 Oct 2022 15:19:25 -0500 Subject: [PATCH 3/4] chore: remove github CI actions for old docker integration tests --- .github/workflows/akash-tests.yml | 35 ------------------------------- .github/workflows/gaia-tests.yml | 35 ------------------------------- 2 files changed, 70 deletions(-) delete mode 100644 .github/workflows/akash-tests.yml delete mode 100644 .github/workflows/gaia-tests.yml diff --git a/.github/workflows/akash-tests.yml b/.github/workflows/akash-tests.yml deleted file mode 100644 index ad1c37336..000000000 --- a/.github/workflows/akash-tests.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: TESTING - akash to gaia integration - -on: - pull_request: - push: - branches: - - master - -jobs: - build: - name: build - runs-on: ubuntu-latest - steps: - # Install and setup go - - name: Set up Go 1.18 - uses: actions/setup-go@v1 - with: - go-version: 1.18 - id: go - - # checkout relayer - - name: checkout relayer - uses: actions/checkout@v2 - - # build cache - - uses: actions/cache@v1 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - # run tests - - name: run akash tests - run: make test-akash diff --git a/.github/workflows/gaia-tests.yml b/.github/workflows/gaia-tests.yml deleted file mode 100644 index faf2878eb..000000000 --- a/.github/workflows/gaia-tests.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: TESTING - gaia to gaia integration - -on: - pull_request: - push: - branches: - - master - -jobs: - build: - name: build - runs-on: ubuntu-latest - steps: - # Install and setup go - - name: Set up Go 1.18 - uses: actions/setup-go@v1 - with: - go-version: 1.18 - id: go - - # checkout relayer - - name: checkout relayer - uses: actions/checkout@v2 - - # build cache - - uses: actions/cache@v1 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - # run tests - - name: run gaia tests - run: make test-gaia From 7f5eb57388ae17b69c9a02b02c16574300b6dcc7 Mon Sep 17 00:00:00 2001 From: jtieri Date: Mon, 17 Oct 2022 15:19:45 -0500 Subject: [PATCH 4/4] chore: remove `_test` directory containing the old docker integration tests --- _test/README.md | 8 - _test/relayer_chain_test.go | 744 ----------------------------------- _test/relayer_compat_test.go | 30 -- _test/setup/akash-setup.sh | 42 -- _test/setup/gaia-setup.sh | 42 -- _test/setup/osmosis-setup.sh | 42 -- _test/setup/valkeys/.gitkeep | 0 _test/test_chains.go | 156 -------- _test/test_queries.go | 125 ------ _test/test_setup.go | 286 -------------- 10 files changed, 1475 deletions(-) delete mode 100644 _test/README.md delete mode 100644 _test/relayer_chain_test.go delete mode 100644 _test/relayer_compat_test.go delete mode 100755 _test/setup/akash-setup.sh delete mode 100755 _test/setup/gaia-setup.sh delete mode 100755 _test/setup/osmosis-setup.sh delete mode 100644 _test/setup/valkeys/.gitkeep delete mode 100644 _test/test_chains.go delete mode 100644 _test/test_queries.go delete mode 100644 _test/test_setup.go diff --git a/_test/README.md b/_test/README.md deleted file mode 100644 index e8286dc8c..000000000 --- a/_test/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# \_test - -This directory contains integration-style tests that require Docker to run. - -The leading underscore on the directory means that go tooling ignores this directory unless specifically requested. -This allows `go test ./...` to work without needing Docker. - -The intended way to run these integration tests is with `make test-integration` from the root directory. diff --git a/_test/relayer_chain_test.go b/_test/relayer_chain_test.go deleted file mode 100644 index fc0e8ae56..000000000 --- a/_test/relayer_chain_test.go +++ /dev/null @@ -1,744 +0,0 @@ -package test - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/avast/retry-go/v4" - sdk "github.com/cosmos/cosmos-sdk/types" - clienttypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types" - tmclient "github.com/cosmos/ibc-go/v5/modules/light-clients/07-tendermint/types" - ibctesting "github.com/cosmos/ibc-go/v5/testing" - ibctestingmock "github.com/cosmos/ibc-go/v5/testing/mock" - "github.com/cosmos/relayer/v2/cmd" - "github.com/cosmos/relayer/v2/relayer" - "github.com/cosmos/relayer/v2/relayer/chains/cosmos" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/crypto/tmhash" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - tmprotoversion "github.com/tendermint/tendermint/proto/tendermint/version" - tmtypes "github.com/tendermint/tendermint/types" - tmversion "github.com/tendermint/tendermint/version" - "go.uber.org/zap/zaptest" - "golang.org/x/sync/errgroup" -) - -const ( - DefaultSrcPortID = "transfer" - DefaultDstPortID = "transfer" - DefaultOrder = "unordered" - DefaultVersion = "ics20-1" -) - -func chainTest(t *testing.T, tcs []testChain) { - chains := spinUpTestChains(t, tcs...) - - c, err := chains.Gets("ibc-0", "ibc-1") - require.NoError(t, err) - - var ( - src = c["ibc-0"] - dst = c["ibc-1"] - testDenom = "samoleans" - testCoin = sdk.NewCoin(testDenom, sdk.NewInt(1000)) - twoTestCoin = sdk.NewCoin(testDenom, sdk.NewInt(2000)) - ) - - p, err := genTestPathAndSet(src, dst) - require.NoError(t, err) - - t.Log("Querying initial balances for later comparison") - var srcExpected, dstExpected sdk.Coins - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - eg, egCtx := errgroup.WithContext(ctx) - eg.Go(func() error { - return retry.Do(func() error { - var err error - srcExpected, err = src.ChainProvider.QueryBalance(egCtx, src.ChainProvider.Key()) - if srcExpected.IsZero() { - return fmt.Errorf("(src chain) expected non-zero balance. Err: %w", err) - } - return err - }) - }) - eg.Go(func() error { - return retry.Do(func() error { - var err error - dstExpected, err = dst.ChainProvider.QueryBalance(egCtx, dst.ChainProvider.Key()) - if dstExpected.IsZero() { - return fmt.Errorf("(dst chain) expected non-zero balance. Err: %w", err) - } - return err - }) - }) - require.NoError(t, eg.Wait()) - - t.Log("Creating clients") - _, _, err = src.CreateClients(ctx, dst, true, true, false, 0, "") - require.NoError(t, err) - testClientPair(ctx, t, src, dst) - - timeout, err := src.GetTimeout() - require.NoError(t, err) - - t.Log("Creating connections") - _, _, err = src.CreateOpenConnections(ctx, dst, 3, timeout, "", 0, "") - require.NoError(t, err) - testConnectionPair(ctx, t, src, dst) - - t.Log("Creating channels") - err = src.CreateOpenChannels(ctx, dst, 3, timeout, DefaultSrcPortID, DefaultDstPortID, DefaultOrder, DefaultVersion, false, "", "") - require.NoError(t, err) - - t.Log("Querying open channels to ensure successful creation") - channels, err := src.ChainProvider.QueryConnectionChannels(ctx, 0, src.ConnectionID()) - require.NoError(t, err) - - channel := channels[0] - testChannelPair(ctx, t, src, dst, channel.ChannelId, channel.PortId) - - dstAddr, err := dst.ChainProvider.Address() - require.NoError(t, err) - - srcAddr, err := src.ChainProvider.Address() - require.NoError(t, err) - - log := zaptest.NewLogger(t) - - t.Log("Sending initial transfers to source chain") - require.NoError(t, src.SendTransferMsg(ctx, log, dst, testCoin, dstAddr, 0, 0, channel)) - require.NoError(t, src.SendTransferMsg(ctx, log, dst, testCoin, dstAddr, 0, 0, channel)) - - t.Log("Sending initial transfers to dest chain") - require.NoError(t, dst.SendTransferMsg(ctx, log, src, testCoin, srcAddr, 0, 0, channel)) - require.NoError(t, dst.SendTransferMsg(ctx, log, src, testCoin, srcAddr, 0, 0, channel)) - - t.Log("Waiting for transfers to reach blocks") - require.NoError(t, dst.ChainProvider.WaitForNBlocks(ctx, 1)) - - t.Log("Starting relayer") - _ = relayer.StartRelayer(ctx, log, c, []relayer.NamedPath{{Path: p}}, 2*cmd.MB, 5, "", relayer.ProcessorEvents, 20, nil) - - t.Log("Waiting for relayer messages to reach both chains") - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 2)) - require.NoError(t, dst.ChainProvider.WaitForNBlocks(ctx, 2)) - - t.Log("Initiating transfer of tokens back where they came from") - require.NoError(t, src.SendTransferMsg(ctx, log, dst, twoTestCoin, dstAddr, 0, 0, channel)) - require.NoError(t, dst.SendTransferMsg(ctx, log, src, twoTestCoin, srcAddr, 0, 0, channel)) - - t.Log("Waiting for transfers to be processed") - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 6)) - require.NoError(t, dst.ChainProvider.WaitForNBlocks(ctx, 6)) - - t.Log("Checking expected source balance") - srcGot, err := src.ChainProvider.QueryBalance(ctx, src.ChainProvider.Key()) - require.NoError(t, err) - require.Equal(t, srcExpected.AmountOf(testDenom).Int64()-4000, srcGot.AmountOf(testDenom).Int64()) - - t.Log("Checking expected dest balance") - dstGot, err := dst.ChainProvider.QueryBalance(ctx, dst.ChainProvider.Key()) - require.NoError(t, err) - require.Equal(t, dstExpected.AmountOf(testDenom).Int64()-4000, dstGot.AmountOf(testDenom).Int64()) -} - -func TestGaiaReuseIdentifiers(t *testing.T) { - // TODO: fix and re-enable this test - t.Skip() - chains := spinUpTestChains(t, []testChain{ - {"testChain0", "ibc-0", 0, gaiaTestConfig, gaiaProviderCfg}, - {"testChain1", "ibc-1", 1, gaiaTestConfig, gaiaProviderCfg}, - }...) - - var ( - src = chains.MustGet("ibc-0") - dst = chains.MustGet("ibc-1") - ) - - _, err := genTestPathAndSet(src, dst) - require.NoError(t, err) - - // create path - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - _, _, err = src.CreateClients(ctx, dst, true, true, false, 0, "") - require.NoError(t, err) - testClientPair(ctx, t, src, dst) - - timeout, err := src.GetTimeout() - require.NoError(t, err) - - _, _, err = src.CreateOpenConnections(ctx, dst, 3, timeout, "", 0, "") - require.NoError(t, err) - testConnectionPair(ctx, t, src, dst) - - err = src.CreateOpenChannels(ctx, dst, 3, timeout, DefaultSrcPortID, DefaultDstPortID, DefaultOrder, DefaultVersion, false, "", "") - require.NoError(t, err) - - // query open channels and ensure there is no error - channels, err := src.ChainProvider.QueryConnectionChannels(ctx, 0, src.ConnectionID()) - require.NoError(t, err) - - channel := channels[0] - testChannelPair(ctx, t, src, dst, channel.ChannelId, channel.PortId) - - expectedSrc := src - expectedDst := dst - - // clear old config - src.PathEnd.ClientID = "" - src.PathEnd.ConnectionID = "" - dst.PathEnd.ClientID = "" - dst.PathEnd.ConnectionID = "" - - _, _, err = src.CreateClients(ctx, dst, true, true, false, 0, "") - require.NoError(t, err) - testClientPair(ctx, t, src, dst) - - _, _, err = src.CreateOpenConnections(ctx, dst, 3, timeout, "", 0, "") - require.NoError(t, err) - testConnectionPair(ctx, t, src, dst) - - err = src.CreateOpenChannels(ctx, dst, 3, timeout, DefaultSrcPortID, DefaultDstPortID, DefaultOrder, DefaultVersion, false, "", "") - require.NoError(t, err) - testChannelPair(ctx, t, src, dst, channel.ChannelId, channel.PortId) - - require.Equal(t, expectedSrc, src) - require.Equal(t, expectedDst, dst) - - expectedSrcClient := src.PathEnd.ClientID - expectedDstClient := dst.PathEnd.ClientID - - // test client creation with override - src.PathEnd.ClientID = "" - dst.PathEnd.ClientID = "" - - _, _, err = src.CreateClients(ctx, dst, true, true, true, 0, "") - require.NoError(t, err) - testClientPair(ctx, t, src, dst) - - require.NotEqual(t, expectedSrcClient, src.PathEnd.ClientID) - require.NotEqual(t, expectedDstClient, dst.PathEnd.ClientID) -} - -func TestGaiaMisbehaviourMonitoring(t *testing.T) { - // TODO: fix and re-enable this test - // need to figure out what this feature is supposed to do - t.Skip() - chains := spinUpTestChains(t, []testChain{ - {"testChain0", "ibc-0", 0, gaiaTestConfig, gaiaProviderCfg}, - {"testChain1", "ibc-1", 1, gaiaTestConfig, gaiaProviderCfg}, - }...) - - c, err := chains.Gets("ibc-0", "ibc-1") - require.NoError(t, err) - - var ( - src = c["ibc-0"] - dst = c["ibc-1"] - ) - - p, err := genTestPathAndSet(src, dst) - require.NoError(t, err) - - // create path - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - _, _, err = src.CreateClients(ctx, dst, true, true, false, 0, "") - require.NoError(t, err) - testClientPair(ctx, t, src, dst) - - timeout, err := src.GetTimeout() - require.NoError(t, err) - - _, _, err = src.CreateOpenConnections(ctx, dst, 3, timeout, "", 0, "") - require.NoError(t, err) - testConnectionPair(ctx, t, src, dst) - - err = src.CreateOpenChannels(ctx, dst, 3, timeout, DefaultSrcPortID, DefaultDstPortID, DefaultOrder, DefaultVersion, false, "", "") - require.NoError(t, err) - - // query open channels and ensure there is no error - channels, err := src.ChainProvider.QueryConnectionChannels(ctx, 0, src.ConnectionID()) - require.NoError(t, err) - - channel := channels[0] - testChannelPair(ctx, t, src, dst, channel.ChannelId, channel.PortId) - - log := zaptest.NewLogger(t) - // start the relayer process in it's own goroutine - _ = relayer.StartRelayer(ctx, log, c, []relayer.NamedPath{{Path: p}}, 2*cmd.MB, 5, "", relayer.ProcessorEvents, 20, nil) - - // Wait for relay message inclusion in both chains - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 1)) - require.NoError(t, dst.ChainProvider.WaitForNBlocks(ctx, 1)) - - latestHeight, err := dst.ChainProvider.QueryLatestHeight(ctx) - require.NoError(t, err) - - header, err := dst.ChainProvider.QueryIBCHeader(ctx, latestHeight) - require.NoError(t, err) - - clientState, err := src.QueryTMClientState(ctx, latestHeight) - require.NoError(t, err) - - height := clientState.GetLatestHeight().(clienttypes.Height) - heightPlus1 := clienttypes.NewHeight(height.RevisionNumber, height.RevisionHeight+1) - - // setup validator for signing duplicate header - // use key for dst - privKey := getSDKPrivKey(1) - privVal := ibctestingmock.PV{ - PrivKey: privKey, - } - pubKey, err := privVal.GetPubKey() - require.NoError(t, err) - - tmHeader, ok := header.(cosmos.CosmosIBCHeader) - if !ok { - t.Fatalf("got data of type %T but wanted cosmos.CosmosIBCHeader", header) - } - validator := tmtypes.NewValidator(pubKey, tmHeader.ValidatorSet.Proposer.VotingPower) - valSet := tmtypes.NewValidatorSet([]*tmtypes.Validator{validator}) - signers := []tmtypes.PrivValidator{privVal} - - // creating duplicate header - newHeader := createTMClientHeader(t, dst.ChainID(), int64(heightPlus1.RevisionHeight), height, - tmHeader.SignedHeader.Time.Add(time.Minute), valSet, valSet, signers, nil) - - // update client with duplicate header - updateMsg, err := src.ChainProvider.MsgUpdateClient(src.PathEnd.ClientID, newHeader) - require.NoError(t, err) - - res, success, err := src.ChainProvider.SendMessage(ctx, updateMsg, "") - require.NoError(t, err) - require.True(t, success) - require.Equal(t, uint32(0), res.Code) - - // wait for packet processing - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 6)) - require.NoError(t, dst.ChainProvider.WaitForNBlocks(ctx, 6)) - - clientState, err = src.QueryTMClientState(ctx, 0) - require.NoError(t, err) - - // clientstate should be frozen i.e., clientstate frozenheight should not be zero - require.False(t, clientState.FrozenHeight.IsZero()) -} - -func TestRelayAllChannelsOnConnection(t *testing.T) { - chains := spinUpTestChains(t, []testChain{ - {"testChain0", "ibc-0", 0, gaiaTestConfig, gaiaProviderCfg}, - {"testChain1", "ibc-1", 1, gaiaTestConfig, gaiaProviderCfg}, - }...) - - c, err := chains.Gets("ibc-0", "ibc-1") - require.NoError(t, err) - - var ( - src = c["ibc-0"] - dst = c["ibc-1"] - testDenom = "samoleans" - testCoin = sdk.NewCoin(testDenom, sdk.NewInt(1000)) - twoTestCoin = sdk.NewCoin(testDenom, sdk.NewInt(2000)) - ) - - p, err := genTestPathAndSet(src, dst) - require.NoError(t, err) - - t.Log("Querying initial balances to compare against at the end") - var srcExpected, dstExpected sdk.Coins - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - eg, egCtx := errgroup.WithContext(ctx) - eg.Go(func() error { - return retry.Do(func() error { - var err error - srcExpected, err = src.ChainProvider.QueryBalance(egCtx, src.ChainProvider.Key()) - if err != nil { - return err - } - - if srcExpected.IsZero() { - return fmt.Errorf("expected non-zero balance. Err: %w", err) - } - - return nil - }) - }) - eg.Go(func() error { - return retry.Do(func() error { - var err error - dstExpected, err = dst.ChainProvider.QueryBalance(egCtx, dst.ChainProvider.Key()) - if err != nil { - return err - } - - if dstExpected.IsZero() { - return fmt.Errorf("expected non-zero balance. Err: %w", err) - } - - return nil - }) - }) - require.NoError(t, eg.Wait()) - - t.Log("Creating clients") - _, _, err = src.CreateClients(ctx, dst, true, true, false, 0, "") - require.NoError(t, err) - testClientPair(ctx, t, src, dst) - - timeout, err := src.GetTimeout() - require.NoError(t, err) - - t.Log("Creating connections") - _, _, err = src.CreateOpenConnections(ctx, dst, 3, timeout, "", 0, "") - require.NoError(t, err) - testConnectionPair(ctx, t, src, dst) - - t.Log("Creating channels") - err = src.CreateOpenChannels(ctx, dst, 3, timeout, DefaultSrcPortID, DefaultDstPortID, DefaultOrder, DefaultVersion, false, "", "") - require.NoError(t, err) - - err = src.CreateOpenChannels(ctx, dst, 3, timeout, DefaultSrcPortID, DefaultDstPortID, DefaultOrder, DefaultVersion, true, "", "") - require.NoError(t, err) - - t.Log("Ensuring two channels exist") - channels, err := src.ChainProvider.QueryConnectionChannels(ctx, 0, src.ConnectionID()) - require.NoError(t, err) - require.Equal(t, 2, len(channels)) - - channelOne := channels[0] - channelTwo := channels[1] - - // send a couple of transfers to the queue on src for first channel - dstAddr, err := dst.ChainProvider.Address() - require.NoError(t, err) - - srcAddr, err := src.ChainProvider.Address() - require.NoError(t, err) - - log := zaptest.NewLogger(t) - - t.Log("Sending transfers from src to dst on first channel") - require.NoError(t, src.SendTransferMsg(ctx, log, dst, testCoin, dstAddr, 0, 0, channelOne)) - require.NoError(t, src.SendTransferMsg(ctx, log, dst, testCoin, dstAddr, 0, 0, channelOne)) - - t.Log("Sending transfers from dst to src on first channel") - require.NoError(t, dst.SendTransferMsg(ctx, log, src, testCoin, srcAddr, 0, 0, channelOne)) - require.NoError(t, dst.SendTransferMsg(ctx, log, src, testCoin, srcAddr, 0, 0, channelOne)) - - t.Log("Sending transfers from src to dst on second channel") - require.NoError(t, src.SendTransferMsg(ctx, log, dst, testCoin, dstAddr, 0, 0, channelTwo)) - require.NoError(t, src.SendTransferMsg(ctx, log, dst, testCoin, dstAddr, 0, 0, channelTwo)) - - t.Log("Sending transfers from dst to src on second channel") - require.NoError(t, dst.SendTransferMsg(ctx, log, src, testCoin, srcAddr, 0, 0, channelTwo)) - require.NoError(t, dst.SendTransferMsg(ctx, log, src, testCoin, srcAddr, 0, 0, channelTwo)) - - t.Log("Waiting for message inclusion in both chains") - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 1)) - require.NoError(t, dst.ChainProvider.WaitForNBlocks(ctx, 1)) - - t.Log("Starting relayer") - _ = relayer.StartRelayer(ctx, log, c, []relayer.NamedPath{{Path: p}}, 2*cmd.MB, 5, "", relayer.ProcessorEvents, 20, nil) - - t.Log("Waiting for relayer message inclusion in both chains") - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 1)) - require.NoError(t, dst.ChainProvider.WaitForNBlocks(ctx, 1)) - - t.Log("Sending tokens back on first channel") - require.NoError(t, src.SendTransferMsg(ctx, log, dst, twoTestCoin, dstAddr, 0, 0, channelOne)) - require.NoError(t, dst.SendTransferMsg(ctx, log, src, twoTestCoin, srcAddr, 0, 0, channelOne)) - - t.Log("Sending tokens back on second channel") - require.NoError(t, src.SendTransferMsg(ctx, log, dst, twoTestCoin, dstAddr, 0, 0, channelTwo)) - require.NoError(t, dst.SendTransferMsg(ctx, log, src, twoTestCoin, srcAddr, 0, 0, channelTwo)) - - t.Log("Waiting for packet processing") - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 6)) - require.NoError(t, dst.ChainProvider.WaitForNBlocks(ctx, 6)) - - t.Log("Checking src balance") - srcGot, err := src.ChainProvider.QueryBalance(ctx, src.ChainProvider.Key()) - require.NoError(t, err) - require.Equal(t, srcExpected.AmountOf(testDenom).Int64()-8000, srcGot.AmountOf(testDenom).Int64()) - - t.Log("Checking dst balance") - dstGot, err := dst.ChainProvider.QueryBalance(ctx, dst.ChainProvider.Key()) - require.NoError(t, err) - require.Equal(t, dstExpected.AmountOf(testDenom).Int64()-8000, dstGot.AmountOf(testDenom).Int64()) -} - -func createTMClientHeader(t *testing.T, chainID string, blockHeight int64, trustedHeight clienttypes.Height, - timestamp time.Time, tmValSet, tmTrustedVals *tmtypes.ValidatorSet, signers []tmtypes.PrivValidator, - oldHeader *tmclient.Header) *tmclient.Header { - var ( - valSet *tmproto.ValidatorSet - trustedVals *tmproto.ValidatorSet - ) - require.NotNil(t, tmValSet) - - vsetHash := tmValSet.Hash() - - tmHeader := tmtypes.Header{ - Version: tmprotoversion.Consensus{Block: tmversion.BlockProtocol, App: 2}, - ChainID: chainID, - Height: blockHeight, - Time: timestamp, - LastBlockID: ibctesting.MakeBlockID(make([]byte, tmhash.Size), 10_000, make([]byte, tmhash.Size)), - LastCommitHash: oldHeader.Header.LastCommitHash, - DataHash: tmhash.Sum([]byte("data_hash")), - ValidatorsHash: vsetHash, - NextValidatorsHash: vsetHash, - ConsensusHash: tmhash.Sum([]byte("consensus_hash")), - AppHash: tmhash.Sum([]byte("app_hash")), - LastResultsHash: tmhash.Sum([]byte("last_results_hash")), - EvidenceHash: tmhash.Sum([]byte("evidence_hash")), - ProposerAddress: tmValSet.Proposer.Address, //nolint:staticcheck - } - hhash := tmHeader.Hash() - blockID := ibctesting.MakeBlockID(hhash, 3, tmhash.Sum([]byte("part_set"))) - voteSet := tmtypes.NewVoteSet(chainID, blockHeight, 1, tmproto.PrecommitType, tmValSet) - - commit, err := tmtypes.MakeCommit(blockID, blockHeight, 1, voteSet, signers, timestamp) - require.NoError(t, err) - - signedHeader := &tmproto.SignedHeader{ - Header: tmHeader.ToProto(), - Commit: commit.ToProto(), - } - - if tmValSet != nil { - valSet, err = tmValSet.ToProto() - if err != nil { - panic(err) - } - } - - if tmTrustedVals != nil { - trustedVals, err = tmTrustedVals.ToProto() - if err != nil { - panic(err) - } - } - - // The trusted fields may be nil. They may be filled before relaying messages to a client. - // The relayer is responsible for querying client and injecting appropriate trusted fields. - return &tmclient.Header{ - SignedHeader: signedHeader, - ValidatorSet: valSet, - TrustedHeight: trustedHeight, - TrustedValidators: trustedVals, - } -} - -// a.Config.Chains[args[0]] -func TestUnorderedChannelBlockHeightTimeout(t *testing.T) { - chains := spinUpTestChains(t, []testChain{ - {"testChain0", "ibc-0", 0, gaiaTestConfig, gaiaProviderCfg}, - {"testChain1", "ibc-1", 1, gaiaTestConfig, gaiaProviderCfg}, - }...) - - c, err := chains.Gets("ibc-0", "ibc-1") - require.NoError(t, err) - - var ( - src = c["ibc-0"] - dst = c["ibc-1"] - testDenom = "samoleans" - twoTestCoin = sdk.NewCoin(testDenom, sdk.NewInt(2000)) - ) - - p, err := genTestPathAndSet(src, dst) - require.NoError(t, err) - - // query initial balances to compare against at the end - var srcExpected, dstExpected sdk.Coins - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - eg, egCtx := errgroup.WithContext(ctx) - eg.Go(func() error { - return retry.Do(func() error { - var err error - srcExpected, err = src.ChainProvider.QueryBalance(egCtx, src.ChainProvider.Key()) - if srcExpected.IsZero() { - return fmt.Errorf("expected non-zero balance. Err: %w", err) - } - return err - }) - }) - eg.Go(func() error { - return retry.Do(func() error { - var err error - dstExpected, err = dst.ChainProvider.QueryBalance(egCtx, dst.ChainProvider.Key()) - if dstExpected.IsZero() { - return fmt.Errorf("expected non-zero balance. Err: %w", err) - } - return err - }) - }) - require.NoError(t, eg.Wait()) - - // create path - _, _, err = src.CreateClients(ctx, dst, true, true, false, 0, "") - require.NoError(t, err) - testClientPair(ctx, t, src, dst) - - timeout, err := src.GetTimeout() - require.NoError(t, err) - - _, _, err = src.CreateOpenConnections(ctx, dst, 3, timeout, "", 0, "") - require.NoError(t, err) - testConnectionPair(ctx, t, src, dst) - - err = src.CreateOpenChannels(ctx, dst, 3, timeout, DefaultSrcPortID, DefaultDstPortID, DefaultOrder, DefaultVersion, false, "", "") - require.NoError(t, err) - - // query open channels and ensure there is no error - channels, err := src.ChainProvider.QueryConnectionChannels(ctx, 0, src.ConnectionID()) - require.NoError(t, err) - - channel := channels[0] - testChannelPair(ctx, t, src, dst, channel.ChannelId, channel.PortId) - - dstAddr, err := dst.ChainProvider.Address() - require.NoError(t, err) - - _, err = src.ChainProvider.Address() - require.NoError(t, err) - - log := zaptest.NewLogger(t) - - // send a packet that should timeout after 10 blocks have passed - require.NoError(t, src.SendTransferMsg(ctx, log, dst, twoTestCoin, dstAddr, uint64(10), 0, channel)) - - // wait for block height timeout offset to be reached - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 11)) - - // start the relayer process in it's own goroutine - _ = relayer.StartRelayer(ctx, log, c, []relayer.NamedPath{{Path: p}}, 2*cmd.MB, 5, "", relayer.ProcessorEvents, 20, nil) - - require.NoError(t, src.ChainProvider.WaitForNBlocks(ctx, 5)) - - // check balance on src against expected - srcGot, err := src.ChainProvider.QueryBalance(ctx, src.ChainProvider.Key()) - require.NoError(t, err) - require.Equal(t, srcExpected.AmountOf(testDenom).Int64(), srcGot.AmountOf(testDenom).Int64()) - - // check balance on dst against expected - dstGot, err := dst.ChainProvider.QueryBalance(ctx, dst.ChainProvider.Key()) - require.NoError(t, err) - require.Equal(t, dstExpected.AmountOf(testDenom).Int64(), dstGot.AmountOf(testDenom).Int64()) -} - -func TestUnorderedChannelTimestampTimeout(t *testing.T) { - chains := spinUpTestChains(t, []testChain{ - {"testChain0", "ibc-0", 0, gaiaTestConfig, gaiaProviderCfg}, - {"testChain1", "ibc-1", 1, gaiaTestConfig, gaiaProviderCfg}, - }...) - - c, err := chains.Gets("ibc-0", "ibc-1") - require.NoError(t, err) - - var ( - src = c["ibc-0"] - dst = c["ibc-1"] - testDenom = "samoleans" - twoTestCoin = sdk.NewCoin(testDenom, sdk.NewInt(2000)) - ) - - p, err := genTestPathAndSet(src, dst) - require.NoError(t, err) - - // query initial balances to compare against at the end - var srcExpected, dstExpected sdk.Coins - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - eg, egCtx := errgroup.WithContext(ctx) - eg.Go(func() error { - return retry.Do(func() error { - var err error - srcExpected, err = src.ChainProvider.QueryBalance(egCtx, src.ChainProvider.Key()) - if srcExpected.IsZero() { - return fmt.Errorf("expected non-zero balance. Err: %w", err) - } - return err - }) - }) - eg.Go(func() error { - return retry.Do(func() error { - var err error - dstExpected, err = dst.ChainProvider.QueryBalance(egCtx, dst.ChainProvider.Key()) - if dstExpected.IsZero() { - return fmt.Errorf("expected non-zero balance. Err: %w", err) - } - return err - }) - }) - require.NoError(t, eg.Wait()) - - // create path - _, _, err = src.CreateClients(ctx, dst, true, true, false, 0, "") - require.NoError(t, err) - testClientPair(ctx, t, src, dst) - - timeout, err := src.GetTimeout() - require.NoError(t, err) - - _, _, err = src.CreateOpenConnections(ctx, dst, 3, timeout, "", 0, "") - require.NoError(t, err) - testConnectionPair(ctx, t, src, dst) - - err = src.CreateOpenChannels(ctx, dst, 3, timeout, DefaultSrcPortID, DefaultDstPortID, DefaultOrder, DefaultVersion, false, "", "") - require.NoError(t, err) - - // query open channels and ensure there is no error - channels, err := src.ChainProvider.QueryConnectionChannels(ctx, 0, src.ConnectionID()) - require.NoError(t, err) - - channel := channels[0] - testChannelPair(ctx, t, src, dst, channel.ChannelId, channel.PortId) - - dstAddr, err := dst.ChainProvider.Address() - require.NoError(t, err) - - _, err = src.ChainProvider.Address() - require.NoError(t, err) - - log := zaptest.NewLogger(t) - - // send a packet that should timeout after 45 seconds - require.NoError(t, src.SendTransferMsg(ctx, log, dst, twoTestCoin, dstAddr, 0, time.Second*15, channel)) - - // wait for timestamp timeout offset to be reached - time.Sleep(time.Second * 20) - - // start the relayer process in it's own goroutine - _ = relayer.StartRelayer(ctx, log, c, []relayer.NamedPath{{Path: p}}, 2*cmd.MB, 5, "", relayer.ProcessorEvents, 20, nil) - - time.Sleep(time.Second * 10) - - // check balance on src against expected - srcGot, err := src.ChainProvider.QueryBalance(ctx, src.ChainProvider.Key()) - require.NoError(t, err) - require.Equal(t, srcExpected.AmountOf(testDenom).Int64(), srcGot.AmountOf(testDenom).Int64()) - - // check balance on dst against expected - dstGot, err := dst.ChainProvider.QueryBalance(ctx, dst.ChainProvider.Key()) - require.NoError(t, err) - require.Equal(t, dstExpected.AmountOf(testDenom).Int64(), dstGot.AmountOf(testDenom).Int64()) -} diff --git a/_test/relayer_compat_test.go b/_test/relayer_compat_test.go deleted file mode 100644 index 2fe18c0dd..000000000 --- a/_test/relayer_compat_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package test - -import "testing" - -var ( - gaiaChains = []testChain{ - {"testChain0", "ibc-0", 0, gaiaTestConfig, gaiaProviderCfg}, - {"testChain1", "ibc-1", 1, gaiaTestConfig, gaiaProviderCfg}, - } - akashChains = []testChain{ - {"testChain0", "ibc-0", 0, gaiaTestConfig, gaiaProviderCfg}, - {"testChain1", "ibc-1", 1, akashTestConfig, akashProviderCfg}, - } - osmoChains = []testChain{ - {"testChain0", "ibc-0", 0, gaiaTestConfig, gaiaProviderCfg}, - {"testChain1", "ibc-1", 1, osmosisTestConfig, osmosisProviderCfg}, - } -) - -func TestGaiaToGaiaRelaying(t *testing.T) { - chainTest(t, gaiaChains) -} - -func TestAkashToGaiaRelaying(t *testing.T) { - chainTest(t, akashChains) -} - -func TestOsmoToGaiaRelaying(t *testing.T) { - chainTest(t, osmoChains) -} diff --git a/_test/setup/akash-setup.sh b/_test/setup/akash-setup.sh deleted file mode 100755 index a7b9001a3..000000000 --- a/_test/setup/akash-setup.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -set -o errexit -o nounset - -CHAINID=$1 -GENACCT=$2 -PRIVPATH=$3 - -if [ -z "$1" ]; then - echo "Need to input chain id..." - exit 1 -fi - -if [ -z "$2" ]; then - echo "Need to input genesis account address..." - exit 1 -fi - -if [ -z "$3" ]; then - echo "Need to input path of priv_validator_key json file" - exit 1 -fi - -# Build genesis file incl account for passed address -coins="10000000000stake,100000000000samoleans" -akash init --chain-id $CHAINID $CHAINID -akash keys add validator --keyring-backend="test" -akash add-genesis-account $(akash keys show validator -a --keyring-backend="test") $coins -akash add-genesis-account $GENACCT $coins -cp $PRIVPATH ~/.akash/config/priv_validator_key.json -akash gentx validator 5000000000stake --keyring-backend="test" --chain-id $CHAINID -akash collect-gentxs - -# Set proper defaults and change ports -sed -i 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.akash/config/config.toml -sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ~/.akash/config/config.toml -sed -i 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.akash/config/config.toml -sed -i 's/index_all_keys = false/index_all_keys = true/g' ~/.akash/config/config.toml - -# Start the akash -akash start --pruning=nothing - diff --git a/_test/setup/gaia-setup.sh b/_test/setup/gaia-setup.sh deleted file mode 100755 index 12fd5c087..000000000 --- a/_test/setup/gaia-setup.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -set -o errexit -o nounset - -CHAINID=$1 -GENACCT=$2 -PRIVPATH=$3 - -if [ -z "$1" ]; then - echo "Need to input chain id..." - exit 1 -fi - -if [ -z "$2" ]; then - echo "Need to input genesis account address..." - exit 1 -fi - -if [ -z "$3" ]; then - echo "Need to input path of priv_validator_key json file" - exit 1 -fi - -# Build genesis file incl account for passed address -coins="10000000000stake,100000000000samoleans" -gaiad init --chain-id $CHAINID $CHAINID -gaiad keys add validator --keyring-backend="test" -gaiad add-genesis-account $(gaiad keys show validator -a --keyring-backend="test") $coins -gaiad add-genesis-account $GENACCT $coins -cp $PRIVPATH ~/.gaia/config/priv_validator_key.json -gaiad gentx validator 5000000000stake --keyring-backend="test" --chain-id $CHAINID -gaiad collect-gentxs - -# Set proper defaults and change ports -sed -i 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.gaia/config/config.toml -sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ~/.gaia/config/config.toml -sed -i 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.gaia/config/config.toml -sed -i 's/index_all_keys = false/index_all_keys = true/g' ~/.gaia/config/config.toml - -# Start the gaia -gaiad start --pruning=nothing --minimum-gas-prices 0.0uatom;0.0stake - diff --git a/_test/setup/osmosis-setup.sh b/_test/setup/osmosis-setup.sh deleted file mode 100755 index 02d925649..000000000 --- a/_test/setup/osmosis-setup.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -set -o errexit -o nounset - -CHAINID=$1 -GENACCT=$2 -PRIVPATH=$3 - -if [ -z "$1" ]; then - echo "Need to input chain id..." - exit 1 -fi - -if [ -z "$2" ]; then - echo "Need to input genesis account address..." - exit 1 -fi - -if [ -z "$3" ]; then - echo "Need to input path of priv_validator_key json file" - exit 1 -fi - -# Build genesis file incl account for passed address -coins="10000000000stake,100000000000samoleans" -osmosisd init --chain-id $CHAINID $CHAINID -osmosisd keys add validator --keyring-backend="test" -osmosisd add-genesis-account $(osmosisd keys show validator -a --keyring-backend="test") $coins -osmosisd add-genesis-account $GENACCT $coins -cp $PRIVPATH ~/.osmosisd/config/priv_validator_key.json -osmosisd gentx validator 5000000000stake --keyring-backend="test" --chain-id $CHAINID -osmosisd collect-gentxs - -# Set proper defaults and change ports -sed -i 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.osmosisd/config/config.toml -sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/g' ~/.osmosisd/config/config.toml -sed -i 's/timeout_propose = "3s"/timeout_propose = "1s"/g' ~/.osmosisd/config/config.toml -sed -i 's/index_all_keys = false/index_all_keys = true/g' ~/.osmosisd/config/config.toml - -# Start the osmosisd -osmosisd start --pruning=nothing - diff --git a/_test/setup/valkeys/.gitkeep b/_test/setup/valkeys/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/_test/test_chains.go b/_test/test_chains.go deleted file mode 100644 index 37c8231d2..000000000 --- a/_test/test_chains.go +++ /dev/null @@ -1,156 +0,0 @@ -package test - -import ( - "fmt" - "os" - "strconv" - "testing" - "time" - - "github.com/cosmos/cosmos-sdk/server" - "github.com/cosmos/relayer/v2/relayer" - "github.com/cosmos/relayer/v2/relayer/chains/cosmos" - "github.com/cosmos/relayer/v2/relayer/provider" - dc "github.com/ory/dockertest/v3/docker" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zaptest" -) - -const ( - // SEED1 is a mnenomic - //nolint:lll - SEED1 = "cake blossom buzz suspect image view round utility meat muffin humble club model latin similar glow draw useless kiwi snow laugh gossip roof public" - // SEED2 is a mnemonic - //nolint:lll - SEED2 = "near little movie lady moon fuel abandon gasp click element muscle elbow taste indoor soft soccer like occur legend coin near random normal adapt" -) - -var ( - gaiaProviderCfg = cosmos.CosmosProviderConfig{ - Key: "", - ChainName: "", - ChainID: "", - RPCAddr: "", - AccountPrefix: "cosmos", - KeyringBackend: "test", - GasAdjustment: 1.3, - GasPrices: "0.00samoleans", - Debug: true, - Timeout: "10s", - OutputFormat: "json", - SignModeStr: "direct", - } - gaiaTestConfig = testChainConfig{ - dockerfile: "docker/gaiad/Dockerfile", - rpcPort: "26657", - buildArgs: []dc.BuildArg{ - {Name: "VERSION", Value: "v7.0.1"}, - }, - } - - akashProviderCfg = cosmos.CosmosProviderConfig{ - Key: "", - ChainName: "", - ChainID: "", - RPCAddr: "", - AccountPrefix: "akash", - KeyringBackend: "test", - GasAdjustment: 1.3, - GasPrices: "0.00samoleans", - Debug: true, - Timeout: "10s", - OutputFormat: "json", - SignModeStr: "direct", - } - akashTestConfig = testChainConfig{ - dockerfile: "docker/akash/Dockerfile", - rpcPort: "26657", - buildArgs: []dc.BuildArg{ - {Name: "VERSION", Value: "v0.16.3"}, - }, - } - - osmosisProviderCfg = cosmos.CosmosProviderConfig{ - Key: "", - ChainName: "", - ChainID: "", - RPCAddr: "", - AccountPrefix: "osmo", - KeyringBackend: "test", - GasAdjustment: 1.3, - GasPrices: "0.00samoleans", - Debug: true, - Timeout: "10s", - OutputFormat: "json", - SignModeStr: "direct", - } - osmosisTestConfig = testChainConfig{ - dockerfile: "docker/osmosis/Dockerfile", - rpcPort: "26657", - buildArgs: []dc.BuildArg{ - {Name: "VERSION", Value: "v8.0.0"}, - }, - } - - seeds = []string{SEED1, SEED2} -) - -type ( - // testChain represents the different configuration options for spinning up a test - // cosmos-sdk based blockchain - testChain struct { - chainName string - chainID string - seed int - t testChainConfig - pcfg provider.ProviderConfig - } - - // testChainConfig represents the chain specific docker and codec configurations - // required. - testChainConfig struct { - dockerfile string - rpcPort string - timeout time.Duration - accountPrefix string - trustingPeriod string - buildArgs []dc.BuildArg - } -) - -// newTestChain generates a new instance of *Chain with a free TCP port configured as the RPC port -func newTestChain(t *testing.T, tc testChain) *relayer.Chain { - _, port, err := server.FreeTCPAddr() - require.NoError(t, err) - - switch tc.pcfg.(type) { - case cosmos.CosmosProviderConfig: - cosmosCfg, _ := tc.pcfg.(cosmos.CosmosProviderConfig) - - cosmosCfg.Key = "testkey-" + port - cosmosCfg.RPCAddr = fmt.Sprintf("http://localhost:%s", port) - cosmosCfg.ChainID = tc.chainID - - tc.pcfg = cosmosCfg - // TODO add case for substrate provider configType here - default: - panic(fmt.Errorf("no case for type %T when trying to edit ProviderConfig", tc.pcfg)) - } - - prov, err := tc.pcfg.NewProvider(zaptest.NewLogger(t), "/tmp", true, tc.chainName) - require.NoError(t, err) - - var debug bool - // add extra logging if TEST_DEBUG=true - if val, ok := os.LookupEnv("TEST_DEBUG"); ok { - debug, err = strconv.ParseBool(val) - if err != nil { - debug = false - } - } - - c := relayer.NewChain(zaptest.NewLogger(t), prov, debug) - c.Chainid = tc.chainID - c.RPCAddr = fmt.Sprintf("http://localhost:%s", port) - return c -} diff --git a/_test/test_queries.go b/_test/test_queries.go deleted file mode 100644 index a8d8998d6..000000000 --- a/_test/test_queries.go +++ /dev/null @@ -1,125 +0,0 @@ -package test - -import ( - "context" - "testing" - "time" - - "github.com/avast/retry-go/v4" - clientypes "github.com/cosmos/ibc-go/v5/modules/core/02-client/types" - chantypes "github.com/cosmos/ibc-go/v5/modules/core/04-channel/types" - "github.com/cosmos/relayer/v2/relayer" - "github.com/stretchr/testify/require" -) - -// testClientPair tests that the client for src on dst and dst on src are the only clients on those chains -func testClientPair(ctx context.Context, t *testing.T, src, dst *relayer.Chain) { - t.Helper() - testClient(ctx, t, src) - testClient(ctx, t, dst) -} - -// testClient queries client for existence of dst on src -func testClient(ctx context.Context, t *testing.T, src *relayer.Chain) { - t.Helper() - - srch, err := src.ChainProvider.QueryLatestHeight(ctx) - require.NoError(t, err) - - var client *clientypes.QueryClientStateResponse - require.NoError(t, retry.Do(func() error { - var err error - client, err = src.ChainProvider.QueryClientStateResponse(ctx, srch, src.ClientID()) - if err != nil { - srch, _ = src.ChainProvider.QueryLatestHeight(ctx) - return err - } - - return nil - })) - - require.NotNil(t, client) - - cs, err := clientypes.UnpackClientState(client.ClientState) - require.NoError(t, err) - require.Equal(t, cs.ClientType(), "07-tendermint") // TODO remove this check or create separate test for substrate -} - -// testConnectionPair tests that the only connection on src and dst is between the two chains -func testConnectionPair(ctx context.Context, t *testing.T, src, dst *relayer.Chain) { - t.Helper() - testConnection(ctx, t, src, dst) - testConnection(ctx, t, dst, src) -} - -// testConnection tests that the only connection on src has a counterparty that is the connection on dst -func testConnection(ctx context.Context, t *testing.T, src, dst *relayer.Chain) { - t.Helper() - - conns, err := src.ChainProvider.QueryConnections(ctx) - require.NoError(t, err) - require.GreaterOrEqual(t, len(conns), 1) - for _, conn := range conns { - require.Equal(t, conn.ClientId, src.PathEnd.ClientID) - require.Equal(t, conn.Counterparty.ClientId, dst.PathEnd.ClientID) - require.Equal(t, conn.Counterparty.ConnectionId, dst.PathEnd.ConnectionID) - - require.Truef(t, - conn.State.String() == "STATE_TRYOPEN" || conn.State.String() == "STATE_OPEN", - "State: %s is not STATE_TRYOPEN or STATE_OPEN", conn.State.String(), - ) - } - h, err := src.ChainProvider.QueryLatestHeight(ctx) - require.NoError(t, err) - - time.Sleep(time.Second * 5) - conn, err := src.ChainProvider.QueryConnection(ctx, h, src.ConnectionID()) - require.NoError(t, err) - require.Equal(t, conn.Connection.ClientId, src.PathEnd.ClientID) - require.Equal(t, conn.Connection.Counterparty.ClientId, dst.PathEnd.ClientID) - require.Equal(t, conn.Connection.Counterparty.ConnectionId, dst.PathEnd.ConnectionID) - require.Equal(t, conn.Connection.State.String(), "STATE_OPEN") -} - -// testChannelPair tests that the only channel on src and dst is between the two chains -func testChannelPair(ctx context.Context, t *testing.T, src, dst *relayer.Chain, channelID, portID string) { - t.Helper() - testChannel(ctx, t, src, dst, channelID, portID) - testChannel(ctx, t, dst, src, channelID, portID) -} - -// testChannel tests that the only channel on src is a counterparty of dst -func testChannel(ctx context.Context, t *testing.T, src, dst *relayer.Chain, channelID, portID string) { - t.Helper() - - chans, err := src.ChainProvider.QueryChannels(ctx) - require.NoError(t, err) - require.GreaterOrEqual(t, len(chans), 1) - - var channel *chantypes.IdentifiedChannel - for _, ch := range chans { - if ch.Counterparty.ChannelId == channelID && ch.Counterparty.PortId == portID { - channel = ch - break - } - } - - require.NotNil(t, channel) - - require.Equal(t, channel.Ordering.String(), "ORDER_UNORDERED") - require.Truef(t, - channel.State.String() == "STATE_TRY_OPEN" || channel.State.String() == "STATE_OPEN", - "State: %s is not STATE_TRY_OPEN or STATE_OPEN", channel.State.String(), - ) - - h, err := src.ChainProvider.QueryLatestHeight(ctx) - require.NoError(t, err) - - time.Sleep(time.Second * 5) - ch, err := src.ChainProvider.QueryChannel(ctx, h, channelID, portID) - require.NoError(t, err) - require.Equal(t, ch.Channel.Ordering.String(), "ORDER_UNORDERED") - require.Equal(t, ch.Channel.State.String(), "STATE_OPEN") - require.Equal(t, ch.Channel.Counterparty.ChannelId, channelID) - require.Equal(t, ch.Channel.Counterparty.PortId, portID) -} diff --git a/_test/test_setup.go b/_test/test_setup.go deleted file mode 100644 index d3f18533f..000000000 --- a/_test/test_setup.go +++ /dev/null @@ -1,286 +0,0 @@ -package test - -import ( - "fmt" - "io" - "os" - "path" - "strings" - "sync" - "testing" - "time" - - "github.com/cosmos/relayer/v2/relayer" - "golang.org/x/sync/errgroup" - - "github.com/ory/dockertest/v3" - dc "github.com/ory/dockertest/v3/docker" - "github.com/stretchr/testify/require" - - sdked25519 "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - sdkcryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - tmed25519 "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/privval" -) - -// spinUpTestChains is to be passed any number of test chains with given configuration options -// to be created as individual docker containers at the beginning of a test. It is safe to run -// in parallel tests as all created resources are independent of eachother -func spinUpTestChains(t *testing.T, testChains ...testChain) relayer.Chains { - var ( - resources []*dockertest.Resource - chains = make(relayer.Chains, len(testChains)) - - wg sync.WaitGroup - rchan = make(chan *dockertest.Resource, len(testChains)) - - testsDone = make(chan struct{}) - contDone = make(chan struct{}) - ) - - // Create temporary relayer test directory - dir := t.TempDir() - - // uses a sensible default on windows (tcp/http) and linux/osx (socket) - pool, err := dockertest.NewPool("") - if err != nil { - require.NoError(t, fmt.Errorf("could not connect to docker at %s: %w", pool.Client.Endpoint(), err)) - } - - var eg errgroup.Group - // make each container and initialize the chains - for _, tc := range testChains { - tc := tc - c := newTestChain(t, tc) - chains[tc.chainName] = c - wg.Add(1) - genPrivValKeyJSON(tc.seed) - eg.Go(func() error { - return spinUpTestContainer(t, rchan, pool, c, tc) - }) - } - - // wait for all containers to be created - require.NoError(t, eg.Wait()) - - // read all the containers out of the channel - for i := 0; i < len(chains); i++ { - r := <-rchan - resources = append(resources, r) - } - - // close the channel - close(rchan) - - // start the wait for cleanup function - go cleanUpTest(t, testsDone, contDone, resources, pool, dir, chains) - - // set the test cleanup function - t.Cleanup(func() { - testsDone <- struct{}{} - <-contDone - }) - - // return the chains and the doneFunc - return chains -} - -func removeTestContainer(pool *dockertest.Pool, containerName string) error { - containers, err := pool.Client.ListContainers(dc.ListContainersOptions{ - All: true, - Filters: map[string][]string{ - "name": {containerName}, - }, - }) - if err != nil { - return fmt.Errorf("error while listing containers with name %s: %w", containerName, err) - } - - if len(containers) == 0 { - return nil - } - - err = pool.Client.RemoveContainer(dc.RemoveContainerOptions{ - ID: containers[0].ID, - Force: true, - RemoveVolumes: true, - }) - if err != nil { - return fmt.Errorf("error while removing container with name %s: %w", containerName, err) - } - - return nil -} - -// spinUpTestContainer spins up a test container with the given configuration -// A docker image is built for each chain using its provided configuration. -// This image is then ran using the options set below. -func spinUpTestContainer(t *testing.T, rchan chan<- *dockertest.Resource, pool *dockertest.Pool, c *relayer.Chain, tc testChain) error { - t.Helper() - - var ( - err error - resource *dockertest.Resource - ) - - // create the test key - if err := c.CreateTestKey(); err != nil { - return err - } - - containerName := c.ChainID() - - // setup docker options - addr, err := c.ChainProvider.Address() - if err != nil { - return err - } - - dockerOpts := &dockertest.RunOptions{ - Name: containerName, - Repository: containerName, // Name must match Repository - Tag: "latest", // Must match docker default build tag - ExposedPorts: []string{tc.t.rpcPort, c.GetRPCPort()}, - Cmd: []string{ - c.ChainID(), - addr, - // TODO getPrivValFileName() is not going to work with substrate. - // it's not immediately clear to me what we need to do here so will need to circle back on this. - getPrivValFileName(tc.seed), - }, - PortBindings: map[dc.Port][]dc.PortBinding{ - dc.Port(tc.t.rpcPort): {{HostPort: c.GetRPCPort()}}, - }, - } - - if err := removeTestContainer(pool, containerName); err != nil { - return err - } - - // create the proper docker image with port forwarding setup - d, err := os.Getwd() - if err != nil { - return err - } - - buildOpts := &BuildOptions{ - Dockerfile: tc.t.dockerfile, - ContextDir: path.Dir(d), - BuildArgs: tc.t.buildArgs, - } - hcOpt := func(hc *dc.HostConfig) { - hc.LogConfig.Type = "json-file" - } - - resource, err = BuildAndRunWithBuildOptions(pool, buildOpts, dockerOpts, hcOpt) - if err != nil { - return err - } - - t.Logf("Chain ID %s spun up in container %s from %s", c.ChainID(), resource.Container.Name, resource.Container.Config.Image) - - // we used to poll here until the container is running without status errors but, - // we no longer expose the status error on the relayer.Chain struct. - // this sleep statement seems to work fine in all cases that we have seen over a few months. - time.Sleep(time.Second * 5) - - t.Logf("Chain ID %s's container at port %s", c.ChainID(), c.RPCAddr) - - rchan <- resource - return nil -} - -// cleanUpTest is called as a goroutine to wait until the tests have completed and -// cleans up the docker containers and relayer config -func cleanUpTest(t *testing.T, testsDone <-chan struct{}, contDone chan<- struct{}, - resources []*dockertest.Resource, pool *dockertest.Pool, dir string, chains relayer.Chains) { - // block here until tests are complete - <-testsDone - - // clean up the tmp dir - if err := os.RemoveAll(dir); err != nil { - require.NoError(t, fmt.Errorf("{cleanUpTest} failed to rm dir(%w), %s ", err, dir)) - } - - // remove all the docker containers - for _, r := range resources { - if err := pool.Purge(r); err != nil { - require.NoError(t, fmt.Errorf("could not purge container %s: %w", r.Container.Name, err)) - } - c := getLoggingChain(chains, r) - t.Logf("Spun down %s's container %s from %s", c.ChainID(), r.Container.Name, r.Container.Config.Image) - } - - // Notify the other side that we have deleted the docker containers - contDone <- struct{}{} -} - -// for the love of logs https://www.youtube.com/watch?v=DtsKcHmceqY -func getLoggingChain(chns relayer.Chains, rsr *dockertest.Resource) *relayer.Chain { - for _, c := range chns { - if strings.Contains(rsr.Container.Name, c.ChainID()) { - return c - } - } - return nil -} - -func genTestPathAndSet(src, dst *relayer.Chain) (*relayer.Path, error) { - p := relayer.GenPath(src.ChainID(), dst.ChainID()) - - src.PathEnd = p.Src - dst.PathEnd = p.Dst - return p, nil -} - -func genPrivValKeyJSON(seedNumber int) { - privKey := getPrivKey(seedNumber) - filePV := getFilePV(privKey, seedNumber) - filePV.Key.Save() -} - -func getPrivKey(seedNumber int) tmed25519.PrivKey { - return tmed25519.GenPrivKeyFromSecret([]byte(seeds[seedNumber])) -} - -func getSDKPrivKey(seedNumber int) sdkcryptotypes.PrivKey { - return sdked25519.GenPrivKeyFromSecret([]byte(seeds[seedNumber])) -} - -func getFilePV(privKey tmed25519.PrivKey, seedNumber int) *privval.FilePV { - return privval.NewFilePV(privKey, getPrivValFileName(seedNumber), "/") -} - -func getPrivValFileName(seedNumber int) string { - return fmt.Sprintf("./setup/valkeys/priv_val%d.json", seedNumber) -} - -type BuildOptions struct { - Dockerfile string - ContextDir string - BuildArgs []dc.BuildArg -} - -var muDockerBuild sync.Mutex - -// BuildAndRunWithBuildOptions builds and starts a docker container. -// Optional modifier functions can be passed in order to change the hostconfig values not covered in RunOptions -func BuildAndRunWithBuildOptions(pool *dockertest.Pool, buildOpts *BuildOptions, runOpts *dockertest.RunOptions, hcOpts ...func(*dc.HostConfig)) (*dockertest.Resource, error) { - muDockerBuild.Lock() - defer muDockerBuild.Unlock() - err := pool.Client.BuildImage(dc.BuildImageOptions{ - Name: runOpts.Name, - Dockerfile: buildOpts.Dockerfile, - OutputStream: io.Discard, - ContextDir: buildOpts.ContextDir, - BuildArgs: buildOpts.BuildArgs, - }) - - if err != nil { - return nil, err - } - - runOpts.Repository = runOpts.Name - - return pool.RunWithOptions(runOpts, hcOpts...) -}