From 72dc5f0723e29a9c7fa6a666fd84a7012d2c62e9 Mon Sep 17 00:00:00 2001 From: Dmitry S <11892559+swift1337@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:44:48 +0200 Subject: [PATCH] test(e2e): eliminate panic usage across testing suite (#2368) * Change runner receiver name to `r` * Remove panics from e2e runner * Remove panics from e2e tests * Remove panics from wait* helpers; minor improvements * Remove panics from "routines" * Remove panics from zetae2e cmd * Update changelog * Lint * Address PR comments [1] * Address PR comments [2] * Lint * Fix conflict --- changelog.md | 2 + cmd/zetaclientd/gen_pre_params.go | 2 +- cmd/zetae2e/local/admin.go | 12 - cmd/zetae2e/local/bitcoin.go | 13 - cmd/zetae2e/local/erc20.go | 13 - cmd/zetae2e/local/ethereum.go | 13 - cmd/zetae2e/local/local.go | 120 ++----- cmd/zetae2e/local/misc.go | 13 - cmd/zetae2e/local/performance.go | 25 -- cmd/zetae2e/local/zeta.go | 13 - cmd/zetae2e/local/zevm_mp.go | 13 - cmd/zetae2e/run.go | 22 +- cmd/zetae2e/stress.go | 125 +++---- e2e/contracts/contextapp/bindings.go | 3 +- e2e/e2etests/helpers.go | 18 +- e2e/e2etests/test_bitcoin_deposit.go | 20 +- .../test_bitcoin_withdraw_invalid_address.go | 42 +-- e2e/e2etests/test_bitcoin_withdraw_legacy.go | 12 +- e2e/e2etests/test_bitcoin_withdraw_p2sh.go | 10 +- e2e/e2etests/test_bitcoin_withdraw_p2wsh.go | 11 +- ...est_bitcoin_withdraw_restricted_address.go | 28 +- e2e/e2etests/test_bitcoin_withdraw_segwit.go | 11 +- e2e/e2etests/test_bitcoin_withdraw_taproot.go | 12 +- e2e/e2etests/test_context_upgrade.go | 39 +-- e2e/e2etests/test_crosschain_swap.go | 137 +++----- e2e/e2etests/test_deploy_contract.go | 17 +- e2e/e2etests/test_donation.go | 19 +- e2e/e2etests/test_erc20_deposit.go | 10 +- e2e/e2etests/test_erc20_deposit_refund.go | 120 +++---- .../test_erc20_deposit_restricted_address.go | 9 +- e2e/e2etests/test_erc20_multiple_deposits.go | 55 +--- e2e/e2etests/test_erc20_multiple_withdraws.go | 72 ++-- e2e/e2etests/test_erc20_withdraw.go | 26 +- e2e/e2etests/test_eth_deposit.go | 10 +- e2e/e2etests/test_eth_deposit_call.go | 111 +++---- .../test_eth_deposit_liquidity_cap.go | 105 +++--- e2e/e2etests/test_eth_deposit_refund.go | 127 +++---- e2e/e2etests/test_eth_withdraw.go | 41 +-- .../test_eth_withdraw_restricted_address.go | 46 ++- .../test_message_passing_evm_to_zevm.go | 82 ++--- ...test_message_passing_evm_to_zevm_revert.go | 99 +++--- ...message_passing_evm_to_zevm_revert_fail.go | 85 ++--- .../test_message_passing_external_chains.go | 61 ++-- ..._message_passing_external_chains_revert.go | 60 ++-- ...age_passing_external_chains_revert_fail.go | 50 ++- .../test_message_passing_zevm_to_evm.go | 112 +++---- ...test_message_passing_zevm_to_evm_revert.go | 102 ++---- ...message_passing_zevm_to_evm_revert_fail.go | 73 ++--- e2e/e2etests/test_migrate_chain_support.go | 87 ++--- e2e/e2etests/test_pause_zrc20.go | 148 ++++----- e2e/e2etests/test_rate_limiter.go | 33 +- e2e/e2etests/test_stress_btc_deposit.go | 26 +- e2e/e2etests/test_stress_btc_withdraw.go | 42 +-- e2e/e2etests/test_stress_eth_deposit.go | 24 +- e2e/e2etests/test_stress_eth_withdraw.go | 38 +-- .../test_update_bytecode_connector.go | 51 +-- e2e/e2etests/test_update_bytecode_zrc20.go | 179 ++++------ e2e/e2etests/test_zeta_deposit.go | 10 +- e2e/e2etests/test_zeta_deposit_new_address.go | 10 +- .../test_zeta_deposit_restricted_address.go | 9 +- e2e/e2etests/test_zeta_withdraw.go | 20 +- .../test_zeta_withdraw_bitcoin_revert.go | 38 +-- e2e/e2etests/test_zrc20_swap.go | 40 +-- e2e/runner/accounting.go | 44 +-- e2e/runner/balances.go | 70 ++-- e2e/runner/bitcoin.go | 310 +++++++----------- e2e/runner/e2etest.go | 6 +- e2e/runner/evm.go | 232 ++++++------- e2e/runner/report.go | 26 +- e2e/runner/run.go | 39 +-- e2e/runner/runner.go | 134 ++++---- e2e/runner/setup_bitcoin.go | 71 ++-- e2e/runner/setup_evm.go | 201 +++++------- e2e/runner/setup_zeta.go | 227 ++++++------- e2e/runner/zeta.go | 258 ++++++--------- e2e/utils/evm.go | 16 +- e2e/utils/require.go | 47 +++ e2e/utils/utils.go | 19 ++ e2e/utils/zetacore.go | 97 +++--- testutil/helpers.go | 38 +++ 80 files changed, 1831 insertions(+), 2980 deletions(-) create mode 100644 e2e/utils/require.go create mode 100644 testutil/helpers.go diff --git a/changelog.md b/changelog.md index ba3c0ed790..bf1a778f93 100644 --- a/changelog.md +++ b/changelog.md @@ -66,8 +66,10 @@ * [2299](https://github.com/zeta-chain/node/pull/2299) - add `zetae2e` command to deploy test contracts * [2360](https://github.com/zeta-chain/node/pull/2360) - add stateful e2e tests. * [2349](https://github.com/zeta-chain/node/pull/2349) - add TestBitcoinDepositRefund and WithdrawBitcoinMultipleTimes E2E tests +* [2368](https://github.com/zeta-chain/node/pull/2368) - eliminate panic usage across testing suite * [2369](https://github.com/zeta-chain/node/pull/2369) - fix random cross-chain swap failure caused by using tiny UTXO + ### Fixes * [1484](https://github.com/zeta-chain/node/issues/1484) - replaced hard-coded `MaxLookaheadNonce` with a default lookback factor diff --git a/cmd/zetaclientd/gen_pre_params.go b/cmd/zetaclientd/gen_pre_params.go index c797a9f206..7837867b74 100644 --- a/cmd/zetaclientd/gen_pre_params.go +++ b/cmd/zetaclientd/gen_pre_params.go @@ -18,7 +18,7 @@ var GenPrePramsCmd = &cobra.Command{ Use: "gen-pre-params ", Short: "Generate pre parameters for TSS", Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, args []string) error { startTime := time.Now() preParams, err := keygen.GeneratePreParams(time.Second * 300) if err != nil { diff --git a/cmd/zetae2e/local/admin.go b/cmd/zetae2e/local/admin.go index 1ac4cb6b60..63cff6fe23 100644 --- a/cmd/zetae2e/local/admin.go +++ b/cmd/zetae2e/local/admin.go @@ -2,7 +2,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -20,17 +19,6 @@ func adminTestRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("admin panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for erc20 advanced test adminRunner, err := initTestRunner( "admin", diff --git a/cmd/zetae2e/local/bitcoin.go b/cmd/zetae2e/local/bitcoin.go index d0f4d8bb12..cfb0501a8c 100644 --- a/cmd/zetae2e/local/bitcoin.go +++ b/cmd/zetae2e/local/bitcoin.go @@ -2,7 +2,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -22,18 +21,6 @@ func bitcoinTestRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("bitcoin panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for bitcoin test bitcoinRunner, err := initTestRunner( "bitcoin", diff --git a/cmd/zetae2e/local/erc20.go b/cmd/zetae2e/local/erc20.go index b7fd74f0d8..fe0fa8bb8a 100644 --- a/cmd/zetae2e/local/erc20.go +++ b/cmd/zetae2e/local/erc20.go @@ -2,7 +2,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -20,18 +19,6 @@ func erc20TestRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("erc20 panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for erc20 test erc20Runner, err := initTestRunner( "erc20", diff --git a/cmd/zetae2e/local/ethereum.go b/cmd/zetae2e/local/ethereum.go index efb37f1fa1..fa9e7754e2 100644 --- a/cmd/zetae2e/local/ethereum.go +++ b/cmd/zetae2e/local/ethereum.go @@ -2,7 +2,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -21,18 +20,6 @@ func ethereumTestRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("ethereum panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for ether test ethereumRunner, err := initTestRunner( "ether", diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 364bdf80a4..bd9dd654a2 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -2,7 +2,6 @@ package local import ( "context" - "fmt" "os" "path/filepath" "time" @@ -18,6 +17,7 @@ import ( "github.com/zeta-chain/zetacore/e2e/txserver" "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/testutil" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -42,6 +42,8 @@ var ( TestTimeout = 15 * time.Minute ) +var noError = testutil.NoError + // NewLocalCmd returns the local command // which runs the E2E tests locally on the machine with localnet for each blockchain func NewLocalCmd() *cobra.Command { @@ -70,58 +72,21 @@ func NewLocalCmd() *cobra.Command { func localE2ETest(cmd *cobra.Command, _ []string) { // fetch flags - waitForHeight, err := cmd.Flags().GetInt64(flagWaitForHeight) - if err != nil { - panic(err) - } - contractsDeployed, err := cmd.Flags().GetBool(flagContractsDeployed) - if err != nil { - panic(err) - } - verbose, err := cmd.Flags().GetBool(flagVerbose) - if err != nil { - panic(err) - } - configOut, err := cmd.Flags().GetString(flagConfigOut) - if err != nil { - panic(err) - } - testAdmin, err := cmd.Flags().GetBool(flagTestAdmin) - if err != nil { - panic(err) - } - testPerformance, err := cmd.Flags().GetBool(flagTestPerformance) - if err != nil { - panic(err) - } - testCustom, err := cmd.Flags().GetBool(flagTestCustom) - if err != nil { - panic(err) - } - skipRegular, err := cmd.Flags().GetBool(flagSkipRegular) - if err != nil { - panic(err) - } - light, err := cmd.Flags().GetBool(flagLight) - if err != nil { - panic(err) - } - setupOnly, err := cmd.Flags().GetBool(flagSetupOnly) - if err != nil { - panic(err) - } - skipSetup, err := cmd.Flags().GetBool(flagSkipSetup) - if err != nil { - panic(err) - } - skipBitcoinSetup, err := cmd.Flags().GetBool(flagSkipBitcoinSetup) - if err != nil { - panic(err) - } - skipHeaderProof, err := cmd.Flags().GetBool(flagSkipHeaderProof) - if err != nil { - panic(err) - } + var ( + waitForHeight = must(cmd.Flags().GetInt64(flagWaitForHeight)) + contractsDeployed = must(cmd.Flags().GetBool(flagContractsDeployed)) + verbose = must(cmd.Flags().GetBool(flagVerbose)) + configOut = must(cmd.Flags().GetString(flagConfigOut)) + testAdmin = must(cmd.Flags().GetBool(flagTestAdmin)) + testPerformance = must(cmd.Flags().GetBool(flagTestPerformance)) + testCustom = must(cmd.Flags().GetBool(flagTestCustom)) + skipRegular = must(cmd.Flags().GetBool(flagSkipRegular)) + light = must(cmd.Flags().GetBool(flagLight)) + setupOnly = must(cmd.Flags().GetBool(flagSetupOnly)) + skipSetup = must(cmd.Flags().GetBool(flagSkipSetup)) + skipBitcoinSetup = must(cmd.Flags().GetBool(flagSkipBitcoinSetup)) + skipHeaderProof = must(cmd.Flags().GetBool(flagSkipHeaderProof)) + ) logger := runner.NewLogger(verbose, color.FgWhite, "setup") @@ -146,16 +111,14 @@ func localE2ETest(cmd *cobra.Command, _ []string) { // initialize tests config conf, err := GetConfig(cmd) - if err != nil { - panic(err) - } + noError(err) // initialize context ctx, cancel := context.WithCancel(context.Background()) // wait for a specific height on ZetaChain if waitForHeight != 0 { - utils.WaitForBlockHeight(ctx, waitForHeight, conf.RPCs.ZetaCoreRPC, logger) + noError(utils.WaitForBlockHeight(ctx, waitForHeight, conf.RPCs.ZetaCoreRPC, logger)) } // set account prefix to zeta @@ -167,9 +130,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { []string{UserFungibleAdminPrivateKey}, conf.ZetaChainID, ) - if err != nil { - panic(fmt.Errorf("failed to initialize ZetaChain tx server: %w", err)) - } + noError(err) // initialize deployer runner with config deployerRunner, err := zetae2econfig.RunnerFromConfig( @@ -182,9 +143,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger, runner.WithZetaTxServer(zetaTxServer), ) - if err != nil { - panic(err) - } + noError(err) // wait for keygen to be completed // if setup is skipped, we assume that the keygen is already completed @@ -193,16 +152,13 @@ func localE2ETest(cmd *cobra.Command, _ []string) { } // query and set the TSS - if err := deployerRunner.SetTSSAddresses(); err != nil { - panic(err) - } + noError(deployerRunner.SetTSSAddresses()) if !skipHeaderProof { - if err := deployerRunner.EnableHeaderVerification([]int64{ + noError(deployerRunner.EnableHeaderVerification([]int64{ chains.GoerliLocalnet.ChainId, - chains.BitcoinRegtest.ChainId}); err != nil { - panic(err) - } + chains.BitcoinRegtest.ChainId, + })) } // setting up the networks @@ -212,30 +168,22 @@ func localE2ETest(cmd *cobra.Command, _ []string) { deployerRunner.SetupEVM(contractsDeployed, true) deployerRunner.SetZEVMContracts() - - // NOTE: this method return an error so we handle it and panic if it occurs unlike other method that panics directly - // TODO: all methods should return errors instead of panicking and this current function should also return an error - // https://github.com/zeta-chain/node/issues/1500 - if err := deployerRunner.FundEmissionsPool(); err != nil { - panic(err) - } + noError(deployerRunner.FundEmissionsPool()) deployerRunner.MintERC20OnEvm(10000) logger.Print("✅ setup completed in %s", time.Since(startTime)) } + // if a config output is specified, write the config if configOut != "" { newConfig := zetae2econfig.ExportContractsFromRunner(deployerRunner, conf) - configOut, err := filepath.Abs(configOut) - if err != nil { - panic(err) - } // write config into stdout - if err := config.WriteConfig(configOut, newConfig); err != nil { - panic(err) - } + configOut, err := filepath.Abs(configOut) + noError(err) + + noError(config.WriteConfig(configOut, newConfig)) logger.Print("✅ config file written in %s", configOut) } @@ -407,3 +355,7 @@ func waitKeygenHeight( logger.Info("Last ZetaHeight: %d", response.Height) } } + +func must[T any](v T, err error) T { + return testutil.Must(v, err) +} diff --git a/cmd/zetae2e/local/misc.go b/cmd/zetae2e/local/misc.go index 081905b5ee..65467ec9e5 100644 --- a/cmd/zetae2e/local/misc.go +++ b/cmd/zetae2e/local/misc.go @@ -2,7 +2,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -20,18 +19,6 @@ func miscTestRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("misc panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for misc test miscRunner, err := initTestRunner( "misc", diff --git a/cmd/zetae2e/local/performance.go b/cmd/zetae2e/local/performance.go index 4b83d66307..7d289c4e90 100644 --- a/cmd/zetae2e/local/performance.go +++ b/cmd/zetae2e/local/performance.go @@ -5,7 +5,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -23,18 +22,6 @@ func ethereumDepositPerformanceRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("ethereum deposit perf panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for ether test r, err := initTestRunner( "ether", @@ -77,18 +64,6 @@ func ethereumWithdrawPerformanceRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("ethereum withdraw perf panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for ether test r, err := initTestRunner( "ether", diff --git a/cmd/zetae2e/local/zeta.go b/cmd/zetae2e/local/zeta.go index 1f95c5f6d6..6f5039b63f 100644 --- a/cmd/zetae2e/local/zeta.go +++ b/cmd/zetae2e/local/zeta.go @@ -2,7 +2,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -20,18 +19,6 @@ func zetaTestRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("zeta panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for zeta test zetaRunner, err := initTestRunner( "zeta", diff --git a/cmd/zetae2e/local/zevm_mp.go b/cmd/zetae2e/local/zevm_mp.go index 969dcfda64..f95fa24390 100644 --- a/cmd/zetae2e/local/zevm_mp.go +++ b/cmd/zetae2e/local/zevm_mp.go @@ -2,7 +2,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -20,18 +19,6 @@ func zevmMPTestRoutine( testNames ...string, ) func() error { return func() (err error) { - // return an error on panic - // TODO: remove and instead return errors in the tests - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("zevm mp panic: %v, stack trace %s", r, stack[:n]) - } - }() - // initialize runner for zevm mp test zevmMPRunner, err := initTestRunner( "zevm_mp", diff --git a/cmd/zetae2e/run.go b/cmd/zetae2e/run.go index 5ed6babf6b..7d57500823 100644 --- a/cmd/zetae2e/run.go +++ b/cmd/zetae2e/run.go @@ -3,6 +3,8 @@ package main import ( "context" "errors" + "fmt" + "os" "strings" "time" @@ -35,17 +37,13 @@ For example: zetae2e run deposit:1000 withdraw: --config config.yml`, } cmd.Flags().StringVarP(&configFile, flagConfig, "c", "", "path to the configuration file") - err := cmd.MarkFlagRequired(flagConfig) - if err != nil { - panic(err) + if err := cmd.MarkFlagRequired(flagConfig); err != nil { + fmt.Println("Error marking flag as required") + os.Exit(1) } // Retain the verbose flag - cmd.Flags().Bool( - flagVerbose, - false, - "set to true to enable verbose logging", - ) + cmd.Flags().Bool(flagVerbose, false, "set to true to enable verbose logging") return cmd } @@ -75,11 +73,11 @@ func runE2ETest(cmd *cobra.Command, args []string) error { // initialize context ctx, cancel := context.WithCancel(context.Background()) + defer cancel() // get EVM address from config evmAddr := conf.Accounts.EVMAddress if !ethcommon.IsHexAddress(evmAddr) { - cancel() return errors.New("invalid EVM address") } @@ -94,7 +92,6 @@ func runE2ETest(cmd *cobra.Command, args []string) error { logger, ) if err != nil { - cancel() return err } @@ -112,31 +109,26 @@ func runE2ETest(cmd *cobra.Command, args []string) error { balancesBefore, err := testRunner.GetAccountBalances(true) if err != nil { - cancel() return err } // parse test names and arguments from cmd args and run them userTestsConfigs, err := parseCmdArgsToE2ETestRunConfig(args) if err != nil { - cancel() return err } testsToRun, err := testRunner.GetE2ETestsToRunByConfig(e2etests.AllE2ETests, userTestsConfigs) if err != nil { - cancel() return err } reports, err := testRunner.RunE2ETestsIntoReport(testsToRun) if err != nil { - cancel() return err } balancesAfter, err := testRunner.GetAccountBalances(true) if err != nil { - cancel() return err } diff --git a/cmd/zetae2e/stress.go b/cmd/zetae2e/stress.go index 472b01fc50..ca0446cbc9 100644 --- a/cmd/zetae2e/stress.go +++ b/cmd/zetae2e/stress.go @@ -24,6 +24,7 @@ import ( "github.com/zeta-chain/zetacore/cmd/zetae2e/local" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" + "github.com/zeta-chain/zetacore/testutil" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -47,6 +48,8 @@ type stressArguments struct { var stressTestArgs = stressArguments{} +var noError = testutil.NoError + func NewStressTestCmd() *cobra.Command { var StressCmd = &cobra.Command{ Use: "stress", @@ -88,27 +91,15 @@ func StressTest(cmd *cobra.Command, _ []string) { cosmosConf.Seal() // initialize E2E tests config - conf, err := local.GetConfig(cmd) - if err != nil { - panic(err) - } + conf := must(local.GetConfig(cmd)) // Initialize clients ---------------------------------------------------------------- - evmClient, err := ethclient.Dial(conf.RPCs.EVM) - if err != nil { - panic(err) - } + evmClient := must(ethclient.Dial(conf.RPCs.EVM)) + bal := must(evmClient.BalanceAt(context.TODO(), local.DeployerAddress, nil)) - bal, err := evmClient.BalanceAt(context.TODO(), local.DeployerAddress, nil) - if err != nil { - panic(err) - } fmt.Printf("Deployer address: %s, balance: %d Wei\n", local.DeployerAddress.Hex(), bal) - grpcConn, err := grpc.Dial(conf.RPCs.ZetaCoreGRPC, grpc.WithInsecure()) - if err != nil { - panic(err) - } + grpcConn := must(grpc.Dial(conf.RPCs.ZetaCoreGRPC, grpc.WithInsecure())) cctxClient := crosschaintypes.NewQueryClient(grpcConn) // ----------------------------------------------------------------------------------- @@ -136,14 +127,11 @@ func StressTest(cmd *cobra.Command, _ []string) { // initialize context ctx, cancel := context.WithCancel(context.Background()) - verbose, err := cmd.Flags().GetBool(flagVerbose) - if err != nil { - panic(err) - } + verbose := must(cmd.Flags().GetBool(flagVerbose)) logger := runner.NewLogger(verbose, color.FgWhite, "setup") // initialize E2E test runner - e2eTest, err := zetae2econfig.RunnerFromConfig( + e2eTest := must(zetae2econfig.RunnerFromConfig( ctx, "deployer", cancel, @@ -151,69 +139,47 @@ func StressTest(cmd *cobra.Command, _ []string) { local.DeployerAddress, local.DeployerPrivateKey, logger, - ) - if err != nil { - panic(err) - } + )) // setup TSS addresses - if err := e2eTest.SetTSSAddresses(); err != nil { - panic(err) - } - + noError(e2eTest.SetTSSAddresses()) e2eTest.SetupEVM(stressTestArgs.contractsDeployed, true) // If stress test is running on local docker environment - if stressTestArgs.network == "LOCAL" { + switch stressTestArgs.network { + case "LOCAL": // deploy and set zevm contract e2eTest.SetZEVMContracts() // deposit on ZetaChain e2eTest.DepositEther(false) e2eTest.DepositZeta() - } else if stressTestArgs.network == "TESTNET" { - ethZRC20Addr, err := e2eTest.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(5)) - if err != nil { - panic(err) - } + case "TESTNET": + ethZRC20Addr := must(e2eTest.SystemContract.GasCoinZRC20ByChainId(&bind.CallOpts{}, big.NewInt(5))) e2eTest.ETHZRC20Addr = ethZRC20Addr - e2eTest.ETHZRC20, err = zrc20.NewZRC20(e2eTest.ETHZRC20Addr, e2eTest.ZEVMClient) - if err != nil { - panic(err) - } - } else { - err := errors.New("invalid network argument: " + stressTestArgs.network) - panic(err) + + e2eTest.ETHZRC20 = must(zrc20.NewZRC20(e2eTest.ETHZRC20Addr, e2eTest.ZEVMClient)) + default: + noError(errors.New("invalid network argument: " + stressTestArgs.network)) } // Check zrc20 balance of Deployer address - ethZRC20Balance, err := e2eTest.ETHZRC20.BalanceOf(nil, local.DeployerAddress) - if err != nil { - panic(err) - } + ethZRC20Balance := must(e2eTest.ETHZRC20.BalanceOf(nil, local.DeployerAddress)) fmt.Printf("eth zrc20 balance: %s Wei \n", ethZRC20Balance.String()) //Pre-approve ETH withdraw on ZEVM - fmt.Printf("approving ETH ZRC20...\n") + fmt.Println("approving ETH ZRC20...") ethZRC20 := e2eTest.ETHZRC20 - tx, err := ethZRC20.Approve(e2eTest.ZEVMAuth, e2eTest.ETHZRC20Addr, big.NewInt(1e18)) - if err != nil { - panic(err) - } - receipt := utils.MustWaitForTxReceipt(ctx, e2eTest.ZEVMClient, tx, logger, e2eTest.ReceiptTimeout) + tx := must(ethZRC20.Approve(e2eTest.ZEVMAuth, e2eTest.ETHZRC20Addr, big.NewInt(1e18))) + + receipt := utils.MustWaitForTxReceipt(e2eTest.Ctx, e2eTest.ZEVMClient, tx, logger, e2eTest.ReceiptTimeout) fmt.Printf("eth zrc20 approve receipt: status %d\n", receipt.Status) // Get current nonce on zevm for DeployerAddress - Need to keep track of nonce at client level - blockNum, err := e2eTest.ZEVMClient.BlockNumber(context.Background()) - if err != nil { - panic(err) - } + blockNum := must(e2eTest.ZEVMClient.BlockNumber(ctx)) // #nosec G701 e2eTest - always in range - nonce, err := e2eTest.ZEVMClient.NonceAt(context.Background(), local.DeployerAddress, big.NewInt(int64(blockNum))) - if err != nil { - panic(err) - } + nonce := must(e2eTest.ZEVMClient.NonceAt(ctx, local.DeployerAddress, big.NewInt(int64(blockNum)))) // #nosec G701 e2e - always in range zevmNonce = big.NewInt(int64(nonce)) @@ -256,24 +222,22 @@ func WithdrawCCtx(runner *runner.E2ERunner) { } } -func EchoNetworkMetrics(runner *runner.E2ERunner) { - ticker := time.NewTicker(time.Second * StatInterval) - var queue = make([]uint64, 0) - var numTicks = 0 - var totalMinedTxns = uint64(0) - var previousMinedTxns = uint64(0) - chainID, err := getChainID(runner.EVMClient) - - if err != nil { - panic(err) - } +func EchoNetworkMetrics(r *runner.E2ERunner) { + var ( + ticker = time.NewTicker(time.Second * StatInterval) + queue = make([]uint64, 0) + numTicks int + totalMinedTxns uint64 + previousMinedTxns uint64 + chainID = must(getChainID(r.EVMClient)) + ) for { select { case <-ticker.C: numTicks++ // Get all pending outbound transactions - cctxResp, err := runner.CctxClient.ListPendingCctx( + cctxResp, err := r.CctxClient.ListPendingCctx( context.Background(), &crosschaintypes.QueryListPendingCctxRequest{ ChainId: chainID.Int64(), @@ -297,7 +261,7 @@ func EchoNetworkMetrics(runner *runner.E2ERunner) { } // // Get all trackers - trackerResp, err := runner.CctxClient.OutboundTrackerAll( + trackerResp, err := r.CctxClient.OutboundTrackerAll( context.Background(), &crosschaintypes.QueryAllOutboundTrackerRequest{}, ) @@ -337,21 +301,22 @@ func EchoNetworkMetrics(runner *runner.E2ERunner) { } } -func WithdrawETHZRC20(runner *runner.E2ERunner) { +func WithdrawETHZRC20(r *runner.E2ERunner) { defer func() { zevmNonce.Add(zevmNonce, big.NewInt(1)) }() - ethZRC20 := runner.ETHZRC20 + ethZRC20 := r.ETHZRC20 + r.ZEVMAuth.Nonce = zevmNonce - runner.ZEVMAuth.Nonce = zevmNonce - _, err := ethZRC20.Withdraw(runner.ZEVMAuth, local.DeployerAddress.Bytes(), big.NewInt(100)) - if err != nil { - panic(err) - } + must(ethZRC20.Withdraw(r.ZEVMAuth, local.DeployerAddress.Bytes(), big.NewInt(100))) } // Get ETH based chain ID func getChainID(client *ethclient.Client) (*big.Int, error) { return client.ChainID(context.Background()) } + +func must[T any](v T, err error) T { + return testutil.Must(v, err) +} diff --git a/e2e/contracts/contextapp/bindings.go b/e2e/contracts/contextapp/bindings.go index e3246d6be5..6b077d4020 100644 --- a/e2e/contracts/contextapp/bindings.go +++ b/e2e/contracts/contextapp/bindings.go @@ -28,8 +28,7 @@ var ( ) func init() { - err := json.Unmarshal(ContextAppJSON, &ContextAppContract) - if err != nil { + if err := json.Unmarshal(ContextAppJSON, &ContextAppContract); err != nil { panic(err) } diff --git a/e2e/e2etests/helpers.go b/e2e/e2etests/helpers.go index 5980679b63..4dc37498d9 100644 --- a/e2e/e2etests/helpers.go +++ b/e2e/e2etests/helpers.go @@ -8,7 +8,6 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcutil" ethcommon "github.com/ethereum/go-ethereum/common" - ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" @@ -26,7 +25,7 @@ func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) require.NoError(r, err) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - requireReceiptApproved(r, receipt) + utils.RequireTxSuccessful(r, receipt) // mine blocks if testing on regnet stop := r.MineBlocksIfLocalBitcoin() @@ -37,7 +36,7 @@ func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) require.NoError(r, err) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - requireReceiptApproved(r, receipt) + utils.RequireTxSuccessful(r, receipt) // mine 10 blocks to confirm the withdrawal tx _, err = r.GenerateToAddressIfLocalBitcoin(10, to) @@ -45,7 +44,7 @@ func withdrawBTCZRC20(r *runner.E2ERunner, to btcutil.Address, amount *big.Int) // get cctx and check status cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) - requireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) // get bitcoin tx according to the outTxHash in cctx outTxHash := cctx.GetCurrentOutboundParam().Hash @@ -134,14 +133,3 @@ func parseBitcoinWithdrawArgs(r *runner.E2ERunner, args []string, defaultReceive return receiver, amount } - -// Testify aliases ==========================================> - -func requireReceiptApproved(t require.TestingT, receipt *ethtypes.Receipt) { - require.Equal(t, ethtypes.ReceiptStatusSuccessful, receipt.Status, "receipt status is not successful") -} - -func requireCCTXStatus(t require.TestingT, cctx *crosschaintypes.CrossChainTx, expected crosschaintypes.CctxStatus) { - require.NotNil(t, cctx.CctxStatus) - require.Equal(t, expected, cctx.CctxStatus.Status, "cctx status is not %q", expected.String()) -} diff --git a/e2e/e2etests/test_bitcoin_deposit.go b/e2e/e2etests/test_bitcoin_deposit.go index 6c70f226f4..48460c42be 100644 --- a/e2e/e2etests/test_bitcoin_deposit.go +++ b/e2e/e2etests/test_bitcoin_deposit.go @@ -1,8 +1,7 @@ package e2etests import ( - "fmt" - "strconv" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -10,14 +9,9 @@ import ( ) func TestBitcoinDeposit(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestBitcoinDeposit requires exactly one argument for the amount.") - } + require.Len(r, args, 1) - depositAmount, err := strconv.ParseFloat(args[0], 64) - if err != nil { - panic("Invalid deposit amount specified for TestBitcoinDeposit.") - } + depositAmount := parseFloat(r, args[0]) r.SetBtcAddress(r.Name, false) @@ -26,11 +20,5 @@ func TestBitcoinDeposit(r *runner.E2ERunner, args []string) { // wait for the cctx to be mined cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, txHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "deposit") - if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic(fmt.Sprintf( - "expected mined status; got %s, message: %s", - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage), - ) - } + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) } diff --git a/e2e/e2etests/test_bitcoin_withdraw_invalid_address.go b/e2e/e2etests/test_bitcoin_withdraw_invalid_address.go index aaa0725a99..00a9ecb5fe 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_invalid_address.go +++ b/e2e/e2etests/test_bitcoin_withdraw_invalid_address.go @@ -1,31 +1,19 @@ package e2etests import ( - "fmt" "math/big" - "strconv" - "github.com/btcsuite/btcutil" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" ) func TestBitcoinWithdrawToInvalidAddress(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestBitcoinWithdrawToInvalidAddress requires exactly one argument for the amount.") - } + require.Len(r, args, 1) - withdrawalAmount, err := strconv.ParseFloat(args[0], 64) - if err != nil { - panic("Invalid withdrawal amount specified for TestBitcoinWithdrawToInvalidAddress.") - } - - withdrawalAmountSat, err := btcutil.NewAmount(withdrawalAmount) - if err != nil { - panic(err) - } - amount := big.NewInt(int64(withdrawalAmountSat)) + withdrawalAmount := parseFloat(r, args[0]) + amount := btcAmountFromFloat64(r, withdrawalAmount) r.SetBtcAddress(r.Name, false) @@ -37,28 +25,20 @@ func withdrawToInvalidAddress(r *runner.E2ERunner, amount *big.Int) { // approve the ZRC20 contract to spend approvalAmount BTC from the deployer address. // the actual amount transferred is provided as test arg BTC, but we approve more to cover withdraw fee tx, err := r.BTCZRC20.Approve(r.ZEVMAuth, r.BTCZRC20Addr, big.NewInt(int64(approvalAmount))) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic(fmt.Errorf("approve receipt status is not 1")) - } + utils.RequireTxSuccessful(r, receipt) // mine blocks if testing on regnet stop := r.MineBlocksIfLocalBitcoin() + defer stop() // withdraw amount provided as test arg BTC from ZRC20 to BTC legacy address // the address "1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3" is for mainnet, not regtest tx, err = r.BTCZRC20.Withdraw(r.ZEVMAuth, []byte("1EYVvXLusCxtVuEwoYvWRyN5EZTXwPVvo3"), amount) - if err != nil { - panic(err) - } - receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 1 { - panic(fmt.Errorf("withdraw receipt status is successful for an invalid BTC address")) - } + require.NoError(r, err) - // stop mining - stop() + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequiredTxFailed(r, receipt) } diff --git a/e2e/e2etests/test_bitcoin_withdraw_legacy.go b/e2e/e2etests/test_bitcoin_withdraw_legacy.go index fc2f7b2ca7..57b96034dc 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_legacy.go +++ b/e2e/e2etests/test_bitcoin_withdraw_legacy.go @@ -2,24 +2,22 @@ package e2etests import ( "github.com/btcsuite/btcutil" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" ) func TestBitcoinWithdrawLegacy(r *runner.E2ERunner, args []string) { // check length of arguments - if len(args) != 2 { - panic("TestBitcoinWithdrawLegacy requires two arguments: [receiver, amount]") - } + require.Len(r, args, 2) + r.SetBtcAddress(r.Name, false) // parse arguments and withdraw BTC - defaultReceiver := "mxpYha3UJKUgSwsAz2qYRqaDSwAkKZ3YEY" receiver, amount := parseBitcoinWithdrawArgs(r, args, defaultReceiver) + _, ok := receiver.(*btcutil.AddressPubKeyHash) - if !ok { - panic("Invalid receiver address specified for TestBitcoinWithdrawLegacy.") - } + require.True(r, ok, "Invalid receiver address specified for TestBitcoinWithdrawLegacy.") withdrawBTCZRC20(r, receiver, amount) } diff --git a/e2e/e2etests/test_bitcoin_withdraw_p2sh.go b/e2e/e2etests/test_bitcoin_withdraw_p2sh.go index 97de7675ca..c63a2d2c6b 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_p2sh.go +++ b/e2e/e2etests/test_bitcoin_withdraw_p2sh.go @@ -2,24 +2,22 @@ package e2etests import ( "github.com/btcsuite/btcutil" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" ) func TestBitcoinWithdrawP2SH(r *runner.E2ERunner, args []string) { // check length of arguments - if len(args) != 2 { - panic("TestBitcoinWithdrawP2SH requires two arguments: [receiver, amount]") - } + require.Len(r, args, 2) + r.SetBtcAddress(r.Name, false) // parse arguments and withdraw BTC defaultReceiver := "2N6AoUj3KPS7wNGZXuCckh8YEWcSYNsGbqd" receiver, amount := parseBitcoinWithdrawArgs(r, args, defaultReceiver) _, ok := receiver.(*btcutil.AddressScriptHash) - if !ok { - panic("Invalid receiver address specified for TestBitcoinWithdrawP2SH.") - } + require.True(r, ok, "Invalid receiver address specified for TestBitcoinWithdrawP2SH.") withdrawBTCZRC20(r, receiver, amount) } diff --git a/e2e/e2etests/test_bitcoin_withdraw_p2wsh.go b/e2e/e2etests/test_bitcoin_withdraw_p2wsh.go index 79943dc948..5748e0b671 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_p2wsh.go +++ b/e2e/e2etests/test_bitcoin_withdraw_p2wsh.go @@ -2,24 +2,21 @@ package e2etests import ( "github.com/btcsuite/btcutil" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" ) func TestBitcoinWithdrawP2WSH(r *runner.E2ERunner, args []string) { - // check length of arguments - if len(args) != 2 { - panic("TestBitcoinWithdrawP2WSH requires two arguments: [receiver, amount]") - } + require.Len(r, args, 2) + r.SetBtcAddress(r.Name, false) // parse arguments and withdraw BTC defaultReceiver := "bcrt1qm9mzhyky4w853ft2ms6dtqdyyu3z2tmrq8jg8xglhyuv0dsxzmgs2f0sqy" receiver, amount := parseBitcoinWithdrawArgs(r, args, defaultReceiver) _, ok := receiver.(*btcutil.AddressWitnessScriptHash) - if !ok { - panic("Invalid receiver address specified for TestBitcoinWithdrawP2WSH.") - } + require.True(r, ok, "Invalid receiver address specified for TestBitcoinWithdrawP2WSH.") withdrawBTCZRC20(r, receiver, amount) } diff --git a/e2e/e2etests/test_bitcoin_withdraw_restricted_address.go b/e2e/e2etests/test_bitcoin_withdraw_restricted_address.go index 918a4fe6e3..96cdc9ed0a 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_restricted_address.go +++ b/e2e/e2etests/test_bitcoin_withdraw_restricted_address.go @@ -1,11 +1,9 @@ package e2etests import ( - "fmt" "math/big" - "strconv" - "github.com/btcsuite/btcutil" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/pkg/chains" @@ -13,20 +11,10 @@ import ( ) func TestBitcoinWithdrawRestricted(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestBitcoinWithdrawRestricted requires exactly one argument for the amount.") - } + require.Len(r, args, 1) - withdrawalAmount, err := strconv.ParseFloat(args[0], 64) - if err != nil { - panic("Invalid withdrawal amount specified for TestBitcoinWithdrawRestricted.") - } - - withdrawalAmountSat, err := btcutil.NewAmount(withdrawalAmount) - if err != nil { - panic(err) - } - amount := big.NewInt(int64(withdrawalAmountSat)) + withdrawalAmount := parseFloat(r, args[0]) + amount := btcAmountFromFloat64(r, withdrawalAmount) r.SetBtcAddress(r.Name, false) @@ -39,13 +27,9 @@ func withdrawBitcoinRestricted(r *runner.E2ERunner, amount *big.Int) { testutils.RestrictedBtcAddressTest, chains.BitcoinRegtest.ChainId, ) - if err != nil { - panic(err) - } + require.NoError(r, err) // the cctx should be cancelled rawTx := withdrawBTCZRC20(r, addressRestricted, amount) - if len(rawTx.Vout) != 2 { - panic(fmt.Errorf("BTC cancelled outtx rawTx.Vout should have 2 outputs")) - } + require.Len(r, rawTx.Vout, 2, "BTC cancelled outtx rawTx.Vout should have 2 outputs") } diff --git a/e2e/e2etests/test_bitcoin_withdraw_segwit.go b/e2e/e2etests/test_bitcoin_withdraw_segwit.go index 31d5d1176b..2bd763693e 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_segwit.go +++ b/e2e/e2etests/test_bitcoin_withdraw_segwit.go @@ -2,24 +2,21 @@ package e2etests import ( "github.com/btcsuite/btcutil" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" ) func TestBitcoinWithdrawSegWit(r *runner.E2ERunner, args []string) { - // check length of arguments - if len(args) != 2 { - panic("TestBitcoinWithdrawSegWit requires two arguments: [receiver, amount]") - } + require.Len(r, args, 2) + r.SetBtcAddress(r.Name, false) // parse arguments defaultReceiver := r.BTCDeployerAddress.EncodeAddress() receiver, amount := parseBitcoinWithdrawArgs(r, args, defaultReceiver) _, ok := receiver.(*btcutil.AddressWitnessPubKeyHash) - if !ok { - panic("Invalid receiver address specified for TestBitcoinWithdrawSegWit.") - } + require.True(r, ok, "Invalid receiver address specified for TestBitcoinWithdrawSegWit.") withdrawBTCZRC20(r, receiver, amount) } diff --git a/e2e/e2etests/test_bitcoin_withdraw_taproot.go b/e2e/e2etests/test_bitcoin_withdraw_taproot.go index 5473a947e5..cc1c5feb87 100644 --- a/e2e/e2etests/test_bitcoin_withdraw_taproot.go +++ b/e2e/e2etests/test_bitcoin_withdraw_taproot.go @@ -1,24 +1,22 @@ package e2etests import ( + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/pkg/chains" ) func TestBitcoinWithdrawTaproot(r *runner.E2ERunner, args []string) { - // check length of arguments - if len(args) != 2 { - panic("TestBitcoinWithdrawTaproot requires two arguments: [receiver, amount]") - } + require.Len(r, args, 2) + r.SetBtcAddress(r.Name, false) // parse arguments and withdraw BTC defaultReceiver := "bcrt1pqqqsyqcyq5rqwzqfpg9scrgwpugpzysnzs23v9ccrydpk8qarc0sj9hjuh" receiver, amount := parseBitcoinWithdrawArgs(r, args, defaultReceiver) _, ok := receiver.(*chains.AddressTaproot) - if !ok { - panic("Invalid receiver address specified for TestBitcoinWithdrawTaproot.") - } + require.True(r, ok, "Invalid receiver address specified for TestBitcoinWithdrawTaproot.") withdrawBTCZRC20(r, receiver, amount) } diff --git a/e2e/e2etests/test_context_upgrade.go b/e2e/e2etests/test_context_upgrade.go index fc1e7599de..4d06ee84d1 100644 --- a/e2e/e2etests/test_context_upgrade.go +++ b/e2e/e2etests/test_context_upgrade.go @@ -6,6 +6,7 @@ import ( "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -13,30 +14,24 @@ import ( // TestContextUpgrade tests sending ETH on ZetaChain and check context data func TestContextUpgrade(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestContextUpgrade requires exactly one argument for the value.") - } + require.Len(r, args, 1) // parse the value from the provided arguments value, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid value specified for TestContextUpgrade.") - } + require.True(r, ok, "Invalid value specified for TestContextUpgrade.") data := make([]byte, 0, 32) data = append(data, r.ContextAppAddr.Bytes()...) data = append(data, []byte("filler")...) // just to make sure that this is a contract call; signedTx, err := r.SendEther(r.TSSAddress, value, data) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("EVM tx sent: %s; to %s, nonce %d", signedTx.Hash().String(), signedTx.To().Hex(), signedTx.Nonce()) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("EVM tx receipt: %d", receipt.Status) r.Logger.Info(" tx hash: %s", receipt.TxHash.String()) r.Logger.Info(" to: %s", signedTx.To().String()) @@ -60,18 +55,13 @@ func TestContextUpgrade(r *runner.E2ERunner, args []string) { r.Logger.Info(" sender: %s", eventIter.Event.Sender.Hex()) r.Logger.Info(" chainid: %d", eventIter.Event.ChainID) r.Logger.Info(" msgsender: %s", eventIter.Event.MsgSender.Hex()) + found = true - if bytes.Compare(eventIter.Event.Origin, r.DeployerAddress.Bytes()) != 0 { - panic("origin mismatch") - } - chainID, err := r.EVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } - if eventIter.Event.ChainID.Cmp(chainID) != 0 { - panic("chainID mismatch") - } + require.Equal(r, 0, bytes.Compare(eventIter.Event.Origin, r.DeployerAddress.Bytes()), "origin mismatch") + chainID, err := r.EVMClient.ChainID(r.Ctx) + require.NoError(r, err) + require.Equal(r, 0, eventIter.Event.ChainID.Cmp(chainID), "chainID mismatch") } if found { break @@ -79,8 +69,5 @@ func TestContextUpgrade(r *runner.E2ERunner, args []string) { time.Sleep(2 * time.Second) } - if !found { - panic("event not found") - } - + require.True(r, found, "event not found") } diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index 358e9ba7d7..f1fe6f54aa 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -1,12 +1,13 @@ package e2etests import ( - "fmt" "math/big" "time" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/ethereum/go-ethereum/accounts/abi/bind" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -24,38 +25,30 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { if err != nil { r.Logger.Print("ℹ️create pair error") } + txERC20ZRC20Approve, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } + require.NoError(r, err) + txBTCApprove, err := r.BTCZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } + require.NoError(r, err) // Fund ZEVMSwapApp with gas ZRC20s txTransferETH, err := r.ETHZRC20.Transfer(r.ZEVMAuth, r.ZEVMSwapAppAddr, big.NewInt(1e7)) - if err != nil { - panic(err) - } + require.NoError(r, err) + txTransferBTC, err := r.BTCZRC20.Transfer(r.ZEVMAuth, r.ZEVMSwapAppAddr, big.NewInt(1e6)) - if err != nil { - panic(err) - } + require.NoError(r, err) - if receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, txERC20ZRC20Approve, r.Logger, r.ReceiptTimeout); receipt.Status != 1 { - panic("ZRC20 ERC20 approve failed") - } - if receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, txBTCApprove, r.Logger, r.ReceiptTimeout); receipt.Status != 1 { - panic("btc approve failed") - } - if receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, txTransferETH, r.Logger, r.ReceiptTimeout); receipt.Status != 1 { - panic("ETH ZRC20 transfer failed") - } - if receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, txTransferBTC, r.Logger, r.ReceiptTimeout); receipt.Status != 1 { - panic("BTC ZRC20 transfer failed") + ensureTxReceipt := func(tx *ethtypes.Transaction, failMessage string) { + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt, failMessage) } + ensureTxReceipt(txERC20ZRC20Approve, "ZRC20 ERC20 approve failed") + ensureTxReceipt(txBTCApprove, "BTC approve failed") + ensureTxReceipt(txTransferETH, "ETH ZRC20 transfer failed") + ensureTxReceipt(txTransferBTC, "BTC ZRC20 transfer failed") + // Add 100 erc20 zrc20 liq and 0.001 BTC txAddLiquidity, err := r.UniswapV2Router.AddLiquidity( r.ZEVMAuth, @@ -68,13 +61,8 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.DeployerAddress, big.NewInt(time.Now().Add(10*time.Minute).Unix()), ) - if err != nil { - panic(fmt.Sprintf("Error liq %s", err.Error())) - } - - if receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, txAddLiquidity, r.Logger, r.ReceiptTimeout); receipt.Status != 1 { - panic("add liq receipt status is not 1") - } + require.NoError(r, err) + ensureTxReceipt(txAddLiquidity, "add liq failed") // msg would be [ZEVMSwapAppAddr, memobytes] // memobytes is dApp specific; see the contracts/ZEVMSwapApp.sol for details @@ -85,10 +73,8 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.BTCZRC20Addr, []byte(r.BTCDeployerAddress.EncodeAddress()), ) + require.NoError(r, err) - if err != nil { - panic(err) - } r.Logger.Info("memobytes(%d) %x", len(memobytes), memobytes) msg = append(msg, memobytes...) @@ -98,80 +84,52 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { cctx1 := utils.WaitCctxMinedByInboundHash(r.Ctx, txHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) // check the cctx status - if cctx1.CctxStatus.Status != types.CctxStatus_OutboundMined { - panic( - fmt.Sprintf( - "expected outbound mined status; got %s, message: %s", - cctx1.CctxStatus.Status.String(), - cctx1.CctxStatus.StatusMessage, - ), - ) - } + utils.RequireCCTXStatus(r, cctx1, types.CctxStatus_OutboundMined) // mine 10 blocks to confirm the outbound tx _, err = r.GenerateToAddressIfLocalBitcoin(10, r.BTCDeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) // mine blocks if testing on regnet stop := r.MineBlocksIfLocalBitcoin() + defer stop() // cctx1 index acts like the inboundHash for the second cctx (the one that withdraws BTC) cctx2 := utils.WaitCctxMinedByInboundHash(r.Ctx, cctx1.Index, r.CctxClient, r.Logger, r.CctxTimeout) // check the cctx status - if cctx2.CctxStatus.Status != types.CctxStatus_OutboundMined { - panic(fmt.Sprintf( - "expected outbound mined status; got %s, message: %s", - cctx2.CctxStatus.Status.String(), - cctx2.CctxStatus.StatusMessage), - ) - } + utils.RequireCCTXStatus(r, cctx2, types.CctxStatus_OutboundMined) r.Logger.Info("cctx2 outbound tx hash %s", cctx2.GetCurrentOutboundParam().Hash) r.Logger.Info("******* Second test: BTC -> ERC20ZRC20") // list deployer utxos utxos, err := r.ListDeployerUTXOs() - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("#utxos %d", len(utxos)) r.Logger.Info("memo address %s", r.ERC20ZRC20Addr) + memo, err := r.ZEVMSwapApp.EncodeMemo(&bind.CallOpts{}, r.ERC20ZRC20Addr, r.DeployerAddress.Bytes()) - if err != nil { - panic(err) - } + require.NoError(r, err) + memo = append(r.ZEVMSwapAppAddr.Bytes(), memo...) r.Logger.Info("memo length %d", len(memo)) txID, err := r.SendToTSSFromDeployerWithMemo(0.01, utxos[0:1], memo) - if err != nil { - panic(err) - } + require.NoError(r, err) cctx3 := utils.WaitCctxMinedByInboundHash(r.Ctx, txID.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx3.CctxStatus.Status != types.CctxStatus_OutboundMined { - panic(fmt.Sprintf( - "expected outbound mined status; got %s, message: %s", - cctx3.CctxStatus.Status.String(), - cctx3.CctxStatus.StatusMessage), - ) - } + utils.RequireCCTXStatus(r, cctx3, types.CctxStatus_OutboundMined) + r.Logger.Info("cctx3 index %s", cctx3.Index) r.Logger.Info(" inbound tx hash %s", cctx3.InboundParams.ObservedHash) r.Logger.Info(" status %s", cctx3.CctxStatus.Status.String()) r.Logger.Info(" status msg: %s", cctx3.CctxStatus.StatusMessage) cctx4 := utils.WaitCctxMinedByInboundHash(r.Ctx, cctx3.Index, r.CctxClient, r.Logger, r.CctxTimeout) - if cctx4.CctxStatus.Status != types.CctxStatus_OutboundMined { - panic(fmt.Sprintf( - "expected outbound mined status; got %s, message: %s", - cctx3.CctxStatus.Status.String(), - cctx3.CctxStatus.StatusMessage), - ) - } + utils.RequireCCTXStatus(r, cctx4, types.CctxStatus_OutboundMined) + r.Logger.Info("cctx4 index %s", cctx4.Index) r.Logger.Info(" outbound tx hash %s", cctx4.GetCurrentOutboundParam().Hash) r.Logger.Info(" status %s", cctx4.CctxStatus.Status.String()) @@ -181,17 +139,14 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { // the following memo will result in a revert in the contract call as targetZRC20 is set to DeployerAddress // which is apparently not a ZRC20 contract; the UNISWAP call will revert memo, err := r.ZEVMSwapApp.EncodeMemo(&bind.CallOpts{}, r.DeployerAddress, r.DeployerAddress.Bytes()) - if err != nil { - panic(err) - } + require.NoError(r, err) + memo = append(r.ZEVMSwapAppAddr.Bytes(), memo...) r.Logger.Info("memo length %d", len(memo)) amount := 0.1 txid, err := r.SendToTSSFromDeployerWithMemo(amount, utxos[1:2], memo) - if err != nil { - panic(err) - } + require.NoError(r, err) cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, txid.String(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.Info("cctx3 index %s", cctx.Index) @@ -199,17 +154,14 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.Logger.Info(" status %s", cctx.CctxStatus.Status.String()) r.Logger.Info(" status msg: %s", cctx.CctxStatus.StatusMessage) - if cctx.CctxStatus.Status != types.CctxStatus_Reverted { - panic(fmt.Sprintf("expected reverted status; got %s", cctx.CctxStatus.Status.String())) - } + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_Reverted) + outboundHash, err := chainhash.NewHashFromStr(cctx.GetCurrentOutboundParam().Hash) - if err != nil { - panic(err) - } + require.NoError(r, err) + txraw, err := r.BtcRPCClient.GetRawTransactionVerbose(outboundHash) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("out txid %s", txraw.Txid) for _, vout := range txraw.Vout { r.Logger.Info(" vout %d", vout.N) @@ -218,7 +170,4 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.Logger.Info(" p2wpkh address: %s", utils.ScriptPKToAddress(vout.ScriptPubKey.Hex, r.BitcoinParams)) } } - - // stop mining - stop() } diff --git a/e2e/e2etests/test_deploy_contract.go b/e2e/e2etests/test_deploy_contract.go index 860ae2e0dc..6133942f60 100644 --- a/e2e/e2etests/test_deploy_contract.go +++ b/e2e/e2etests/test_deploy_contract.go @@ -4,6 +4,7 @@ import ( "fmt" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testdapp" "github.com/zeta-chain/zetacore/e2e/runner" @@ -21,28 +22,20 @@ var deployMap = map[string]deployFunc{ // TestDeployContract deploys the specified contract func TestDeployContract(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + availableContractNames := make([]string, 0, len(deployMap)) for contractName := range deployMap { availableContractNames = append(availableContractNames, contractName) } availableContractNamesMessage := fmt.Sprintf("Available contract names: %v", availableContractNames) - - if len(args) != 1 { - panic( - "TestDeployContract requires exactly one argument for the contract name. " + availableContractNamesMessage, - ) - } contractName := args[0] deployFunc, ok := deployMap[contractName] - if !ok { - panic(fmt.Sprintf("Unknown contract name: %s, %s", contractName, availableContractNamesMessage)) - } + require.True(r, ok, "Unknown contract name: %s, %s", contractName, availableContractNamesMessage) addr, err := deployFunc(r) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Print("%s deployed at %s", contractName, addr.Hex()) } diff --git a/e2e/e2etests/test_donation.go b/e2e/e2etests/test_donation.go index f6d9bac3ff..2347e97e23 100644 --- a/e2e/e2etests/test_donation.go +++ b/e2e/e2etests/test_donation.go @@ -3,6 +3,8 @@ package e2etests import ( "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/pkg/constant" @@ -10,25 +12,18 @@ import ( // TestDonationEther tests donation of ether to the tss address func TestDonationEther(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestDonationEther requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestDonationEther.") - } + require.True(r, ok, "Invalid amount specified for TestDonationEther.") txDonation, err := r.SendEther(r.TSSAddress, amount, []byte(constant.DonationMessage)) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.EVMTransaction(*txDonation, "donation") // check contract deployment receipt receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, txDonation, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "donation") - if receipt.Status != 1 { - panic("donation tx failed") - } + utils.RequireTxSuccessful(r, receipt) } diff --git a/e2e/e2etests/test_erc20_deposit.go b/e2e/e2etests/test_erc20_deposit.go index f550ce4aa7..2f763f34b0 100644 --- a/e2e/e2etests/test_erc20_deposit.go +++ b/e2e/e2etests/test_erc20_deposit.go @@ -3,19 +3,17 @@ package e2etests import ( "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" ) func TestERC20Deposit(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestERC20Deposit requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestERC20Deposit.") - } + require.True(r, ok, "Invalid amount specified for TestERC20Deposit.") hash := r.DepositERC20WithAmountAndMessage(r.DeployerAddress, amount, []byte{}) diff --git a/e2e/e2etests/test_erc20_deposit_refund.go b/e2e/e2etests/test_erc20_deposit_refund.go index 684adf3d6f..ad0a962507 100644 --- a/e2e/e2etests/test_erc20_deposit_refund.go +++ b/e2e/e2etests/test_erc20_deposit_refund.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -17,9 +18,7 @@ import ( func TestERC20DepositAndCallRefund(r *runner.E2ERunner, _ []string) { // Get the initial balance of the deployer initialBal, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("Sending a deposit that should revert without a liquidity pool makes the cctx aborted") @@ -27,46 +26,34 @@ func TestERC20DepositAndCallRefund(r *runner.E2ERunner, _ []string) { // send the deposit inboundHash, err := sendInvalidERC20Deposit(r, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) // There is no liquidity pool, therefore the cctx should abort cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, inboundHash, r.CctxClient, r.Logger, r.CctxTimeout) + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_Aborted) + require.False(r, cctx.CctxStatus.IsAbortRefunded, "expected cctx status to be not refunded") + r.Logger.CCTX(*cctx, "deposit") - if cctx.CctxStatus.Status != types.CctxStatus_Aborted { - panic(fmt.Sprintf("expected cctx status to be Aborted; got %s", cctx.CctxStatus.Status)) - } + r.Logger.Info("Refunding the cctx via admin") - if cctx.CctxStatus.IsAbortRefunded != false { - panic(fmt.Sprintf("expected cctx status to be not refunded; got %t", cctx.CctxStatus.IsAbortRefunded)) - } + msg := types.NewMsgRefundAbortedCCTX(r.ZetaTxServer.GetAccountAddress(0), cctx.Index, r.DeployerAddress.String()) - r.Logger.Info("Refunding the cctx via admin") - msg := types.NewMsgRefundAbortedCCTX( - r.ZetaTxServer.GetAccountAddress(0), - cctx.Index, - r.DeployerAddress.String()) _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msg) - if err != nil { - panic(err) - } + require.NoError(r, err) // Check that the erc20 in the aborted cctx was refunded on ZetaChain newBalance, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + expectedBalance := initialBal.Add(initialBal, amount) - if newBalance.Cmp(expectedBalance) != 0 { - panic( - fmt.Sprintf( - "expected balance to be %s after refund; got %s", - expectedBalance.String(), - newBalance.String(), - ), - ) - } + require.Equal( + r, + 0, + newBalance.Cmp(expectedBalance), + "expected balance to be %s after refund; got %s", + expectedBalance.String(), + newBalance.String(), + ) r.Logger.Info("CCTX has been aborted on ZetaChain") // test refund when there is a liquidity pool @@ -74,67 +61,54 @@ func TestERC20DepositAndCallRefund(r *runner.E2ERunner, _ []string) { r.Logger.Info("Creating the liquidity pool USTD/ZETA") err = createZetaERC20LiquidityPool(r) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("Liquidity pool created") erc20Balance, err := r.ERC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) // send the deposit amount = big.NewInt(1e7) inboundHash, err = sendInvalidERC20Deposit(r, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) + erc20BalanceAfterSend := big.NewInt(0).Sub(erc20Balance, amount) // there is a liquidity pool, therefore the cctx should revert - cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, inboundHash, r.CctxClient, r.Logger, r.CctxTimeout) - // the revert tx creation will fail because the sender, used as the recipient, is not defined in the cctx - if cctx.CctxStatus.Status != types.CctxStatus_Reverted { - panic(fmt.Sprintf( - "expected cctx status to be PendingRevert; got %s, aborted message: %s", - cctx.CctxStatus.Status, - cctx.CctxStatus.StatusMessage, - )) - } + cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, inboundHash, r.CctxClient, r.Logger, r.CctxTimeout) + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_Reverted) // get revert tx revertTxHash := cctx.GetCurrentOutboundParam().Hash receipt, err := r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(revertTxHash)) - if err != nil { - panic(err) - } - if receipt.Status == 0 { - panic("expected the revert tx receipt to have status 1; got 0") - } + require.NoError(r, err) + utils.RequireTxSuccessful(r, receipt) // check that the erc20 in the reverted cctx was refunded on EVM erc20BalanceAfterRefund, err := r.ERC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + // the new balance must be higher than the previous one because of the revert refund - if erc20BalanceAfterSend.Cmp(erc20BalanceAfterRefund) != -1 { - panic(fmt.Sprintf( - "expected balance to be higher after refund than after send %s < %s", - erc20BalanceAfterSend.String(), - erc20BalanceAfterRefund.String(), - )) - } + require.Equal( + r, + -1, + erc20BalanceAfterSend.Cmp(erc20BalanceAfterRefund), + "expected balance to be higher after refund than after send %s < %s", + erc20BalanceAfterSend.String(), + erc20BalanceAfterRefund.String(), + ) + // it must also be lower than the previous balance + the amount because of the gas fee for the revert tx - if erc20BalanceAfterRefund.Cmp(erc20Balance) != -1 { - panic(fmt.Sprintf( - "expected balance to be lower after refund than before send %s < %s", - erc20BalanceAfterRefund.String(), - erc20Balance.String()), - ) - } + require.Equal( + r, + -1, + erc20BalanceAfterRefund.Cmp(erc20Balance), + "expected balance to be lower after refund than before send %s < %s", + erc20BalanceAfterRefund.String(), + erc20Balance.String(), + ) r.Logger.Info("ERC20 CCTX successfully reverted") r.Logger.Info("\tbalance before refund: %s", erc20Balance.String()) diff --git a/e2e/e2etests/test_erc20_deposit_restricted_address.go b/e2e/e2etests/test_erc20_deposit_restricted_address.go index 1823f9236d..758da5a969 100644 --- a/e2e/e2etests/test_erc20_deposit_restricted_address.go +++ b/e2e/e2etests/test_erc20_deposit_restricted_address.go @@ -4,20 +4,17 @@ import ( "math/big" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/zetaclient/testutils" ) func TestERC20DepositRestricted(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestERC20DepositRestricted requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestERC20DepositRestricted.") - } + require.True(r, ok) // deposit ERC20 to restricted address r.DepositERC20WithAmountAndMessage(ethcommon.HexToAddress(testutils.RestrictedEVMAddressTest), amount, []byte{}) diff --git a/e2e/e2etests/test_erc20_multiple_deposits.go b/e2e/e2etests/test_erc20_multiple_deposits.go index b09c363c8d..a99642f356 100644 --- a/e2e/e2etests/test_erc20_multiple_deposits.go +++ b/e2e/e2etests/test_erc20_multiple_deposits.go @@ -1,11 +1,11 @@ package e2etests import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -13,24 +13,17 @@ import ( ) func TestMultipleERC20Deposit(r *runner.E2ERunner, args []string) { - if len(args) != 2 { - panic("TestMultipleERC20Deposit requires exactly two arguments: the deposit amount and the number of deposits.") - } + require.Len(r, args, 2) depositAmount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid deposit amount specified for TestMultipleERC20Deposit.") - } + require.True(r, ok) numberOfDeposits, ok := big.NewInt(0).SetString(args[1], 10) - if !ok || numberOfDeposits.Int64() < 1 { - panic("Invalid number of deposits specified for TestMultipleERC20Deposit.") - } + require.True(r, ok) + require.NotZero(r, numberOfDeposits.Int64()) initialBal, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) txhash := multipleDeposits(r, depositAmount, numberOfDeposits) cctxs := utils.WaitCctxsMinedByInboundHash( @@ -41,51 +34,39 @@ func TestMultipleERC20Deposit(r *runner.E2ERunner, args []string) { r.Logger, r.CctxTimeout, ) - if len(cctxs) != 3 { - panic(fmt.Sprintf("cctxs length is not correct: %d", len(cctxs))) - } + require.Len(r, cctxs, 3) // check new balance is increased by amount * count bal, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + diff := big.NewInt(0).Sub(bal, initialBal) total := depositAmount.Mul(depositAmount, numberOfDeposits) - if diff.Cmp(total) != 0 { - panic(fmt.Sprintf("balance difference is not correct: %d", diff.Int64())) - } + + require.Equal(r, 0, diff.Cmp(total), "balance difference is not correct") } func multipleDeposits(r *runner.E2ERunner, amount, count *big.Int) ethcommon.Hash { // deploy depositor depositorAddr, _, depositor, err := testcontract.DeployDepositor(r.EVMAuth, r.EVMClient, r.ERC20CustodyAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) fullAmount := big.NewInt(0).Mul(amount, count) // approve tx, err := r.ERC20.Approve(r.EVMAuth, depositorAddr, fullAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } + utils.RequireTxSuccessful(r, receipt) r.Logger.Info("ERC20 Approve receipt tx hash: %s", tx.Hash().Hex()) // deposit tx, err = depositor.RunDeposits(r.EVMAuth, r.DeployerAddress.Bytes(), r.ERC20Addr, amount, []byte{}, count) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposits failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("Deposits receipt tx hash: %s", tx.Hash().Hex()) for _, log := range receipt.Logs { diff --git a/e2e/e2etests/test_erc20_multiple_withdraws.go b/e2e/e2etests/test_erc20_multiple_withdraws.go index de13c7b6b8..14bbb176ca 100644 --- a/e2e/e2etests/test_erc20_multiple_withdraws.go +++ b/e2e/e2etests/test_erc20_multiple_withdraws.go @@ -1,10 +1,10 @@ package e2etests import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -12,67 +12,55 @@ import ( ) func TestMultipleERC20Withdraws(r *runner.E2ERunner, args []string) { + require.Len(r, args, 2) + approvedAmount := big.NewInt(1e18) - if len(args) != 2 { - panic( - "TestMultipleWithdraws requires exactly two arguments: the withdrawal amount and the number of withdrawals.", - ) - } withdrawalAmount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok || withdrawalAmount.Cmp(approvedAmount) >= 0 { - panic("Invalid withdrawal amount specified for TestMultipleWithdraws.") - } + require.True(r, ok) + require.Equal( + r, + -1, + withdrawalAmount.Cmp(approvedAmount), + "Invalid withdrawal amount specified for TestMultipleWithdraws.", + ) numberOfWithdrawals, ok := big.NewInt(0).SetString(args[1], 10) - if !ok || numberOfWithdrawals.Int64() < 1 { - panic("Invalid number of withdrawals specified for TestMultipleWithdraws.") - } + require.True(r, ok) + require.NotEmpty(r, numberOfWithdrawals.Int64()) // calculate total withdrawal to ensure it doesn't exceed approved amount. totalWithdrawal := big.NewInt(0).Mul(withdrawalAmount, numberOfWithdrawals) - if totalWithdrawal.Cmp(approvedAmount) >= 0 { - panic("Total withdrawal amount exceeds approved limit.") - } + require.Equal(r, -1, totalWithdrawal.Cmp(approvedAmount), "Total withdrawal amount exceeds approved limit.") // deploy withdrawer withdrawerAddr, _, withdrawer, err := testcontract.DeployWithdrawer(r.ZEVMAuth, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) // approve tx, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, withdrawerAddr, approvedAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("ERC20 ZRC20 approve receipt: status %d", receipt.Status) // approve gas token tx, err = r.ETHZRC20.Approve(r.ZEVMAuth, withdrawerAddr, approvedAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve gas token failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("eth zrc20 approve receipt: status %d", receipt.Status) // check the balance bal, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("balance of deployer on ERC20 ZRC20: %d", bal) - if bal.Int64() < totalWithdrawal.Int64() { - panic("not enough ERC20 ZRC20 balance!") - } + require.Less(r, totalWithdrawal.Int64(), bal.Int64(), "not enough ERC20 ZRC20 balance!") // withdraw tx, err = withdrawer.RunWithdraws( @@ -82,13 +70,9 @@ func TestMultipleERC20Withdraws(r *runner.E2ERunner, args []string) { withdrawalAmount, numberOfWithdrawals, ) - if err != nil { - panic(err) - } + require.NoError(r, err) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("withdraw failed") - } + utils.RequireTxSuccessful(r, receipt) cctxs := utils.WaitCctxsMinedByInboundHash( r.Ctx, @@ -98,9 +82,7 @@ func TestMultipleERC20Withdraws(r *runner.E2ERunner, args []string) { r.Logger, r.CctxTimeout, ) - if len(cctxs) != 3 { - panic(fmt.Sprintf("cctxs length is not correct: %d", len(cctxs))) - } + require.Len(r, cctxs, 3) // verify the withdraw value for _, cctx := range cctxs { diff --git a/e2e/e2etests/test_erc20_withdraw.go b/e2e/e2etests/test_erc20_withdraw.go index 3d24b1670a..f2ce31b5c3 100644 --- a/e2e/e2etests/test_erc20_withdraw.go +++ b/e2e/e2etests/test_erc20_withdraw.go @@ -3,34 +3,27 @@ package e2etests import ( "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" ) func TestERC20Withdraw(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + approvedAmount := big.NewInt(1e18) - if len(args) != 1 { - panic("TestERC20Withdraw requires exactly one argument for the withdrawal amount.") - } withdrawalAmount, ok := new(big.Int).SetString(args[0], 10) - if !ok { - panic("Invalid withdrawal amount specified for TestERC20Withdraw.") - } - - if withdrawalAmount.Cmp(approvedAmount) >= 0 { - panic("Withdrawal amount must be less than the approved amount (1e18).") - } + require.True(r, ok, "Invalid withdrawal amount specified for TestERC20Withdraw.") + require.Equal(r, -1, withdrawalAmount.Cmp(approvedAmount)) // approve tx, err := r.ETHZRC20.Approve(r.ZEVMAuth, r.ERC20ZRC20Addr, approvedAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } + utils.RequireTxSuccessful(r, receipt) r.Logger.Info("eth zrc20 approve receipt: status %d", receipt.Status) // withdraw @@ -38,5 +31,6 @@ func TestERC20Withdraw(r *runner.E2ERunner, args []string) { // verify the withdraw value cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + verifyTransferAmountFromCCTX(r, cctx, withdrawalAmount.Int64()) } diff --git a/e2e/e2etests/test_eth_deposit.go b/e2e/e2etests/test_eth_deposit.go index 5b06bfe3bc..03da8f6da4 100644 --- a/e2e/e2etests/test_eth_deposit.go +++ b/e2e/e2etests/test_eth_deposit.go @@ -3,20 +3,18 @@ package e2etests import ( "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" ) // TestEtherDeposit tests deposit of ethers func TestEtherDeposit(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestEtherDeposit requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestEtherDeposit.") - } + require.True(r, ok, "Invalid amount specified for TestEtherDeposit.") hash := r.DepositEtherWithAmount(false, amount) // in wei // wait for the cctx to be mined diff --git a/e2e/e2etests/test_eth_deposit_call.go b/e2e/e2etests/test_eth_deposit_call.go index dc6cc5cb32..0d7734fbdb 100644 --- a/e2e/e2etests/test_eth_deposit_call.go +++ b/e2e/e2etests/test_eth_deposit_call.go @@ -1,13 +1,12 @@ package e2etests import ( - "fmt" "math/big" - "strings" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -17,125 +16,91 @@ import ( // TestEtherDepositAndCall tests deposit of ethers calling a example contract func TestEtherDepositAndCall(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestEtherDepositAndCall requires exactly one argument for the amount.") - } + require.Len(r, args, 1) value, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestEtherDepositAndCall.") - } + require.True(r, ok, "Invalid amount specified for TestEtherDepositAndCall.") r.Logger.Info("Deploying example contract") exampleAddr, _, exampleContract, err := testcontract.DeployExample(r.ZEVMAuth, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("Example contract deployed") // preparing tx evmClient := r.EVMClient gasLimit := uint64(23000) gasPrice, err := evmClient.SuggestGasPrice(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) + nonce, err := evmClient.PendingNonceAt(r.Ctx, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) data := append(exampleAddr.Bytes(), []byte("hello sailors")...) tx := ethtypes.NewTransaction(nonce, r.TSSAddress, value, gasLimit, gasPrice, data) chainID, err := evmClient.NetworkID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) + deployerPrivkey, err := crypto.HexToECDSA(r.DeployerPrivateKey) - if err != nil { - panic(err) - } + require.NoError(r, err) + signedTx, err := ethtypes.SignTx(tx, ethtypes.NewEIP155Signer(chainID), deployerPrivkey) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("Sending a cross-chain call to example contract") err = evmClient.SendTransaction(r.Ctx, signedTx) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, signedTx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != types.CctxStatus_OutboundMined { - panic(fmt.Sprintf("expected cctx status to be mined; got %s", cctx.CctxStatus.Status)) - } + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_OutboundMined) // Checking example contract has been called, bar value should be set to amount bar, err := exampleContract.Bar(&bind.CallOpts{}) - if err != nil { - panic(err) - } - if bar.Cmp(value) != 0 { - panic( - fmt.Sprintf( - "cross-chain call failed bar value %s should be equal to amount %s", - bar.String(), - value.String(), - ), - ) - } + require.NoError(r, err) + require.Equal( + r, + 0, + bar.Cmp(value), + "cross-chain call failed bar value %s should be equal to amount %s", + bar.String(), + value.String(), + ) r.Logger.Info("Cross-chain call succeeded") r.Logger.Info("Deploying reverter contract") reverterAddr, _, _, err := testcontract.DeployReverter(r.ZEVMAuth, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("Example reverter deployed") // preparing tx for reverter gasPrice, err = evmClient.SuggestGasPrice(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) + nonce, err = evmClient.PendingNonceAt(r.Ctx, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) data = append(reverterAddr.Bytes(), []byte("hello sailors")...) tx = ethtypes.NewTransaction(nonce, r.TSSAddress, value, gasLimit, gasPrice, data) signedTx, err = ethtypes.SignTx(tx, ethtypes.NewEIP155Signer(chainID), deployerPrivkey) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("Sending a cross-chain call to reverter contract") err = evmClient.SendTransaction(r.Ctx, signedTx) - if err != nil { - panic(err) - } + require.NoError(r, err) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, signedTx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != types.CctxStatus_Reverted { - panic(fmt.Sprintf("expected cctx status to be reverted; got %s", cctx.CctxStatus.Status)) - } + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_Reverted) + r.Logger.Info("Cross-chain call to reverter reverted") // check the status message contains revert error hash in case of revert // 0xbfb4ebcf is the hash of "Foo()" - if !strings.Contains(cctx.CctxStatus.StatusMessage, "0xbfb4ebcf") { - panic( - fmt.Sprintf("expected cctx status message to contain revert reason; got %s", cctx.CctxStatus.StatusMessage), - ) - } + require.Contains(r, cctx.CctxStatus.StatusMessage, "0xbfb4ebcf") } diff --git a/e2e/e2etests/test_eth_deposit_liquidity_cap.go b/e2e/e2etests/test_eth_deposit_liquidity_cap.go index a132fdd35e..f64b041478 100644 --- a/e2e/e2etests/test_eth_deposit_liquidity_cap.go +++ b/e2e/e2etests/test_eth_deposit_liquidity_cap.go @@ -1,11 +1,11 @@ package e2etests import ( - "fmt" "math/big" "cosmossdk.io/math" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -15,15 +15,11 @@ import ( // TestDepositEtherLiquidityCap tests depositing Ethers in a context where a liquidity cap is set func TestDepositEtherLiquidityCap(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestDepositEtherLiquidityCap requires exactly one argument for the liquidity cap.") - } + require.Len(r, args, 1) liquidityCapArg := math.NewUintFromString(args[0]) supply, err := r.ETHZRC20.TotalSupply(&bind.CallOpts{}) - if err != nil { - panic(err) - } + require.NoError(r, err) liquidityCap := math.NewUintFromBigInt(supply).Add(liquidityCapArg) amountLessThanCap := liquidityCapArg.BigInt().Div(liquidityCapArg.BigInt(), big.NewInt(10)) // 1/10 of the cap @@ -34,63 +30,41 @@ func TestDepositEtherLiquidityCap(r *runner.E2ERunner, args []string) { liquidityCap, ) res, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msg) - if err != nil { - panic(err) - } - r.Logger.Info("set liquidity cap tx hash: %s", res.TxHash) + require.NoError(r, err) + r.Logger.Info("set liquidity cap tx hash: %s", res.TxHash) r.Logger.Info("Depositing more than liquidity cap should make cctx reverted") + signedTx, err := r.SendEther(r.TSSAddress, amountMoreThanCap, nil) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposit eth tx failed") - } + utils.RequireTxSuccessful(r, receipt) + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, signedTx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != types.CctxStatus_Reverted { - panic(fmt.Sprintf("expected cctx status to be Reverted; got %s", cctx.CctxStatus.Status)) - } + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_Reverted) + r.Logger.Info("CCTX has been reverted") r.Logger.Info("Depositing less than liquidity cap should still succeed") initialBal, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + signedTx, err = r.SendEther(r.TSSAddress, amountLessThanCap, nil) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposit eth tx failed") - } + utils.RequireTxSuccessful(r, receipt) + cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, signedTx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != types.CctxStatus_OutboundMined { - - panic(fmt.Sprintf( - "expected cctx status to be Success; got %s; message: %s; supply: %s; liquidity cap: %s, amountLessThanCap: %s, amountMoreThanCap: %s", - cctx.CctxStatus.Status, - cctx.CctxStatus.StatusMessage, - supply.String(), - liquidityCap.String(), - amountLessThanCap.String(), - amountMoreThanCap.String(), - )) - } + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_OutboundMined) expectedBalance := big.NewInt(0).Add(initialBal, amountLessThanCap) bal, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } - if bal.Cmp(expectedBalance) != 0 { + require.NoError(r, err) + require.Equal(r, 0, bal.Cmp(expectedBalance)) - panic(fmt.Sprintf("expected balance to be %s; got %s", expectedBalance.String(), bal.String())) - } r.Logger.Info("Deposit succeeded") r.Logger.Info("Removing the liquidity cap") @@ -99,32 +73,33 @@ func TestDepositEtherLiquidityCap(r *runner.E2ERunner, args []string) { r.ETHZRC20Addr.Hex(), math.ZeroUint(), ) + res, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msg) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("remove liquidity cap tx hash: %s", res.TxHash) + initialBal, err = r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + signedTx, err = r.SendEther(r.TSSAddress, amountMoreThanCap, nil) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposit eth tx failed") - } + utils.RequireTxSuccessful(r, receipt) + utils.WaitCctxMinedByInboundHash(r.Ctx, signedTx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) expectedBalance = big.NewInt(0).Add(initialBal, amountMoreThanCap) bal, err = r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } - if bal.Cmp(expectedBalance) != 0 { - panic(fmt.Sprintf("expected balance to be %s; got %s", expectedBalance.String(), bal.String())) - } + require.NoError(r, err) + require.Equal(r, + 0, + bal.Cmp(expectedBalance), + "expected balance to be %s; got %s", + expectedBalance.String(), + bal.String(), + ) + r.Logger.Info("New deposit succeeded") } diff --git a/e2e/e2etests/test_eth_deposit_refund.go b/e2e/e2etests/test_eth_deposit_refund.go index 2de41965ea..394ffdd8e4 100644 --- a/e2e/e2etests/test_eth_deposit_refund.go +++ b/e2e/e2etests/test_eth_deposit_refund.go @@ -1,12 +1,12 @@ package e2etests import ( - "fmt" "math/big" ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -14,109 +14,74 @@ import ( ) func TestEtherDepositAndCallRefund(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestEtherDepositAndCallRefund requires exactly one argument for the amount.") - } + require.Len(r, args, 1) value, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestEtherDepositAndCallRefund.") - } + require.True(r, ok, "Invalid amount specified for TestEtherDepositAndCallRefund.") evmClient := r.EVMClient nonce, err := evmClient.PendingNonceAt(r.Ctx, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) gasLimit := uint64(23000) // in units gasPrice, err := evmClient.SuggestGasPrice(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) data := append(r.BTCZRC20Addr.Bytes(), []byte("hello sailors")...) // this data tx := ethtypes.NewTransaction(nonce, r.TSSAddress, value, gasLimit, gasPrice, data) chainID, err := evmClient.NetworkID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) + deployerPrivkey, err := crypto.HexToECDSA(r.DeployerPrivateKey) - if err != nil { - panic(err) - } + require.NoError(r, err) signedTx, err := ethtypes.SignTx(tx, ethtypes.NewEIP155Signer(chainID), deployerPrivkey) - if err != nil { - panic(err) - } + require.NoError(r, err) + err = evmClient.SendTransaction(r.Ctx, signedTx) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("EVM tx sent: %s; to %s, nonce %d", signedTx.Hash().String(), signedTx.To().Hex(), signedTx.Nonce()) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) + r.Logger.Info("EVM tx receipt: %d", receipt.Status) r.Logger.Info(" tx hash: %s", receipt.TxHash.String()) r.Logger.Info(" to: %s", signedTx.To().String()) r.Logger.Info(" value: %d", signedTx.Value()) r.Logger.Info(" block num: %d", receipt.BlockNumber) - func() { - cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, signedTx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) - r.Logger.Info("cctx status message: %s", cctx.CctxStatus.StatusMessage) - revertTxHash := cctx.GetCurrentOutboundParam().Hash - r.Logger.Info("EVM revert tx receipt: status %d", receipt.Status) - - tx, _, err := r.EVMClient.TransactionByHash(r.Ctx, ethcommon.HexToHash(revertTxHash)) - if err != nil { - panic(err) - } - receipt, err := r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(revertTxHash)) - if err != nil { - panic(err) - } - - printTxInfo := func() { - // debug info when test fails - r.Logger.Info(" tx: %+v", tx) - r.Logger.Info(" receipt: %+v", receipt) - r.Logger.Info("cctx http://localhost:1317/zeta-chain/crosschain/cctx/%s", cctx.Index) - } - - if cctx.CctxStatus.Status != types.CctxStatus_Reverted { - printTxInfo() - panic(fmt.Sprintf("expected cctx status to be PendingRevert; got %s", cctx.CctxStatus.Status)) - } - - if receipt.Status == 0 { - printTxInfo() - panic("expected the revert tx receipt to have status 1; got 0") - } - - if *tx.To() != r.DeployerAddress { - printTxInfo() - panic(fmt.Sprintf("expected tx to %s; got %s", r.DeployerAddress.Hex(), tx.To().Hex())) - } - - // the received value must be lower than the original value because of the paid fees for the revert tx - // we check that the value is still greater than 0 - if tx.Value().Cmp(value) != -1 || tx.Value().Cmp(big.NewInt(0)) != 1 { - printTxInfo() - panic( - fmt.Sprintf( - "expected tx value %s; should be non-null and lower than %s", - tx.Value().String(), - value.String(), - ), - ) - } - - r.Logger.Info("REVERT tx receipt: %d", receipt.Status) - r.Logger.Info(" tx hash: %s", receipt.TxHash.String()) - r.Logger.Info(" to: %s", tx.To().String()) - r.Logger.Info(" value: %s", tx.Value().String()) - r.Logger.Info(" block num: %d", receipt.BlockNumber) - }() + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, signedTx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + r.Logger.Info("cctx status message: %s", cctx.CctxStatus.StatusMessage) + revertTxHash := cctx.GetCurrentOutboundParam().Hash + r.Logger.Info("EVM revert tx receipt: status %d", receipt.Status) + + tx, _, err = r.EVMClient.TransactionByHash(r.Ctx, ethcommon.HexToHash(revertTxHash)) + require.NoError(r, err) + + receipt, err = r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(revertTxHash)) + require.NoError(r, err) + + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_Reverted) + utils.RequireTxSuccessful(r, receipt) + + require.Equal(r, r.DeployerAddress, *tx.To(), "expected tx to %s; got %s", r.DeployerAddress.Hex(), tx.To().Hex()) + + // the received value must be lower than the original value because of the paid fees for the revert tx + // we check that the value is still greater than 0 + invariant := tx.Value().Cmp(value) != -1 || tx.Value().Cmp(big.NewInt(0)) != 1 + require.False( + r, + invariant, + "expected tx value %s; should be non-null and lower than %s", + tx.Value().String(), + value.String(), + ) + + r.Logger.Info("REVERT tx receipt: %d", receipt.Status) + r.Logger.Info(" tx hash: %s", receipt.TxHash.String()) + r.Logger.Info(" to: %s", tx.To().String()) + r.Logger.Info(" value: %s", tx.Value().String()) + r.Logger.Info(" block num: %d", receipt.BlockNumber) } diff --git a/e2e/e2etests/test_eth_withdraw.go b/e2e/e2etests/test_eth_withdraw.go index 5a71ec65fb..798704fe39 100644 --- a/e2e/e2etests/test_eth_withdraw.go +++ b/e2e/e2etests/test_eth_withdraw.go @@ -3,51 +3,46 @@ package e2etests import ( "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" ) -// TestEtherWithdraw tests the withdraw of ether +// TestEtherWithdraw tests the withdrawal of ether func TestEtherWithdraw(r *runner.E2ERunner, args []string) { - r.Logger.Info("TestEtherWithdraw") + require.Len(r, args, 1) approvedAmount := big.NewInt(1e18) - if len(args) != 1 { - panic("TestEtherWithdraw requires exactly one argument for the withdrawal amount.") - } - withdrawalAmount, ok := new(big.Int).SetString(args[0], 10) - if !ok { - panic("Invalid withdrawal amount specified for TestEtherWithdraw.") - } - - if withdrawalAmount.Cmp(approvedAmount) >= 0 { - panic("Withdrawal amount must be less than the approved amount (1e18).") - } + require.True(r, ok, "Invalid withdrawal amount specified for TestEtherWithdraw.") + require.Equal( + r, + -1, + withdrawalAmount.Cmp(approvedAmount), + "Withdrawal amount must be less than the approved amount (1e18).", + ) // approve tx, err := r.ETHZRC20.Approve(r.ZEVMAuth, r.ETHZRC20Addr, approvedAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.EVMTransaction(*tx, "approve") receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.EVMReceipt(*receipt, "approve") // withdraw tx = r.WithdrawEther(withdrawalAmount) - // verify the withdraw value + // verify the withdrawal value cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "withdraw") - if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic("cctx status is not outbound mined") - } + + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) r.Logger.Info("TestEtherWithdraw completed") } diff --git a/e2e/e2etests/test_eth_withdraw_restricted_address.go b/e2e/e2etests/test_eth_withdraw_restricted_address.go index 8f17cb4edb..793bfc42c5 100644 --- a/e2e/e2etests/test_eth_withdraw_restricted_address.go +++ b/e2e/e2etests/test_eth_withdraw_restricted_address.go @@ -4,6 +4,7 @@ import ( "math/big" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -13,54 +14,47 @@ import ( // TestEtherWithdrawRestricted tests the withdrawal to a restricted receiver address func TestEtherWithdrawRestricted(r *runner.E2ERunner, args []string) { + require.Len(r, args, 1) + approvedAmount := big.NewInt(1e18) - if len(args) != 1 { - panic("TestEtherWithdrawRestricted requires exactly one argument for the withdrawal amount.") - } withdrawalAmount, ok := new(big.Int).SetString(args[0], 10) - if !ok { - panic("Invalid withdrawal amount specified for TestEtherWithdrawRestricted.") - } - - if withdrawalAmount.Cmp(approvedAmount) >= 0 { - panic("Withdrawal amount must be less than the approved amount (1e18).") - } + require.True(r, ok) + require.True( + r, + withdrawalAmount.Cmp(approvedAmount) <= 0, + "Withdrawal amount must be less than the approved amount (1e18)", + ) // approve tx, err := r.ETHZRC20.Approve(r.ZEVMAuth, r.ETHZRC20Addr, approvedAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.EVMTransaction(*tx, "approve") receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.EVMReceipt(*receipt, "approve") // withdraw restrictedAddress := ethcommon.HexToAddress(testutils.RestrictedEVMAddressTest) tx, err = r.ETHZRC20.Withdraw(r.ZEVMAuth, restrictedAddress.Bytes(), withdrawalAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.EVMTransaction(*tx, "withdraw to restricted address") receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("withdraw failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.EVMReceipt(*receipt, "withdraw") r.Logger.ZRC20Withdrawal(r.ETHZRC20, *receipt, "withdraw") - // verify the withdraw value + // verify the withdrawal value cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "withdraw") - if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic("cctx status is not outbound mined") - } + + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) // the cctx should be cancelled with zero value verifyTransferAmountFromCCTX(r, cctx, 0) diff --git a/e2e/e2etests/test_message_passing_evm_to_zevm.go b/e2e/e2etests/test_message_passing_evm_to_zevm.go index bedfd50965..4a7ac7f906 100644 --- a/e2e/e2etests/test_message_passing_evm_to_zevm.go +++ b/e2e/e2etests/test_message_passing_evm_to_zevm.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testdapp" "github.com/zeta-chain/zetacore/e2e/runner" @@ -14,81 +15,56 @@ import ( ) func TestMessagePassingEVMtoZEVM(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassingEVMtoZEVM requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassingEVMtoZEVM.") - } + require.True(r, ok, "Invalid amount specified for TestMessagePassingEVMtoZEVM.") // Set destination details zEVMChainID, err := r.ZEVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) destinationAddress := r.ZevmTestDAppAddr // Contract call originates from EVM chain tx, err := r.ZetaEth.Approve(r.EVMAuth, r.EvmTestDAppAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("approve tx failed") - } + utils.RequireTxSuccessful(r, receipt) r.Logger.Info("Approve tx receipt: %d", receipt.Status) testDAppEVM, err := testdapp.NewTestDApp(r.EvmTestDAppAddr, r.EVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) // Get ZETA balance on ZEVM TestDApp previousBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZevmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) previousBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.EVMAuth.From) - if err != nil { - panic(err) - } + require.NoError(r, err) // Call the SendHelloWorld function on the EVM dapp Contract which would in turn create a new send, to be picked up by the zeta-clients // set Do revert to false which adds a message to signal the ZEVM zetaReceiver to not revert the transaction tx, err = testDAppEVM.SendHelloWorld(r.EVMAuth, destinationAddress, zEVMChainID, amount, false) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("TestDApp.SendHello tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) // New inbound message picked up by zeta-clients and voted on by observers to initiate a contract call on zEVM cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_OutboundMined { - panic("expected cctx to be outbound_mined") - } + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_OutboundMined) + r.Logger.Info(fmt.Sprintf("🔄 Cctx mined for contract call chain zevm %s", cctx.Index)) // On finalization the Fungible module calls the onReceive function which in turn calls the onZetaMessage function on the destination contract receipt, err = r.ZEVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(cctx.GetCurrentOutboundParam().Hash)) - if err != nil { - panic(err) - } - if receipt.Status != 1 { - panic("tx failed") - } + require.NoError(r, err) + utils.RequireTxSuccessful(r, receipt) testDAppZEVM, err := testdapp.NewTestDApp(r.ZevmTestDAppAddr, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) // Check event emitted receivedHelloWorldEvent := false @@ -99,33 +75,15 @@ func TestMessagePassingEVMtoZEVM(r *runner.E2ERunner, args []string) { receivedHelloWorldEvent = true } } - if !receivedHelloWorldEvent { - panic(fmt.Sprintf("expected HelloWorld event, logs: %+v", receipt.Logs)) - } + require.True(r, receivedHelloWorldEvent, "expected HelloWorld event") // Check ZETA balance on ZEVM TestDApp and check new balance is previous balance + amount newBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZevmTestDAppAddr) - if err != nil { - panic(err) - } - if newBalanceZEVM.Cmp(big.NewInt(0).Add(previousBalanceZEVM, amount)) != 0 { - panic(fmt.Sprintf( - "expected new balance to be %s, got %s", - big.NewInt(0).Add(previousBalanceZEVM, amount).String(), - newBalanceZEVM.String()), - ) - } + require.NoError(r, err) + require.Equal(r, 0, newBalanceZEVM.Cmp(big.NewInt(0).Add(previousBalanceZEVM, amount))) // Check ZETA balance on EVM TestDApp and check new balance is previous balance - amount newBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.EVMAuth.From) - if err != nil { - panic(err) - } - if newBalanceEVM.Cmp(big.NewInt(0).Sub(previousBalanceEVM, amount)) != 0 { - panic(fmt.Sprintf( - "expected new balance to be %s, got %s", - big.NewInt(0).Sub(previousBalanceEVM, amount).String(), - newBalanceEVM.String()), - ) - } + require.NoError(r, err) + require.Equal(r, 0, newBalanceEVM.Cmp(big.NewInt(0).Sub(previousBalanceEVM, amount))) } diff --git a/e2e/e2etests/test_message_passing_evm_to_zevm_revert.go b/e2e/e2etests/test_message_passing_evm_to_zevm_revert.go index 3c12711aed..b99ea8513f 100644 --- a/e2e/e2etests/test_message_passing_evm_to_zevm_revert.go +++ b/e2e/e2etests/test_message_passing_evm_to_zevm_revert.go @@ -1,11 +1,11 @@ package e2etests import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testdapp" "github.com/zeta-chain/zetacore/e2e/runner" @@ -14,57 +14,43 @@ import ( ) func TestMessagePassingEVMtoZEVMRevert(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassingEVMtoZEVMRevert requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassingEVMtoZEVMRevert.") - } + require.True(r, ok) // Set destination details zEVMChainID, err := r.ZEVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) destinationAddress := r.ZevmTestDAppAddr // Contract call originates from EVM chain tx, err := r.ZetaEth.Approve(r.EVMAuth, r.EvmTestDAppAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("Approve tx receipt: %d", receipt.Status) testDAppEVM, err := testdapp.NewTestDApp(r.EvmTestDAppAddr, r.EVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) // Get ZETA balance before test previousBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZevmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) + previousBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.EvmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) // Call the SendHelloWorld function on the EVM dapp Contract which would in turn create a new send, to be picked up by the zeta-clients // set Do revert to true which adds a message to signal the ZEVM zetaReceiver to revert the transaction tx, err = testDAppEVM.SendHelloWorld(r.EVMAuth, destinationAddress, zEVMChainID, amount, true) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("TestDApp.SendHello tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) @@ -72,18 +58,13 @@ func TestMessagePassingEVMtoZEVMRevert(r *runner.E2ERunner, args []string) { // New inbound message picked up by zeta-clients and voted on by observers to initiate a contract call on zEVM which would revert the transaction // A revert transaction is created and gets fialized on the original sender chain. cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_Reverted { - panic("expected cctx to be reverted") - } + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_Reverted) // On finalization the Tss address calls the onRevert function which in turn calls the onZetaRevert function on the sender contract receipt, err = r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(cctx.GetCurrentOutboundParam().Hash)) - if err != nil { - panic(err) - } - if receipt.Status != 1 { - panic("tx failed") - } + require.NoError(r, err) + utils.RequireTxSuccessful(r, receipt) + receivedHelloWorldEvent := false for _, log := range receipt.Logs { _, err := testDAppEVM.ParseRevertedHelloWorldEvent(*log) @@ -92,37 +73,37 @@ func TestMessagePassingEVMtoZEVMRevert(r *runner.E2ERunner, args []string) { receivedHelloWorldEvent = true } } - if !receivedHelloWorldEvent { - panic(fmt.Sprintf("expected Reverted HelloWorld event, logs: %+v", receipt.Logs)) - } + require.True(r, receivedHelloWorldEvent, "expected Reverted HelloWorld event") // Check ZETA balance on ZEVM TestDApp and check new balance is previous balance newBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZevmTestDAppAddr) - if err != nil { - panic(err) - } - if newBalanceZEVM.Cmp(previousBalanceZEVM) != 0 { - panic( - fmt.Sprintf("expected new balance to be %s, got %s", previousBalanceZEVM.String(), newBalanceZEVM.String()), - ) - } + require.NoError(r, err) + require.Equal( + r, + 0, + newBalanceZEVM.Cmp(previousBalanceZEVM), + "expected new balance to be %s, got %s", + previousBalanceZEVM.String(), + newBalanceZEVM.String(), + ) // Check ZETA balance on EVM TestDApp and check new balance is between previous balance and previous balance + amount // New balance is increased because ZETA are sent from the sender but sent back to the contract // New balance is less than previous balance + amount because of the gas fee to pay newBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.EvmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) + previousBalanceAndAmountEVM := big.NewInt(0).Add(previousBalanceEVM, amount) // check higher than previous balance and lower than previous balance + amount - if newBalanceEVM.Cmp(previousBalanceEVM) <= 0 || newBalanceEVM.Cmp(previousBalanceAndAmountEVM) > 0 { - panic(fmt.Sprintf( - "expected new balance to be between %s and %s, got %s", - previousBalanceEVM.String(), - previousBalanceAndAmountEVM.String(), - newBalanceEVM.String()), - ) - } + invariant := newBalanceEVM.Cmp(previousBalanceEVM) <= 0 || newBalanceEVM.Cmp(previousBalanceAndAmountEVM) > 0 + require.False( + r, + invariant, + "expected new balance to be between %s and %s, got %s", + previousBalanceEVM.String(), + previousBalanceAndAmountEVM.String(), + newBalanceEVM.String(), + ) + } diff --git a/e2e/e2etests/test_message_passing_evm_to_zevm_revert_fail.go b/e2e/e2etests/test_message_passing_evm_to_zevm_revert_fail.go index 352fe959a8..a767f619ad 100644 --- a/e2e/e2etests/test_message_passing_evm_to_zevm_revert_fail.go +++ b/e2e/e2etests/test_message_passing_evm_to_zevm_revert_fail.go @@ -1,10 +1,10 @@ package e2etests import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testdappnorevert" "github.com/zeta-chain/zetacore/e2e/runner" @@ -13,14 +13,10 @@ import ( ) func TestMessagePassingEVMtoZEVMRevertFail(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassingEVMtoZEVMRevertFail requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassingEVMtoZEVMRevertFail.") - } + require.True(r, ok, "Invalid amount specified for TestMessagePassingEVMtoZEVMRevertFail.") // Deploying a test contract not containing a logic for reverting the cctx testDappNoRevertEVMAddr, tx, testDappNoRevertEVM, err := testdappnorevert.DeployTestDAppNoRevert( @@ -29,87 +25,66 @@ func TestMessagePassingEVMtoZEVMRevertFail(r *runner.E2ERunner, args []string) { r.ConnectorEthAddr, r.ZetaEthAddr, ) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("TestDAppNoRevertEVM deployed at: %s", testDappNoRevertEVMAddr.Hex()) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt) + r.Logger.EVMReceipt(*receipt, "deploy TestDAppNoRevert") - if receipt.Status == 0 { - panic("deploy TestDAppNoRevert failed") - } // Set destination details zEVMChainID, err := r.ZEVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) destinationAddress := r.ZevmTestDAppAddr // Contract call originates from EVM chain tx, err = r.ZetaEth.Approve(r.EVMAuth, testDappNoRevertEVMAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("Approve tx receipt: %d", receipt.Status) // Get ZETA balance before test previousBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZevmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) + previousBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, testDappNoRevertEVMAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) // Send message with doRevert tx, err = testDappNoRevertEVM.SendHelloWorld(r.EVMAuth, destinationAddress, zEVMChainID, amount, true) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("TestDAppNoRevert.SendHello tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) // New inbound message picked up by zeta-clients and voted on by observers to initiate a contract call on zEVM which would revert the transaction - // A revert transaction is created and gets fialized on the original sender chain. + // A revert transaction is created and gets finalized on the original sender chain. cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_Aborted { - panic("expected cctx to be reverted") - } + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_Aborted) // Check ZETA balance on ZEVM TestDApp and check new balance is previous balance newBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZevmTestDAppAddr) - if err != nil { - panic(err) - } - if newBalanceZEVM.Cmp(previousBalanceZEVM) != 0 { - panic(fmt.Sprintf( - "expected new balance to be %s, got %s", - previousBalanceZEVM.String(), - newBalanceZEVM.String()), - ) - } + require.NoError(r, err) + require.Equal( + r, + 0, + newBalanceZEVM.Cmp(previousBalanceZEVM), + "expected new balance to be %s, got %s", + previousBalanceZEVM.String(), + newBalanceZEVM.String(), + ) // Check ZETA balance on EVM TestDApp and check new balance is previous balance newBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, testDappNoRevertEVMAddr) - if err != nil { - panic(err) - } - if newBalanceEVM.Cmp(previousBalanceEVM) != 0 { - panic(fmt.Sprintf( - "expected new balance to be %s, got %s", - previousBalanceEVM.String(), - newBalanceEVM.String()), - ) - } + require.NoError(r, err) + require.Equal(r, 0, newBalanceEVM.Cmp(previousBalanceEVM)) } diff --git a/e2e/e2etests/test_message_passing_external_chains.go b/e2e/e2etests/test_message_passing_external_chains.go index 5a6fed227e..317665920b 100644 --- a/e2e/e2etests/test_message_passing_external_chains.go +++ b/e2e/e2etests/test_message_passing_external_chains.go @@ -1,10 +1,10 @@ package e2etests import ( - "fmt" "math/big" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" "github.com/zeta-chain/zetacore/e2e/runner" @@ -16,32 +16,25 @@ import ( // TODO: Use two external EVM chains for these tests // https://github.com/zeta-chain/node/issues/2185 func TestMessagePassingExternalChains(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassing requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassing.") - } + require.True(r, ok, "Invalid amount specified for TestMessagePassing.") chainID, err := r.EVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("Approving ConnectorEth to spend deployer's ZetaEth") auth := r.EVMAuth + tx, err := r.ZetaEth.Approve(auth, r.ConnectorEthAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("Approve tx receipt: %d", receipt.Status) r.Logger.Info("Calling ConnectorEth.Send") tx, err = r.ConnectorEth.Send(auth, zetaconnectoreth.ZetaInterfacesSendInput{ @@ -52,15 +45,13 @@ func TestMessagePassingExternalChains(r *runner.E2ERunner, args []string) { ZetaValueAndGas: amount, ZetaParams: nil, }) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("ConnectorEth.Send tx hash: %s", tx.Hash().Hex()) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("ConnectorEth.Send tx receipt: status %d", receipt.Status) r.Logger.Info(" Logs:") for _, log := range receipt.Logs { @@ -75,22 +66,14 @@ func TestMessagePassingExternalChains(r *runner.E2ERunner, args []string) { r.Logger.Info("Waiting for ConnectorEth.Send CCTX to be mined...") r.Logger.Info(" INTX hash: %s", receipt.TxHash.String()) + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_OutboundMined { - panic(fmt.Sprintf( - "expected cctx status to be %s; got %s, message %s", - cctxtypes.CctxStatus_OutboundMined, - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage, - )) - } + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_OutboundMined) + receipt, err = r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(cctx.GetCurrentOutboundParam().Hash)) - if err != nil { - panic(err) - } - if receipt.Status != 1 { - panic("tx failed") - } + require.NoError(r, err) + utils.RequireTxSuccessful(r, receipt) + for _, log := range receipt.Logs { event, err := r.ConnectorEth.ParseZetaReceived(*log) if err == nil { @@ -98,9 +81,9 @@ func TestMessagePassingExternalChains(r *runner.E2ERunner, args []string) { r.Logger.Info(" Dest Addr: %s", event.DestinationAddress) r.Logger.Info(" Zeta Value: %d", event.ZetaValue) r.Logger.Info(" src chainid: %d", event.SourceChainId) - if event.ZetaValue.Cmp(cctx.GetCurrentOutboundParam().Amount.BigInt()) != 0 { - panic("Zeta value mismatch") - } + + comp := event.ZetaValue.Cmp(cctx.GetCurrentOutboundParam().Amount.BigInt()) + require.Equal(r, 0, comp, "Zeta value mismatch") } } } diff --git a/e2e/e2etests/test_message_passing_external_chains_revert.go b/e2e/e2etests/test_message_passing_external_chains_revert.go index fee09b3bb0..37146a4c78 100644 --- a/e2e/e2etests/test_message_passing_external_chains_revert.go +++ b/e2e/e2etests/test_message_passing_external_chains_revert.go @@ -5,6 +5,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testdapp" "github.com/zeta-chain/zetacore/e2e/runner" @@ -16,65 +17,48 @@ import ( // TODO: Use two external EVM chains for these tests // https://github.com/zeta-chain/node/issues/2185 func TestMessagePassingRevertSuccessExternalChains(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassingRevertSuccess requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassingRevertSuccess.") - } + require.True(r, ok) chainID, err := r.EVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) auth := r.EVMAuth tx, err := r.ZetaEth.Approve(auth, r.EvmTestDAppAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) r.Logger.Info("Approve tx receipt: %d", receipt.Status) r.Logger.Info("Calling TestDApp.SendHello on contract address %s", r.EvmTestDAppAddr.Hex()) testDApp, err := testdapp.NewTestDApp(r.EvmTestDAppAddr, r.EVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) + + res2, err := r.BankClient.SupplyOf(r.Ctx, &banktypes.QuerySupplyOfRequest{Denom: "azeta"}) + require.NoError(r, err) - res2, err := r.BankClient.SupplyOf(r.Ctx, &banktypes.QuerySupplyOfRequest{ - Denom: "azeta", - }) - if err != nil { - panic(err) - } r.Logger.Info("$$$ Before: SUPPLY OF AZETA: %d", res2.Amount.Amount) tx, err = testDApp.SendHelloWorld(auth, r.EvmTestDAppAddr, chainID, amount, true) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("TestDApp.SendHello tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.Info("TestDApp.SendHello tx receipt: status %d", receipt.Status) cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_Reverted { - panic("expected cctx to be reverted") - } + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_Reverted) + outTxHash := cctx.GetCurrentOutboundParam().Hash receipt, err = r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(outTxHash)) - if err != nil { - panic(err) - } + require.NoError(r, err) + for _, log := range receipt.Logs { event, err := r.ConnectorEth.ParseZetaReverted(*log) if err == nil { @@ -85,12 +69,10 @@ func TestMessagePassingRevertSuccessExternalChains(r *runner.E2ERunner, args []s r.Logger.Info(" Message: %x", event.Message) } } - res3, err := r.BankClient.SupplyOf(r.Ctx, &banktypes.QuerySupplyOfRequest{ - Denom: "azeta", - }) - if err != nil { - panic(err) - } + + res3, err := r.BankClient.SupplyOf(r.Ctx, &banktypes.QuerySupplyOfRequest{Denom: "azeta"}) + require.NoError(r, err) + r.Logger.Info("$$$ After: SUPPLY OF AZETA: %d", res3.Amount.Amount.BigInt()) r.Logger.Info("$$$ Diff: SUPPLY OF AZETA: %d", res3.Amount.Amount.Sub(res2.Amount.Amount).BigInt()) } diff --git a/e2e/e2etests/test_message_passing_external_chains_revert_fail.go b/e2e/e2etests/test_message_passing_external_chains_revert_fail.go index e9bdeb0c7e..3950a8cdd5 100644 --- a/e2e/e2etests/test_message_passing_external_chains_revert_fail.go +++ b/e2e/e2etests/test_message_passing_external_chains_revert_fail.go @@ -4,6 +4,8 @@ import ( "math/big" ethcommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" "github.com/zeta-chain/zetacore/e2e/runner" @@ -15,32 +17,26 @@ import ( // TODO: Use two external EVM chains for these tests // https://github.com/zeta-chain/node/issues/2185 func TestMessagePassingRevertFailExternalChains(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassingRevertFail requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassingRevertFail.") - } + require.True(r, ok, "Invalid amount specified for TestMessagePassingRevertFail.") chainID, err := r.EVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) auth := r.EVMAuth tx, err := r.ZetaEth.Approve(auth, r.ConnectorEthAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("Approve tx receipt: %d", receipt.Status) r.Logger.Info("Calling ConnectorEth.Send") + tx, err = r.ConnectorEth.Send(auth, zetaconnectoreth.ZetaInterfacesSendInput{ DestinationChainId: chainID, DestinationAddress: r.DeployerAddress.Bytes(), @@ -51,14 +47,13 @@ func TestMessagePassingRevertFailExternalChains(r *runner.E2ERunner, args []stri ZetaValueAndGas: amount, ZetaParams: nil, }) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("ConnectorEth.Send tx hash: %s", tx.Hash().Hex()) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Info("ConnectorEth.Send tx receipt: status %d", receipt.Status) r.Logger.Info(" Logs:") for _, log := range receipt.Logs { @@ -74,14 +69,9 @@ func TestMessagePassingRevertFailExternalChains(r *runner.E2ERunner, args []stri // expect revert tx to fail cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) receipt, err = r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(cctx.GetCurrentOutboundParam().Hash)) - if err != nil { - panic(err) - } + require.NoError(r, err) + // expect revert tx to fail as well - if receipt.Status != 0 { - panic("expected revert tx to fail") - } - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_Aborted { - panic("expected cctx to be aborted") - } + require.Equal(r, ethtypes.ReceiptStatusFailed, receipt.Status) + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_Aborted) } diff --git a/e2e/e2etests/test_message_passing_zevm_to_evm.go b/e2e/e2etests/test_message_passing_zevm_to_evm.go index 0e7c888be2..dde161f2f9 100644 --- a/e2e/e2etests/test_message_passing_zevm_to_evm.go +++ b/e2e/e2etests/test_message_passing_zevm_to_evm.go @@ -1,11 +1,11 @@ package e2etests import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testdapp" "github.com/zeta-chain/zetacore/e2e/runner" @@ -14,96 +14,65 @@ import ( ) func TestMessagePassingZEVMtoEVM(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassingZEVMtoEVM requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassingZEVMtoEVM.") - } + require.True(r, ok, "Invalid amount specified for TestMessagePassingZEVMtoEVM.") // Set destination details EVMChainID, err := r.EVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) + destinationAddress := r.EvmTestDAppAddr // Contract call originates from ZEVM chain r.ZEVMAuth.Value = amount tx, err := r.WZeta.Deposit(r.ZEVMAuth) - if err != nil { - panic(err) - } + require.NoError(r, err) r.ZEVMAuth.Value = big.NewInt(0) r.Logger.Info("wzeta deposit tx hash: %s", tx.Hash().Hex()) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "wzeta deposit") - if receipt.Status == 0 { - panic("deposit failed") - } + utils.RequireTxSuccessful(r, receipt) tx, err = r.WZeta.Approve(r.ZEVMAuth, r.ZevmTestDAppAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("wzeta approve tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "wzeta approve") - if receipt.Status == 0 { - panic(fmt.Sprintf("approve failed, logs: %+v", receipt.Logs)) - } + utils.RequireTxSuccessful(r, receipt) testDAppZEVM, err := testdapp.NewTestDApp(r.ZevmTestDAppAddr, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) // Get previous balances previousBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.EvmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) previousBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZEVMAuth.From) - if err != nil { - panic(err) - } + require.NoError(r, err) // Call the SendHelloWorld function on the ZEVM dapp Contract which would in turn create a new send, to be picked up by the zetanode evm hooks // set Do revert to false which adds a message to signal the EVM zetaReceiver to not revert the transaction tx, err = testDAppZEVM.SendHelloWorld(r.ZEVMAuth, destinationAddress, EVMChainID, amount, false) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("TestDApp.SendHello tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic(fmt.Sprintf("send failed, logs: %+v", receipt.Logs)) - } + utils.RequireTxSuccessful(r, receipt) // Transaction is picked up by the zetanode evm hooks and a new contract call is initiated on the EVM chain cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_OutboundMined { - panic("expected cctx to be outbound_mined") - } + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_OutboundMined) // On finalization the Tss calls the onReceive function which in turn calls the onZetaMessage function on the destination contract. receipt, err = r.EVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(cctx.GetCurrentOutboundParam().Hash)) - if err != nil { - panic(err) - } - if receipt.Status != 1 { - panic("tx failed") - } + require.NoError(r, err) + utils.RequireTxSuccessful(r, receipt) testDAppEVM, err := testdapp.NewTestDApp(r.EvmTestDAppAddr, r.EVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) receivedHelloWorldEvent := false for _, log := range receipt.Logs { @@ -113,38 +82,35 @@ func TestMessagePassingZEVMtoEVM(r *runner.E2ERunner, args []string) { receivedHelloWorldEvent = true } } - if !receivedHelloWorldEvent { - panic(fmt.Sprintf("expected HelloWorld event, logs: %+v", receipt.Logs)) - } + require.True(r, receivedHelloWorldEvent, "expected HelloWorld event") // Check ZETA balance on EVM TestDApp and check new balance between previous balance and previous balance + amount // Contract receive less than the amount because of the gas fee to pay newBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.EvmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) + previousBalanceAndAmountEVM := big.NewInt(0).Add(previousBalanceEVM, amount) // check higher than previous balance and lower than previous balance + amount - if newBalanceEVM.Cmp(previousBalanceEVM) <= 0 || newBalanceEVM.Cmp(previousBalanceAndAmountEVM) > 0 { - panic(fmt.Sprintf( - "expected new balance to be between %s and %s, got %s", - previousBalanceEVM.String(), - previousBalanceAndAmountEVM.String(), - newBalanceEVM.String()), - ) - } + invariant := newBalanceEVM.Cmp(previousBalanceEVM) <= 0 || newBalanceEVM.Cmp(previousBalanceAndAmountEVM) > 0 + require.False( + r, + invariant, + "expected new balance to be between %s and %s, got %s", + previousBalanceEVM.String(), + previousBalanceAndAmountEVM.String(), + newBalanceEVM.String(), + ) // Check ZETA balance on ZEVM TestDApp and check new balance is previous balance - amount newBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZEVMAuth.From) - if err != nil { - panic(err) - } - if newBalanceZEVM.Cmp(big.NewInt(0).Sub(previousBalanceZEVM, amount)) != 0 { - panic(fmt.Sprintf( - "expected new balance to be %s, got %s", - big.NewInt(0).Sub(previousBalanceZEVM, amount).String(), - newBalanceZEVM.String()), - ) - } + require.NoError(r, err) + require.Equal( + r, + 0, + newBalanceZEVM.Cmp(big.NewInt(0).Sub(previousBalanceZEVM, amount)), + "expected new balance to be %s, got %s", + big.NewInt(0).Sub(previousBalanceZEVM, amount).String(), + newBalanceZEVM.String(), + ) } diff --git a/e2e/e2etests/test_message_passing_zevm_to_evm_revert.go b/e2e/e2etests/test_message_passing_zevm_to_evm_revert.go index 0badfefdcb..85f81f0a04 100644 --- a/e2e/e2etests/test_message_passing_zevm_to_evm_revert.go +++ b/e2e/e2etests/test_message_passing_zevm_to_evm_revert.go @@ -1,11 +1,11 @@ package e2etests import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testdapp" "github.com/zeta-chain/zetacore/e2e/runner" @@ -14,91 +14,64 @@ import ( ) func TestMessagePassingZEVMtoEVMRevert(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassingZEVMtoEVMRevert requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassingZEVMtoEVMRevert.") - } + require.True(r, ok, "Invalid amount specified for TestMessagePassingZEVMtoEVMRevert.") // Set destination details EVMChainID, err := r.EVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) + destinationAddress := r.EvmTestDAppAddr // Contract call originates from ZEVM chain r.ZEVMAuth.Value = amount tx, err := r.WZeta.Deposit(r.ZEVMAuth) - if err != nil { - panic(err) - } + require.NoError(r, err) r.ZEVMAuth.Value = big.NewInt(0) r.Logger.Info("wzeta deposit tx hash: %s", tx.Hash().Hex()) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "wzeta deposit") - if receipt.Status == 0 { - panic("deposit failed") - } + utils.RequireTxSuccessful(r, receipt) tx, err = r.WZeta.Approve(r.ZEVMAuth, r.ZevmTestDAppAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("wzeta approve tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "wzeta approve") - if receipt.Status == 0 { - panic(fmt.Sprintf("approve failed, logs: %+v", receipt.Logs)) - } + utils.RequireTxSuccessful(r, receipt) testDAppZEVM, err := testdapp.NewTestDApp(r.ZevmTestDAppAddr, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) // Get ZETA balance before test previousBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZevmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) + previousBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.EvmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) // Call the SendHelloWorld function on the ZEVM dapp Contract which would in turn create a new send, to be picked up by the zetanode evm hooks // set Do revert to true which adds a message to signal the EVM zetaReceiver to revert the transaction tx, err = testDAppZEVM.SendHelloWorld(r.ZEVMAuth, destinationAddress, EVMChainID, amount, true) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("TestDApp.SendHello tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic(fmt.Sprintf("send failed, logs: %+v", receipt.Logs)) - } + utils.RequireTxSuccessful(r, receipt) // New inbound message picked up by zetanode evm hooks and processed directly to initiate a contract call on EVM which would revert the transaction cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_Reverted { - panic("expected cctx to be reverted") - } + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_Reverted) // On finalization the Fungible module calls the onRevert function which in turn calls the onZetaRevert function on the sender contract receipt, err = r.ZEVMClient.TransactionReceipt(r.Ctx, ethcommon.HexToHash(cctx.GetCurrentOutboundParam().Hash)) - if err != nil { - panic(err) - } - if receipt.Status != 1 { - panic("tx failed") - } + require.NoError(r, err) + utils.RequireTxSuccessful(r, receipt) receivedHelloWorldEvent := false for _, log := range receipt.Logs { @@ -108,39 +81,28 @@ func TestMessagePassingZEVMtoEVMRevert(r *runner.E2ERunner, args []string) { receivedHelloWorldEvent = true } } - if !receivedHelloWorldEvent { - panic(fmt.Sprintf("expected Reverted HelloWorld event, logs: %+v", receipt.Logs)) - } + require.True(r, receivedHelloWorldEvent, "expected Reverted HelloWorld event") // Check ZETA balance on ZEVM TestDApp and check new balance is between previous balance and previous balance + amount // New balance is increased because ZETA are sent from the sender but sent back to the contract // Contract receive less than the amount because of the gas fee to pay newBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.ZevmTestDAppAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) + previousBalanceAndAmountZEVM := big.NewInt(0).Add(previousBalanceZEVM, amount) // check higher than previous balance and lower than previous balance + amount - if newBalanceZEVM.Cmp(previousBalanceZEVM) <= 0 || newBalanceZEVM.Cmp(previousBalanceAndAmountZEVM) > 0 { - panic(fmt.Sprintf( - "expected new balance to be between %s and %s, got %s", - previousBalanceZEVM.String(), - previousBalanceAndAmountZEVM.String(), - newBalanceZEVM.String()), - ) - } + invariant := newBalanceZEVM.Cmp(previousBalanceZEVM) <= 0 || newBalanceZEVM.Cmp(previousBalanceAndAmountZEVM) > 0 + require.False(r, + invariant, + "expected new balance to be between %s and %s, got %s", + previousBalanceZEVM.String(), + previousBalanceAndAmountZEVM.String(), + newBalanceZEVM.String(), + ) // Check ZETA balance on EVM TestDApp and check new balance is previous balance newBalanceEVM, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.EvmTestDAppAddr) - if err != nil { - panic(err) - } - if newBalanceEVM.Cmp(previousBalanceEVM) != 0 { - panic(fmt.Sprintf( - "expected new balance to be %s, got %s", - previousBalanceEVM.String(), - newBalanceEVM.String()), - ) - } + require.NoError(r, err) + require.Equal(r, 0, newBalanceEVM.Cmp(previousBalanceEVM), "expected new balance to be equal to previous balance") } diff --git a/e2e/e2etests/test_message_passing_zevm_to_evm_revert_fail.go b/e2e/e2etests/test_message_passing_zevm_to_evm_revert_fail.go index b822199af6..cc22db23a3 100644 --- a/e2e/e2etests/test_message_passing_zevm_to_evm_revert_fail.go +++ b/e2e/e2etests/test_message_passing_zevm_to_evm_revert_fail.go @@ -1,10 +1,10 @@ package e2etests import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testdappnorevert" "github.com/zeta-chain/zetacore/e2e/runner" @@ -13,14 +13,10 @@ import ( ) func TestMessagePassingZEVMtoEVMRevertFail(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestMessagePassingZEVMtoEVMRevertFail requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestMessagePassingZEVMtoEVMRevertFail.") - } + require.True(r, ok, "Invalid amount specified for TestMessagePassingZEVMtoEVMRevertFail.") // Deploying a test contract not containing a logic for reverting the cctx testDappNoRevertAddr, tx, testDappNoRevert, err := testdappnorevert.DeployTestDAppNoRevert( @@ -29,83 +25,64 @@ func TestMessagePassingZEVMtoEVMRevertFail(r *runner.E2ERunner, args []string) { r.ConnectorZEVMAddr, r.WZetaAddr, ) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("TestDAppNoRevert deployed at: %s", testDappNoRevertAddr.Hex()) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "deploy TestDAppNoRevert") - if receipt.Status == 0 { - panic("deploy TestDAppNoRevert failed") - } + utils.RequireTxSuccessful(r, receipt) // Set destination details EVMChainID, err := r.EVMClient.ChainID(r.Ctx) - if err != nil { - panic(err) - } + require.NoError(r, err) + destinationAddress := r.EvmTestDAppAddr // Contract call originates from ZEVM chain r.ZEVMAuth.Value = amount tx, err = r.WZeta.Deposit(r.ZEVMAuth) - if err != nil { - panic(err) - } + require.NoError(r, err) r.ZEVMAuth.Value = big.NewInt(0) r.Logger.Info("wzeta deposit tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "wzeta deposit") - if receipt.Status == 0 { - panic("deposit failed") - } + utils.RequireTxSuccessful(r, receipt) tx, err = r.WZeta.Approve(r.ZEVMAuth, testDappNoRevertAddr, amount) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("wzeta approve tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "wzeta approve") - if receipt.Status == 0 { - panic(fmt.Sprintf("approve failed, logs: %+v", receipt.Logs)) - } + utils.RequireTxSuccessful(r, receipt) // Get previous balances to check funds are not minted anywhere when aborted previousBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, testDappNoRevertAddr) - if err != nil { - panic(err) - } + require.NoError(r, err) // Send message with doRevert tx, err = testDappNoRevert.SendHelloWorld(r.ZEVMAuth, destinationAddress, EVMChainID, amount, true) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("TestDAppNoRevert.SendHello tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic(fmt.Sprintf("send failed, logs: %+v", receipt.Logs)) - } + utils.RequireTxSuccessful(r, receipt) // The revert tx will fail, the cctx state should be aborted cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, receipt.TxHash.String(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != cctxtypes.CctxStatus_Aborted { - panic("expected cctx to be reverted") - } + utils.RequireCCTXStatus(r, cctx, cctxtypes.CctxStatus_Aborted) // Check the funds are not minted to the contract as the cctx has been aborted newBalanceZEVM, err := r.WZeta.BalanceOf(&bind.CallOpts{}, testDappNoRevertAddr) - if err != nil { - panic(err) - } - if newBalanceZEVM.Cmp(previousBalanceZEVM) != 0 { - panic( - fmt.Sprintf("expected new balance to be %s, got %s", previousBalanceZEVM.String(), newBalanceZEVM.String()), - ) - } + require.NoError(r, err) + require.Equal(r, + 0, + newBalanceZEVM.Cmp(previousBalanceZEVM), + "expected new balance to be %s, got %s", + previousBalanceZEVM.String(), + newBalanceZEVM.String(), + ) } diff --git a/e2e/e2etests/test_migrate_chain_support.go b/e2e/e2etests/test_migrate_chain_support.go index f39bcbc2a3..848335ddef 100644 --- a/e2e/e2etests/test_migrate_chain_support.go +++ b/e2e/e2etests/test_migrate_chain_support.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/fatih/color" + "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zrc20.sol" "github.com/zeta-chain/zetacore/e2e/runner" @@ -44,9 +45,8 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // create runner for the new EVM and set it up newRunner, err := configureEVM2(r) - if err != nil { - panic(err) - } + require.NoError(r, err) + newRunner.SetupEVM(false, false) // mint some ERC20 @@ -59,21 +59,16 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { // update the chain params to set up the chain chainParams := getNewEVMChainParams(newRunner) adminAddr, err := newRunner.ZetaTxServer.GetAccountAddressFromName(utils.FungibleAdminName) - if err != nil { - panic(err) - } + require.NoError(r, err) + _, err = newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, observertypes.NewMsgUpdateChainParams( adminAddr, chainParams, )) - if err != nil { - panic(err) - } + require.NoError(r, err) // setup the gas token - if err != nil { - panic(err) - } + require.NoError(r, err) _, err = newRunner.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, fungibletypes.NewMsgDeployFungibleCoinZRC20( adminAddr, "", @@ -84,26 +79,19 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { coin.CoinType_Gas, 100000, )) - if err != nil { - panic(err) - } + require.NoError(r, err) // set the gas token in the runner ethZRC20Addr, err := newRunner.SystemContract.GasCoinZRC20ByChainId( &bind.CallOpts{}, big.NewInt(chainParams.ChainId), ) - if err != nil { - panic(err) - } - if (ethZRC20Addr == ethcommon.Address{}) { - panic("eth zrc20 not found") - } + require.NoError(r, err) + require.NotEqual(r, ethcommon.Address{}, ethZRC20Addr) + newRunner.ETHZRC20Addr = ethZRC20Addr ethZRC20, err := zrc20.NewZRC20(ethZRC20Addr, newRunner.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) newRunner.ETHZRC20 = ethZRC20 // set the chain nonces for the new chain @@ -113,9 +101,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { 0, 0, )) - if err != nil { - panic(err) - } + require.NoError(r, err) // deactivate the previous chain chainParams = observertypes.GetDefaultGoerliLocalnetChainParams() @@ -124,15 +110,11 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { adminAddr, chainParams, )) - if err != nil { - panic(err) - } + require.NoError(r, err) // restart ZetaClient to pick up the new chain r.Logger.Print("🔄 restarting ZetaClient to pick up the new chain") - if err := restartZetaClient(); err != nil { - panic(err) - } + require.NoError(r, restartZetaClient()) // wait 10 set for the chain to start time.Sleep(10 * time.Second) @@ -141,18 +123,14 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { txWithdraw, err := r.ETHZRC20.Withdraw(r.ZEVMAuth, r.DeployerAddress.Bytes(), big.NewInt(10000000000000000)) if err == nil { receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, txWithdraw, r.Logger, r.ReceiptTimeout) - if receipt.Status == 1 { - panic("withdraw should have failed on the previous chain") - } + utils.RequiredTxFailed(r, receipt) } // test cross-chain functionalities on the new network // we use a Go routine to manually mine blocks because Anvil network only mine blocks on tx by default // we need automatic block mining to get the necessary confirmations for the cross-chain functionalities stopMining, err := newRunner.AnvilMineBlocks(EVM2RPCURL, 3) - if err != nil { - panic(err) - } + require.NoError(r, err) // deposit Ethers and ERC20 on ZetaChain etherAmount := big.NewInt(1e18) @@ -166,14 +144,7 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { tx := newRunner.WithdrawZeta(amount, true) cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "zeta withdraw") - if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic(fmt.Errorf( - "expected cctx status to be %s; got %s, message %s", - crosschaintypes.CctxStatus_OutboundMined, - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage, - )) - } + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) TestEtherWithdraw(newRunner, []string{"50000000000000000"}) @@ -193,32 +164,24 @@ func TestMigrateChainSupport(r *runner.E2ERunner, _ []string) { 18, 100000, )) - if err != nil { - panic(err) - } + require.NoError(r, err) // retrieve zrc20 and cctx from event whitelistCCTXIndex, err := txserver.FetchAttributeFromTxResponse(res, "whitelist_cctx_index") - if err != nil { - panic(err) - } + require.NoError(r, err) erc20zrc20Addr, err := txserver.FetchAttributeFromTxResponse(res, "zrc20_address") - if err != nil { - panic(err) - } + require.NoError(r, err) // wait for the whitelist cctx to be mined newRunner.WaitForMinedCCTXFromIndex(whitelistCCTXIndex) // set erc20 zrc20 contract address - if !ethcommon.IsHexAddress(erc20zrc20Addr) { - panic(fmt.Errorf("invalid contract address: %s", erc20zrc20Addr)) - } + require.True(r, ethcommon.IsHexAddress(erc20zrc20Addr), "invalid contract address: %s", erc20zrc20Addr) + erc20ZRC20, err := zrc20.NewZRC20(ethcommon.HexToAddress(erc20zrc20Addr), newRunner.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) + newRunner.ERC20ZRC20 = erc20ZRC20 // deposit ERC20 on ZetaChain diff --git a/e2e/e2etests/test_pause_zrc20.go b/e2e/e2etests/test_pause_zrc20.go index dbe5182e80..1495a7ac60 100644 --- a/e2e/e2etests/test_pause_zrc20.go +++ b/e2e/e2etests/test_pause_zrc20.go @@ -1,9 +1,10 @@ package e2etests import ( - "fmt" "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/contracts/vault" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -16,26 +17,20 @@ func TestPauseZRC20(r *runner.E2ERunner, _ []string) { // Setup vault used to test zrc20 interactions r.Logger.Info("Deploying vault") vaultAddr, _, vaultContract, err := vault.DeployVault(r.ZEVMAuth, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) + // Approving vault to spend ZRC20 tx, err := r.ETHZRC20.Approve(r.ZEVMAuth, vaultAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("Vault approval should succeed") - } + utils.RequireTxSuccessful(r, receipt) + tx, err = r.ERC20ZRC20.Approve(r.ZEVMAuth, vaultAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("Vault approval should succeed") - } + utils.RequireTxSuccessful(r, receipt) // Pause ETH ZRC20 r.Logger.Info("Pausing ETH") @@ -44,86 +39,68 @@ func TestPauseZRC20(r *runner.E2ERunner, _ []string) { []string{r.ETHZRC20Addr.Hex()}, ) res, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgPause) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("pause zrc20 tx hash: %s", res.TxHash) // Fetch and check pause status fcRes, err := r.FungibleClient.ForeignCoins(r.Ctx, &fungibletypes.QueryGetForeignCoinsRequest{ Index: r.ETHZRC20Addr.Hex(), }) - if err != nil { - panic(err) - } - if !fcRes.GetForeignCoins().Paused { - panic("ETH should be paused") - } + require.NoError(r, err) + require.True(r, fcRes.GetForeignCoins().Paused, "ETH should be paused") + r.Logger.Info("ETH is paused") // Try operations with ETH ZRC20 r.Logger.Info("Can no longer do operations on ETH ZRC20") + tx, err = r.ETHZRC20.Transfer(r.ZEVMAuth, sample.EthAddress(), big.NewInt(1e5)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 1 { - panic("transfer should fail") - } + utils.RequiredTxFailed(r, receipt) + tx, err = r.ETHZRC20.Burn(r.ZEVMAuth, big.NewInt(1e5)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 1 { - panic("burn should fail") - } + utils.RequiredTxFailed(r, receipt) // Operation on a contract that interact with ETH ZRC20 should fail r.Logger.Info("Vault contract can no longer interact with ETH ZRC20: %s", r.ETHZRC20Addr.Hex()) tx, err = vaultContract.Deposit(r.ZEVMAuth, r.ETHZRC20Addr, big.NewInt(1e5)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 1 { - panic("deposit should fail") - } + utils.RequiredTxFailed(r, receipt) + r.Logger.Info("Operations all failed") // Check we can still interact with ERC20 ZRC20 r.Logger.Info("Check other ZRC20 can still be operated") + tx, err = r.ERC20ZRC20.Transfer(r.ZEVMAuth, sample.EthAddress(), big.NewInt(1e3)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("ERC20 ZRC20 transfer should succeed") - } + utils.RequireTxSuccessful(r, receipt) + tx, err = vaultContract.Deposit(r.ZEVMAuth, r.ERC20ZRC20Addr, big.NewInt(1e3)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("ERC20 ZRC20 vault deposit should succeed") - } + utils.RequireTxSuccessful(r, receipt) // Check deposit revert when paused signedTx, err := r.SendEther(r.TSSAddress, big.NewInt(1e17), nil) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposit eth tx failed") - } + utils.RequireTxSuccessful(r, receipt) + cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, signedTx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) - if cctx.CctxStatus.Status != types.CctxStatus_Reverted { - panic(fmt.Sprintf("expected cctx status to be Reverted; got %s", cctx.CctxStatus.Status)) - } + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_Reverted) + r.Logger.Info("CCTX has been reverted") // Unpause ETH ZRC20 @@ -133,51 +110,40 @@ func TestPauseZRC20(r *runner.E2ERunner, _ []string) { []string{r.ETHZRC20Addr.Hex()}, ) res, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgUnpause) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("unpause zrc20 tx hash: %s", res.TxHash) // Fetch and check pause status fcRes, err = r.FungibleClient.ForeignCoins(r.Ctx, &fungibletypes.QueryGetForeignCoinsRequest{ Index: r.ETHZRC20Addr.Hex(), }) - if err != nil { - panic(err) - } - if fcRes.GetForeignCoins().Paused { - panic("ETH should be unpaused") - } + require.NoError(r, err) + require.False(r, fcRes.GetForeignCoins().Paused, "ETH should be unpaused") + r.Logger.Info("ETH is unpaused") // Try operations with ETH ZRC20 r.Logger.Info("Can do operations on ETH ZRC20 again") + tx, err = r.ETHZRC20.Transfer(r.ZEVMAuth, sample.EthAddress(), big.NewInt(1e5)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("transfer should succeed") - } + utils.RequireTxSuccessful(r, receipt) + tx, err = r.ETHZRC20.Burn(r.ZEVMAuth, big.NewInt(1e5)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("burn should succeed") - } + utils.RequireTxSuccessful(r, receipt) // Can deposit tokens into the vault again tx, err = vaultContract.Deposit(r.ZEVMAuth, r.ETHZRC20Addr, big.NewInt(1e5)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposit should succeed") - } + utils.RequireTxSuccessful(r, receipt) r.Logger.Info("Operations all succeeded") } diff --git a/e2e/e2etests/test_rate_limiter.go b/e2e/e2etests/test_rate_limiter.go index db8d67f348..8b88dc28aa 100644 --- a/e2e/e2etests/test_rate_limiter.go +++ b/e2e/e2etests/test_rate_limiter.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" "github.com/zeta-chain/zetacore/e2e/runner" @@ -55,47 +56,31 @@ func TestRateLimiter(r *runner.E2ERunner, _ []string) { erc20Amount := big.NewInt(1e6) // approve tokens for the tests - if err := approveTokens(r); err != nil { - panic(err) - } + require.NoError(r, approveTokens(r)) // add liquidity in the pool to prevent high slippage in WZETA/gas pair - if err := addZetaGasLiquidity(r); err != nil { - panic(err) - } + require.NoError(r, addZetaGasLiquidity(r)) // Set the rate limiter to 0.5ZETA per 10 blocks // These rate limiter flags will only allow to process 1 withdraw per 10 blocks r.Logger.Info("setting up rate limiter flags") - if err := setupRateLimiterFlags(r, rateLimiterFlags); err != nil { - panic(err) - } + require.NoError(r, setupRateLimiterFlags(r, rateLimiterFlags)) // Test with rate limiter // TODO: define proper assertion to check the rate limiter is working // https://github.com/zeta-chain/node/issues/2090 r.Logger.Print("rate limiter enabled") - if err := createAndWaitWithdraws(r, withdrawTypeZETA, zetaAmount); err != nil { - panic(err) - } - if err := createAndWaitWithdraws(r, withdrawTypeETH, ethAmount); err != nil { - panic(err) - } - if err := createAndWaitWithdraws(r, withdrawTypeERC20, erc20Amount); err != nil { - panic(err) - } + require.NoError(r, createAndWaitWithdraws(r, withdrawTypeZETA, zetaAmount)) + require.NoError(r, createAndWaitWithdraws(r, withdrawTypeZETA, ethAmount)) + require.NoError(r, createAndWaitWithdraws(r, withdrawTypeZETA, erc20Amount)) // Disable rate limiter r.Logger.Info("disabling rate limiter") - if err := setupRateLimiterFlags(r, crosschaintypes.RateLimiterFlags{Enabled: false}); err != nil { - panic(err) - } + require.NoError(r, setupRateLimiterFlags(r, crosschaintypes.RateLimiterFlags{Enabled: false})) // Test without rate limiter again and try again ZETA withdraws r.Logger.Print("rate limiter disabled") - if err := createAndWaitWithdraws(r, withdrawTypeZETA, zetaAmount); err != nil { - panic(err) - } + require.NoError(r, createAndWaitWithdraws(r, withdrawTypeZETA, zetaAmount)) } // createAndWaitWithdraws performs RateLimiterWithdrawNumber withdraws diff --git a/e2e/e2etests/test_stress_btc_deposit.go b/e2e/e2etests/test_stress_btc_deposit.go index 51e1b8857f..b6c3e7c6a8 100644 --- a/e2e/e2etests/test_stress_btc_deposit.go +++ b/e2e/e2etests/test_stress_btc_deposit.go @@ -2,10 +2,10 @@ package e2etests import ( "fmt" - "strconv" "time" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" "github.com/zeta-chain/zetacore/e2e/runner" @@ -15,19 +15,10 @@ import ( // TestStressBTCDeposit tests the stressing deposit of BTC func TestStressBTCDeposit(r *runner.E2ERunner, args []string) { - if len(args) != 2 { - panic("TestStressBTCDeposit requires exactly two arguments: the deposit amount and the number of deposits.") - } + require.Len(r, args, 2) - depositAmount, err := strconv.ParseFloat(args[1], 64) - if err != nil { - panic("Invalid deposit amount specified for TestStressBTCDeposit.") - } - - numDeposits, err := strconv.Atoi(args[1]) - if err != nil || numDeposits < 1 { - panic("Invalid number of deposits specified for TestStressBTCDeposit.") - } + depositAmount := parseFloat(r, args[0]) + numDeposits := parseInt(r, args[1]) r.SetBtcAddress(r.Name, false) @@ -42,15 +33,10 @@ func TestStressBTCDeposit(r *runner.E2ERunner, args []string) { txHash := r.DepositBTCWithAmount(depositAmount) r.Logger.Print("index %d: starting deposit, tx hash: %s", i, txHash.String()) - eg.Go(func() error { - return monitorBTCDeposit(r, txHash, i, time.Now()) - }) + eg.Go(func() error { return monitorBTCDeposit(r, txHash, i, time.Now()) }) } - // wait for all the deposits to complete - if err := eg.Wait(); err != nil { - panic(err) - } + require.NoError(r, eg.Wait()) r.Logger.Print("all deposits completed") } diff --git a/e2e/e2etests/test_stress_btc_withdraw.go b/e2e/e2etests/test_stress_btc_withdraw.go index 28ccb77178..08c5844448 100644 --- a/e2e/e2etests/test_stress_btc_withdraw.go +++ b/e2e/e2etests/test_stress_btc_withdraw.go @@ -3,11 +3,11 @@ package e2etests import ( "fmt" "math/big" - "strconv" "time" "github.com/btcsuite/btcutil" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" "github.com/zeta-chain/zetacore/e2e/runner" @@ -17,21 +17,10 @@ import ( // TestStressBTCWithdraw tests the stressing withdraw of btc func TestStressBTCWithdraw(r *runner.E2ERunner, args []string) { - if len(args) != 2 { - panic( - "TestStressBTCWithdraw requires exactly two arguments: the withdrawal amount and the number of withdrawals.", - ) - } - - withdrawalAmount, err := strconv.ParseFloat(args[0], 64) - if err != nil { - panic("Invalid withdrawal amount specified for TestStressBTCWithdraw.") - } + require.Len(r, args, 2) - numWithdraws, err := strconv.Atoi(args[1]) - if err != nil || numWithdraws < 1 { - panic("Invalid number of withdrawals specified for TestStressBTCWithdraw.") - } + withdrawalAmount := parseFloat(r, args[0]) + numWithdraws := parseInt(r, args[1]) r.SetBtcAddress(r.Name, false) @@ -41,9 +30,7 @@ func TestStressBTCWithdraw(r *runner.E2ERunner, args []string) { var eg errgroup.Group satAmount, err := btcutil.NewAmount(withdrawalAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) // send the withdraws for i := 0; i < numWithdraws; i++ { @@ -53,25 +40,16 @@ func TestStressBTCWithdraw(r *runner.E2ERunner, args []string) { []byte(r.BTCDeployerAddress.EncodeAddress()), big.NewInt(int64(satAmount)), ) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - //r.Logger.Info("index %d: withdraw evm tx failed", index) - panic(fmt.Sprintf("index %d: withdraw btc tx %s failed", i, tx.Hash().Hex())) - } + utils.RequireTxSuccessful(r, receipt) r.Logger.Print("index %d: starting withdraw, tx hash: %s", i, tx.Hash().Hex()) - eg.Go(func() error { - return monitorBTCWithdraw(r, tx, i, time.Now()) - }) + eg.Go(func() error { return monitorBTCWithdraw(r, tx, i, time.Now()) }) } - // wait for all the withdraws to complete - if err := eg.Wait(); err != nil { - panic(err) - } + require.NoError(r, eg.Wait()) r.Logger.Print("all withdraws completed") } diff --git a/e2e/e2etests/test_stress_eth_deposit.go b/e2e/e2etests/test_stress_eth_deposit.go index f3b1e94dc8..9e0208f7e3 100644 --- a/e2e/e2etests/test_stress_eth_deposit.go +++ b/e2e/e2etests/test_stress_eth_deposit.go @@ -3,10 +3,10 @@ package e2etests import ( "fmt" "math/big" - "strconv" "time" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" "github.com/zeta-chain/zetacore/e2e/runner" @@ -16,19 +16,12 @@ import ( // TestStressEtherDeposit tests the stressing deposit of ether func TestStressEtherDeposit(r *runner.E2ERunner, args []string) { - if len(args) != 2 { - panic("TestStressEtherDeposit requires exactly two arguments: the deposit amount and the number of deposits.") - } + require.Len(r, args, 2) depositAmount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid deposit amount specified for TestMultipleERC20Deposit.") - } + require.True(r, ok) - numDeposits, err := strconv.Atoi(args[1]) - if err != nil || numDeposits < 1 { - panic("Invalid number of deposits specified for TestStressEtherDeposit.") - } + numDeposits := parseInt(r, args[1]) r.Logger.Print("starting stress test of %d deposits", numDeposits) @@ -41,15 +34,10 @@ func TestStressEtherDeposit(r *runner.E2ERunner, args []string) { hash := r.DepositEtherWithAmount(false, depositAmount) r.Logger.Print("index %d: starting deposit, tx hash: %s", i, hash.Hex()) - eg.Go(func() error { - return monitorEtherDeposit(r, hash, i, time.Now()) - }) + eg.Go(func() error { return monitorEtherDeposit(r, hash, i, time.Now()) }) } - // wait for all the deposits to complete - if err := eg.Wait(); err != nil { - panic(err) - } + require.NoError(r, eg.Wait()) r.Logger.Print("all deposits completed") } diff --git a/e2e/e2etests/test_stress_eth_withdraw.go b/e2e/e2etests/test_stress_eth_withdraw.go index 7f73e863a0..3a67ca8f94 100644 --- a/e2e/e2etests/test_stress_eth_withdraw.go +++ b/e2e/e2etests/test_stress_eth_withdraw.go @@ -7,6 +7,7 @@ import ( "time" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" "github.com/zeta-chain/zetacore/e2e/runner" @@ -16,26 +17,18 @@ import ( // TestStressEtherWithdraw tests the stressing withdraw of ether func TestStressEtherWithdraw(r *runner.E2ERunner, args []string) { - if len(args) != 2 { - panic( - "TestStressEtherWithdraw requires exactly two arguments: the withdrawal amount and the number of withdrawals.", - ) - } + require.Len(r, args, 2) withdrawalAmount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid withdrawal amount specified for TestStressEtherWithdraw.") - } + require.True(r, ok, "Invalid withdrawal amount specified for TestStressEtherWithdraw.") numWithdraws, err := strconv.Atoi(args[1]) - if err != nil || numWithdraws < 1 { - panic("Invalid number of withdrawals specified for TestStressEtherWithdraw.") - } + require.NoError(r, err) + require.GreaterOrEqual(r, numWithdraws, 1) tx, err := r.ETHZRC20.Approve(r.ZEVMAuth, r.ETHZRC20Addr, big.NewInt(1e18)) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.WaitForTxReceiptOnZEVM(tx) r.Logger.Print("starting stress test of %d withdraws", numWithdraws) @@ -46,15 +39,13 @@ func TestStressEtherWithdraw(r *runner.E2ERunner, args []string) { // send the withdraws for i := 0; i < numWithdraws; i++ { i := i + tx, err := r.ETHZRC20.Withdraw(r.ZEVMAuth, r.DeployerAddress.Bytes(), withdrawalAmount) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status == 0 { - //r.Logger.Info("index %d: withdraw evm tx failed", index) - panic(fmt.Sprintf("index %d: withdraw evm tx %s failed", i, tx.Hash().Hex())) - } + utils.RequireTxSuccessful(r, receipt) + r.Logger.Print("index %d: starting withdraw, tx hash: %s", i, tx.Hash().Hex()) eg.Go(func() error { @@ -62,10 +53,7 @@ func TestStressEtherWithdraw(r *runner.E2ERunner, args []string) { }) } - // wait for all the withdraws to complete - if err := eg.Wait(); err != nil { - panic(err) - } + require.NoError(r, eg.Wait()) r.Logger.Print("all withdraws completed") } diff --git a/e2e/e2etests/test_update_bytecode_connector.go b/e2e/e2etests/test_update_bytecode_connector.go index 6b88e14972..73786f2971 100644 --- a/e2e/e2etests/test_update_bytecode_connector.go +++ b/e2e/e2etests/test_update_bytecode_connector.go @@ -1,10 +1,10 @@ package e2etests import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testconnectorzevm" "github.com/zeta-chain/zetacore/e2e/runner" @@ -18,17 +18,12 @@ func TestUpdateBytecodeConnector(r *runner.E2ERunner, _ []string) { // Can withdraw 10ZETA amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(10)) r.DepositAndApproveWZeta(amount) + tx := r.WithdrawZeta(amount, true) cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) + r.Logger.CCTX(*cctx, "zeta withdraw") - if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic(fmt.Errorf( - "expected cctx status to be %s; got %s, message %s", - crosschaintypes.CctxStatus_OutboundMined, - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage, - )) - } // Deploy the test contract newTestConnectorAddr, tx, _, err := testconnectorzevm.DeployTestZetaConnectorZEVM( @@ -36,23 +31,17 @@ func TestUpdateBytecodeConnector(r *runner.E2ERunner, _ []string) { r.ZEVMClient, r.WZetaAddr, ) - if err != nil { - panic(err) - } + require.NoError(r, err) // Wait for the contract to be deployed receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("contract deployment failed") - } + utils.RequireTxSuccessful(r, receipt) // Get the code hash of the new contract codeHashRes, err := r.FungibleClient.CodeHash(r.Ctx, &fungibletypes.QueryCodeHashRequest{ Address: newTestConnectorAddr.String(), }) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("New contract code hash: %s", codeHashRes.CodeHash) r.Logger.Info("Updating the bytecode of the Connector") @@ -62,37 +51,21 @@ func TestUpdateBytecodeConnector(r *runner.E2ERunner, _ []string) { codeHashRes.CodeHash, ) res, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msg) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("Update connector bytecode tx hash: %s", res.TxHash) r.Logger.Info("Can interact with the new code of the contract") testConnectorContract, err := testconnectorzevm.NewTestZetaConnectorZEVM(r.ConnectorZEVMAddr, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) response, err := testConnectorContract.Foo(&bind.CallOpts{}) - if err != nil { - panic(err) - } - - if response != "foo" { - panic("unexpected response") - } + require.NoError(r, err) + require.Equal(r, "foo", response) // Can continue to interact with the connector: withdraw 10ZETA r.DepositAndApproveWZeta(amount) tx = r.WithdrawZeta(amount, true) cctx = utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "zeta withdraw") - if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic(fmt.Errorf( - "expected cctx status to be %s; got %s, message %s", - crosschaintypes.CctxStatus_OutboundMined, - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage, - )) - } + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) } diff --git a/e2e/e2etests/test_update_bytecode_zrc20.go b/e2e/e2etests/test_update_bytecode_zrc20.go index 4762ec94bb..ba914655d1 100644 --- a/e2e/e2etests/test_update_bytecode_zrc20.go +++ b/e2e/e2etests/test_update_bytecode_zrc20.go @@ -4,6 +4,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/contracts/testzrc20" "github.com/zeta-chain/zetacore/e2e/runner" @@ -18,13 +19,10 @@ func TestUpdateBytecodeZRC20(r *runner.E2ERunner, _ []string) { // Random approval approved := sample.EthAddress() tx, err := r.ETHZRC20.Approve(r.ZEVMAuth, approved, big.NewInt(1e10)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("approval failed") - } + utils.RequireTxSuccessful(r, receipt) // Deploy the TestZRC20 contract r.Logger.Info("Deploying contract with new bytecode") @@ -35,50 +33,38 @@ func TestUpdateBytecodeZRC20(r *runner.E2ERunner, _ []string) { // #nosec G701 test - always in range uint8(coin.CoinType_Gas), ) - if err != nil { - panic(err) - } + require.NoError(r, err) // Wait for the contract to be deployed receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("contract deployment failed") - } + utils.RequireTxSuccessful(r, receipt) // Get the code hash of the new contract codeHashRes, err := r.FungibleClient.CodeHash(r.Ctx, &fungibletypes.QueryCodeHashRequest{ Address: newZRC20Address.String(), }) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("New contract code hash: %s", codeHashRes.CodeHash) // Get current info of the ZRC20 name, err := r.ETHZRC20.Name(&bind.CallOpts{}) - if err != nil { - panic(err) - } + require.NoError(r, err) + symbol, err := r.ETHZRC20.Symbol(&bind.CallOpts{}) - if err != nil { - panic(err) - } + require.NoError(r, err) + decimals, err := r.ETHZRC20.Decimals(&bind.CallOpts{}) - if err != nil { - panic(err) - } + require.NoError(r, err) + totalSupply, err := r.ETHZRC20.TotalSupply(&bind.CallOpts{}) - if err != nil { - panic(err) - } + require.NoError(r, err) + balance, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + approval, err := r.ETHZRC20.Allowance(&bind.CallOpts{}, r.DeployerAddress, approved) - if err != nil { - panic(err) - } + require.NoError(r, err) r.Logger.Info("Updating the bytecode of the ZRC20") msg := fungibletypes.NewMsgUpdateContractBytecode( @@ -87,116 +73,75 @@ func TestUpdateBytecodeZRC20(r *runner.E2ERunner, _ []string) { codeHashRes.CodeHash, ) res, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msg) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("Update zrc20 bytecode tx hash: %s", res.TxHash) // Get new info of the ZRC20 r.Logger.Info("Checking the state of the ZRC20 remains the same") newName, err := r.ETHZRC20.Name(&bind.CallOpts{}) - if err != nil { - panic(err) - } - if name != newName { - panic("name shouldn't change upon bytecode update") - } + require.NoError(r, err) + require.Equal(r, name, newName) + newSymbol, err := r.ETHZRC20.Symbol(&bind.CallOpts{}) - if err != nil { - panic(err) - } - if symbol != newSymbol { - panic("symbol shouldn't change upon bytecode update") - } + require.NoError(r, err) + require.Equal(r, symbol, newSymbol) + newDecimals, err := r.ETHZRC20.Decimals(&bind.CallOpts{}) - if err != nil { - panic(err) - } - if decimals != newDecimals { - panic("decimals shouldn't change upon bytecode update") - } + require.NoError(r, err) + require.Equal(r, decimals, newDecimals) + newTotalSupply, err := r.ETHZRC20.TotalSupply(&bind.CallOpts{}) - if err != nil { - panic(err) - } - if totalSupply.Cmp(newTotalSupply) != 0 { - panic("total supply shouldn't change upon bytecode update") - } + require.NoError(r, err) + require.Equal(r, 0, totalSupply.Cmp(newTotalSupply)) + newBalance, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } - if balance.Cmp(newBalance) != 0 { - panic("balance shouldn't change upon bytecode update") - } + require.NoError(r, err) + require.Equal(r, 0, balance.Cmp(newBalance)) + newApproval, err := r.ETHZRC20.Allowance(&bind.CallOpts{}, r.DeployerAddress, approved) - if err != nil { - panic(err) - } - if approval.Cmp(newApproval) != 0 { - panic("approval shouldn't change upon bytecode update") - } + require.NoError(r, err) + require.Equal(r, 0, approval.Cmp(newApproval)) r.Logger.Info("Can interact with the new code of the contract") + testZRC20Contract, err := testzrc20.NewTestZRC20(r.ETHZRC20Addr, r.ZEVMClient) - if err != nil { - panic(err) - } + require.NoError(r, err) + tx, err = testZRC20Contract.UpdateNewField(r.ZEVMAuth, big.NewInt(1e10)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("update new field failed") - } + utils.RequireTxSuccessful(r, receipt) + newField, err := testZRC20Contract.NewField(&bind.CallOpts{}) - if err != nil { - panic(err) - } - if newField.Cmp(big.NewInt(1e10)) != 0 { - panic("new field value mismatch") - } + require.NoError(r, err) + require.Equal(r, 0, newField.Cmp(big.NewInt(1e10))) r.Logger.Info("Interacting with the bytecode contract doesn't disrupt the zrc20 contract") tx, err = newZRC20Contract.UpdateNewField(r.ZEVMAuth, big.NewInt(1e5)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("update new field failed") - } + utils.RequireTxSuccessful(r, receipt) + newField, err = newZRC20Contract.NewField(&bind.CallOpts{}) - if err != nil { - panic(err) - } - if newField.Cmp(big.NewInt(1e5)) != 0 { - panic("new field value mismatch on bytecode contract") - } + require.NoError(r, err) + require.Equal(r, 0, newField.Cmp(big.NewInt(1e5)), "new field value mismatch on bytecode contract") + newField, err = testZRC20Contract.NewField(&bind.CallOpts{}) - if err != nil { - panic(err) - } - if newField.Cmp(big.NewInt(1e10)) != 0 { - panic("new field value mismatch on zrc20 contract") - } + require.NoError(r, err) + require.Equal(r, 0, newField.Cmp(big.NewInt(1e10)), "new field value mismatch on zrc20 contract") // can continue to operate the ZRC20 r.Logger.Info("Checking the ZRC20 can continue to operate after state change") tx, err = r.ETHZRC20.Transfer(r.ZEVMAuth, approved, big.NewInt(1e14)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) - if receipt.Status != 1 { - panic("transfer failed") - } + utils.RequireTxSuccessful(r, receipt) + newBalance, err = r.ETHZRC20.BalanceOf(&bind.CallOpts{}, approved) - if err != nil { - panic(err) - } - if newBalance.Cmp(big.NewInt(1e14)) != 0 { - panic("balance not updated") - } + require.NoError(r, err) + require.Equal(r, 0, newBalance.Cmp(big.NewInt(1e14))) } diff --git a/e2e/e2etests/test_zeta_deposit.go b/e2e/e2etests/test_zeta_deposit.go index a6fa98dbcf..056ee5709f 100644 --- a/e2e/e2etests/test_zeta_deposit.go +++ b/e2e/e2etests/test_zeta_deposit.go @@ -3,19 +3,17 @@ package e2etests import ( "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" ) func TestZetaDeposit(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestZetaDeposit requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestZetaDeposit.") - } + require.True(r, ok, "Invalid amount specified for TestZetaDeposit.") hash := r.DepositZetaWithAmount(r.DeployerAddress, amount) diff --git a/e2e/e2etests/test_zeta_deposit_new_address.go b/e2e/e2etests/test_zeta_deposit_new_address.go index c0be712e33..047fbd7042 100644 --- a/e2e/e2etests/test_zeta_deposit_new_address.go +++ b/e2e/e2etests/test_zeta_deposit_new_address.go @@ -3,20 +3,18 @@ package e2etests import ( "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/testutil/sample" ) func TestZetaDepositNewAddress(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestZetaDepositNewAddress requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestZetaDepositNewAddress.") - } + require.True(r, ok) newAddress := sample.EthAddress() hash := r.DepositZetaWithAmount(newAddress, amount) diff --git a/e2e/e2etests/test_zeta_deposit_restricted_address.go b/e2e/e2etests/test_zeta_deposit_restricted_address.go index e6a9d4f23b..d525a97d79 100644 --- a/e2e/e2etests/test_zeta_deposit_restricted_address.go +++ b/e2e/e2etests/test_zeta_deposit_restricted_address.go @@ -4,20 +4,17 @@ import ( "math/big" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/zetaclient/testutils" ) func TestZetaDepositRestricted(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestZetaDepositRestricted requires exactly one argument for the amount.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestZetaDepositRestricted.") - } + require.True(r, ok, "Invalid amount specified for TestZetaDepositRestricted.") // Deposit amount to restricted address r.DepositZetaWithAmount(ethcommon.HexToAddress(testutils.RestrictedEVMAddressTest), amount) diff --git a/e2e/e2etests/test_zeta_withdraw.go b/e2e/e2etests/test_zeta_withdraw.go index b46a403aa2..25b9d3d34a 100644 --- a/e2e/e2etests/test_zeta_withdraw.go +++ b/e2e/e2etests/test_zeta_withdraw.go @@ -1,35 +1,25 @@ package e2etests import ( - "fmt" "math/big" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" ) func TestZetaWithdraw(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestZetaWithdraw requires exactly one argument for the withdrawal.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("invalid amount specified") - } + require.True(r, ok) r.DepositAndApproveWZeta(amount) tx := r.WithdrawZeta(amount, true) cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, tx.Hash().Hex(), r.CctxClient, r.Logger, r.CctxTimeout) r.Logger.CCTX(*cctx, "zeta withdraw") - if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic(fmt.Errorf( - "expected cctx status to be %s; got %s, message %s", - crosschaintypes.CctxStatus_OutboundMined, - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage, - )) - } + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) } diff --git a/e2e/e2etests/test_zeta_withdraw_bitcoin_revert.go b/e2e/e2etests/test_zeta_withdraw_bitcoin_revert.go index 151d140a97..ae34058c94 100644 --- a/e2e/e2etests/test_zeta_withdraw_bitcoin_revert.go +++ b/e2e/e2etests/test_zeta_withdraw_bitcoin_revert.go @@ -3,6 +3,7 @@ package e2etests import ( "math/big" + "github.com/stretchr/testify/require" connectorzevm "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zetaconnectorzevm.sol" "github.com/zeta-chain/zetacore/e2e/runner" @@ -11,40 +12,31 @@ import ( ) func TestZetaWithdrawBTCRevert(r *runner.E2ERunner, args []string) { - if len(args) != 1 { - panic("TestZetaWithdrawBTCRevert requires exactly one argument for the withdrawal.") - } + require.Len(r, args, 1) amount, ok := big.NewInt(0).SetString(args[0], 10) - if !ok { - panic("Invalid amount specified for TestZetaWithdrawBTCRevert.") - } + require.True(r, ok) r.ZEVMAuth.Value = amount tx, err := r.WZeta.Deposit(r.ZEVMAuth) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.ZEVMAuth.Value = big.NewInt(0) r.Logger.Info("Deposit tx hash: %s", tx.Hash().Hex()) receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.EVMReceipt(*receipt, "Deposit") - if receipt.Status != 1 { - panic("Deposit failed") - } + utils.RequireTxSuccessful(r, receipt) tx, err = r.WZeta.Approve(r.ZEVMAuth, r.ConnectorZEVMAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("wzeta.approve tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt) + r.Logger.EVMReceipt(*receipt, "Approve") - if receipt.Status != 1 { - panic("Approve failed") - } lessThanAmount := amount.Div(amount, big.NewInt(10)) // 1/10 of amount tx, err = r.ConnectorZEVM.Send(r.ZEVMAuth, connectorzevm.ZetaInterfacesSendInput{ @@ -55,14 +47,12 @@ func TestZetaWithdrawBTCRevert(r *runner.E2ERunner, args []string) { ZetaValueAndGas: lessThanAmount, ZetaParams: nil, }) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("send tx hash: %s", tx.Hash().Hex()) receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequiredTxFailed(r, receipt) + r.Logger.EVMReceipt(*receipt, "send") - if receipt.Status != 0 { - panic("Was able to send ZETA to BTC") - } } diff --git a/e2e/e2etests/test_zrc20_swap.go b/e2e/e2etests/test_zrc20_swap.go index 4dfea02cf1..661d2fc40f 100644 --- a/e2e/e2etests/test_zrc20_swap.go +++ b/e2e/e2etests/test_zrc20_swap.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -24,22 +25,19 @@ func TestZRC20Swap(r *runner.E2ERunner, _ []string) { } zrc20EthPair, err := r.UniswapV2Factory.GetPair(&bind.CallOpts{}, r.ERC20ZRC20Addr, r.ETHZRC20Addr) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("ZRC20-ETH pair receipt pair addr %s", zrc20EthPair.Hex()) tx, err = r.ERC20ZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.Info("ERC20 ZRC20 approval receipt txhash %s status %d", receipt.TxHash, receipt.Status) tx, err = r.ETHZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.Info("ETH ZRC20 approval receipt txhash %s status %d", receipt.TxHash, receipt.Status) @@ -61,16 +59,14 @@ func TestZRC20Swap(r *runner.E2ERunner, _ []string) { r.DeployerAddress, big.NewInt(time.Now().Add(10*time.Minute).Unix()), ) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.Info("Add liquidity receipt txhash %s status %d", receipt.TxHash, receipt.Status) balETHBefore, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + ethOutAmout := big.NewInt(1) tx, err = r.UniswapV2Router.SwapExactTokensForTokens( r.ZEVMAuth, @@ -80,18 +76,14 @@ func TestZRC20Swap(r *runner.E2ERunner, _ []string) { r.DeployerAddress, big.NewInt(time.Now().Add(10*time.Minute).Unix()), ) - if err != nil { - panic(err) - } + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) r.Logger.Info("Swap ERC20 ZRC20 for ETH ZRC20 %s status %d", receipt.TxHash, receipt.Status) balETHAfter, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + ethDiff := big.NewInt(0).Sub(balETHAfter, balETHBefore) - if ethDiff.Cmp(ethOutAmout) < 0 { - panic("swap failed") - } + require.NotEqual(r, -1, ethDiff.Cmp(ethOutAmout), "swap failed") } diff --git a/e2e/runner/accounting.go b/e2e/runner/accounting.go index 31a53f9371..4992d46ad8 100644 --- a/e2e/runner/accounting.go +++ b/e2e/runner/accounting.go @@ -19,46 +19,46 @@ type Response struct { Amount Amount `json:"amount"` } -func (runner *E2ERunner) CheckZRC20ReserveAndSupply() error { - runner.Logger.Info("Checking ZRC20 Reserve and Supply") - if err := runner.checkEthTSSBalance(); err != nil { +func (r *E2ERunner) CheckZRC20ReserveAndSupply() error { + r.Logger.Info("Checking ZRC20 Reserve and Supply") + if err := r.checkEthTSSBalance(); err != nil { return err } - if err := runner.checkERC20TSSBalance(); err != nil { + if err := r.checkERC20TSSBalance(); err != nil { return err } - return runner.checkZetaTSSBalance() + return r.checkZetaTSSBalance() } -func (runner *E2ERunner) checkEthTSSBalance() error { - tssBal, err := runner.EVMClient.BalanceAt(runner.Ctx, runner.TSSAddress, nil) +func (r *E2ERunner) checkEthTSSBalance() error { + tssBal, err := r.EVMClient.BalanceAt(r.Ctx, r.TSSAddress, nil) if err != nil { return err } - zrc20Supply, err := runner.ETHZRC20.TotalSupply(&bind.CallOpts{}) + zrc20Supply, err := r.ETHZRC20.TotalSupply(&bind.CallOpts{}) if err != nil { return err } if tssBal.Cmp(zrc20Supply) < 0 { return fmt.Errorf("ETH: TSS balance (%d) < ZRC20 TotalSupply (%d) ", tssBal, zrc20Supply) } - runner.Logger.Info("ETH: TSS balance (%d) >= ZRC20 TotalSupply (%d)", tssBal, zrc20Supply) + r.Logger.Info("ETH: TSS balance (%d) >= ZRC20 TotalSupply (%d)", tssBal, zrc20Supply) return nil } -func (runner *E2ERunner) CheckBtcTSSBalance() error { - utxos, err := runner.BtcRPCClient.ListUnspent() +func (r *E2ERunner) CheckBtcTSSBalance() error { + utxos, err := r.BtcRPCClient.ListUnspent() if err != nil { return err } var btcBalance float64 for _, utxo := range utxos { - if utxo.Address == runner.BTCTSSAddress.EncodeAddress() { + if utxo.Address == r.BTCTSSAddress.EncodeAddress() { btcBalance += utxo.Amount } } - zrc20Supply, err := runner.BTCZRC20.TotalSupply(&bind.CallOpts{}) + zrc20Supply, err := r.BTCZRC20.TotalSupply(&bind.CallOpts{}) if err != nil { return err } @@ -75,7 +75,7 @@ func (runner *E2ERunner) CheckBtcTSSBalance() error { ) } // #nosec G701 test - always in range - runner.Logger.Info( + r.Logger.Info( "BTC: Balance (%d) >= ZRC20 TotalSupply (%d)", int64(btcBalance*1e8), zrc20Supply.Int64()-10000000, @@ -84,24 +84,24 @@ func (runner *E2ERunner) CheckBtcTSSBalance() error { return nil } -func (runner *E2ERunner) checkERC20TSSBalance() error { - erc20Balance, err := runner.ERC20.BalanceOf(&bind.CallOpts{}, runner.ERC20CustodyAddr) +func (r *E2ERunner) checkERC20TSSBalance() error { + erc20Balance, err := r.ERC20.BalanceOf(&bind.CallOpts{}, r.ERC20CustodyAddr) if err != nil { return err } - erc20zrc20Supply, err := runner.ERC20ZRC20.TotalSupply(&bind.CallOpts{}) + erc20zrc20Supply, err := r.ERC20ZRC20.TotalSupply(&bind.CallOpts{}) if err != nil { return err } if erc20Balance.Cmp(erc20zrc20Supply) < 0 { return fmt.Errorf("ERC20: TSS balance (%d) < ZRC20 TotalSupply (%d) ", erc20Balance, erc20zrc20Supply) } - runner.Logger.Info("ERC20: TSS balance (%d) >= ERC20 ZRC20 TotalSupply (%d)", erc20Balance, erc20zrc20Supply) + r.Logger.Info("ERC20: TSS balance (%d) >= ERC20 ZRC20 TotalSupply (%d)", erc20Balance, erc20zrc20Supply) return nil } -func (runner *E2ERunner) checkZetaTSSBalance() error { - zetaLocked, err := runner.ConnectorEth.GetLockedAmount(&bind.CallOpts{}) +func (r *E2ERunner) checkZetaTSSBalance() error { + zetaLocked, err := r.ConnectorEth.GetLockedAmount(&bind.CallOpts{}) if err != nil { return err } @@ -121,9 +121,9 @@ func (runner *E2ERunner) checkZetaTSSBalance() error { } zetaSupply, _ := big.NewInt(0).SetString(result.Amount.Amount, 10) if zetaLocked.Cmp(zetaSupply) < 0 { - runner.Logger.Info(fmt.Sprintf("ZETA: TSS balance (%d) < ZRC20 TotalSupply (%d)", zetaLocked, zetaSupply)) + r.Logger.Info(fmt.Sprintf("ZETA: TSS balance (%d) < ZRC20 TotalSupply (%d)", zetaLocked, zetaSupply)) } else { - runner.Logger.Info("ZETA: TSS balance (%d) >= ZRC20 TotalSupply (%d)", zetaLocked, zetaSupply) + r.Logger.Info("ZETA: TSS balance (%d) >= ZRC20 TotalSupply (%d)", zetaLocked, zetaSupply) } return nil } diff --git a/e2e/runner/balances.go b/e2e/runner/balances.go index 3e176bcb8d..8a0c37782a 100644 --- a/e2e/runner/balances.go +++ b/e2e/runner/balances.go @@ -31,39 +31,39 @@ type AccountBalancesDiff struct { } // GetAccountBalances returns the account balances of the accounts used in the E2E test -func (runner *E2ERunner) GetAccountBalances(skipBTC bool) (AccountBalances, error) { +func (r *E2ERunner) GetAccountBalances(skipBTC bool) (AccountBalances, error) { // zevm - zetaZeta, err := runner.ZEVMClient.BalanceAt(runner.Ctx, runner.DeployerAddress, nil) + zetaZeta, err := r.ZEVMClient.BalanceAt(r.Ctx, r.DeployerAddress, nil) if err != nil { return AccountBalances{}, err } - zetaWZeta, err := runner.WZeta.BalanceOf(&bind.CallOpts{}, runner.DeployerAddress) + zetaWZeta, err := r.WZeta.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) if err != nil { return AccountBalances{}, err } - zetaEth, err := runner.ETHZRC20.BalanceOf(&bind.CallOpts{}, runner.DeployerAddress) + zetaEth, err := r.ETHZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) if err != nil { return AccountBalances{}, err } - zetaErc20, err := runner.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, runner.DeployerAddress) + zetaErc20, err := r.ERC20ZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) if err != nil { return AccountBalances{}, err } - zetaBtc, err := runner.BTCZRC20.BalanceOf(&bind.CallOpts{}, runner.DeployerAddress) + zetaBtc, err := r.BTCZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) if err != nil { return AccountBalances{}, err } // evm - evmEth, err := runner.EVMClient.BalanceAt(runner.Ctx, runner.DeployerAddress, nil) + evmEth, err := r.EVMClient.BalanceAt(r.Ctx, r.DeployerAddress, nil) if err != nil { return AccountBalances{}, err } - evmZeta, err := runner.ZetaEth.BalanceOf(&bind.CallOpts{}, runner.DeployerAddress) + evmZeta, err := r.ZetaEth.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) if err != nil { return AccountBalances{}, err } - evmErc20, err := runner.ERC20.BalanceOf(&bind.CallOpts{}, runner.DeployerAddress) + evmErc20, err := r.ERC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) if err != nil { return AccountBalances{}, err } @@ -71,7 +71,7 @@ func (runner *E2ERunner) GetAccountBalances(skipBTC bool) (AccountBalances, erro // bitcoin var BtcBTC string if !skipBTC { - if BtcBTC, err = runner.GetBitcoinBalance(); err != nil { + if BtcBTC, err = r.GetBitcoinBalance(); err != nil { return AccountBalances{}, err } } @@ -90,18 +90,18 @@ func (runner *E2ERunner) GetAccountBalances(skipBTC bool) (AccountBalances, erro } // GetBitcoinBalance returns the spendable BTC balance of the BTC address -func (runner *E2ERunner) GetBitcoinBalance() (string, error) { - addr, _, err := runner.GetBtcAddress() +func (r *E2ERunner) GetBitcoinBalance() (string, error) { + addr, _, err := r.GetBtcAddress() if err != nil { return "", fmt.Errorf("failed to get BTC address: %w", err) } - address, err := btcutil.DecodeAddress(addr, runner.BitcoinParams) + address, err := btcutil.DecodeAddress(addr, r.BitcoinParams) if err != nil { return "", fmt.Errorf("failed to decode BTC address: %w", err) } - total, err := runner.GetBitcoinBalanceByAddress(address) + total, err := r.GetBitcoinBalanceByAddress(address) if err != nil { return "", err } @@ -110,8 +110,8 @@ func (runner *E2ERunner) GetBitcoinBalance() (string, error) { } // GetBitcoinBalanceByAddress get btc balance by address. -func (runner *E2ERunner) GetBitcoinBalanceByAddress(address btcutil.Address) (btcutil.Amount, error) { - unspentList, err := runner.BtcRPCClient.ListUnspentMinMaxAddresses(1, 9999999, []btcutil.Address{address}) +func (r *E2ERunner) GetBitcoinBalanceByAddress(address btcutil.Address) (btcutil.Amount, error) { + unspentList, err := r.BtcRPCClient.ListUnspentMinMaxAddresses(1, 9999999, []btcutil.Address{address}) if err != nil { return 0, errors.Wrap(err, "failed to list unspent") } @@ -128,43 +128,43 @@ func (runner *E2ERunner) GetBitcoinBalanceByAddress(address btcutil.Address) (bt // PrintAccountBalances shows the account balances of the accounts used in the E2E test // Note: USDT is mentioned as erc20 here because we want to show the balance of any erc20 contract -func (runner *E2ERunner) PrintAccountBalances(balances AccountBalances) { - runner.Logger.Print(" ---💰 Account info %s ---", runner.DeployerAddress.Hex()) +func (r *E2ERunner) PrintAccountBalances(balances AccountBalances) { + r.Logger.Print(" ---💰 Account info %s ---", r.DeployerAddress.Hex()) // zevm - runner.Logger.Print("ZetaChain:") - runner.Logger.Print("* ZETA balance: %s", balances.ZetaZETA.String()) - runner.Logger.Print("* WZETA balance: %s", balances.ZetaWZETA.String()) - runner.Logger.Print("* ETH balance: %s", balances.ZetaETH.String()) - runner.Logger.Print("* ERC20 balance: %s", balances.ZetaERC20.String()) - runner.Logger.Print("* BTC balance: %s", balances.ZetaBTC.String()) + r.Logger.Print("ZetaChain:") + r.Logger.Print("* ZETA balance: %s", balances.ZetaZETA.String()) + r.Logger.Print("* WZETA balance: %s", balances.ZetaWZETA.String()) + r.Logger.Print("* ETH balance: %s", balances.ZetaETH.String()) + r.Logger.Print("* ERC20 balance: %s", balances.ZetaERC20.String()) + r.Logger.Print("* BTC balance: %s", balances.ZetaBTC.String()) // evm - runner.Logger.Print("EVM:") - runner.Logger.Print("* ZETA balance: %s", balances.EvmZETA.String()) - runner.Logger.Print("* ETH balance: %s", balances.EvmETH.String()) - runner.Logger.Print("* ERC20 balance: %s", balances.EvmERC20.String()) + r.Logger.Print("EVM:") + r.Logger.Print("* ZETA balance: %s", balances.EvmZETA.String()) + r.Logger.Print("* ETH balance: %s", balances.EvmETH.String()) + r.Logger.Print("* ERC20 balance: %s", balances.EvmERC20.String()) // bitcoin - runner.Logger.Print("Bitcoin:") - runner.Logger.Print("* BTC balance: %s", balances.BtcBTC) + r.Logger.Print("Bitcoin:") + r.Logger.Print("* BTC balance: %s", balances.BtcBTC) return } // PrintTotalDiff shows the difference in the account balances of the accounts used in the e2e test from two balances structs -func (runner *E2ERunner) PrintTotalDiff(accoutBalancesDiff AccountBalancesDiff) { - runner.Logger.Print(" ---💰 Total gas spent ---") +func (r *E2ERunner) PrintTotalDiff(accoutBalancesDiff AccountBalancesDiff) { + r.Logger.Print(" ---💰 Total gas spent ---") // show the value only if it is not zero if accoutBalancesDiff.ZETA.Cmp(big.NewInt(0)) != 0 { - runner.Logger.Print("* ZETA spent: %s", accoutBalancesDiff.ZETA.String()) + r.Logger.Print("* ZETA spent: %s", accoutBalancesDiff.ZETA.String()) } if accoutBalancesDiff.ETH.Cmp(big.NewInt(0)) != 0 { - runner.Logger.Print("* ETH spent: %s", accoutBalancesDiff.ETH.String()) + r.Logger.Print("* ETH spent: %s", accoutBalancesDiff.ETH.String()) } if accoutBalancesDiff.ERC20.Cmp(big.NewInt(0)) != 0 { - runner.Logger.Print("* ERC20 spent: %s", accoutBalancesDiff.ERC20.String()) + r.Logger.Print("* ERC20 spent: %s", accoutBalancesDiff.ERC20.String()) } } diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index b2b82d2132..c096bfc748 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/hex" "fmt" - "math/big" "time" "github.com/btcsuite/btcd/btcjson" @@ -30,19 +29,19 @@ import ( var blockHeaderBTCTimeout = 5 * time.Minute // ListDeployerUTXOs list the deployer's UTXOs -func (runner *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error) { +func (r *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error) { // query UTXOs from node - utxos, err := runner.BtcRPCClient.ListUnspentMinMaxAddresses( + utxos, err := r.BtcRPCClient.ListUnspentMinMaxAddresses( 1, 9999999, - []btcutil.Address{runner.BTCDeployerAddress}, + []btcutil.Address{r.BTCDeployerAddress}, ) if err != nil { return nil, err } // filter big-enough UTXOs for test if running on Regtest - if runner.IsLocalBitcoin() { + if r.IsLocalBitcoin() { utxosFiltered := []btcjson.ListUnspentResult{} for _, utxo := range utxos { if utxo.Amount >= 1.0 { @@ -56,14 +55,12 @@ func (runner *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error } // DepositBTCWithAmount deposits BTC on ZetaChain with a specific amount -func (runner *E2ERunner) DepositBTCWithAmount(amount float64) (txHash *chainhash.Hash) { - runner.Logger.Print("⏳ depositing BTC into ZEVM") +func (r *E2ERunner) DepositBTCWithAmount(amount float64) *chainhash.Hash { + r.Logger.Print("⏳ depositing BTC into ZEVM") // list deployer utxos - utxos, err := runner.ListDeployerUTXOs() - if err != nil { - panic(err) - } + utxos, err := r.ListDeployerUTXOs() + require.NoError(r, err) spendableAmount := 0.0 spendableUTXOs := 0 @@ -74,42 +71,33 @@ func (runner *E2ERunner) DepositBTCWithAmount(amount float64) (txHash *chainhash } } - if spendableAmount < amount { - panic(fmt.Errorf( - "not enough spendable BTC to run the test; have %f, require %f", - spendableAmount, - amount, - )) - } + require.LessOrEqual(r, amount, spendableAmount, "not enough spendable BTC to run the test") - runner.Logger.Info("ListUnspent:") - runner.Logger.Info(" spendableAmount: %f", spendableAmount) - runner.Logger.Info(" spendableUTXOs: %d", spendableUTXOs) - runner.Logger.Info("Now sending two txs to TSS address...") + r.Logger.Info("ListUnspent:") + r.Logger.Info(" spendableAmount: %f", spendableAmount) + r.Logger.Info(" spendableUTXOs: %d", spendableUTXOs) + r.Logger.Info("Now sending two txs to TSS address...") - amount = amount + zetabitcoin.DefaultDepositorFee - txHash, err = runner.SendToTSSFromDeployerToDeposit(amount, utxos) - if err != nil { - panic(err) - } - runner.Logger.Info("send BTC to TSS txHash: %s", txHash.String()) + amount += zetabitcoin.DefaultDepositorFee + txHash, err := r.SendToTSSFromDeployerToDeposit(amount, utxos) + require.NoError(r, err) + + r.Logger.Info("send BTC to TSS txHash: %s", txHash.String()) return txHash } // DepositBTC deposits BTC on ZetaChain -func (runner *E2ERunner) DepositBTC(testHeader bool) { - runner.Logger.Print("⏳ depositing BTC into ZEVM") +func (r *E2ERunner) DepositBTC(testHeader bool) { + r.Logger.Print("⏳ depositing BTC into ZEVM") startTime := time.Now() defer func() { - runner.Logger.Print("✅ BTC deposited in %s", time.Since(startTime)) + r.Logger.Print("✅ BTC deposited in %s", time.Since(startTime)) }() // list deployer utxos - utxos, err := runner.ListDeployerUTXOs() - if err != nil { - panic(err) - } + utxos, err := r.ListDeployerUTXOs() + require.NoError(r, err) spendableAmount := 0.0 spendableUTXOs := 0 @@ -120,85 +108,66 @@ func (runner *E2ERunner) DepositBTC(testHeader bool) { } } - if spendableAmount < 1.15 { - panic(fmt.Errorf("not enough spendable BTC to run the test; have %f", spendableAmount)) - } - if spendableUTXOs < 5 { - panic(fmt.Errorf("not enough spendable BTC UTXOs to run the test; have %d", spendableUTXOs)) - } + require.GreaterOrEqual(r, spendableAmount, 1.15, "not enough spendable BTC to run the test") + require.GreaterOrEqual(r, spendableUTXOs, 5, "not enough spendable BTC UTXOs to run the test") - runner.Logger.Info("ListUnspent:") - runner.Logger.Info(" spendableAmount: %f", spendableAmount) - runner.Logger.Info(" spendableUTXOs: %d", spendableUTXOs) - runner.Logger.Info("Now sending two txs to TSS address...") + r.Logger.Info("ListUnspent:") + r.Logger.Info(" spendableAmount: %f", spendableAmount) + r.Logger.Info(" spendableUTXOs: %d", spendableUTXOs) + r.Logger.Info("Now sending two txs to TSS address...") // send two transactions to the TSS address amount1 := 1.1 + zetabitcoin.DefaultDepositorFee - txHash1, err := runner.SendToTSSFromDeployerToDeposit(amount1, utxos[:2]) - if err != nil { - panic(err) - } + txHash1, err := r.SendToTSSFromDeployerToDeposit(amount1, utxos[:2]) + require.NoError(r, err) + amount2 := 0.05 + zetabitcoin.DefaultDepositorFee - txHash2, err := runner.SendToTSSFromDeployerToDeposit(amount2, utxos[2:4]) - if err != nil { - panic(err) - } + txHash2, err := r.SendToTSSFromDeployerToDeposit(amount2, utxos[2:4]) + require.NoError(r, err) // send a donation to the TSS address to compensate for the funds minted automatically during pool creation // and prevent accounting errors - _, err = runner.SendToTSSFromDeployerWithMemo(0.11, utxos[4:5], []byte(constant.DonationMessage)) - if err != nil { - panic(err) - } + _, err = r.SendToTSSFromDeployerWithMemo(0.11, utxos[4:5], []byte(constant.DonationMessage)) + require.NoError(r, err) - runner.Logger.Info("testing if the deposit into BTC ZRC20 is successful...") + r.Logger.Info("testing if the deposit into BTC ZRC20 is successful...") cctx := utils.WaitCctxMinedByInboundHash( - runner.Ctx, + r.Ctx, txHash2.String(), - runner.CctxClient, - runner.Logger, - runner.CctxTimeout, + r.CctxClient, + r.Logger, + r.CctxTimeout, ) - if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic(fmt.Sprintf( - "expected mined status; got %s, message: %s", - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage), - ) - } + utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined) - balance, err := runner.BTCZRC20.BalanceOf(&bind.CallOpts{}, runner.DeployerAddress) - if err != nil { - panic(err) - } - if balance.Cmp(big.NewInt(0)) != 1 { - panic("balance should be positive") - } + balance, err := r.BTCZRC20.BalanceOf(&bind.CallOpts{}, r.DeployerAddress) + require.NoError(r, err) + require.Equal(r, 1, balance.Sign(), "balance should be positive") // due to the high block throughput in localnet, ZetaClient might catch up slowly with the blocks // to optimize block header proof test, this test is directly executed here on the first deposit instead of having a separate test if testHeader { - runner.ProveBTCTransaction(txHash1) + r.ProveBTCTransaction(txHash1) } } -func (runner *E2ERunner) SendToTSSFromDeployerToDeposit(amount float64, inputUTXOs []btcjson.ListUnspentResult) ( +func (r *E2ERunner) SendToTSSFromDeployerToDeposit(amount float64, inputUTXOs []btcjson.ListUnspentResult) ( *chainhash.Hash, error, ) { - return runner.SendToTSSFromDeployerWithMemo(amount, inputUTXOs, runner.DeployerAddress.Bytes()) + return r.SendToTSSFromDeployerWithMemo(amount, inputUTXOs, r.DeployerAddress.Bytes()) } -func (runner *E2ERunner) SendToTSSFromDeployerWithMemo( +func (r *E2ERunner) SendToTSSFromDeployerWithMemo( amount float64, inputUTXOs []btcjson.ListUnspentResult, memo []byte, ) (*chainhash.Hash, error) { - btcRPC := runner.BtcRPCClient - to := runner.BTCTSSAddress - btcDeployerAddress := runner.BTCDeployerAddress - require.NotNil(runner, runner.BTCDeployerAddress, "btcDeployerAddress is nil") + btcRPC := r.BtcRPCClient + to := r.BTCTSSAddress + btcDeployerAddress := r.BTCDeployerAddress + require.NotNil(r, r.BTCDeployerAddress, "btcDeployerAddress is nil") // prepare inputs inputs := make([]btcjson.TransactionInput, len(inputUTXOs)) @@ -229,38 +198,32 @@ func (runner *E2ERunner) SendToTSSFromDeployerWithMemo( } // create raw - runner.Logger.Info("ADDRESS: %s, %s", btcDeployerAddress.EncodeAddress(), to.EncodeAddress()) + r.Logger.Info("ADDRESS: %s, %s", btcDeployerAddress.EncodeAddress(), to.EncodeAddress()) tx, err := btcRPC.CreateRawTransaction(inputs, amountMap, nil) - if err != nil { - panic(err) - } + require.NoError(r, err) // this adds a OP_RETURN + single BYTE len prefix to the data nullData, err := txscript.NullDataScript(memo) - if err != nil { - panic(err) - } - runner.Logger.Info("nulldata (len %d): %x", len(nullData), nullData) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("nulldata (len %d): %x", len(nullData), nullData) + require.NoError(r, err) memoOutput := wire.TxOut{Value: 0, PkScript: nullData} tx.TxOut = append(tx.TxOut, &memoOutput) tx.TxOut[1], tx.TxOut[2] = tx.TxOut[2], tx.TxOut[1] // make sure that TxOut[0] is sent to "to" address; TxOut[2] is change to oneself. TxOut[1] is memo. if !bytes.Equal(tx.TxOut[0].PkScript[2:], to.ScriptAddress()) { - runner.Logger.Info("tx.TxOut[0].PkScript: %x", tx.TxOut[0].PkScript) - runner.Logger.Info("to.ScriptAddress(): %x", to.ScriptAddress()) - runner.Logger.Info("swapping txout[0] with txout[2]") + r.Logger.Info("tx.TxOut[0].PkScript: %x", tx.TxOut[0].PkScript) + r.Logger.Info("to.ScriptAddress(): %x", to.ScriptAddress()) + r.Logger.Info("swapping txout[0] with txout[2]") tx.TxOut[0], tx.TxOut[2] = tx.TxOut[2], tx.TxOut[0] } - runner.Logger.Info("raw transaction: \n") + r.Logger.Info("raw transaction: \n") for idx, txout := range tx.TxOut { - runner.Logger.Info("txout %d", idx) - runner.Logger.Info(" value: %d", txout.Value) - runner.Logger.Info(" PkScript: %x", txout.PkScript) + r.Logger.Info("txout %d", idx) + r.Logger.Info(" value: %d", txout.Value) + r.Logger.Info(" PkScript: %x", txout.PkScript) } inputsForSign := make([]btcjson.RawTxWitnessInput, len(inputs)) @@ -274,75 +237,63 @@ func (runner *E2ERunner) SendToTSSFromDeployerWithMemo( } stx, signed, err := btcRPC.SignRawTransactionWithWallet2(tx, inputsForSign) - require.NoError(runner, err) - require.True(runner, signed, "btc transaction is not signed") + require.NoError(r, err) + require.True(r, signed, "btc transaction is not signed") txid, err := btcRPC.SendRawTransaction(stx, true) - if err != nil { - panic(err) - } - runner.Logger.Info("txid: %+v", txid) - _, err = runner.GenerateToAddressIfLocalBitcoin(6, btcDeployerAddress) - if err != nil { - panic(err) - } + require.NoError(r, err) + r.Logger.Info("txid: %+v", txid) + _, err = r.GenerateToAddressIfLocalBitcoin(6, btcDeployerAddress) + require.NoError(r, err) gtx, err := btcRPC.GetTransaction(txid) - if err != nil { - panic(err) - } - runner.Logger.Info("rawtx confirmation: %d", gtx.BlockIndex) + require.NoError(r, err) + r.Logger.Info("rawtx confirmation: %d", gtx.BlockIndex) rawtx, err := btcRPC.GetRawTransactionVerbose(txid) - if err != nil { - panic(err) - } + require.NoError(r, err) depositorFee := zetabitcoin.DefaultDepositorFee events, err := btcobserver.FilterAndParseIncomingTx( btcRPC, []btcjson.TxRawResult{*rawtx}, 0, - runner.BTCTSSAddress.EncodeAddress(), + r.BTCTSSAddress.EncodeAddress(), log.Logger, - runner.BitcoinParams, + r.BitcoinParams, depositorFee, ) - if err != nil { - panic(err) - } - runner.Logger.Info("bitcoin inbound events:") + require.NoError(r, err) + r.Logger.Info("bitcoin inbound events:") for _, event := range events { - runner.Logger.Info(" TxHash: %s", event.TxHash) - runner.Logger.Info(" From: %s", event.FromAddress) - runner.Logger.Info(" To: %s", event.ToAddress) - runner.Logger.Info(" Amount: %f", event.Value) - runner.Logger.Info(" Memo: %x", event.MemoBytes) + r.Logger.Info(" TxHash: %s", event.TxHash) + r.Logger.Info(" From: %s", event.FromAddress) + r.Logger.Info(" To: %s", event.ToAddress) + r.Logger.Info(" Amount: %f", event.Value) + r.Logger.Info(" Memo: %x", event.MemoBytes) } return txid, nil } // GetBitcoinChainID gets the bitcoin chain ID from the network params -func (runner *E2ERunner) GetBitcoinChainID() int64 { - chainID, err := chains.BitcoinChainIDFromNetworkName(runner.BitcoinParams.Name) - if err != nil { - panic(err) - } +func (r *E2ERunner) GetBitcoinChainID() int64 { + chainID, err := chains.BitcoinChainIDFromNetworkName(r.BitcoinParams.Name) + require.NoError(r, err) return chainID } // IsLocalBitcoin returns true if the runner is running on a local bitcoin network -func (runner *E2ERunner) IsLocalBitcoin() bool { - return runner.BitcoinParams.Name == chains.BitcoinRegnetParams.Name +func (r *E2ERunner) IsLocalBitcoin() bool { + return r.BitcoinParams.Name == chains.BitcoinRegnetParams.Name } // GenerateToAddressIfLocalBitcoin generates blocks to an address if the runner is interacting // with a local bitcoin network -func (runner *E2ERunner) GenerateToAddressIfLocalBitcoin( +func (r *E2ERunner) GenerateToAddressIfLocalBitcoin( numBlocks int64, address btcutil.Address, ) ([]*chainhash.Hash, error) { // if not local bitcoin network, do nothing - if runner.IsLocalBitcoin() { - return runner.BtcRPCClient.GenerateToAddress(numBlocks, address, nil) + if r.IsLocalBitcoin() { + return r.BtcRPCClient.GenerateToAddress(numBlocks, address, nil) } return nil, nil } @@ -350,7 +301,7 @@ func (runner *E2ERunner) GenerateToAddressIfLocalBitcoin( // MineBlocksIfLocalBitcoin mines blocks on the local BTC chain at a rate of 1 blocks every 5 seconds // and returns a channel that can be used to stop the mining // If the chain is not local, the function does nothing -func (runner *E2ERunner) MineBlocksIfLocalBitcoin() func() { +func (r *E2ERunner) MineBlocksIfLocalBitcoin() func() { stopChan := make(chan struct{}) go func() { for { @@ -358,10 +309,9 @@ func (runner *E2ERunner) MineBlocksIfLocalBitcoin() func() { case <-stopChan: return default: - _, err := runner.GenerateToAddressIfLocalBitcoin(1, runner.BTCDeployerAddress) - if err != nil { - panic(err) - } + _, err := r.GenerateToAddressIfLocalBitcoin(1, r.BTCDeployerAddress) + require.NoError(r, err) + time.Sleep(3 * time.Second) } } @@ -373,78 +323,61 @@ func (runner *E2ERunner) MineBlocksIfLocalBitcoin() func() { } // ProveBTCTransaction proves that a BTC transaction is in a block header and that the block header is in ZetaChain -func (runner *E2ERunner) ProveBTCTransaction(txHash *chainhash.Hash) { +func (r *E2ERunner) ProveBTCTransaction(txHash *chainhash.Hash) { // get tx result - btc := runner.BtcRPCClient + btc := r.BtcRPCClient txResult, err := btc.GetTransaction(txHash) - if err != nil { - panic("should get outTx result") - } - if txResult.Confirmations <= 0 { - panic("outTx should have already confirmed") - } + require.NoError(r, err, "should get tx result") + require.True(r, txResult.Confirmations > 0, "tx should have already confirmed") + txBytes, err := hex.DecodeString(txResult.Hex) - if err != nil { - panic(err) - } + require.NoError(r, err) // get the block with verbose transactions blockHash, err := chainhash.NewHashFromStr(txResult.BlockHash) - if err != nil { - panic(err) - } + require.NoError(r, err) + blockVerbose, err := btc.GetBlockVerboseTx(blockHash) - if err != nil { - panic("should get block verbose tx") - } + require.NoError(r, err, "should get block verbose tx") // get the block header header, err := btc.GetBlockHeader(blockHash) - if err != nil { - panic("should get block header") - } + require.NoError(r, err, "should get block header") // collect all the txs in the block txns := []*btcutil.Tx{} for _, res := range blockVerbose.Tx { txBytes, err := hex.DecodeString(res.Hex) - if err != nil { - panic(err) - } + require.NoError(r, err) + tx, err := btcutil.NewTxFromBytes(txBytes) - if err != nil { - panic(err) - } + require.NoError(r, err) + txns = append(txns, tx) } // build merkle proof mk := bitcoin.NewMerkle(txns) path, index, err := mk.BuildMerkleProof(int(txResult.BlockIndex)) - if err != nil { - panic("should build merkle proof") - } + require.NoError(r, err, "should build merkle proof") // verify merkle proof statically pass := bitcoin.Prove(*txHash, header.MerkleRoot, path, index) - if !pass { - panic("should verify merkle proof") - } + require.True(r, pass, "should verify merkle proof") // wait for block header to show up in ZetaChain startTime := time.Now() hash := header.BlockHash() for { // timeout - if time.Since(startTime) > blockHeaderBTCTimeout { - panic("timed out waiting for block header to show up in observer") - } + reachedTimeout := time.Since(startTime) > blockHeaderBTCTimeout + require.False(r, reachedTimeout, "timed out waiting for block header to show up in observer") - _, err := runner.LightclientClient.BlockHeader(runner.Ctx, &lightclienttypes.QueryGetBlockHeaderRequest{ + _, err := r.LightclientClient.BlockHeader(r.Ctx, &lightclienttypes.QueryGetBlockHeaderRequest{ BlockHash: hash.CloneBytes(), }) if err != nil { - runner.Logger.Info( + r.Logger.Info( "waiting for block header to show up in observer... current hash %s; err %s", hash.String(), err.Error(), @@ -457,18 +390,15 @@ func (runner *E2ERunner) ProveBTCTransaction(txHash *chainhash.Hash) { } // verify merkle proof through RPC - res, err := runner.LightclientClient.Prove(runner.Ctx, &lightclienttypes.QueryProveRequest{ + res, err := r.LightclientClient.Prove(r.Ctx, &lightclienttypes.QueryProveRequest{ ChainId: chains.BitcoinRegtest.ChainId, TxHash: txHash.String(), BlockHash: blockHash.String(), Proof: proofs.NewBitcoinProof(txBytes, path, index), TxIndex: 0, // bitcoin doesn't use txIndex }) - if err != nil { - panic(err) - } - if !res.Valid { - panic("txProof should be valid") - } - runner.Logger.Info("OK: txProof verified for inTx: %s", txHash.String()) + require.NoError(r, err) + require.True(r, res.Valid, "txProof should be valid") + + r.Logger.Info("OK: txProof verified for inTx: %s", txHash.String()) } diff --git a/e2e/runner/e2etest.go b/e2e/runner/e2etest.go index c6e49bdc9d..1ee9c34c19 100644 --- a/e2e/runner/e2etest.go +++ b/e2e/runner/e2etest.go @@ -61,7 +61,7 @@ type E2ETestRunConfig struct { } // GetE2ETestsToRunByName prepares a list of E2ETests to run based on given test names without arguments -func (runner *E2ERunner) GetE2ETestsToRunByName(availableTests []E2ETest, testNames ...string) ([]E2ETest, error) { +func (r *E2ERunner) GetE2ETestsToRunByName(availableTests []E2ETest, testNames ...string) ([]E2ETest, error) { tests := []E2ETestRunConfig{} for _, testName := range testNames { tests = append(tests, E2ETestRunConfig{ @@ -69,11 +69,11 @@ func (runner *E2ERunner) GetE2ETestsToRunByName(availableTests []E2ETest, testNa Args: []string{}, }) } - return runner.GetE2ETestsToRunByConfig(availableTests, tests) + return r.GetE2ETestsToRunByConfig(availableTests, tests) } // GetE2ETestsToRunByConfig prepares a list of E2ETests to run based on provided test names and their corresponding arguments -func (runner *E2ERunner) GetE2ETestsToRunByConfig( +func (r *E2ERunner) GetE2ETestsToRunByConfig( availableTests []E2ETest, testConfigs []E2ETestRunConfig, ) ([]E2ETest, error) { diff --git a/e2e/runner/evm.go b/e2e/runner/evm.go index 355b692ec5..523e01e207 100644 --- a/e2e/runner/evm.go +++ b/e2e/runner/evm.go @@ -9,6 +9,7 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/pkg/chains" @@ -20,169 +21,146 @@ import ( var blockHeaderETHTimeout = 5 * time.Minute // WaitForTxReceiptOnEvm waits for a tx receipt on EVM -func (runner *E2ERunner) WaitForTxReceiptOnEvm(tx *ethtypes.Transaction) { - defer func() { - runner.Unlock() - }() - runner.Lock() +func (r *E2ERunner) WaitForTxReceiptOnEvm(tx *ethtypes.Transaction) { + r.Lock() + defer r.Unlock() - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt) } // MintERC20OnEvm mints ERC20 on EVM // amount is a multiple of 1e18 -func (runner *E2ERunner) MintERC20OnEvm(amountERC20 int64) { - defer func() { - runner.Unlock() - }() - runner.Lock() +func (r *E2ERunner) MintERC20OnEvm(amountERC20 int64) { + r.Lock() + defer r.Unlock() amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(amountERC20)) - tx, err := runner.ERC20.Mint(runner.EVMAuth, amount) - if err != nil { - panic(err) - } - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - if receipt.Status == 0 { - panic("mint failed") - } - runner.Logger.Info("Mint receipt tx hash: %s", tx.Hash().Hex()) + tx, err := r.ERC20.Mint(r.EVMAuth, amount) + require.NoError(r, err) + + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt) + + r.Logger.Info("Mint receipt tx hash: %s", tx.Hash().Hex()) } // SendERC20OnEvm sends ERC20 to an address on EVM // this allows the ERC20 contract deployer to funds other accounts on EVM // amountERC20 is a multiple of 1e18 -func (runner *E2ERunner) SendERC20OnEvm(address ethcommon.Address, amountERC20 int64) *ethtypes.Transaction { +func (r *E2ERunner) SendERC20OnEvm(address ethcommon.Address, amountERC20 int64) *ethtypes.Transaction { // the deployer might be sending ERC20 in different goroutines - defer func() { - runner.Unlock() - }() - runner.Lock() + r.Lock() + defer r.Unlock() amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(amountERC20)) // transfer - tx, err := runner.ERC20.Transfer(runner.EVMAuth, address, amount) - if err != nil { - panic(err) - } + tx, err := r.ERC20.Transfer(r.EVMAuth, address, amount) + require.NoError(r, err) + return tx } -func (runner *E2ERunner) DepositERC20() ethcommon.Hash { - runner.Logger.Print("⏳ depositing ERC20 into ZEVM") +func (r *E2ERunner) DepositERC20() ethcommon.Hash { + r.Logger.Print("⏳ depositing ERC20 into ZEVM") - return runner.DepositERC20WithAmountAndMessage(runner.DeployerAddress, big.NewInt(1e18), []byte{}) + return r.DepositERC20WithAmountAndMessage(r.DeployerAddress, big.NewInt(1e18), []byte{}) } -func (runner *E2ERunner) DepositERC20WithAmountAndMessage( - to ethcommon.Address, - amount *big.Int, - msg []byte, -) ethcommon.Hash { +func (r *E2ERunner) DepositERC20WithAmountAndMessage(to ethcommon.Address, amount *big.Int, msg []byte) ethcommon.Hash { // reset allowance, necessary for USDT - tx, err := runner.ERC20.Approve(runner.EVMAuth, runner.ERC20CustodyAddr, big.NewInt(0)) - if err != nil { - panic(err) - } - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } - runner.Logger.Info("ERC20 Approve receipt tx hash: %s", tx.Hash().Hex()) + tx, err := r.ERC20.Approve(r.EVMAuth, r.ERC20CustodyAddr, big.NewInt(0)) + require.NoError(r, err) - tx, err = runner.ERC20.Approve(runner.EVMAuth, runner.ERC20CustodyAddr, amount) - if err != nil { - panic(err) - } - receipt = utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - if receipt.Status == 0 { - panic("approve failed") - } - runner.Logger.Info("ERC20 Approve receipt tx hash: %s", tx.Hash().Hex()) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt) - tx, err = runner.ERC20Custody.Deposit(runner.EVMAuth, to.Bytes(), runner.ERC20Addr, amount, msg) - runner.Logger.Info("TX: %v", tx) + r.Logger.Info("ERC20 Approve receipt tx hash: %s", tx.Hash().Hex()) - if err != nil { - panic(err) - } - receipt = utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposit failed") - } - runner.Logger.Info("Deposit receipt tx hash: %s, status %d", receipt.TxHash.Hex(), receipt.Status) + tx, err = r.ERC20.Approve(r.EVMAuth, r.ERC20CustodyAddr, amount) + require.NoError(r, err) + + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt) + + r.Logger.Info("ERC20 Approve receipt tx hash: %s", tx.Hash().Hex()) + + tx, err = r.ERC20Custody.Deposit(r.EVMAuth, to.Bytes(), r.ERC20Addr, amount, msg) + require.NoError(r, err) + + r.Logger.Info("TX: %v", tx) + + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt) + + r.Logger.Info("Deposit receipt tx hash: %s, status %d", receipt.TxHash.Hex(), receipt.Status) for _, log := range receipt.Logs { - event, err := runner.ERC20Custody.ParseDeposited(*log) + event, err := r.ERC20Custody.ParseDeposited(*log) if err != nil { continue } - runner.Logger.Info("Deposited event:") - runner.Logger.Info(" Recipient address: %x", event.Recipient) - runner.Logger.Info(" ERC20 address: %s", event.Asset.Hex()) - runner.Logger.Info(" Amount: %d", event.Amount) - runner.Logger.Info(" Message: %x", event.Message) + r.Logger.Info("Deposited event:") + r.Logger.Info(" Recipient address: %x", event.Recipient) + r.Logger.Info(" ERC20 address: %s", event.Asset.Hex()) + r.Logger.Info(" Amount: %d", event.Amount) + r.Logger.Info(" Message: %x", event.Message) } return tx.Hash() } // DepositEther sends Ethers into ZEVM -func (runner *E2ERunner) DepositEther(testHeader bool) ethcommon.Hash { +func (r *E2ERunner) DepositEther(testHeader bool) ethcommon.Hash { amount := big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(100)) // 100 eth - return runner.DepositEtherWithAmount(testHeader, amount) + return r.DepositEtherWithAmount(testHeader, amount) } // DepositEtherWithAmount sends Ethers into ZEVM -func (runner *E2ERunner) DepositEtherWithAmount(testHeader bool, amount *big.Int) ethcommon.Hash { - runner.Logger.Print("⏳ depositing Ethers into ZEVM") +func (r *E2ERunner) DepositEtherWithAmount(testHeader bool, amount *big.Int) ethcommon.Hash { + r.Logger.Print("⏳ depositing Ethers into ZEVM") - signedTx, err := runner.SendEther(runner.TSSAddress, amount, nil) - if err != nil { - panic(err) - } - runner.Logger.EVMTransaction(*signedTx, "send to TSS") + signedTx, err := r.SendEther(r.TSSAddress, amount, nil) + require.NoError(r, err) - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, signedTx, runner.Logger, runner.ReceiptTimeout) - if receipt.Status == 0 { - panic("deposit failed") - } - runner.Logger.EVMReceipt(*receipt, "send to TSS") + r.Logger.EVMTransaction(*signedTx, "send to TSS") + + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, signedTx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt, "deposit failed") + + r.Logger.EVMReceipt(*receipt, "send to TSS") // due to the high block throughput in localnet, ZetaClient might catch up slowly with the blocks // to optimize block header proof test, this test is directly executed here on the first deposit instead of having a separate test if testHeader { - runner.ProveEthTransaction(receipt) + r.ProveEthTransaction(receipt) } return signedTx.Hash() } // SendEther sends ethers to the TSS on EVM -func (runner *E2ERunner) SendEther(_ ethcommon.Address, value *big.Int, data []byte) (*ethtypes.Transaction, error) { - evmClient := runner.EVMClient +func (r *E2ERunner) SendEther(_ ethcommon.Address, value *big.Int, data []byte) (*ethtypes.Transaction, error) { + evmClient := r.EVMClient - nonce, err := evmClient.PendingNonceAt(runner.Ctx, runner.DeployerAddress) + nonce, err := evmClient.PendingNonceAt(r.Ctx, r.DeployerAddress) if err != nil { return nil, err } gasLimit := uint64(30000) // in units - gasPrice, err := evmClient.SuggestGasPrice(runner.Ctx) + gasPrice, err := evmClient.SuggestGasPrice(r.Ctx) if err != nil { return nil, err } - tx := ethtypes.NewTransaction(nonce, runner.TSSAddress, value, gasLimit, gasPrice, data) - chainID, err := evmClient.ChainID(runner.Ctx) + tx := ethtypes.NewTransaction(nonce, r.TSSAddress, value, gasLimit, gasPrice, data) + chainID, err := evmClient.ChainID(r.Ctx) if err != nil { return nil, err } - deployerPrivkey, err := crypto.HexToECDSA(runner.DeployerPrivateKey) + deployerPrivkey, err := crypto.HexToECDSA(r.DeployerPrivateKey) if err != nil { return nil, err } @@ -191,7 +169,7 @@ func (runner *E2ERunner) SendEther(_ ethcommon.Address, value *big.Int, data []b if err != nil { return nil, err } - err = evmClient.SendTransaction(runner.Ctx, signedTx) + err = evmClient.SendTransaction(r.Ctx, signedTx) if err != nil { return nil, err } @@ -200,7 +178,7 @@ func (runner *E2ERunner) SendEther(_ ethcommon.Address, value *big.Int, data []b } // ProveEthTransaction proves an ETH transaction on ZetaChain -func (runner *E2ERunner) ProveEthTransaction(receipt *ethtypes.Receipt) { +func (r *E2ERunner) ProveEthTransaction(receipt *ethtypes.Receipt) { startTime := time.Now() txHash := receipt.TxHash @@ -209,23 +187,21 @@ func (runner *E2ERunner) ProveEthTransaction(receipt *ethtypes.Receipt) { // #nosec G701 test - always in range txIndex := int(receipt.TransactionIndex) - block, err := runner.EVMClient.BlockByHash(runner.Ctx, blockHash) - if err != nil { - panic(err) - } + block, err := r.EVMClient.BlockByHash(r.Ctx, blockHash) + require.NoError(r, err) + for { // check timeout - if time.Since(startTime) > blockHeaderETHTimeout { - panic("timeout waiting for block header") - } + reachedTimeout := time.Since(startTime) > blockHeaderETHTimeout + require.False(r, reachedTimeout, "timeout waiting for block header") - _, err := runner.LightclientClient.BlockHeader(runner.Ctx, &lightclienttypes.QueryGetBlockHeaderRequest{ + _, err := r.LightclientClient.BlockHeader(r.Ctx, &lightclienttypes.QueryGetBlockHeaderRequest{ BlockHash: blockHash.Bytes(), }) if err != nil { - runner.Logger.Info("WARN: block header not found; retrying... error: %s", err.Error()) + r.Logger.Info("WARN: block header not found; retrying... error: %s", err.Error()) } else { - runner.Logger.Info("OK: block header found") + r.Logger.Info("OK: block header found") break } @@ -233,42 +209,36 @@ func (runner *E2ERunner) ProveEthTransaction(receipt *ethtypes.Receipt) { } trie := ethereum.NewTrie(block.Transactions()) - if trie.Hash() != block.Header().TxHash { - panic("tx root hash & block tx root mismatch") - } + require.Equal(r, trie.Hash(), block.Header().TxHash, "tx root hash & block tx root mismatch") + txProof, err := trie.GenerateProof(txIndex) - if err != nil { - panic("error generating txProof") - } + require.NoError(r, err, "error generating txProof") + val, err := txProof.Verify(block.TxHash(), txIndex) - if err != nil { - panic("error verifying txProof") - } + require.NoError(r, err, "error verifying txProof") + var txx ethtypes.Transaction - err = txx.UnmarshalBinary(val) - if err != nil { - panic("error unmarshalling txProof'd tx") - } - res, err := runner.LightclientClient.Prove(runner.Ctx, &lightclienttypes.QueryProveRequest{ + require.NoError(r, txx.UnmarshalBinary(val)) + + res, err := r.LightclientClient.Prove(r.Ctx, &lightclienttypes.QueryProveRequest{ BlockHash: blockHash.Hex(), TxIndex: int64(txIndex), TxHash: txHash.Hex(), Proof: proofs.NewEthereumProof(txProof), ChainId: chains.GoerliLocalnet.ChainId, }) - if err != nil { - panic(err) - } - if !res.Valid { - panic("txProof invalid") // FIXME: don't do this in production - } - runner.Logger.Info("OK: txProof verified") + + // FIXME: @lumtis: don't do this in production + require.NoError(r, err) + require.True(r, res.Valid, "txProof invalid") + + r.Logger.Info("OK: txProof verified") } // AnvilMineBlocks mines blocks on Anvil localnet // the block time is provided in seconds // the method returns a function to stop the mining -func (runner *E2ERunner) AnvilMineBlocks(url string, blockTime int) (func(), error) { +func (r *E2ERunner) AnvilMineBlocks(url string, blockTime int) (func(), error) { stop := make(chan struct{}) client, err := rpc.Dial(url) @@ -286,7 +256,7 @@ func (runner *E2ERunner) AnvilMineBlocks(url string, blockTime int) (func(), err time.Sleep(time.Duration(blockTime) * time.Second) var result interface{} - err = client.CallContext(runner.Ctx, &result, "evm_mine") + err = client.CallContext(r.Ctx, &result, "evm_mine") if err != nil { log.Fatalf("Failed to mine a new block: %v", err) } diff --git a/e2e/runner/report.go b/e2e/runner/report.go index a25360a109..82bb263856 100644 --- a/e2e/runner/report.go +++ b/e2e/runner/report.go @@ -53,13 +53,13 @@ func (tr TestReports) String(prefix string) (string, error) { } // PrintTestReports prints the test reports -func (runner *E2ERunner) PrintTestReports(tr TestReports) { - runner.Logger.Print(" ---📈 E2E Test Report ---") +func (r *E2ERunner) PrintTestReports(tr TestReports) { + r.Logger.Print(" ---📈 E2E Test Report ---") table, err := tr.String("") if err != nil { - runner.Logger.Print("Error rendering test report: %s", err) + r.Logger.Print("Error rendering test report: %s", err) } - runner.Logger.PrintNoPrefix(table) + r.Logger.PrintNoPrefix(table) } // NetworkReport is a struct that contains the report for the network used after running e2e tests @@ -87,9 +87,9 @@ func (nr NetworkReport) Validate() error { } // GenerateNetworkReport generates a report for the network used after running e2e tests -func (runner *E2ERunner) GenerateNetworkReport() (NetworkReport, error) { +func (r *E2ERunner) GenerateNetworkReport() (NetworkReport, error) { // get the emissions pool balance - balanceRes, err := runner.BankClient.Balance(runner.Ctx, &banktypes.QueryBalanceRequest{ + balanceRes, err := r.BankClient.Balance(r.Ctx, &banktypes.QueryBalanceRequest{ Address: txserver.EmissionsPoolAddress, Denom: config.BaseDenom, }) @@ -101,13 +101,13 @@ func (runner *E2ERunner) GenerateNetworkReport() (NetworkReport, error) { // fetch the height and number of cctxs, this gives a better idea on the activity of the network // get the block height - blockRes, err := runner.ZEVMClient.BlockNumber(runner.Ctx) + blockRes, err := r.ZEVMClient.BlockNumber(r.Ctx) if err != nil { return NetworkReport{}, err } // get the number of cctxs - cctxsRes, err := runner.CctxClient.CctxAll(runner.Ctx, &crosschaintypes.QueryAllCctxRequest{}) + cctxsRes, err := r.CctxClient.CctxAll(r.Ctx, &crosschaintypes.QueryAllCctxRequest{}) if err != nil { return NetworkReport{}, err } @@ -121,10 +121,10 @@ func (runner *E2ERunner) GenerateNetworkReport() (NetworkReport, error) { } // PrintNetworkReport prints the network report -func (runner *E2ERunner) PrintNetworkReport(nr NetworkReport) { - runner.Logger.Print(" ---📈 Network Report ---") - runner.Logger.Print("Block Height: %d", nr.Height) - runner.Logger.Print("CCTX Processed: %d", nr.CctxCount) - runner.Logger.Print("Emissions Pool Balance: %sZETA", nr.EmissionsPoolBalance.Quo(sdkmath.NewIntFromUint64(1e18))) +func (r *E2ERunner) PrintNetworkReport(nr NetworkReport) { + r.Logger.Print(" ---📈 Network Report ---") + r.Logger.Print("Block Height: %d", nr.Height) + r.Logger.Print("CCTX Processed: %d", nr.CctxCount) + r.Logger.Print("Emissions Pool Balance: %sZETA", nr.EmissionsPoolBalance.Quo(sdkmath.NewIntFromUint64(1e18))) } diff --git a/e2e/runner/run.go b/e2e/runner/run.go index f24ff9d9f8..c05129b775 100644 --- a/e2e/runner/run.go +++ b/e2e/runner/run.go @@ -1,15 +1,13 @@ package runner import ( - "fmt" - "runtime" "time" ) // RunE2ETests runs a list of e2e tests -func (runner *E2ERunner) RunE2ETests(e2eTests []E2ETest) (err error) { +func (r *E2ERunner) RunE2ETests(e2eTests []E2ETest) (err error) { for _, e2eTest := range e2eTests { - if err := runner.RunE2ETest(e2eTest, true); err != nil { + if err := r.RunE2ETest(e2eTest, true); err != nil { return err } } @@ -17,64 +15,53 @@ func (runner *E2ERunner) RunE2ETests(e2eTests []E2ETest) (err error) { } // RunE2ETest runs a e2e test -func (runner *E2ERunner) RunE2ETest(e2eTest E2ETest, checkAccounting bool) (err error) { - // return an error on panic - // https://github.com/zeta-chain/node/issues/1500 - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("%s failed: %v, stack trace %s", e2eTest.Name, r, stack[:n]) - } - }() - +func (r *E2ERunner) RunE2ETest(e2eTest E2ETest, checkAccounting bool) error { startTime := time.Now() - runner.Logger.Print("⏳running - %s", e2eTest.Description) + r.Logger.Print("⏳running - %s", e2eTest.Description) // run e2e test, if args are not provided, use default args args := e2eTest.Args if len(args) == 0 { args = e2eTest.DefaultArgs() } - e2eTest.E2ETest(runner, args) + e2eTest.E2ETest(r, args) //check supplies if checkAccounting { - if err := runner.CheckZRC20ReserveAndSupply(); err != nil { + if err := r.CheckZRC20ReserveAndSupply(); err != nil { return err } } - runner.Logger.Print("✅ completed in %s - %s", time.Since(startTime), e2eTest.Description) + r.Logger.Print("✅ completed in %s - %s", time.Since(startTime), e2eTest.Description) - return err + return nil } // RunE2ETestsIntoReport runs a list of e2e tests by name in a list of e2e tests and returns a report // The function doesn't return an error, it returns a report with the error -func (runner *E2ERunner) RunE2ETestsIntoReport(e2eTests []E2ETest) (TestReports, error) { +func (r *E2ERunner) RunE2ETestsIntoReport(e2eTests []E2ETest) (TestReports, error) { // go through all tests reports := make(TestReports, 0, len(e2eTests)) for _, test := range e2eTests { // get info before test - balancesBefore, err := runner.GetAccountBalances(true) + balancesBefore, err := r.GetAccountBalances(true) if err != nil { return nil, err } timeBefore := time.Now() // run test - testErr := runner.RunE2ETest(test, false) + testErr := r.RunE2ETest(test, false) if testErr != nil { - runner.Logger.Print("test %s failed: %s", test.Name, testErr.Error()) + r.Logger.Print("test %s failed: %s", test.Name, testErr.Error()) } // wait 5 sec to make sure we get updated balances time.Sleep(5 * time.Second) // get info after test - balancesAfter, err := runner.GetAccountBalances(true) + balancesAfter, err := r.GetAccountBalances(true) if err != nil { return nil, err } diff --git a/e2e/runner/runner.go b/e2e/runner/runner.go index 2f2f0e49cc..e27de63247 100644 --- a/e2e/runner/runner.go +++ b/e2e/runner/runner.go @@ -13,6 +13,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/erc20custody.sol" zetaeth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zeta.eth.sol" @@ -28,6 +29,7 @@ import ( "github.com/zeta-chain/zetacore/e2e/contracts/erc20" "github.com/zeta-chain/zetacore/e2e/contracts/zevmswap" "github.com/zeta-chain/zetacore/e2e/txserver" + "github.com/zeta-chain/zetacore/e2e/utils" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" @@ -144,7 +146,6 @@ func NewE2ERunner( ) *E2ERunner { r := &E2ERunner{ Name: name, - Ctx: ctx, CtxCancel: ctxCancel, DeployerAddress: deployerAddress, @@ -165,91 +166,95 @@ func NewE2ERunner( Logger: logger, } + + r.Ctx = utils.WithTesting(ctx, r) + for _, opt := range opts { opt(r) } + return r } // CopyAddressesFrom copies addresses from another E2ETestRunner that initialized the contracts -func (runner *E2ERunner) CopyAddressesFrom(other *E2ERunner) (err error) { +func (r *E2ERunner) CopyAddressesFrom(other *E2ERunner) (err error) { // copy TSS address - runner.TSSAddress = other.TSSAddress - runner.BTCTSSAddress = other.BTCTSSAddress + r.TSSAddress = other.TSSAddress + r.BTCTSSAddress = other.BTCTSSAddress // copy addresses - runner.ZetaEthAddr = other.ZetaEthAddr - runner.ConnectorEthAddr = other.ConnectorEthAddr - runner.ERC20CustodyAddr = other.ERC20CustodyAddr - runner.ERC20Addr = other.ERC20Addr - runner.ERC20ZRC20Addr = other.ERC20ZRC20Addr - runner.ETHZRC20Addr = other.ETHZRC20Addr - runner.BTCZRC20Addr = other.BTCZRC20Addr - runner.UniswapV2FactoryAddr = other.UniswapV2FactoryAddr - runner.UniswapV2RouterAddr = other.UniswapV2RouterAddr - runner.ConnectorZEVMAddr = other.ConnectorZEVMAddr - runner.WZetaAddr = other.WZetaAddr - runner.EvmTestDAppAddr = other.EvmTestDAppAddr - runner.ZEVMSwapAppAddr = other.ZEVMSwapAppAddr - runner.ContextAppAddr = other.ContextAppAddr - runner.SystemContractAddr = other.SystemContractAddr - runner.ZevmTestDAppAddr = other.ZevmTestDAppAddr + r.ZetaEthAddr = other.ZetaEthAddr + r.ConnectorEthAddr = other.ConnectorEthAddr + r.ERC20CustodyAddr = other.ERC20CustodyAddr + r.ERC20Addr = other.ERC20Addr + r.ERC20ZRC20Addr = other.ERC20ZRC20Addr + r.ETHZRC20Addr = other.ETHZRC20Addr + r.BTCZRC20Addr = other.BTCZRC20Addr + r.UniswapV2FactoryAddr = other.UniswapV2FactoryAddr + r.UniswapV2RouterAddr = other.UniswapV2RouterAddr + r.ConnectorZEVMAddr = other.ConnectorZEVMAddr + r.WZetaAddr = other.WZetaAddr + r.EvmTestDAppAddr = other.EvmTestDAppAddr + r.ZEVMSwapAppAddr = other.ZEVMSwapAppAddr + r.ContextAppAddr = other.ContextAppAddr + r.SystemContractAddr = other.SystemContractAddr + r.ZevmTestDAppAddr = other.ZevmTestDAppAddr // create instances of contracts - runner.ZetaEth, err = zetaeth.NewZetaEth(runner.ZetaEthAddr, runner.EVMClient) + r.ZetaEth, err = zetaeth.NewZetaEth(r.ZetaEthAddr, r.EVMClient) if err != nil { return err } - runner.ConnectorEth, err = zetaconnectoreth.NewZetaConnectorEth(runner.ConnectorEthAddr, runner.EVMClient) + r.ConnectorEth, err = zetaconnectoreth.NewZetaConnectorEth(r.ConnectorEthAddr, r.EVMClient) if err != nil { return err } - runner.ERC20Custody, err = erc20custody.NewERC20Custody(runner.ERC20CustodyAddr, runner.EVMClient) + r.ERC20Custody, err = erc20custody.NewERC20Custody(r.ERC20CustodyAddr, r.EVMClient) if err != nil { return err } - runner.ERC20, err = erc20.NewERC20(runner.ERC20Addr, runner.EVMClient) + r.ERC20, err = erc20.NewERC20(r.ERC20Addr, r.EVMClient) if err != nil { return err } - runner.ERC20ZRC20, err = zrc20.NewZRC20(runner.ERC20ZRC20Addr, runner.ZEVMClient) + r.ERC20ZRC20, err = zrc20.NewZRC20(r.ERC20ZRC20Addr, r.ZEVMClient) if err != nil { return err } - runner.ETHZRC20, err = zrc20.NewZRC20(runner.ETHZRC20Addr, runner.ZEVMClient) + r.ETHZRC20, err = zrc20.NewZRC20(r.ETHZRC20Addr, r.ZEVMClient) if err != nil { return err } - runner.BTCZRC20, err = zrc20.NewZRC20(runner.BTCZRC20Addr, runner.ZEVMClient) + r.BTCZRC20, err = zrc20.NewZRC20(r.BTCZRC20Addr, r.ZEVMClient) if err != nil { return err } - runner.UniswapV2Factory, err = uniswapv2factory.NewUniswapV2Factory(runner.UniswapV2FactoryAddr, runner.ZEVMClient) + r.UniswapV2Factory, err = uniswapv2factory.NewUniswapV2Factory(r.UniswapV2FactoryAddr, r.ZEVMClient) if err != nil { return err } - runner.UniswapV2Router, err = uniswapv2router.NewUniswapV2Router02(runner.UniswapV2RouterAddr, runner.ZEVMClient) + r.UniswapV2Router, err = uniswapv2router.NewUniswapV2Router02(r.UniswapV2RouterAddr, r.ZEVMClient) if err != nil { return err } - runner.ConnectorZEVM, err = connectorzevm.NewZetaConnectorZEVM(runner.ConnectorZEVMAddr, runner.ZEVMClient) + r.ConnectorZEVM, err = connectorzevm.NewZetaConnectorZEVM(r.ConnectorZEVMAddr, r.ZEVMClient) if err != nil { return err } - runner.WZeta, err = wzeta.NewWETH9(runner.WZetaAddr, runner.ZEVMClient) + r.WZeta, err = wzeta.NewWETH9(r.WZetaAddr, r.ZEVMClient) if err != nil { return err } - runner.ZEVMSwapApp, err = zevmswap.NewZEVMSwapApp(runner.ZEVMSwapAppAddr, runner.ZEVMClient) + r.ZEVMSwapApp, err = zevmswap.NewZEVMSwapApp(r.ZEVMSwapAppAddr, r.ZEVMClient) if err != nil { return err } - runner.ContextApp, err = contextapp.NewContextApp(runner.ContextAppAddr, runner.ZEVMClient) + r.ContextApp, err = contextapp.NewContextApp(r.ContextAppAddr, r.ZEVMClient) if err != nil { return err } - runner.SystemContract, err = systemcontract.NewSystemContract(runner.SystemContractAddr, runner.ZEVMClient) + r.SystemContract, err = systemcontract.NewSystemContract(r.SystemContractAddr, r.ZEVMClient) if err != nil { return err } @@ -257,50 +262,55 @@ func (runner *E2ERunner) CopyAddressesFrom(other *E2ERunner) (err error) { } // Lock locks the mutex -func (runner *E2ERunner) Lock() { - runner.mutex.Lock() +func (r *E2ERunner) Lock() { + r.mutex.Lock() } // Unlock unlocks the mutex -func (runner *E2ERunner) Unlock() { - runner.mutex.Unlock() +func (r *E2ERunner) Unlock() { + r.mutex.Unlock() } // PrintContractAddresses prints the addresses of the contracts // the printed contracts are grouped in a zevm and evm section // there is a padding used to print the addresses at the same position -func (runner *E2ERunner) PrintContractAddresses() { +func (r *E2ERunner) PrintContractAddresses() { // zevm contracts - runner.Logger.Print(" --- 📜zEVM contracts ---") - runner.Logger.Print("SystemContract: %s", runner.SystemContractAddr.Hex()) - runner.Logger.Print("ETHZRC20: %s", runner.ETHZRC20Addr.Hex()) - runner.Logger.Print("ERC20ZRC20: %s", runner.ERC20ZRC20Addr.Hex()) - runner.Logger.Print("BTCZRC20: %s", runner.BTCZRC20Addr.Hex()) - runner.Logger.Print("UniswapFactory: %s", runner.UniswapV2FactoryAddr.Hex()) - runner.Logger.Print("UniswapRouter: %s", runner.UniswapV2RouterAddr.Hex()) - runner.Logger.Print("ConnectorZEVM: %s", runner.ConnectorZEVMAddr.Hex()) - runner.Logger.Print("WZeta: %s", runner.WZetaAddr.Hex()) - - runner.Logger.Print("ZEVMSwapApp: %s", runner.ZEVMSwapAppAddr.Hex()) - runner.Logger.Print("ContextApp: %s", runner.ContextAppAddr.Hex()) - runner.Logger.Print("TestDappZEVM: %s", runner.ZevmTestDAppAddr.Hex()) + r.Logger.Print(" --- 📜zEVM contracts ---") + r.Logger.Print("SystemContract: %s", r.SystemContractAddr.Hex()) + r.Logger.Print("ETHZRC20: %s", r.ETHZRC20Addr.Hex()) + r.Logger.Print("ERC20ZRC20: %s", r.ERC20ZRC20Addr.Hex()) + r.Logger.Print("BTCZRC20: %s", r.BTCZRC20Addr.Hex()) + r.Logger.Print("UniswapFactory: %s", r.UniswapV2FactoryAddr.Hex()) + r.Logger.Print("UniswapRouter: %s", r.UniswapV2RouterAddr.Hex()) + r.Logger.Print("ConnectorZEVM: %s", r.ConnectorZEVMAddr.Hex()) + r.Logger.Print("WZeta: %s", r.WZetaAddr.Hex()) + + r.Logger.Print("ZEVMSwapApp: %s", r.ZEVMSwapAppAddr.Hex()) + r.Logger.Print("ContextApp: %s", r.ContextAppAddr.Hex()) + r.Logger.Print("TestDappZEVM: %s", r.ZevmTestDAppAddr.Hex()) // evm contracts - runner.Logger.Print(" --- 📜EVM contracts ---") - runner.Logger.Print("ZetaEth: %s", runner.ZetaEthAddr.Hex()) - runner.Logger.Print("ConnectorEth: %s", runner.ConnectorEthAddr.Hex()) - runner.Logger.Print("ERC20Custody: %s", runner.ERC20CustodyAddr.Hex()) - runner.Logger.Print("ERC20: %s", runner.ERC20Addr.Hex()) - runner.Logger.Print("TestDappEVM: %s", runner.EvmTestDAppAddr.Hex()) + r.Logger.Print(" --- 📜EVM contracts ---") + r.Logger.Print("ZetaEth: %s", r.ZetaEthAddr.Hex()) + r.Logger.Print("ConnectorEth: %s", r.ConnectorEthAddr.Hex()) + r.Logger.Print("ERC20Custody: %s", r.ERC20CustodyAddr.Hex()) + r.Logger.Print("ERC20: %s", r.ERC20Addr.Hex()) + r.Logger.Print("TestDappEVM: %s", r.EvmTestDAppAddr.Hex()) } // Errorf logs an error message. Mimics the behavior of testing.T.Errorf -func (runner *E2ERunner) Errorf(format string, args ...any) { - runner.Logger.Error(format, args...) +func (r *E2ERunner) Errorf(format string, args ...any) { + r.Logger.Error(format, args...) } // FailNow implemented to mimic the behavior of testing.T.FailNow -func (runner *E2ERunner) FailNow() { - runner.Logger.Error("Test failed") +func (r *E2ERunner) FailNow() { + r.Logger.Error("Test failed") + r.CtxCancel() os.Exit(1) } + +func (r *E2ERunner) requireTxSuccessful(receipt *ethtypes.Receipt, msgAndArgs ...any) { + utils.RequireTxSuccessful(r, receipt, msgAndArgs...) +} diff --git a/e2e/runner/setup_bitcoin.go b/e2e/runner/setup_bitcoin.go index 8e39d0143e..92a7eac428 100644 --- a/e2e/runner/setup_bitcoin.go +++ b/e2e/runner/setup_bitcoin.go @@ -2,7 +2,6 @@ package runner import ( "encoding/hex" - "strings" "time" "github.com/btcsuite/btcd/btcec" @@ -11,58 +10,50 @@ import ( "github.com/stretchr/testify/require" ) -func (runner *E2ERunner) SetupBitcoinAccount(initNetwork bool) { - runner.Logger.Print("⚙️ setting up Bitcoin account") +func (r *E2ERunner) SetupBitcoinAccount(initNetwork bool) { + r.Logger.Print("⚙️ setting up Bitcoin account") startTime := time.Now() defer func() { - runner.Logger.Print("✅ Bitcoin account setup in %s\n", time.Since(startTime)) + r.Logger.Print("✅ Bitcoin account setup in %s\n", time.Since(startTime)) }() - _, err := runner.BtcRPCClient.CreateWallet(runner.Name, rpcclient.WithCreateWalletBlank()) + _, err := r.BtcRPCClient.CreateWallet(r.Name, rpcclient.WithCreateWalletBlank()) if err != nil { - if !strings.Contains(err.Error(), "Database already exists") { - panic(err) - } + require.ErrorContains(r, err, "Database already exists") } - runner.SetBtcAddress(runner.Name, true) + r.SetBtcAddress(r.Name, true) if initNetwork { // import the TSS address - err = runner.BtcRPCClient.ImportAddress(runner.BTCTSSAddress.EncodeAddress()) - if err != nil { - panic(err) - } + err = r.BtcRPCClient.ImportAddress(r.BTCTSSAddress.EncodeAddress()) + require.NoError(r, err) // mine some blocks to get some BTC into the deployer address - _, err = runner.GenerateToAddressIfLocalBitcoin(101, runner.BTCDeployerAddress) - if err != nil { - panic(err) - } - - _, err = runner.GenerateToAddressIfLocalBitcoin(4, runner.BTCDeployerAddress) - if err != nil { - panic(err) - } + _, err = r.GenerateToAddressIfLocalBitcoin(101, r.BTCDeployerAddress) + require.NoError(r, err) + + _, err = r.GenerateToAddressIfLocalBitcoin(4, r.BTCDeployerAddress) + require.NoError(r, err) } } // GetBtcAddress returns the BTC address of the deployer from its EVM private key -func (runner *E2ERunner) GetBtcAddress() (string, string, error) { - skBytes, err := hex.DecodeString(runner.DeployerPrivateKey) +func (r *E2ERunner) GetBtcAddress() (string, string, error) { + skBytes, err := hex.DecodeString(r.DeployerPrivateKey) if err != nil { return "", "", err } sk, _ := btcec.PrivKeyFromBytes(btcec.S256(), skBytes) - privkeyWIF, err := btcutil.NewWIF(sk, runner.BitcoinParams, true) + privkeyWIF, err := btcutil.NewWIF(sk, r.BitcoinParams, true) if err != nil { return "", "", err } address, err := btcutil.NewAddressWitnessPubKeyHash( btcutil.Hash160(privkeyWIF.SerializePubKey()), - runner.BitcoinParams, + r.BitcoinParams, ) if err != nil { return "", "", err @@ -73,30 +64,24 @@ func (runner *E2ERunner) GetBtcAddress() (string, string, error) { } // SetBtcAddress imports the deployer's private key into the Bitcoin node -func (runner *E2ERunner) SetBtcAddress(name string, rescan bool) { - skBytes, err := hex.DecodeString(runner.DeployerPrivateKey) - if err != nil { - panic(err) - } +func (r *E2ERunner) SetBtcAddress(name string, rescan bool) { + skBytes, err := hex.DecodeString(r.DeployerPrivateKey) + require.NoError(r, err) sk, _ := btcec.PrivKeyFromBytes(btcec.S256(), skBytes) - privkeyWIF, err := btcutil.NewWIF(sk, runner.BitcoinParams, true) - if err != nil { - panic(err) - } + privkeyWIF, err := btcutil.NewWIF(sk, r.BitcoinParams, true) + require.NoError(r, err) if rescan { - err := runner.BtcRPCClient.ImportPrivKeyRescan(privkeyWIF, name, true) - require.NoError(runner, err, "failed to execute ImportPrivKeyRescan") + err := r.BtcRPCClient.ImportPrivKeyRescan(privkeyWIF, name, true) + require.NoError(r, err, "failed to execute ImportPrivKeyRescan") } - runner.BTCDeployerAddress, err = btcutil.NewAddressWitnessPubKeyHash( + r.BTCDeployerAddress, err = btcutil.NewAddressWitnessPubKeyHash( btcutil.Hash160(privkeyWIF.PrivKey.PubKey().SerializeCompressed()), - runner.BitcoinParams, + r.BitcoinParams, ) - if err != nil { - panic(err) - } + require.NoError(r, err) - runner.Logger.Info("BTCDeployerAddress: %s", runner.BTCDeployerAddress.EncodeAddress()) + r.Logger.Info("BTCDeployerAddress: %s", r.BTCDeployerAddress.EncodeAddress()) } diff --git a/e2e/runner/setup_evm.go b/e2e/runner/setup_evm.go index 2bc0aeb70d..ff5b2e0ddc 100644 --- a/e2e/runner/setup_evm.go +++ b/e2e/runner/setup_evm.go @@ -5,6 +5,8 @@ import ( "time" ethcommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/erc20custody.sol" zetaeth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zeta.eth.sol" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" @@ -21,181 +23,148 @@ const ( ) // SetEVMContractsFromConfig set EVM contracts for e2e test from the config -func (runner *E2ERunner) SetEVMContractsFromConfig() { +func (r *E2ERunner) SetEVMContractsFromConfig() { conf, err := config.ReadConfig(ContractsConfigFile) - if err != nil { - panic(err) - } + require.NoError(r, err) // Set ZetaEthAddr - runner.ZetaEthAddr = ethcommon.HexToAddress(conf.Contracts.EVM.ZetaEthAddress) - runner.ZetaEth, err = zetaeth.NewZetaEth(runner.ZetaEthAddr, runner.EVMClient) - if err != nil { - panic(err) - } + r.ZetaEthAddr = ethcommon.HexToAddress(conf.Contracts.EVM.ZetaEthAddress) + r.ZetaEth, err = zetaeth.NewZetaEth(r.ZetaEthAddr, r.EVMClient) + require.NoError(r, err) // Set ConnectorEthAddr - runner.ConnectorEthAddr = ethcommon.HexToAddress(conf.Contracts.EVM.ConnectorEthAddr) - runner.ConnectorEth, err = zetaconnectoreth.NewZetaConnectorEth(runner.ConnectorEthAddr, runner.EVMClient) - if err != nil { - panic(err) - } + r.ConnectorEthAddr = ethcommon.HexToAddress(conf.Contracts.EVM.ConnectorEthAddr) + r.ConnectorEth, err = zetaconnectoreth.NewZetaConnectorEth(r.ConnectorEthAddr, r.EVMClient) + require.NoError(r, err) } // SetupEVM setup contracts on EVM for e2e test -func (runner *E2ERunner) SetupEVM(contractsDeployed bool, whitelistERC20 bool) { - runner.Logger.Print("⚙️ setting up EVM network") +func (r *E2ERunner) SetupEVM(contractsDeployed bool, whitelistERC20 bool) { + r.Logger.Print("⚙️ setting up EVM network") startTime := time.Now() defer func() { - runner.Logger.Info("EVM setup took %s\n", time.Since(startTime)) + r.Logger.Info("EVM setup took %s\n", time.Since(startTime)) }() // TODO: put this logic outside of this function // We use this config to be consistent with the old implementation // https://github.com/zeta-chain/node-private/issues/41 if contractsDeployed { - runner.SetEVMContractsFromConfig() + r.SetEVMContractsFromConfig() return } conf := config.DefaultConfig() - runner.Logger.InfoLoud("Deploy ZetaETH ConnectorETH ERC20Custody ERC20\n") + r.Logger.InfoLoud("Deploy ZetaETH ConnectorETH ERC20Custody ERC20\n") // donate to the TSS address to avoid account errors because deploying gas token ZRC20 will automatically mint // gas token on ZetaChain to initialize the pool - txDonation, err := runner.SendEther( - runner.TSSAddress, - big.NewInt(101000000000000000), - []byte(constant.DonationMessage), - ) - if err != nil { - panic(err) - } + txDonation, err := r.SendEther(r.TSSAddress, big.NewInt(101000000000000000), []byte(constant.DonationMessage)) + require.NoError(r, err) - runner.Logger.Info("Deploying ZetaEth contract") + r.Logger.Info("Deploying ZetaEth contract") zetaEthAddr, txZetaEth, ZetaEth, err := zetaeth.DeployZetaEth( - runner.EVMAuth, - runner.EVMClient, - runner.DeployerAddress, + r.EVMAuth, + r.EVMClient, + r.DeployerAddress, big.NewInt(21_000_000_000), ) - if err != nil { - panic(err) - } - runner.ZetaEth = ZetaEth - runner.ZetaEthAddr = zetaEthAddr + require.NoError(r, err) + + r.ZetaEth = ZetaEth + r.ZetaEthAddr = zetaEthAddr conf.Contracts.EVM.ZetaEthAddress = zetaEthAddr.String() - runner.Logger.Info("ZetaEth contract address: %s, tx hash: %s", zetaEthAddr.Hex(), zetaEthAddr.Hash().Hex()) + r.Logger.Info("ZetaEth contract address: %s, tx hash: %s", zetaEthAddr.Hex(), zetaEthAddr.Hash().Hex()) - runner.Logger.Info("Deploying ZetaConnectorEth contract") + r.Logger.Info("Deploying ZetaConnectorEth contract") connectorEthAddr, txConnector, ConnectorEth, err := zetaconnectoreth.DeployZetaConnectorEth( - runner.EVMAuth, - runner.EVMClient, + r.EVMAuth, + r.EVMClient, zetaEthAddr, - runner.TSSAddress, - runner.DeployerAddress, - runner.DeployerAddress, + r.TSSAddress, + r.DeployerAddress, + r.DeployerAddress, ) - if err != nil { - panic(err) - } - runner.ConnectorEth = ConnectorEth - runner.ConnectorEthAddr = connectorEthAddr + require.NoError(r, err) + + r.ConnectorEth = ConnectorEth + r.ConnectorEthAddr = connectorEthAddr conf.Contracts.EVM.ConnectorEthAddr = connectorEthAddr.String() - runner.Logger.Info( + r.Logger.Info( "ZetaConnectorEth contract address: %s, tx hash: %s", connectorEthAddr.Hex(), txConnector.Hash().Hex(), ) - runner.Logger.Info("Deploying ERC20Custody contract") + r.Logger.Info("Deploying ERC20Custody contract") erc20CustodyAddr, txCustody, ERC20Custody, err := erc20custody.DeployERC20Custody( - runner.EVMAuth, - runner.EVMClient, - runner.DeployerAddress, - runner.DeployerAddress, + r.EVMAuth, + r.EVMClient, + r.DeployerAddress, + r.DeployerAddress, big.NewInt(0), big.NewInt(1e18), ethcommon.HexToAddress("0x"), ) - if err != nil { - panic(err) - } - runner.ERC20CustodyAddr = erc20CustodyAddr - runner.ERC20Custody = ERC20Custody - runner.Logger.Info("ERC20Custody contract address: %s, tx hash: %s", erc20CustodyAddr.Hex(), txCustody.Hash().Hex()) - - runner.Logger.Info("Deploying ERC20 contract") - erc20Addr, txERC20, erc20, err := erc20.DeployERC20(runner.EVMAuth, runner.EVMClient, "TESTERC20", "TESTERC20", 6) - if err != nil { - panic(err) - } - runner.ERC20 = erc20 - runner.ERC20Addr = erc20Addr - runner.Logger.Info("ERC20 contract address: %s, tx hash: %s", erc20Addr.Hex(), txERC20.Hash().Hex()) + require.NoError(r, err) + + r.ERC20CustodyAddr = erc20CustodyAddr + r.ERC20Custody = ERC20Custody + r.Logger.Info("ERC20Custody contract address: %s, tx hash: %s", erc20CustodyAddr.Hex(), txCustody.Hash().Hex()) + + r.Logger.Info("Deploying ERC20 contract") + erc20Addr, txERC20, erc20, err := erc20.DeployERC20(r.EVMAuth, r.EVMClient, "TESTERC20", "TESTERC20", 6) + require.NoError(r, err) + + r.ERC20 = erc20 + r.ERC20Addr = erc20Addr + r.Logger.Info("ERC20 contract address: %s, tx hash: %s", erc20Addr.Hex(), txERC20.Hash().Hex()) // deploy TestDApp contract appAddr, txApp, _, err := testdapp.DeployTestDApp( - runner.EVMAuth, - runner.EVMClient, - runner.ConnectorEthAddr, - runner.ZetaEthAddr, + r.EVMAuth, + r.EVMClient, + r.ConnectorEthAddr, + r.ZetaEthAddr, ) - if err != nil { - panic(err) + require.NoError(r, err) + + r.EvmTestDAppAddr = appAddr + r.Logger.Info("TestDApp contract address: %s, tx hash: %s", appAddr.Hex(), txApp.Hash().Hex()) + + ensureTxReceipt := func(tx *ethtypes.Transaction, failMessage string) { + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt, failMessage) } - runner.EvmTestDAppAddr = appAddr - runner.Logger.Info("TestDApp contract address: %s, tx hash: %s", appAddr.Hex(), txApp.Hash().Hex()) // check contract deployment receipt - if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txDonation, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { - panic("EVM donation tx failed") - } - if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txZetaEth, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { - panic("ZetaEth deployment failed") - } - if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txConnector, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { - panic("ZetaConnectorEth deployment failed") - } - if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txCustody, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { - panic("ERC20Custody deployment failed") - } - if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txERC20, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { - panic("ERC20 deployment failed") - } - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txApp, runner.Logger, runner.ReceiptTimeout) - if receipt.Status != 1 { - panic("TestDApp deployment failed") - } + ensureTxReceipt(txDonation, "EVM donation tx failed") + ensureTxReceipt(txZetaEth, "ZetaEth deployment failed") + ensureTxReceipt(txConnector, "ZetaConnectorEth deployment failed") + ensureTxReceipt(txCustody, "ERC20Custody deployment failed") + ensureTxReceipt(txERC20, "ERC20 deployment failed") + ensureTxReceipt(txApp, "TestDApp deployment failed") // initialize custody contract - runner.Logger.Info("Whitelist ERC20") + r.Logger.Info("Whitelist ERC20") if whitelistERC20 { - txWhitelist, err := ERC20Custody.Whitelist(runner.EVMAuth, erc20Addr) - if err != nil { - panic(err) - } - if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txWhitelist, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { - panic("ERC20 whitelist failed") - } + txWhitelist, err := ERC20Custody.Whitelist(r.EVMAuth, erc20Addr) + require.NoError(r, err) + ensureTxReceipt(txWhitelist, "ERC20 whitelist failed") } - runner.Logger.Info("Set TSS address") - txCustody, err = ERC20Custody.UpdateTSSAddress(runner.EVMAuth, runner.TSSAddress) - if err != nil { - panic(err) - } - if receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, txCustody, runner.Logger, runner.ReceiptTimeout); receipt.Status != 1 { - panic("ERC20 update TSS address failed") - } - runner.Logger.Info("TSS set receipt tx hash: %s", txCustody.Hash().Hex()) + r.Logger.Info("Set TSS address") + txCustody, err = ERC20Custody.UpdateTSSAddress(r.EVMAuth, r.TSSAddress) + require.NoError(r, err) + + ensureTxReceipt(txCustody, "ERC20 update TSS address failed") + + r.Logger.Info("TSS set receipt tx hash: %s", txCustody.Hash().Hex()) // save config containing contract addresses // TODO: put this logic outside of this function in a general config // We use this config to be consistent with the old implementation // https://github.com/zeta-chain/node-private/issues/41 - if err := config.WriteConfig(ContractsConfigFile, conf); err != nil { - panic(err) - } + require.NoError(r, config.WriteConfig(ContractsConfigFile, conf)) } diff --git a/e2e/runner/setup_zeta.go b/e2e/runner/setup_zeta.go index ac24c02de2..ef3acbd64b 100644 --- a/e2e/runner/setup_zeta.go +++ b/e2e/runner/setup_zeta.go @@ -7,6 +7,7 @@ import ( "github.com/btcsuite/btcutil" "github.com/ethereum/go-ethereum/accounts/abi/bind" ethcommon "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/systemcontract.sol" "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/wzeta.sol" connectorzevm "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zetaconnectorzevm.sol" @@ -29,23 +30,23 @@ import ( var EmissionsPoolFunding = big.NewInt(0).Mul(big.NewInt(1e18), big.NewInt(2e7)) // SetTSSAddresses set TSS addresses from information queried from ZetaChain -func (runner *E2ERunner) SetTSSAddresses() error { - runner.Logger.Print("⚙️ setting up TSS address") +func (r *E2ERunner) SetTSSAddresses() error { + r.Logger.Print("⚙️ setting up TSS address") - btcChainID, err := chains.GetBTCChainIDFromChainParams(runner.BitcoinParams) + btcChainID, err := chains.GetBTCChainIDFromChainParams(r.BitcoinParams) if err != nil { return err } res := &observertypes.QueryGetTssAddressResponse{} for i := 0; ; i++ { - res, err = runner.ObserverClient.GetTssAddress(runner.Ctx, &observertypes.QueryGetTssAddressRequest{ + res, err = r.ObserverClient.GetTssAddress(r.Ctx, &observertypes.QueryGetTssAddressRequest{ BitcoinChainId: btcChainID, }) if err != nil { if i%10 == 0 { - runner.Logger.Info("ObserverClient.TSS error %s", err.Error()) - runner.Logger.Info("TSS not ready yet, waiting for TSS to be appear in zetacore network...") + r.Logger.Info("ObserverClient.TSS error %s", err.Error()) + r.Logger.Info("TSS not ready yet, waiting for TSS to be appear in zetacore network...") } time.Sleep(1 * time.Second) continue @@ -55,199 +56,165 @@ func (runner *E2ERunner) SetTSSAddresses() error { tssAddress := ethcommon.HexToAddress(res.Eth) - btcTSSAddress, err := btcutil.DecodeAddress(res.Btc, runner.BitcoinParams) - if err != nil { - panic(err) - } + btcTSSAddress, err := btcutil.DecodeAddress(res.Btc, r.BitcoinParams) + require.NoError(r, err) - runner.TSSAddress = tssAddress - runner.BTCTSSAddress = btcTSSAddress + r.TSSAddress = tssAddress + r.BTCTSSAddress = btcTSSAddress return nil } // SetZEVMContracts set contracts for the ZEVM -func (runner *E2ERunner) SetZEVMContracts() { - runner.Logger.Print("⚙️ deploying system contracts and ZRC20s on ZEVM") +func (r *E2ERunner) SetZEVMContracts() { + r.Logger.Print("⚙️ deploying system contracts and ZRC20s on ZEVM") startTime := time.Now() defer func() { - runner.Logger.Info("System contract deployments took %s\n", time.Since(startTime)) + r.Logger.Info("System contract deployments took %s\n", time.Since(startTime)) }() // deploy system contracts and ZRC20 contracts on ZetaChain - uniswapV2FactoryAddr, uniswapV2RouterAddr, zevmConnectorAddr, wzetaAddr, erc20zrc20Addr, err := runner.ZetaTxServer.DeploySystemContractsAndZRC20( + uniswapV2FactoryAddr, uniswapV2RouterAddr, zevmConnectorAddr, wzetaAddr, erc20zrc20Addr, err := r.ZetaTxServer.DeploySystemContractsAndZRC20( e2eutils.FungibleAdminName, - runner.ERC20Addr.Hex(), + r.ERC20Addr.Hex(), ) - if err != nil { - panic(err) - } + require.NoError(r, err) // Set ERC20ZRC20Addr - runner.ERC20ZRC20Addr = ethcommon.HexToAddress(erc20zrc20Addr) - runner.ERC20ZRC20, err = zrc20.NewZRC20(runner.ERC20ZRC20Addr, runner.ZEVMClient) - if err != nil { - panic(err) - } + r.ERC20ZRC20Addr = ethcommon.HexToAddress(erc20zrc20Addr) + r.ERC20ZRC20, err = zrc20.NewZRC20(r.ERC20ZRC20Addr, r.ZEVMClient) + require.NoError(r, err) // UniswapV2FactoryAddr - runner.UniswapV2FactoryAddr = ethcommon.HexToAddress(uniswapV2FactoryAddr) - runner.UniswapV2Factory, err = uniswapv2factory.NewUniswapV2Factory(runner.UniswapV2FactoryAddr, runner.ZEVMClient) - if err != nil { - panic(err) - } + r.UniswapV2FactoryAddr = ethcommon.HexToAddress(uniswapV2FactoryAddr) + r.UniswapV2Factory, err = uniswapv2factory.NewUniswapV2Factory(r.UniswapV2FactoryAddr, r.ZEVMClient) + require.NoError(r, err) // UniswapV2RouterAddr - runner.UniswapV2RouterAddr = ethcommon.HexToAddress(uniswapV2RouterAddr) - runner.UniswapV2Router, err = uniswapv2router.NewUniswapV2Router02(runner.UniswapV2RouterAddr, runner.ZEVMClient) - if err != nil { - panic(err) - } + r.UniswapV2RouterAddr = ethcommon.HexToAddress(uniswapV2RouterAddr) + r.UniswapV2Router, err = uniswapv2router.NewUniswapV2Router02(r.UniswapV2RouterAddr, r.ZEVMClient) + require.NoError(r, err) // ZevmConnectorAddr - runner.ConnectorZEVMAddr = ethcommon.HexToAddress(zevmConnectorAddr) - runner.ConnectorZEVM, err = connectorzevm.NewZetaConnectorZEVM(runner.ConnectorZEVMAddr, runner.ZEVMClient) - if err != nil { - panic(err) - } + r.ConnectorZEVMAddr = ethcommon.HexToAddress(zevmConnectorAddr) + r.ConnectorZEVM, err = connectorzevm.NewZetaConnectorZEVM(r.ConnectorZEVMAddr, r.ZEVMClient) + require.NoError(r, err) // WZetaAddr - runner.WZetaAddr = ethcommon.HexToAddress(wzetaAddr) - runner.WZeta, err = wzeta.NewWETH9(runner.WZetaAddr, runner.ZEVMClient) - if err != nil { - panic(err) - } + r.WZetaAddr = ethcommon.HexToAddress(wzetaAddr) + r.WZeta, err = wzeta.NewWETH9(r.WZetaAddr, r.ZEVMClient) + require.NoError(r, err) // query system contract address from the chain - systemContractRes, err := runner.FungibleClient.SystemContract( - runner.Ctx, + systemContractRes, err := r.FungibleClient.SystemContract( + r.Ctx, &fungibletypes.QueryGetSystemContractRequest{}, ) - if err != nil { - panic(err) - } - systemContractAddr := ethcommon.HexToAddress(systemContractRes.SystemContract.SystemContract) + require.NoError(r, err) - SystemContract, err := systemcontract.NewSystemContract( + systemContractAddr := ethcommon.HexToAddress(systemContractRes.SystemContract.SystemContract) + systemContract, err := systemcontract.NewSystemContract( systemContractAddr, - runner.ZEVMClient, + r.ZEVMClient, ) - if err != nil { - panic(err) - } + require.NoError(r, err) - runner.SystemContract = SystemContract - runner.SystemContractAddr = systemContractAddr + r.SystemContract = systemContract + r.SystemContractAddr = systemContractAddr // set ZRC20 contracts - runner.SetupETHZRC20() - runner.SetupBTCZRC20() + r.SetupETHZRC20() + r.SetupBTCZRC20() // deploy TestDApp contract on zEVM appAddr, txApp, _, err := testdapp.DeployTestDApp( - runner.ZEVMAuth, - runner.ZEVMClient, - runner.ConnectorZEVMAddr, - runner.WZetaAddr, + r.ZEVMAuth, + r.ZEVMClient, + r.ConnectorZEVMAddr, + r.WZetaAddr, ) - if err != nil { - panic(err) - } - runner.ZevmTestDAppAddr = appAddr - runner.Logger.Info("TestDApp Zevm contract address: %s, tx hash: %s", appAddr.Hex(), txApp.Hash().Hex()) + require.NoError(r, err) + + r.ZevmTestDAppAddr = appAddr + r.Logger.Info("TestDApp Zevm contract address: %s, tx hash: %s", appAddr.Hex(), txApp.Hash().Hex()) // deploy ZEVMSwapApp and ContextApp zevmSwapAppAddr, txZEVMSwapApp, zevmSwapApp, err := zevmswap.DeployZEVMSwapApp( - runner.ZEVMAuth, - runner.ZEVMClient, - runner.UniswapV2RouterAddr, - runner.SystemContractAddr, + r.ZEVMAuth, + r.ZEVMClient, + r.UniswapV2RouterAddr, + r.SystemContractAddr, ) - if err != nil { - panic(err) - } + require.NoError(r, err) - contextAppAddr, txContextApp, contextApp, err := contextapp.DeployContextApp(runner.ZEVMAuth, runner.ZEVMClient) - if err != nil { - panic(err) - } + contextAppAddr, txContextApp, contextApp, err := contextapp.DeployContextApp(r.ZEVMAuth, r.ZEVMClient) + require.NoError(r, err) receipt := e2eutils.MustWaitForTxReceipt( - runner.Ctx, - runner.ZEVMClient, + r.Ctx, + r.ZEVMClient, txZEVMSwapApp, - runner.Logger, - runner.ReceiptTimeout, + r.Logger, + r.ReceiptTimeout, ) - if receipt.Status != 1 { - panic("ZEVMSwapApp deployment failed") - } - runner.ZEVMSwapAppAddr = zevmSwapAppAddr - runner.ZEVMSwapApp = zevmSwapApp + r.requireTxSuccessful(receipt, "ZEVMSwapApp deployment failed") + + r.ZEVMSwapAppAddr = zevmSwapAppAddr + r.ZEVMSwapApp = zevmSwapApp receipt = e2eutils.MustWaitForTxReceipt( - runner.Ctx, - runner.ZEVMClient, + r.Ctx, + r.ZEVMClient, txContextApp, - runner.Logger, - runner.ReceiptTimeout, + r.Logger, + r.ReceiptTimeout, ) - if receipt.Status != 1 { - panic("ContextApp deployment failed") - } - runner.ContextAppAddr = contextAppAddr - runner.ContextApp = contextApp + r.requireTxSuccessful(receipt, "ContextApp deployment failed") + r.ContextAppAddr = contextAppAddr + r.ContextApp = contextApp } // SetupETHZRC20 sets up the ETH ZRC20 in the runner from the values queried from the chain -func (runner *E2ERunner) SetupETHZRC20() { - ethZRC20Addr, err := runner.SystemContract.GasCoinZRC20ByChainId( +func (r *E2ERunner) SetupETHZRC20() { + ethZRC20Addr, err := r.SystemContract.GasCoinZRC20ByChainId( &bind.CallOpts{}, big.NewInt(chains.GoerliLocalnet.ChainId), ) - if err != nil { - panic(err) - } - if (ethZRC20Addr == ethcommon.Address{}) { - panic("eth zrc20 not found") - } - runner.ETHZRC20Addr = ethZRC20Addr - ethZRC20, err := zrc20.NewZRC20(ethZRC20Addr, runner.ZEVMClient) - if err != nil { - panic(err) - } - runner.ETHZRC20 = ethZRC20 + require.NoError(r, err) + require.NotEqual(r, ethcommon.Address{}, ethZRC20Addr, "eth zrc20 not found") + + r.ETHZRC20Addr = ethZRC20Addr + ethZRC20, err := zrc20.NewZRC20(ethZRC20Addr, r.ZEVMClient) + require.NoError(r, err) + + r.ETHZRC20 = ethZRC20 } // SetupBTCZRC20 sets up the BTC ZRC20 in the runner from the values queried from the chain -func (runner *E2ERunner) SetupBTCZRC20() { - BTCZRC20Addr, err := runner.SystemContract.GasCoinZRC20ByChainId( +func (r *E2ERunner) SetupBTCZRC20() { + BTCZRC20Addr, err := r.SystemContract.GasCoinZRC20ByChainId( &bind.CallOpts{}, big.NewInt(chains.BitcoinRegtest.ChainId), ) - if err != nil { - panic(err) - } - runner.BTCZRC20Addr = BTCZRC20Addr - runner.Logger.Info("BTCZRC20Addr: %s", BTCZRC20Addr.Hex()) - BTCZRC20, err := zrc20.NewZRC20(BTCZRC20Addr, runner.ZEVMClient) - if err != nil { - panic(err) - } - runner.BTCZRC20 = BTCZRC20 + require.NoError(r, err) + r.BTCZRC20Addr = BTCZRC20Addr + r.Logger.Info("BTCZRC20Addr: %s", BTCZRC20Addr.Hex()) + BTCZRC20, err := zrc20.NewZRC20(BTCZRC20Addr, r.ZEVMClient) + require.NoError(r, err) + r.BTCZRC20 = BTCZRC20 } // EnableHeaderVerification enables the header verification for the given chain IDs -func (runner *E2ERunner) EnableHeaderVerification(chainIDList []int64) error { - runner.Logger.Print("⚙️ enabling verification flags for block headers") +func (r *E2ERunner) EnableHeaderVerification(chainIDList []int64) error { + r.Logger.Print("⚙️ enabling verification flags for block headers") - return runner.ZetaTxServer.EnableHeaderVerification(e2eutils.FungibleAdminName, chainIDList) + return r.ZetaTxServer.EnableHeaderVerification(e2eutils.FungibleAdminName, chainIDList) } // FundEmissionsPool funds the emissions pool on ZetaChain with the same value as used originally on mainnet (20M ZETA) -func (runner *E2ERunner) FundEmissionsPool() error { - runner.Logger.Print("⚙️ funding the emissions pool on ZetaChain with 20M ZETA (%s)", txserver.EmissionsPoolAddress) +func (r *E2ERunner) FundEmissionsPool() error { + r.Logger.Print("⚙️ funding the emissions pool on ZetaChain with 20M ZETA (%s)", txserver.EmissionsPoolAddress) - return runner.ZetaTxServer.FundEmissionsPool(e2eutils.FungibleAdminName, EmissionsPoolFunding) + return r.ZetaTxServer.FundEmissionsPool(e2eutils.FungibleAdminName, EmissionsPoolFunding) } diff --git a/e2e/runner/zeta.go b/e2e/runner/zeta.go index 104fb4900f..726f3f5cb6 100644 --- a/e2e/runner/zeta.go +++ b/e2e/runner/zeta.go @@ -1,11 +1,11 @@ package runner import ( - "fmt" "math/big" ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" zetaconnectoreth "github.com/zeta-chain/protocol-contracts/pkg/contracts/evm/zetaconnector.eth.sol" connectorzevm "github.com/zeta-chain/protocol-contracts/pkg/contracts/zevm/zetaconnectorzevm.sol" @@ -14,103 +14,77 @@ import ( ) // WaitForTxReceiptOnZEVM waits for a tx receipt on ZEVM -func (runner *E2ERunner) WaitForTxReceiptOnZEVM(tx *ethtypes.Transaction) { - defer func() { - runner.Unlock() - }() - runner.Lock() - - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, tx, runner.Logger, runner.ReceiptTimeout) - if receipt.Status != 1 { - panic("tx failed") - } +func (r *E2ERunner) WaitForTxReceiptOnZEVM(tx *ethtypes.Transaction) { + r.Lock() + defer r.Unlock() + + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt) } // WaitForMinedCCTX waits for a cctx to be mined from a tx -func (runner *E2ERunner) WaitForMinedCCTX(txHash ethcommon.Hash) { - defer func() { - runner.Unlock() - }() - runner.Lock() +func (r *E2ERunner) WaitForMinedCCTX(txHash ethcommon.Hash) { + r.Lock() + defer r.Unlock() cctx := utils.WaitCctxMinedByInboundHash( - runner.Ctx, + r.Ctx, txHash.Hex(), - runner.CctxClient, - runner.Logger, - runner.CctxTimeout, + r.CctxClient, + r.Logger, + r.CctxTimeout, ) - if cctx.CctxStatus.Status != types.CctxStatus_OutboundMined { - panic(fmt.Sprintf("expected cctx status to be mined; got %s, message: %s", - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage), - ) - } + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_OutboundMined) } // WaitForMinedCCTXFromIndex waits for a cctx to be mined from its index -func (runner *E2ERunner) WaitForMinedCCTXFromIndex(index string) { - defer func() { - runner.Unlock() - }() - runner.Lock() - - cctx := utils.WaitCCTXMinedByIndex(runner.Ctx, index, runner.CctxClient, runner.Logger, runner.CctxTimeout) - if cctx.CctxStatus.Status != types.CctxStatus_OutboundMined { - panic(fmt.Sprintf("expected cctx status to be mined; got %s, message: %s", - cctx.CctxStatus.Status.String(), - cctx.CctxStatus.StatusMessage), - ) - } +func (r *E2ERunner) WaitForMinedCCTXFromIndex(index string) { + r.Lock() + defer r.Unlock() + + cctx := utils.WaitCCTXMinedByIndex(r.Ctx, index, r.CctxClient, r.Logger, r.CctxTimeout) + utils.RequireCCTXStatus(r, cctx, types.CctxStatus_OutboundMined) } // SendZetaOnEvm sends ZETA to an address on EVM // this allows the ZETA contract deployer to funds other accounts on EVM -func (runner *E2ERunner) SendZetaOnEvm(address ethcommon.Address, zetaAmount int64) *ethtypes.Transaction { +func (r *E2ERunner) SendZetaOnEvm(address ethcommon.Address, zetaAmount int64) *ethtypes.Transaction { // the deployer might be sending ZETA in different goroutines - defer func() { - runner.Unlock() - }() - runner.Lock() + r.Lock() + defer r.Unlock() amount := big.NewInt(1e18) amount = amount.Mul(amount, big.NewInt(zetaAmount)) - tx, err := runner.ZetaEth.Transfer(runner.EVMAuth, address, amount) - if err != nil { - panic(err) - } + tx, err := r.ZetaEth.Transfer(r.EVMAuth, address, amount) + require.NoError(r, err) + return tx } // DepositZeta deposits ZETA on ZetaChain from the ZETA smart contract on EVM -func (runner *E2ERunner) DepositZeta() ethcommon.Hash { +func (r *E2ERunner) DepositZeta() ethcommon.Hash { amount := big.NewInt(1e18) amount = amount.Mul(amount, big.NewInt(100)) // 100 Zeta - return runner.DepositZetaWithAmount(runner.DeployerAddress, amount) + return r.DepositZetaWithAmount(r.DeployerAddress, amount) } // DepositZetaWithAmount deposits ZETA on ZetaChain from the ZETA smart contract on EVM with the specified amount -func (runner *E2ERunner) DepositZetaWithAmount(to ethcommon.Address, amount *big.Int) ethcommon.Hash { - tx, err := runner.ZetaEth.Approve(runner.EVMAuth, runner.ConnectorEthAddr, amount) - if err != nil { - panic(err) - } - runner.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) +func (r *E2ERunner) DepositZetaWithAmount(to ethcommon.Address, amount *big.Int) ethcommon.Hash { + tx, err := r.ZetaEth.Approve(r.EVMAuth, r.ConnectorEthAddr, amount) + require.NoError(r, err) - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - runner.Logger.EVMReceipt(*receipt, "approve") - if receipt.Status != 1 { - panic("approve tx failed") - } + r.Logger.Info("Approve tx hash: %s", tx.Hash().Hex()) + + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.Logger.EVMReceipt(*receipt, "approve") + r.requireTxSuccessful(receipt, "approve tx failed") // query the chain ID using zevm client - zetaChainID, err := runner.ZEVMClient.ChainID(runner.Ctx) - if err != nil { - panic(err) - } + zetaChainID, err := r.ZEVMClient.ChainID(r.Ctx) + require.NoError(r, err) - tx, err = runner.ConnectorEth.Send(runner.EVMAuth, zetaconnectoreth.ZetaInterfacesSendInput{ + tx, err = r.ConnectorEth.Send(r.EVMAuth, zetaconnectoreth.ZetaInterfacesSendInput{ // TODO: allow user to specify destination chain id // https://github.com/zeta-chain/node-private/issues/41 DestinationChainId: zetaChainID, @@ -120,27 +94,24 @@ func (runner *E2ERunner) DepositZetaWithAmount(to ethcommon.Address, amount *big ZetaValueAndGas: amount, ZetaParams: nil, }) - if err != nil { - panic(err) - } - runner.Logger.Info("Send tx hash: %s", tx.Hash().Hex()) + require.NoError(r, err) - receipt = utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - runner.Logger.EVMReceipt(*receipt, "send") - if receipt.Status != 1 { - panic(fmt.Sprintf("expected tx receipt status to be 1; got %d", receipt.Status)) - } + r.Logger.Info("Send tx hash: %s", tx.Hash().Hex()) - runner.Logger.Info(" Logs:") + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + r.Logger.EVMReceipt(*receipt, "send") + r.requireTxSuccessful(receipt, "send tx failed") + + r.Logger.Info(" Logs:") for _, log := range receipt.Logs { - sentLog, err := runner.ConnectorEth.ParseZetaSent(*log) + sentLog, err := r.ConnectorEth.ParseZetaSent(*log) if err == nil { - runner.Logger.Info(" Connector: %s", runner.ConnectorEthAddr.String()) - runner.Logger.Info(" Dest Addr: %s", ethcommon.BytesToAddress(sentLog.DestinationAddress).Hex()) - runner.Logger.Info(" Dest Chain: %d", sentLog.DestinationChainId) - runner.Logger.Info(" Dest Gas: %d", sentLog.DestinationGasLimit) - runner.Logger.Info(" Zeta Value: %d", sentLog.ZetaValueAndGas) - runner.Logger.Info(" Block Num: %d", log.BlockNumber) + r.Logger.Info(" Connector: %s", r.ConnectorEthAddr.String()) + r.Logger.Info(" Dest Addr: %s", ethcommon.BytesToAddress(sentLog.DestinationAddress).Hex()) + r.Logger.Info(" Dest Chain: %d", sentLog.DestinationChainId) + r.Logger.Info(" Dest Gas: %d", sentLog.DestinationGasLimit) + r.Logger.Info(" Zeta Value: %d", sentLog.ZetaValueAndGas) + r.Logger.Info(" Block Num: %d", log.BlockNumber) } } @@ -148,71 +119,59 @@ func (runner *E2ERunner) DepositZetaWithAmount(to ethcommon.Address, amount *big } // DepositAndApproveWZeta deposits and approves WZETA on ZetaChain from the ZETA smart contract on ZEVM -func (runner *E2ERunner) DepositAndApproveWZeta(amount *big.Int) { - runner.ZEVMAuth.Value = amount - tx, err := runner.WZeta.Deposit(runner.ZEVMAuth) - if err != nil { - panic(err) - } - runner.ZEVMAuth.Value = big.NewInt(0) - runner.Logger.Info("wzeta deposit tx hash: %s", tx.Hash().Hex()) +func (r *E2ERunner) DepositAndApproveWZeta(amount *big.Int) { + r.ZEVMAuth.Value = amount + tx, err := r.WZeta.Deposit(r.ZEVMAuth) + require.NoError(r, err) - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, tx, runner.Logger, runner.ReceiptTimeout) - runner.Logger.EVMReceipt(*receipt, "wzeta deposit") - if receipt.Status == 0 { - panic("deposit failed") - } + r.ZEVMAuth.Value = big.NewInt(0) + r.Logger.Info("wzeta deposit tx hash: %s", tx.Hash().Hex()) - tx, err = runner.WZeta.Approve(runner.ZEVMAuth, runner.ConnectorZEVMAddr, amount) - if err != nil { - panic(err) - } - runner.Logger.Info("wzeta approve tx hash: %s", tx.Hash().Hex()) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + r.Logger.EVMReceipt(*receipt, "wzeta deposit") + r.requireTxSuccessful(receipt, "deposit failed") - receipt = utils.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, tx, runner.Logger, runner.ReceiptTimeout) - runner.Logger.EVMReceipt(*receipt, "wzeta approve") - if receipt.Status == 0 { - panic(fmt.Sprintf("approve failed, logs: %+v", receipt.Logs)) - } + tx, err = r.WZeta.Approve(r.ZEVMAuth, r.ConnectorZEVMAddr, amount) + require.NoError(r, err) + + r.Logger.Info("wzeta approve tx hash: %s", tx.Hash().Hex()) + + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + r.Logger.EVMReceipt(*receipt, "wzeta approve") + r.requireTxSuccessful(receipt, "approve failed, logs: %+v", receipt.Logs) } // WithdrawZeta withdraws ZETA from ZetaChain to the ZETA smart contract on EVM // waitReceipt specifies whether to wait for the tx receipt and check if the tx was successful -func (runner *E2ERunner) WithdrawZeta(amount *big.Int, waitReceipt bool) *ethtypes.Transaction { - chainID, err := runner.EVMClient.ChainID(runner.Ctx) - if err != nil { - panic(err) - } +func (r *E2ERunner) WithdrawZeta(amount *big.Int, waitReceipt bool) *ethtypes.Transaction { + chainID, err := r.EVMClient.ChainID(r.Ctx) + require.NoError(r, err) - tx, err := runner.ConnectorZEVM.Send(runner.ZEVMAuth, connectorzevm.ZetaInterfacesSendInput{ + tx, err := r.ConnectorZEVM.Send(r.ZEVMAuth, connectorzevm.ZetaInterfacesSendInput{ DestinationChainId: chainID, - DestinationAddress: runner.DeployerAddress.Bytes(), + DestinationAddress: r.DeployerAddress.Bytes(), DestinationGasLimit: big.NewInt(400_000), Message: nil, ZetaValueAndGas: amount, ZetaParams: nil, }) - if err != nil { - panic(err) - } - runner.Logger.Info("send tx hash: %s", tx.Hash().Hex()) + require.NoError(r, err) - if waitReceipt { - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, tx, runner.Logger, runner.ReceiptTimeout) - runner.Logger.EVMReceipt(*receipt, "send") - if receipt.Status == 0 { - panic(fmt.Sprintf("send failed, logs: %+v", receipt.Logs)) + r.Logger.Info("send tx hash: %s", tx.Hash().Hex()) - } + if waitReceipt { + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + r.Logger.EVMReceipt(*receipt, "send") + r.requireTxSuccessful(receipt, "send failed, logs: %+v", receipt.Logs) - runner.Logger.Info(" Logs:") + r.Logger.Info(" Logs:") for _, log := range receipt.Logs { - sentLog, err := runner.ConnectorZEVM.ParseZetaSent(*log) + sentLog, err := r.ConnectorZEVM.ParseZetaSent(*log) if err == nil { - runner.Logger.Info(" Dest Addr: %s", ethcommon.BytesToAddress(sentLog.DestinationAddress).Hex()) - runner.Logger.Info(" Dest Chain: %d", sentLog.DestinationChainId) - runner.Logger.Info(" Dest Gas: %d", sentLog.DestinationGasLimit) - runner.Logger.Info(" Zeta Value: %d", sentLog.ZetaValueAndGas) + r.Logger.Info(" Dest Addr: %s", ethcommon.BytesToAddress(sentLog.DestinationAddress).Hex()) + r.Logger.Info(" Dest Chain: %d", sentLog.DestinationChainId) + r.Logger.Info(" Dest Gas: %d", sentLog.DestinationGasLimit) + r.Logger.Info(" Zeta Value: %d", sentLog.ZetaValueAndGas) } } } @@ -221,40 +180,37 @@ func (runner *E2ERunner) WithdrawZeta(amount *big.Int, waitReceipt bool) *ethtyp } // WithdrawEther withdraws Ether from ZetaChain to the ZETA smart contract on EVM -func (runner *E2ERunner) WithdrawEther(amount *big.Int) *ethtypes.Transaction { +func (r *E2ERunner) WithdrawEther(amount *big.Int) *ethtypes.Transaction { // withdraw - tx, err := runner.ETHZRC20.Withdraw(runner.ZEVMAuth, runner.DeployerAddress.Bytes(), amount) - if err != nil { - panic(err) - } - runner.Logger.EVMTransaction(*tx, "withdraw") + tx, err := r.ETHZRC20.Withdraw(r.ZEVMAuth, r.DeployerAddress.Bytes(), amount) + require.NoError(r, err) - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, tx, runner.Logger, runner.ReceiptTimeout) - if receipt.Status == 0 { - panic("withdraw failed") - } - runner.Logger.EVMReceipt(*receipt, "withdraw") - runner.Logger.ZRC20Withdrawal(runner.ETHZRC20, *receipt, "withdraw") + r.Logger.EVMTransaction(*tx, "withdraw") + + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + r.requireTxSuccessful(receipt, "withdraw failed") + + r.Logger.EVMReceipt(*receipt, "withdraw") + r.Logger.ZRC20Withdrawal(r.ETHZRC20, *receipt, "withdraw") return tx } // WithdrawERC20 withdraws an ERC20 token from ZetaChain to the ZETA smart contract on EVM -func (runner *E2ERunner) WithdrawERC20(amount *big.Int) *ethtypes.Transaction { - tx, err := runner.ERC20ZRC20.Withdraw(runner.ZEVMAuth, runner.DeployerAddress.Bytes(), amount) - if err != nil { - panic(err) - } - runner.Logger.EVMTransaction(*tx, "withdraw") +func (r *E2ERunner) WithdrawERC20(amount *big.Int) *ethtypes.Transaction { + tx, err := r.ERC20ZRC20.Withdraw(r.ZEVMAuth, r.DeployerAddress.Bytes(), amount) + require.NoError(r, err) + + r.Logger.EVMTransaction(*tx, "withdraw") - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.ZEVMClient, tx, runner.Logger, runner.ReceiptTimeout) - runner.Logger.Info("Receipt txhash %s status %d", receipt.TxHash, receipt.Status) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + r.Logger.Info("Receipt txhash %s status %d", receipt.TxHash, receipt.Status) for _, log := range receipt.Logs { - event, err := runner.ERC20ZRC20.ParseWithdrawal(*log) + event, err := r.ERC20ZRC20.ParseWithdrawal(*log) if err != nil { continue } - runner.Logger.Info( + r.Logger.Info( " logs: from %s, to %x, value %d, gasfee %d", event.From.Hex(), event.To, diff --git a/e2e/utils/evm.go b/e2e/utils/evm.go index fc6792d617..45b2a55890 100644 --- a/e2e/utils/evm.go +++ b/e2e/utils/evm.go @@ -11,6 +11,7 @@ import ( ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/require" ) const ( @@ -34,24 +35,23 @@ func CheckNonce( } // MustWaitForTxReceipt waits until a broadcasted tx to be mined and return its receipt -// timeout and panic after 30s. func MustWaitForTxReceipt( ctx context.Context, client *ethclient.Client, tx *ethtypes.Transaction, logger infoLogger, - receiptTimeout time.Duration, + timeout time.Duration, ) *ethtypes.Receipt { - timeout := DefaultReceiptTimeout - if receiptTimeout != 0 { - timeout = receiptTimeout + if timeout == 0 { + timeout = DefaultReceiptTimeout } + t := TestingFromContext(ctx) + start := time.Now() for i := 0; ; i++ { - if time.Since(start) > timeout { - panic("waiting tx receipt timeout") - } + require.False(t, time.Since(start) > timeout, "waiting tx receipt timeout") + receipt, err := client.TransactionReceipt(ctx, tx.Hash()) if err != nil { if !errors.Is(err, ethereum.NotFound) && i%10 == 0 { diff --git a/e2e/utils/require.go b/e2e/utils/require.go new file mode 100644 index 0000000000..ffedb62e59 --- /dev/null +++ b/e2e/utils/require.go @@ -0,0 +1,47 @@ +package utils + +import ( + "fmt" + + ethtypes "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/require" + + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +// RequireCCTXStatus checks if the cctx status is equal to the expected status +func RequireCCTXStatus( + t require.TestingT, + cctx *crosschaintypes.CrossChainTx, + expected crosschaintypes.CctxStatus, + msgAndArgs ...any, +) { + msg := fmt.Sprintf("cctx status is not %q", expected.String()) + + require.NotNil(t, cctx.CctxStatus) + require.Equal(t, expected, cctx.CctxStatus.Status, msg+errSuffix(msgAndArgs...)) +} + +// RequireTxSuccessful checks if the receipt status is successful. +// Currently, it accepts eth receipt, but we can make this more generic by using type assertion. +func RequireTxSuccessful(t require.TestingT, receipt *ethtypes.Receipt, msgAndArgs ...any) { + msg := "receipt status is not successful" + require.Equal(t, ethtypes.ReceiptStatusSuccessful, receipt.Status, msg+errSuffix(msgAndArgs...)) +} + +// RequiredTxFailed checks if the receipt status is failed. +// Currently, it accepts eth receipt, but we can make this more generic by using type assertion. +func RequiredTxFailed(t require.TestingT, receipt *ethtypes.Receipt, msgAndArgs ...any) { + msg := "receipt status is not successful" + require.Equal(t, ethtypes.ReceiptStatusFailed, receipt.Status, msg+errSuffix(msgAndArgs...)) +} + +func errSuffix(msgAndArgs ...any) string { + if len(msgAndArgs) == 0 { + return "" + } + + template := "; " + msgAndArgs[0].(string) + + return fmt.Sprintf(template, msgAndArgs[1:]) +} diff --git a/e2e/utils/utils.go b/e2e/utils/utils.go index bfa3d509b3..5bc451c606 100644 --- a/e2e/utils/utils.go +++ b/e2e/utils/utils.go @@ -1,10 +1,12 @@ package utils import ( + "context" "encoding/hex" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcutil" + "github.com/stretchr/testify/require" ) // ScriptPKToAddress is a hex string for P2WPKH script @@ -26,3 +28,20 @@ type infoLogger interface { type NoopLogger struct{} func (nl NoopLogger) Info(_ string, _ ...interface{}) {} + +type testingKey struct{} + +// WithTesting allows to store a testing.T instance in the context +func WithTesting(ctx context.Context, t require.TestingT) context.Context { + return context.WithValue(ctx, testingKey{}, t) +} + +// TestingFromContext extracts require.TestingT from the context or panics. +func TestingFromContext(ctx context.Context) require.TestingT { + t, ok := ctx.Value(testingKey{}).(require.TestingT) + if !ok { + panic("context missing require.TestingT key") + } + + return t +} diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index a641ea9518..cbba05de75 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -2,11 +2,10 @@ package utils import ( "context" - "fmt" "time" rpchttp "github.com/cometbft/cometbft/rpc/client/http" - coretypes "github.com/cometbft/cometbft/rpc/core/types" + "github.com/pkg/errors" "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -26,14 +25,14 @@ const ( func WaitCctxMinedByInboundHash( ctx context.Context, inboundHash string, - cctxClient crosschaintypes.QueryClient, + client crosschaintypes.QueryClient, logger infoLogger, - cctxTimeout time.Duration, + timeout time.Duration, ) *crosschaintypes.CrossChainTx { - cctxs := WaitCctxsMinedByInboundHash(ctx, inboundHash, cctxClient, 1, logger, cctxTimeout) - if len(cctxs) == 0 { - panic(fmt.Sprintf("cctx not found, inboundHash: %s", inboundHash)) - } + t := TestingFromContext(ctx) + cctxs := WaitCctxsMinedByInboundHash(ctx, inboundHash, client, 1, logger, timeout) + require.NotEmpty(t, cctxs, "cctx not found, inboundHash: %s", inboundHash) + return cctxs[len(cctxs)-1] } @@ -41,41 +40,35 @@ func WaitCctxMinedByInboundHash( func WaitCctxsMinedByInboundHash( ctx context.Context, inboundHash string, - cctxClient crosschaintypes.QueryClient, + client crosschaintypes.QueryClient, cctxsCount int, logger infoLogger, - cctxTimeout time.Duration, + timeout time.Duration, ) []*crosschaintypes.CrossChainTx { - startTime := time.Now() - - timeout := DefaultCctxTimeout - if cctxTimeout != 0 { - timeout = cctxTimeout + if timeout == 0 { + timeout = DefaultCctxTimeout } + t := TestingFromContext(ctx) + + startTime := time.Now() + in := &crosschaintypes.QueryInboundHashToCctxDataRequest{InboundHash: inboundHash} + // fetch cctxs by inboundHash for i := 0; ; i++ { // declare cctxs here so we can print the last fetched one if we reach timeout var cctxs []*crosschaintypes.CrossChainTx - if time.Since(startTime) > timeout { - cctxMessage := "" - if len(cctxs) > 0 { - cctxMessage = fmt.Sprintf(", last cctx: %v", cctxs[0].String()) - } + timedOut := time.Since(startTime) > timeout + require.False(t, timedOut, "waiting cctx timeout, cctx not mined, inbound hash: %s", inboundHash) - panic(fmt.Sprintf("waiting cctx timeout, cctx not mined, inboundHash: %s%s", inboundHash, cctxMessage)) - } time.Sleep(1 * time.Second) // We use InTxHashToCctxData instead of InboundTrackerAllByChain to able to run these tests with the previous version // for the update tests // TODO: replace with InboundHashToCctxData once removed // https://github.com/zeta-chain/node/issues/2200 - res, err := cctxClient.InTxHashToCctxData(ctx, &crosschaintypes.QueryInboundHashToCctxDataRequest{ - InboundHash: inboundHash, - }) - + res, err := client.InTxHashToCctxData(ctx, in) if err != nil { // prevent spamming logs if i%10 == 0 { @@ -126,30 +119,27 @@ func WaitCctxsMinedByInboundHash( func WaitCCTXMinedByIndex( ctx context.Context, cctxIndex string, - cctxClient crosschaintypes.QueryClient, + client crosschaintypes.QueryClient, logger infoLogger, - cctxTimeout time.Duration, + timeout time.Duration, ) *crosschaintypes.CrossChainTx { - startTime := time.Now() - - timeout := DefaultCctxTimeout - if cctxTimeout != 0 { - timeout = cctxTimeout + if timeout == 0 { + timeout = DefaultCctxTimeout } + t := TestingFromContext(ctx) + startTime := time.Now() + in := &crosschaintypes.QueryGetCctxRequest{Index: cctxIndex} + for i := 0; ; i++ { - if time.Since(startTime) > timeout { - panic(fmt.Sprintf( - "waiting cctx timeout, cctx not mined, cctx: %s", - cctxIndex, - )) + require.False(t, time.Since(startTime) > timeout, "waiting cctx timeout, cctx not mined, cctx: %s", cctxIndex) + + if i > 0 { + time.Sleep(1 * time.Second) } - time.Sleep(1 * time.Second) // fetch cctx by index - res, err := cctxClient.Cctx(ctx, &crosschaintypes.QueryGetCctxRequest{ - Index: cctxIndex, - }) + res, err := client.Cctx(ctx, in) if err != nil { // prevent spamming logs if i%10 == 0 { @@ -157,6 +147,7 @@ func WaitCCTXMinedByIndex( } continue } + cctx := res.CrossChainTx if !IsTerminalStatus(cctx.CctxStatus.Status) { // prevent spamming logs @@ -259,26 +250,32 @@ func IsTerminalStatus(status crosschaintypes.CctxStatus) bool { // WaitForBlockHeight waits until the block height reaches the given height func WaitForBlockHeight( ctx context.Context, - height int64, + desiredHeight int64, rpcURL string, logger infoLogger, -) { +) error { // initialize rpc and check status rpc, err := rpchttp.New(rpcURL, "/websocket") if err != nil { - panic(err) + return errors.Wrap(err, "unable to create rpc client") } - status := &coretypes.ResultStatus{} - for i := 0; status.SyncInfo.LatestBlockHeight < height; i++ { - status, err = rpc.Status(ctx) + + var currentHeight int64 + for i := 0; currentHeight < desiredHeight; i++ { + s, err := rpc.Status(ctx) if err != nil { - panic(err) + return errors.Wrap(err, "unable to get status") } + + currentHeight = s.SyncInfo.LatestBlockHeight + time.Sleep(1 * time.Second) // prevent spamming logs if i%10 == 0 { - logger.Info("waiting for block: %d, current height: %d\n", height, status.SyncInfo.LatestBlockHeight) + logger.Info("waiting for block: %d, current height: %d\n", desiredHeight, currentHeight) } } + + return nil } diff --git a/testutil/helpers.go b/testutil/helpers.go new file mode 100644 index 0000000000..dc49a0b024 --- /dev/null +++ b/testutil/helpers.go @@ -0,0 +1,38 @@ +package testutil + +import ( + "fmt" + "os" + "strings" + + "github.com/stretchr/testify/assert" +) + +const helpersFile = "testutil/helpers.go" + +// Must a helper that terminates the program if the error is not nil. +func Must[T any](v T, err error) T { + NoError(err) + return v +} + +// NoError terminates the program if the error is not nil. +func NoError(err error) { + if err != nil { + exit(err) + } +} + +func exit(err error) { + fmt.Printf("Unable to continue execution: %s.\nStacktrace:\n", err) + + for _, line := range assert.CallerInfo() { + if strings.Contains(line, helpersFile) { + continue + } + + fmt.Println(" ", line) + } + + os.Exit(1) +}