From 4258421c4635eedba894e861c725f3704464e8f3 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 25 Jul 2024 17:56:16 -0400 Subject: [PATCH 01/29] rebase develop --- x/observer/keeper/chain_params.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/x/observer/keeper/chain_params.go b/x/observer/keeper/chain_params.go index 9277010c3c..1c2cf4e7c4 100644 --- a/x/observer/keeper/chain_params.go +++ b/x/observer/keeper/chain_params.go @@ -76,6 +76,19 @@ func (k Keeper) GetSupportedChains(ctx sdk.Context) []chains.Chain { return c } +// GetSupportedChainsByConsensus returns the list of supported chains by consensus +func (k Keeper) GetSupportedForeignChainsByConsensus(ctx sdk.Context, consensus chains.Consensus) []chains.Chain { + allChains := k.GetSupportedChains(ctx) + + foreignChains := make([]chains.Chain, 0) + for _, chain := range allChains { + if !chain.IsZetaChain() && chain.GetConsensus() == consensus { + foreignChains = append(foreignChains, chain) + } + } + return foreignChains +} + // GetSupportedForeignChains returns the list of supported foreign chains func (k Keeper) GetSupportedForeignChains(ctx sdk.Context) []chains.Chain { allChains := k.GetSupportedChains(ctx) From 82f52e5265e16a04c102b05d1783c2429020ee64 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 25 Jul 2024 17:56:31 -0400 Subject: [PATCH 02/29] rebase develop --- changelog.md | 1 + testutil/keeper/mocks/crosschain/observer.go | 20 ++++ x/crosschain/keeper/msg_server_update_tss.go | 10 +- .../keeper/msg_server_update_tss_test.go | 43 ++++++-- x/crosschain/types/expected_keepers.go | 1 + x/observer/keeper/chain_params_test.go | 103 ++++++++++++++++++ 6 files changed, 166 insertions(+), 12 deletions(-) diff --git a/changelog.md b/changelog.md index 2bf19bd85b..541f8f6ef4 100644 --- a/changelog.md +++ b/changelog.md @@ -66,6 +66,7 @@ * [2464](https://github.com/zeta-chain/node/pull/2464) - move common voting logic to voting.go and add new function VoteOnBallot * [2515](https://github.com/zeta-chain/node/pull/2515) - replace chainName by chainID for ChainNonces indexing * [2542](https://github.com/zeta-chain/node/pull/2542) - adjust permissions to be more restrictive +* [2556](https://github.com/zeta-chain/node/pull/2556) - refactor migrator length check to use consensus type ### Tests diff --git a/testutil/keeper/mocks/crosschain/observer.go b/testutil/keeper/mocks/crosschain/observer.go index d71673848f..63789912ce 100644 --- a/testutil/keeper/mocks/crosschain/observer.go +++ b/testutil/keeper/mocks/crosschain/observer.go @@ -624,6 +624,26 @@ func (_m *CrosschainObserverKeeper) GetSupportedForeignChains(ctx types.Context) return r0 } +// GetSupportedForeignChainsByConsensus provides a mock function with given fields: ctx, consensus +func (_m *CrosschainObserverKeeper) GetSupportedForeignChainsByConsensus(ctx types.Context, consensus chains.Consensus) []chains.Chain { + ret := _m.Called(ctx, consensus) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedForeignChainsByConsensus") + } + + var r0 []chains.Chain + if rf, ok := ret.Get(0).(func(types.Context, chains.Consensus) []chains.Chain); ok { + r0 = rf(ctx, consensus) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]chains.Chain) + } + } + + return r0 +} + // GetTSS provides a mock function with given fields: ctx func (_m *CrosschainObserverKeeper) GetTSS(ctx types.Context) (observertypes.TSS, bool) { ret := _m.Called(ctx) diff --git a/x/crosschain/keeper/msg_server_update_tss.go b/x/crosschain/keeper/msg_server_update_tss.go index 78c3b833d7..e088412e9d 100644 --- a/x/crosschain/keeper/msg_server_update_tss.go +++ b/x/crosschain/keeper/msg_server_update_tss.go @@ -6,6 +6,7 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/pkg/chains" authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -37,8 +38,9 @@ func (k msgServer) UpdateTssAddress( } tssMigrators := k.zetaObserverKeeper.GetAllTssFundMigrators(ctx) + // Each connected chain should have its own tss migrator - if len(k.zetaObserverKeeper.GetSupportedForeignChains(ctx)) != len(tssMigrators) { + if len(k.GetChainsSupportingMigration(ctx)) != len(tssMigrators) { return nil, errorsmod.Wrap( types.ErrUnableToUpdateTss, "cannot update tss address incorrect number of migrations have been created and completed", @@ -70,3 +72,9 @@ func (k msgServer) UpdateTssAddress( return &types.MsgUpdateTssAddressResponse{}, nil } + +// GetChainsSupportingMigration returns the chains that support migration. +func (k *Keeper) GetChainsSupportingMigration(ctx sdk.Context) []chains.Chain { + return append(k.zetaObserverKeeper.GetSupportedForeignChainsByConsensus(ctx, chains.Consensus_ethereum), + k.zetaObserverKeeper.GetSupportedForeignChainsByConsensus(ctx, chains.Consensus_bitcoin)...) +} diff --git a/x/crosschain/keeper/msg_server_update_tss_test.go b/x/crosschain/keeper/msg_server_update_tss_test.go index 761ff617c8..bc747e7389 100644 --- a/x/crosschain/keeper/msg_server_update_tss_test.go +++ b/x/crosschain/keeper/msg_server_update_tss_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" @@ -65,7 +66,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSSHistory(ctx, tssNew) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetSupportedForeignChains(ctx) { + for _, chain := range k.GetChainsSupportingMigration(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -78,7 +79,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { require.Equal( t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), - len(k.GetObserverKeeper().GetSupportedForeignChains(ctx)), + len(k.GetChainsSupportingMigration(ctx)), ) msg := crosschaintypes.MsgUpdateTssAddress{ @@ -109,7 +110,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { + for _, chain := range k.GetChainsSupportingMigration(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -122,7 +123,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { require.Equal( t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), - len(k.GetObserverKeeper().GetSupportedChains(ctx)), + len(k.GetChainsSupportingMigration(ctx)), ) msg := crosschaintypes.MsgUpdateTssAddress{ @@ -139,7 +140,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { require.Equal( t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), - len(k.GetObserverKeeper().GetSupportedChains(ctx)), + len(k.GetChainsSupportingMigration(ctx)), ) }) @@ -156,7 +157,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { k.GetObserverKeeper().SetTSSHistory(ctx, tssOld) k.GetObserverKeeper().SetTSS(ctx, tssOld) - for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { + for _, chain := range k.GetChainsSupportingMigration(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -169,7 +170,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { require.Equal( t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), - len(k.GetObserverKeeper().GetSupportedChains(ctx)), + len(k.GetChainsSupportingMigration(ctx)), ) msg := crosschaintypes.MsgUpdateTssAddress{ @@ -186,7 +187,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { require.Equal( t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), - len(k.GetObserverKeeper().GetSupportedChains(ctx)), + len(k.GetChainsSupportingMigration(ctx)), ) }) @@ -207,7 +208,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { setSupportedChain(ctx, zk, getValidEthChainIDWithIndex(t, 0), getValidEthChainIDWithIndex(t, 1)) // set a single migrator while there are 2 supported chains - chain := k.GetObserverKeeper().GetSupportedChains(ctx)[0] + chain := k.GetChainsSupportingMigration(ctx)[0] index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -254,7 +255,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { k.GetObserverKeeper().SetTSS(ctx, tssOld) setSupportedChain(ctx, zk, getValidEthChainIDWithIndex(t, 0), getValidEthChainIDWithIndex(t, 1)) - for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { + for _, chain := range k.GetChainsSupportingMigration(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -301,7 +302,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { k.GetObserverKeeper().SetTSS(ctx, tssOld) setSupportedChain(ctx, zk, getValidEthChainIDWithIndex(t, 0), getValidEthChainIDWithIndex(t, 1)) - for _, chain := range k.GetObserverKeeper().GetSupportedChains(ctx) { + for _, chain := range k.GetChainsSupportingMigration(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -329,3 +330,23 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { require.Equal(t, len(k.GetObserverKeeper().GetSupportedChains(ctx)), len(migrators)) }) } + +func TestKeeper_GetChainsSupportingMigration(t *testing.T) { + t.Run("should return only ethereum and bitcoin chains", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{}) + chainList := chains.ExternalChainList([]chains.Chain{}) + var chainParamsList types.ChainParamsList + for _, chain := range chainList { + chainParamsList.ChainParams = append(chainParamsList.ChainParams, sample.ChainParamsSupported(chain.ChainId)) + } + zk.ObserverKeeper.SetChainParamsList(ctx, chainParamsList) + + chainsSupportingMigration := k.GetChainsSupportingMigration(ctx) + for _, chain := range chainsSupportingMigration { + require.NotEqual(t, chain.Consensus, chains.Consensus_solana_consensus) + require.NotEqual(t, chain.Consensus, chains.Consensus_op_stack) + require.NotEqual(t, chain.Consensus, chains.Consensus_tendermint) + require.Equal(t, chain.IsExternal, true) + } + }) +} diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index b66ab1a12c..b159f84148 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -104,6 +104,7 @@ type ObserverKeeper interface { GetSupportedChainFromChainID(ctx sdk.Context, chainID int64) (chains.Chain, bool) GetSupportedChains(ctx sdk.Context) []chains.Chain GetSupportedForeignChains(ctx sdk.Context) []chains.Chain + GetSupportedForeignChainsByConsensus(ctx sdk.Context, consensus chains.Consensus) []chains.Chain } type FungibleKeeper interface { diff --git a/x/observer/keeper/chain_params_test.go b/x/observer/keeper/chain_params_test.go index 733fafc0b8..f4de631043 100644 --- a/x/observer/keeper/chain_params_test.go +++ b/x/observer/keeper/chain_params_test.go @@ -110,3 +110,106 @@ func TestKeeper_GetSupportedChains(t *testing.T) { require.EqualValues(t, supported4.ChainId, supportedChains[3].ChainId) }) } + +func TestKeeper_GetSupportedForeignChainsByConsensus(t *testing.T) { + t.Run("return empty list if not chans are supported", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + require.Empty(t, k.GetSupportedForeignChainsByConsensus(ctx, chains.Consensus_ethereum)) + }) + + t.Run("return list of supported chains for ethereum consensus", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + chainList := chains.ExternalChainList([]chains.Chain{}) + var chainParamsList types.ChainParamsList + for _, chain := range chainList { + chainParamsList.ChainParams = append( + chainParamsList.ChainParams, + sample.ChainParamsSupported(chain.ChainId), + ) + } + k.SetChainParamsList(ctx, chainParamsList) + consensus := chains.Consensus_ethereum + + supportedChainsList := k.GetSupportedForeignChainsByConsensus(ctx, consensus) + require.NotEmpty(t, supportedChainsList) + + require.ElementsMatch(t, getForeignChains(consensus), supportedChainsList) + }) + + t.Run("return list of supported chains for bitcoin consensus", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + chainList := chains.ExternalChainList([]chains.Chain{}) + var chainParamsList types.ChainParamsList + for _, chain := range chainList { + chainParamsList.ChainParams = append( + chainParamsList.ChainParams, + sample.ChainParamsSupported(chain.ChainId), + ) + } + k.SetChainParamsList(ctx, chainParamsList) + consensus := chains.Consensus_bitcoin + + supportedChainsList := k.GetSupportedForeignChainsByConsensus(ctx, consensus) + require.NotEmpty(t, supportedChainsList) + require.ElementsMatch(t, getForeignChains(consensus), supportedChainsList) + }) + + t.Run("return list of supported chains for solana consensus", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + chainList := chains.ExternalChainList([]chains.Chain{}) + var chainParamsList types.ChainParamsList + for _, chain := range chainList { + chainParamsList.ChainParams = append( + chainParamsList.ChainParams, + sample.ChainParamsSupported(chain.ChainId), + ) + } + k.SetChainParamsList(ctx, chainParamsList) + consensus := chains.Consensus_solana_consensus + + supportedChainsList := k.GetSupportedForeignChainsByConsensus(ctx, consensus) + require.NotEmpty(t, supportedChainsList) + require.ElementsMatch(t, getForeignChains(consensus), supportedChainsList) + }) +} + +func TestKeeper_GetSupportedForeignChains(t *testing.T) { + t.Run("return empty list if not chans are supported", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + require.Empty(t, k.GetSupportedForeignChains(ctx)) + }) + + t.Run("return list of supported chains", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + chainList := chains.ExternalChainList([]chains.Chain{}) + var chainParamsList types.ChainParamsList + for _, chain := range chainList { + chainParamsList.ChainParams = append( + chainParamsList.ChainParams, + sample.ChainParamsSupported(chain.ChainId), + ) + } + k.SetChainParamsList(ctx, chainParamsList) + + supportedChainsList := k.GetSupportedForeignChains(ctx) + require.NotEmpty(t, supportedChainsList) + + require.ElementsMatch(t, getAllForeignChains(), supportedChainsList) + }) +} + +func getAllForeignChains() []chains.Chain { + return chains.ExternalChainList([]chains.Chain{}) +} + +func getForeignChains(consensus chains.Consensus) []chains.Chain { + evmChains := chains.ChainListByConsensus(consensus, []chains.Chain{}) + foreignEvmChains := make([]chains.Chain, 0) + + for _, chain := range evmChains { + if !chain.IsZetaChain() { + foreignEvmChains = append(foreignEvmChains, chain) + } + } + return foreignEvmChains +} From f7a0d0f58abafea12c15936a8a9886e407be72d1 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 26 Jul 2024 09:42:43 -0400 Subject: [PATCH 03/29] add connectors --- cmd/zetae2e/local/local.go | 31 +++++++++++++++++++++++++++++++ e2e/e2etests/test_migrate_tss.go | 2 -- e2e/runner/setup_evm.go | 1 + e2e/utils/evm.go | 2 +- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index c83abf3e8a..51314dda94 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -3,10 +3,12 @@ package local import ( "context" "errors" + "fmt" "os" "path/filepath" "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/fatih/color" "github.com/spf13/cobra" "github.com/stretchr/testify/require" @@ -399,6 +401,32 @@ func waitKeygenHeight( } } +func updateTssAddressForConnector(runner *runner.E2ERunner) { + + tssAddress, err := runner.ConnectorEth.TssAddress(&bind.CallOpts{Context: runner.Ctx}) + require.NoError(runner, err) + runner.Logger.Print(fmt.Sprintf("TSS Address Before: %s", tssAddress.String())) + + tssUpdater, err := runner.ConnectorEth.TssAddressUpdater(&bind.CallOpts{Context: runner.Ctx}) + require.NoError(runner, err) + runner.Logger.Print(fmt.Sprintf("TSS Updater: %s", tssUpdater.String())) + + runner.Logger.Print("Update TSS") + noError(runner.SetTSSAddresses()) + runner.Logger.Print("TSS Deployer Address: %s", runner.TSSAddress) + + tx, err := runner.ConnectorEth.UpdateTssAddress(runner.EVMAuth, runner.TSSAddress) + require.NoError(runner, err) + runner.Logger.Print(fmt.Sprintf("TSS Address Update Tx: %s", tx.Hash().String())) + receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) + utils.RequireTxSuccessful(runner, receipt) + + tssAddress, err = runner.ConnectorEth.TssAddress(&bind.CallOpts{Context: runner.Ctx}) + require.NoError(runner, err) + runner.Logger.Print(fmt.Sprintf("TSS Address After: %s", tssAddress.String())) + +} + func runTSSMigrationTest(deployerRunner *runner.E2ERunner, logger *runner.Logger, verbose bool, conf config.Config) { migrationStartTime := time.Now() logger.Print("🏁 starting tss migration") @@ -426,11 +454,13 @@ func runTSSMigrationTest(deployerRunner *runner.E2ERunner, logger *runner.Logger } logger.Print("βœ… migration completed in %s ", time.Since(migrationStartTime).String()) + //updateTssAddressForConnector(deployerRunner) logger.Print("🏁 starting post migration tests") tests := []string{ e2etests.TestBitcoinWithdrawSegWitName, e2etests.TestEtherWithdrawName, + e2etests.TestZetaWithdrawName, } fn = postMigrationTestRoutine(conf, deployerRunner, verbose, tests...) @@ -439,6 +469,7 @@ func runTSSMigrationTest(deployerRunner *runner.E2ERunner, logger *runner.Logger logger.Print("❌ post migration tests failed") os.Exit(1) } + } func must[T any](v T, err error) T { diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index c72b876f0f..8063a2154b 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -11,7 +11,6 @@ import ( "github.com/btcsuite/btcutil" "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" "github.com/zeta-chain/zetacore/pkg/chains" @@ -160,7 +159,6 @@ func TestMigrateTSS(r *runner.E2ERunner, _ []string) { require.LessOrEqual(r, btcTSSBalanceNew*1e8, btcTSSBalanceOld*1e8) // ETH - r.TSSAddress = common.HexToAddress(newTss.Eth) ethTSSBalanceNew, err := r.EVMClient.BalanceAt(context.Background(), r.TSSAddress, nil) require.NoError(r, err) diff --git a/e2e/runner/setup_evm.go b/e2e/runner/setup_evm.go index 7b61d43163..d998063d1a 100644 --- a/e2e/runner/setup_evm.go +++ b/e2e/runner/setup_evm.go @@ -77,6 +77,7 @@ func (r *E2ERunner) SetupEVM(contractsDeployed bool, whitelistERC20 bool) { r.Logger.Info("ZetaEth contract address: %s, tx hash: %s", zetaEthAddr.Hex(), zetaEthAddr.Hash().Hex()) r.Logger.Info("Deploying ZetaConnectorEth contract") + r.Logger.Print("Connector constructor args: ZetaETH %s, TSS %s, Updated %s, Pauser %s\n", zetaEthAddr.Hex(), r.TSSAddress.Hex(), r.EVMAddress().Hex(), r.EVMAddress().Hex()) connectorEthAddr, txConnector, ConnectorEth, err := zetaconnectoreth.DeployZetaConnectorEth( r.EVMAuth, r.EVMClient, diff --git a/e2e/utils/evm.go b/e2e/utils/evm.go index 45b2a55890..7cc611b4d6 100644 --- a/e2e/utils/evm.go +++ b/e2e/utils/evm.go @@ -15,7 +15,7 @@ import ( ) const ( - DefaultReceiptTimeout = 30 * time.Second + DefaultReceiptTimeout = 300 * time.Second ) func CheckNonce( From 40a2580b3e9d33cbcd150d7d4e09fa786917c60a Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 30 Jul 2024 09:53:08 -0400 Subject: [PATCH 04/29] debug fees --- Makefile | 1 + cmd/zetae2e/local/bitcoin.go | 4 +- cmd/zetae2e/local/local.go | 111 +++++++++++------- .../localnet/orchestrator/start-zetae2e.sh | 37 ++++++ e2e/utils/zetacore.go | 2 +- zetaclient/zetacore/constant.go | 2 +- 6 files changed, 112 insertions(+), 45 deletions(-) diff --git a/Makefile b/Makefile index 0cbdff1614..d39aafff8d 100644 --- a/Makefile +++ b/Makefile @@ -260,6 +260,7 @@ start-stress-test: zetanode start-tss-migration-test: zetanode @echo "--> Starting migration test" + export LOCALNET_MODE=migrate && \ export E2E_ARGS="--test-tss-migration" && \ cd contrib/localnet/ && $(DOCKER) compose up -d diff --git a/cmd/zetae2e/local/bitcoin.go b/cmd/zetae2e/local/bitcoin.go index 05098fd5a9..4dfbbce614 100644 --- a/cmd/zetae2e/local/bitcoin.go +++ b/cmd/zetae2e/local/bitcoin.go @@ -49,7 +49,9 @@ func bitcoinTestRoutine( bitcoinRunner.WaitForMinedCCTX(txERC20Deposit) bitcoinRunner.SetupBitcoinAccount(initBitcoinNetwork) - bitcoinRunner.DepositBTC(testHeader) + if initBitcoinNetwork { + bitcoinRunner.DepositBTC(testHeader) + } // run bitcoin test // Note: due to the extensive block generation in Bitcoin localnet, block header test is run first diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 51314dda94..be302e8f06 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -225,47 +225,47 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestERC20WithdrawName, e2etests.TestMultipleERC20WithdrawsName, e2etests.TestERC20DepositAndCallRefundName, - e2etests.TestZRC20SwapName, + //e2etests.TestZRC20SwapName, } erc20AdvancedTests := []string{ e2etests.TestERC20DepositRestrictedName, } zetaTests := []string{ - e2etests.TestZetaWithdrawName, + //e2etests.TestZetaWithdrawName, e2etests.TestMessagePassingExternalChainsName, e2etests.TestMessagePassingRevertFailExternalChainsName, - e2etests.TestMessagePassingRevertSuccessExternalChainsName, - } - zetaAdvancedTests := []string{ - e2etests.TestZetaDepositRestrictedName, - e2etests.TestZetaDepositName, - e2etests.TestZetaDepositNewAddressName, + //e2etests.TestMessagePassingRevertSuccessExternalChainsName, } + //zetaAdvancedTests := []string{ + // e2etests.TestZetaDepositRestrictedName, + // e2etests.TestZetaDepositName, + // e2etests.TestZetaDepositNewAddressName, + //} zevmMPTests := []string{} zevmMPAdvancedTests := []string{ e2etests.TestMessagePassingZEVMToEVMName, e2etests.TestMessagePassingEVMtoZEVMName, e2etests.TestMessagePassingEVMtoZEVMRevertName, - e2etests.TestMessagePassingZEVMtoEVMRevertName, - e2etests.TestMessagePassingZEVMtoEVMRevertFailName, - e2etests.TestMessagePassingEVMtoZEVMRevertFailName, + //e2etests.TestMessagePassingZEVMtoEVMRevertName, + //e2etests.TestMessagePassingZEVMtoEVMRevertFailName, + //e2etests.TestMessagePassingEVMtoZEVMRevertFailName, } bitcoinTests := []string{ - e2etests.TestBitcoinDepositName, - e2etests.TestBitcoinDepositRefundName, + //e2etests.TestBitcoinDepositName, + //e2etests.TestBitcoinDepositRefundName, e2etests.TestBitcoinWithdrawSegWitName, - e2etests.TestBitcoinWithdrawInvalidAddressName, - e2etests.TestZetaWithdrawBTCRevertName, - e2etests.TestCrosschainSwapName, + //e2etests.TestBitcoinWithdrawInvalidAddressName, + //e2etests.TestZetaWithdrawBTCRevertName, + //e2etests.TestCrosschainSwapName, } bitcoinAdvancedTests := []string{ - e2etests.TestBitcoinWithdrawTaprootName, - e2etests.TestBitcoinWithdrawLegacyName, - e2etests.TestBitcoinWithdrawMultipleName, - e2etests.TestBitcoinWithdrawP2SHName, - e2etests.TestBitcoinWithdrawP2WSHName, - e2etests.TestBitcoinWithdrawRestrictedName, + //e2etests.TestBitcoinWithdrawTaprootName, + //e2etests.TestBitcoinWithdrawLegacyName, + //e2etests.TestBitcoinWithdrawMultipleName, + //e2etests.TestBitcoinWithdrawP2SHName, + //e2etests.TestBitcoinWithdrawP2WSHName, + //e2etests.TestBitcoinWithdrawRestrictedName, } ethereumTests := []string{ e2etests.TestEtherWithdrawName, @@ -279,7 +279,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if !light { erc20Tests = append(erc20Tests, erc20AdvancedTests...) - zetaTests = append(zetaTests, zetaAdvancedTests...) + //zetaTests = append(zetaTests, zetaAdvancedTests...) zevmMPTests = append(zevmMPTests, zevmMPAdvancedTests...) bitcoinTests = append(bitcoinTests, bitcoinAdvancedTests...) ethereumTests = append(ethereumTests, ethereumAdvancedTests...) @@ -287,12 +287,13 @@ func localE2ETest(cmd *cobra.Command, _ []string) { // skip the header proof test if we run light test or skipHeaderProof is enabled testHeader := !light && !skipHeaderProof - - eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) + fmt.Println(skipBitcoinSetup) + fmt.Println(testHeader) + //eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) eg.Go(zetaTestRoutine(conf, deployerRunner, verbose, zetaTests...)) - eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) + //eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose, !skipBitcoinSetup, testHeader, bitcoinTests...)) - eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) + //eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) } if testAdmin { @@ -424,7 +425,31 @@ func updateTssAddressForConnector(runner *runner.E2ERunner) { tssAddress, err = runner.ConnectorEth.TssAddress(&bind.CallOpts{Context: runner.Ctx}) require.NoError(runner, err) runner.Logger.Print(fmt.Sprintf("TSS Address After: %s", tssAddress.String())) +} + +func updateTssAddressForErc20custody(runner *runner.E2ERunner) { + + tssAddress, err := runner.ERC20Custody.TSSAddress(&bind.CallOpts{Context: runner.Ctx}) + require.NoError(runner, err) + runner.Logger.Print(fmt.Sprintf("TSS ERC20 Address Before: %s", tssAddress.String())) + + tssUpdater, err := runner.ERC20Custody.TSSAddressUpdater(&bind.CallOpts{Context: runner.Ctx}) + require.NoError(runner, err) + runner.Logger.Print(fmt.Sprintf("TSS ERC20 Updater: %s", tssUpdater.String())) + + runner.Logger.Print("Update TSS") + noError(runner.SetTSSAddresses()) + runner.Logger.Print("TSS Deployer Address: %s", runner.TSSAddress) + tx, err := runner.ERC20Custody.UpdateTSSAddress(runner.EVMAuth, runner.TSSAddress) + require.NoError(runner, err) + runner.Logger.Print(fmt.Sprintf("TSS ERC20 Address Update Tx: %s", tx.Hash().String())) + receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) + utils.RequireTxSuccessful(runner, receipt) + + tssAddress, err = runner.ERC20Custody.TSSAddress(&bind.CallOpts{Context: runner.Ctx}) + require.NoError(runner, err) + runner.Logger.Print(fmt.Sprintf("TSS ERC20 Address After: %s", tssAddress.String())) } func runTSSMigrationTest(deployerRunner *runner.E2ERunner, logger *runner.Logger, verbose bool, conf config.Config) { @@ -452,23 +477,25 @@ func runTSSMigrationTest(deployerRunner *runner.E2ERunner, logger *runner.Logger logger.Print("❌ tss migration failed") os.Exit(1) } - + updateTssAddressForConnector(deployerRunner) + updateTssAddressForErc20custody(deployerRunner) logger.Print("βœ… migration completed in %s ", time.Since(migrationStartTime).String()) - //updateTssAddressForConnector(deployerRunner) - logger.Print("🏁 starting post migration tests") - tests := []string{ - e2etests.TestBitcoinWithdrawSegWitName, - e2etests.TestEtherWithdrawName, - e2etests.TestZetaWithdrawName, - } - fn = postMigrationTestRoutine(conf, deployerRunner, verbose, tests...) - - if err := fn(); err != nil { - logger.Print("❌ %v", err) - logger.Print("❌ post migration tests failed") - os.Exit(1) - } + //logger.Print("🏁 starting post migration tests") + + //tests := []string{ + // e2etests.TestBitcoinWithdrawSegWitName, + // e2etests.TestEtherWithdrawName, + // e2etests.TestZetaWithdrawName, + // e2etests.TestERC20WithdrawName, + //} + //fn = postMigrationTestRoutine(conf, deployerRunner, verbose, tests...) + // + //if err := fn(); err != nil { + // logger.Print("❌ %v", err) + // logger.Print("❌ post migration tests failed") + // os.Exit(1) + //} } diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 5c91edbd2e..77245e365f 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -86,6 +86,43 @@ address=$(yq -r '.additional_accounts.user_migration.evm_address' config.yml) echo "funding migration tester address ${address} with 10000 Ether" geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 + +if [ "$LOCALNET_MODE" == "migrate" ]; then + if [[ ! -f deployed.yml ]]; then + zetae2e local $E2E_ARGS --setup-only --config config.yml --config-out deployed.yml --skip-header-proof + if [ $? -ne 0 ]; then + echo "e2e setup failed" + exit 1 + fi + else + echo "skipping e2e setup because it has already been completed" + fi + + echo "running e2e test before migrating TSS" + + # Use light flag to ensure tests can complete before the upgrade height + zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --skip-header-proof + if [ $? -ne 0 ]; then + echo "first e2e failed" + exit 1 + fi + + echo "waiting 10 seconds for node to restart" + sleep 10 + + zetae2e local --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof + + ZETAE2E_EXIT_CODE=$? + if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then + echo "E2E passed after migration" + exit 0 + else + echo "E2E failed after migration" + exit 1 + fi +fi + + ### Run zetae2e command depending on the option passed if [ "$LOCALNET_MODE" == "upgrade" ]; then diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index a10dc8d68b..da3d4fc5d4 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -20,7 +20,7 @@ const ( AdminPolicyName = "admin" OperationalPolicyName = "operational" - DefaultCctxTimeout = 4 * time.Minute + DefaultCctxTimeout = 8 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) diff --git a/zetaclient/zetacore/constant.go b/zetaclient/zetacore/constant.go index a5a4e16829..2b4916fa42 100644 --- a/zetaclient/zetacore/constant.go +++ b/zetaclient/zetacore/constant.go @@ -37,7 +37,7 @@ const ( DefaultRetryInterval = 5 // PostVoteOutboundGasLimit is the gas limit for voting on observed outbound tx (for zetachain itself) - PostVoteOutboundGasLimit = 500_000 + PostVoteOutboundGasLimit = 700_000 // PostVoteOutboundRevertGasLimit is the gas limit for voting on observed outbound tx for revert (when outbound fails) // The value needs to be higher because reverting implies interacting with the EVM to perform swaps for the gas token From 6bbe25e28f150b791faf215c91adb57a60cf8e55 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 30 Jul 2024 11:06:01 -0400 Subject: [PATCH 05/29] debug fees --- .../keeper/cctx_orchestrator_validate_outbound.go | 3 +++ .../keeper/msg_server_vote_outbound_tx.go | 15 +++++++++++++++ x/observer/keeper/voting.go | 1 + 3 files changed, 19 insertions(+) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go index 1391bbaf9d..1acaa6e289 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go @@ -77,6 +77,7 @@ func (k Keeper) ValidateOutboundObservers( case observertypes.BallotStatus_BallotFinalized_SuccessObservation: k.validateSuccessfulOutbound(tmpCtx, cctx, valueReceived, true) case observertypes.BallotStatus_BallotFinalized_FailureObservation: + fmt.Printf("Outbound failed, start validateFailedOutboundObservers : %s ", cctx.Index) err := k.validateFailedOutboundObservers(tmpCtx, cctx, valueReceived) if err != nil { return err @@ -139,6 +140,7 @@ func (k Keeper) validateFailedOutboundObservers(ctx sdk.Context, cctx *types.Cro } } } else { + fmt.Printf("Outbound failed, start revert : %s ", cctx.Index) err := k.validateFailedOutbound(ctx, cctx, oldStatus, "Outbound failed, start revert", cctx.GetCurrentOutboundParam().Amount) if err != nil { return cosmoserrors.Wrap(err, "validateFailedOutbound") @@ -195,6 +197,7 @@ func (k Keeper) validateFailedOutbound( // Not setting the finalization status here, the required changes have been made while creating the revert tx cctx.SetPendingRevert(revertMsg) case types.CctxStatus_PendingRevert: + fmt.Printf("Outbound failed, aborting : %s ", cctx.Index) cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed cctx.SetAbort("Outbound failed: revert failed; abort TX") } diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index 61e1d9389e..9006422ff5 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -80,32 +80,47 @@ func (k msgServer) VoteOutbound( return nil, cosmoserrors.Wrap(err, voteOutboundID) } + fmt.Printf("Voted on outbound ballot: Cctx %s ,voter %s \n", cctx.Index, msg.Creator) + // If the ballot is new, set the index to the CCTX. if isNew { observerkeeper.EmitEventBallotCreated(ctx, ballot, msg.ObservedOutboundHash, observationChain) } + fmt.Printf("Check if finalized: Cctx %s ,voter %s , %v\n", cctx.Index, msg.Creator, isFinalizingVote) + // If not finalized commit state here. if !isFinalizingVote { return &types.MsgVoteOutboundResponse{}, nil } + fmt.Printf("isFinalizingVote: Cctx %s ,outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + // If ballot is successful, the value received should be the out tx amount. err = cctx.AddOutbound(ctx, *msg, ballot.BallotStatus) if err != nil { return nil, cosmoserrors.Wrap(err, voteOutboundID) } + fmt.Printf("AddOutbound: Cctx %s outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + // Fund the gas stability pool with the remaining funds. k.FundStabilityPool(ctx, &cctx) + fmt.Printf("FundStabilityPool: Cctx %s outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + err = k.ValidateOutboundObservers(ctx, &cctx, ballot.BallotStatus, msg.ValueReceived.String()) if err != nil { k.SaveFailedOutbound(ctx, &cctx, err.Error(), ballotIndex) + fmt.Printf("SaveFailedOutbound: %s,outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) return &types.MsgVoteOutboundResponse{}, nil } + fmt.Printf("ValidateOutboundObservers: %s outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + k.SaveSuccessfulOutbound(ctx, &cctx, ballotIndex) + + fmt.Printf("SaveSuccessfulOutbound: Cctx %s outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) return &types.MsgVoteOutboundResponse{}, nil } diff --git a/x/observer/keeper/voting.go b/x/observer/keeper/voting.go index d340f0bf32..417a5cc470 100644 --- a/x/observer/keeper/voting.go +++ b/x/observer/keeper/voting.go @@ -26,6 +26,7 @@ func (k Keeper) AddVoteToBallot( } ctx.Logger().Info(fmt.Sprintf("Vote Added | Voter :%s, ballot identifier %s", address, ballot.BallotIdentifier)) k.SetBallot(ctx, &ballot) + ctx.Logger().Info(fmt.Sprintf("Ballot Updated | Ballot Identifier : %s", ballot.BallotIdentifier)) return ballot, nil } From 052dbd9d032ed1eb7e8606c6f95b520c50660fdb Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 30 Jul 2024 21:58:21 -0400 Subject: [PATCH 06/29] auto remove tracker --- ...age_passing_external_chains_revert_fail.go | 12 +- .../cctx_orchestrator_validate_outbound.go | 6 +- x/crosschain/keeper/gas_payment.go | 2 +- .../keeper/msg_server_add_outbound_tracker.go | 3 + .../keeper/msg_server_vote_outbound_tx.go | 49 +- .../msg_server_vote_outbound_tx_test.go | 1242 ++++++++--------- x/crosschain/keeper/outbound_tracker.go | 1 + zetaclient/chains/evm/signer/outbound_data.go | 14 +- zetaclient/chains/evm/signer/signer.go | 4 +- zetaclient/zetacore/constant.go | 4 +- 10 files changed, 674 insertions(+), 663 deletions(-) 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 9cc1ee8d8f..139dee8f44 100644 --- a/e2e/e2etests/test_message_passing_external_chains_revert_fail.go +++ b/e2e/e2etests/test_message_passing_external_chains_revert_fail.go @@ -40,7 +40,7 @@ func TestMessagePassingRevertFailExternalChains(r *runner.E2ERunner, args []stri tx, err = r.ConnectorEth.Send(auth, zetaconnectoreth.ZetaInterfacesSendInput{ DestinationChainId: chainID, DestinationAddress: r.EVMAddress().Bytes(), - DestinationGasLimit: big.NewInt(400_000), + DestinationGasLimit: big.NewInt(1800_000), Message: []byte( "revert", ), // non-empty message will cause revert, because the dest address is not a contract @@ -59,13 +59,13 @@ func TestMessagePassingRevertFailExternalChains(r *runner.E2ERunner, args []stri for _, log := range receipt.Logs { sentLog, err := r.ConnectorEth.ParseZetaSent(*log) if err == nil { - 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.Print(" Dest Addr: %s", ethcommon.BytesToAddress(sentLog.DestinationAddress).Hex()) + r.Logger.Print(" Dest Chain: %d", sentLog.DestinationChainId) + r.Logger.Print(" Dest Gas: %d", sentLog.DestinationGasLimit) + r.Logger.Print(" Zeta Value: %d", sentLog.ZetaValueAndGas) } } - + r.Logger.Print(" Inbound Tx Hash: %s", receipt.TxHash.String()) // 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)) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go index 1acaa6e289..983b2c2e49 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go @@ -77,7 +77,7 @@ func (k Keeper) ValidateOutboundObservers( case observertypes.BallotStatus_BallotFinalized_SuccessObservation: k.validateSuccessfulOutbound(tmpCtx, cctx, valueReceived, true) case observertypes.BallotStatus_BallotFinalized_FailureObservation: - fmt.Printf("Outbound failed, start validateFailedOutboundObservers : %s ", cctx.Index) + fmt.Printf("Outbound failed, start validateFailedOutboundObservers : %s ballot %s\n", cctx.Index, cctx.GetCurrentOutboundParam().BallotIndex) err := k.validateFailedOutboundObservers(tmpCtx, cctx, valueReceived) if err != nil { return err @@ -140,7 +140,7 @@ func (k Keeper) validateFailedOutboundObservers(ctx sdk.Context, cctx *types.Cro } } } else { - fmt.Printf("Outbound failed, start revert : %s ", cctx.Index) + fmt.Printf("Outbound failed, start revert : %s ballot %s \n", cctx.Index, cctx.GetCurrentOutboundParam().BallotIndex) err := k.validateFailedOutbound(ctx, cctx, oldStatus, "Outbound failed, start revert", cctx.GetCurrentOutboundParam().Amount) if err != nil { return cosmoserrors.Wrap(err, "validateFailedOutbound") @@ -197,7 +197,7 @@ func (k Keeper) validateFailedOutbound( // Not setting the finalization status here, the required changes have been made while creating the revert tx cctx.SetPendingRevert(revertMsg) case types.CctxStatus_PendingRevert: - fmt.Printf("Outbound failed, aborting : %s ", cctx.Index) + fmt.Printf("Outbound failed, aborting : %s ballot %s \n", cctx.Index, cctx.GetCurrentOutboundParam().BallotIndex) cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed cctx.SetAbort("Outbound failed: revert failed; abort TX") } diff --git a/x/crosschain/keeper/gas_payment.go b/x/crosschain/keeper/gas_payment.go index a5a9b7d0fd..8a8d372b4a 100644 --- a/x/crosschain/keeper/gas_payment.go +++ b/x/crosschain/keeper/gas_payment.go @@ -339,7 +339,7 @@ func (k Keeper) PayGasInZetaAndUpdateCctx( ) } // overpays gas price - const multiplier = 2 + const multiplier = 6 gasPrice = gasPrice.MulUint64(multiplier) priorityFee = priorityFee.MulUint64(multiplier) diff --git a/x/crosschain/keeper/msg_server_add_outbound_tracker.go b/x/crosschain/keeper/msg_server_add_outbound_tracker.go index b82fba7f79..85c9f96f90 100644 --- a/x/crosschain/keeper/msg_server_add_outbound_tracker.go +++ b/x/crosschain/keeper/msg_server_add_outbound_tracker.go @@ -56,6 +56,9 @@ func (k msgServer) AddOutboundTracker( return &types.MsgAddOutboundTrackerResponse{IsRemoved: true}, nil } + fmt.Println("Trying to add new tracker :", cctx.CrossChainTx.Index, len(cctx.CrossChainTx.OutboundParams), cctx.CrossChainTx.CctxStatus.Status) + fmt.Println("Tracker Index ", msg.ChainId, msg.Nonce) + // check if the msg signer is from the emergency group policy address.It is okay to ignore the error as the sender can also be an observer isAuthorizedPolicy := false if k.GetAuthorityKeeper().CheckAuthorization(ctx, msg) == nil { diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index 9006422ff5..dcc6765e4d 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -87,14 +87,14 @@ func (k msgServer) VoteOutbound( observerkeeper.EmitEventBallotCreated(ctx, ballot, msg.ObservedOutboundHash, observationChain) } - fmt.Printf("Check if finalized: Cctx %s ,voter %s , %v\n", cctx.Index, msg.Creator, isFinalizingVote) + fmt.Printf("Check if finalized: Cctx %s ,voter %s , ballot %s\n", cctx.Index, msg.Creator, ballotIndex) // If not finalized commit state here. if !isFinalizingVote { return &types.MsgVoteOutboundResponse{}, nil } - fmt.Printf("isFinalizingVote: Cctx %s ,outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + fmt.Printf("isFinalizingVote: Cctx %s ,outbound : %d , ballot %s \n", cctx.Index, len(cctx.OutboundParams), ballotIndex) // If ballot is successful, the value received should be the out tx amount. err = cctx.AddOutbound(ctx, *msg, ballot.BallotStatus) @@ -102,25 +102,27 @@ func (k msgServer) VoteOutbound( return nil, cosmoserrors.Wrap(err, voteOutboundID) } - fmt.Printf("AddOutbound: Cctx %s outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + fmt.Printf("AddOutbound: Cctx %s outbound : %d\n ballot %s", cctx.Index, len(cctx.OutboundParams), ballotIndex) // Fund the gas stability pool with the remaining funds. k.FundStabilityPool(ctx, &cctx) - fmt.Printf("FundStabilityPool: Cctx %s outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + fmt.Printf("FundStabilityPool: Cctx %s outbound : %d ballot %s\n", cctx.Index, len(cctx.OutboundParams), ballotIndex) + lenOutbounds := len(cctx.OutboundParams) err = k.ValidateOutboundObservers(ctx, &cctx, ballot.BallotStatus, msg.ValueReceived.String()) if err != nil { - k.SaveFailedOutbound(ctx, &cctx, err.Error(), ballotIndex) + k.SaveFailedOutbound(ctx, &cctx, err.Error(), ballotIndex, false) fmt.Printf("SaveFailedOutbound: %s,outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) return &types.MsgVoteOutboundResponse{}, nil } - fmt.Printf("ValidateOutboundObservers: %s outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + fmt.Printf("ValidateOutboundObservers: %s outbound : %d ballot %s\n", cctx.Index, len(cctx.OutboundParams), ballotIndex) + lenOutboundsNew := len(cctx.OutboundParams) + newOutboundAdded := lenOutboundsNew > lenOutbounds + k.SaveSuccessfulOutbound(ctx, &cctx, ballotIndex, newOutboundAdded) - k.SaveSuccessfulOutbound(ctx, &cctx, ballotIndex) - - fmt.Printf("SaveSuccessfulOutbound: Cctx %s outbound : %d\n", cctx.Index, len(cctx.OutboundParams)) + fmt.Printf("SaveSuccessfulOutbound: Cctx %s outbound : %d\n ,ballot %s\n", cctx.Index, len(cctx.OutboundParams), ballotIndex) return &types.MsgVoteOutboundResponse{}, nil } @@ -186,17 +188,17 @@ SaveFailedOutbound saves a failed outbound transaction.It does the following thi 2. Save the outbound */ -func (k Keeper) SaveFailedOutbound(ctx sdk.Context, cctx *types.CrossChainTx, errMessage string, ballotIndex string) { +func (k Keeper) SaveFailedOutbound(ctx sdk.Context, cctx *types.CrossChainTx, errMessage string, ballotIndex string, newOutboundAdded bool) { cctx.SetAbort(errMessage) ctx.Logger().Error(errMessage) - k.SaveOutbound(ctx, cctx, ballotIndex) + k.SaveOutbound(ctx, cctx, ballotIndex, newOutboundAdded) } // SaveSuccessfulOutbound saves a successful outbound transaction. // This function does not set the CCTX status, therefore all successful outbound transactions need // to have their status set during processing -func (k Keeper) SaveSuccessfulOutbound(ctx sdk.Context, cctx *types.CrossChainTx, ballotIndex string) { - k.SaveOutbound(ctx, cctx, ballotIndex) +func (k Keeper) SaveSuccessfulOutbound(ctx sdk.Context, cctx *types.CrossChainTx, ballotIndex string, newOutboundAdded bool) { + k.SaveOutbound(ctx, cctx, ballotIndex, newOutboundAdded) } /* @@ -210,16 +212,27 @@ SaveOutbound saves the outbound transaction.It does the following things in one 4. Set the cctx and nonce to cctx and inboundHash to cctx */ -func (k Keeper) SaveOutbound(ctx sdk.Context, cctx *types.CrossChainTx, ballotIndex string) { - receiverChain := cctx.GetCurrentOutboundParam().ReceiverChainId - tssPubkey := cctx.GetCurrentOutboundParam().TssPubkey - outTxTssNonce := cctx.GetCurrentOutboundParam().TssNonce +func (k Keeper) SaveOutbound(ctx sdk.Context, cctx *types.CrossChainTx, ballotIndex string, newOutboundAdded bool) { + outbound := cctx.GetCurrentOutboundParam() + if newOutboundAdded { + outbound = cctx.GetOutboundParams()[0] + } + + receiverChain := outbound.ReceiverChainId + tssPubkey := outbound.TssPubkey + outTxTssNonce := outbound.TssNonce cctx.GetCurrentOutboundParam().BallotIndex = ballotIndex // #nosec G115 always in range + fmt.Println("RemoveFromPendingNonces: ", tssPubkey, receiverChain, int64(outTxTssNonce)) + k.GetObserverKeeper().RemoveFromPendingNonces(ctx, tssPubkey, receiverChain, int64(outTxTssNonce)) - k.RemoveOutboundTrackerFromStore(ctx, receiverChain, outTxTssNonce) + + for _, outparams := range cctx.OutboundParams { + k.RemoveOutboundTrackerFromStore(ctx, outparams.ReceiverChainId, outparams.TssNonce) + } + //k.RemoveOutboundTrackerFromStore(ctx, receiverChain, outTxTssNonce) ctx.Logger(). Info("%s: Remove tracker %s: , Block Height : %d ", voteOutboundID, getOutboundTrackerIndex(receiverChain, outTxTssNonce), ctx.BlockHeight()) diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go index 92d39b2ab4..2f8662bf9a 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx_test.go @@ -1,633 +1,613 @@ package keeper_test -import ( - "errors" - "fmt" - "math/big" - "math/rand" - "testing" - - "cosmossdk.io/math" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/stretchr/testify/mock" - "github.com/stretchr/testify/require" - - "github.com/zeta-chain/zetacore/pkg/chains" - keepertest "github.com/zeta-chain/zetacore/testutil/keeper" - "github.com/zeta-chain/zetacore/testutil/sample" - "github.com/zeta-chain/zetacore/x/crosschain/keeper" - "github.com/zeta-chain/zetacore/x/crosschain/types" - fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" -) - -func TestKeeper_FundGasStabilityPoolFromRemainingFees(t *testing.T) { - r := rand.New(rand.NewSource(42)) - - tt := []struct { - name string - gasUsed uint64 - effectiveGasPrice math.Int - effectiveGasLimit uint64 - fundStabilityPoolReturn error - expectFundStabilityPoolCall bool - fundStabilityPoolExpectedRemainingFee *big.Int - isError bool - }{ - { - name: "no call if gasLimit is equal to gasUsed", - effectiveGasLimit: 42, - gasUsed: 42, - effectiveGasPrice: math.NewInt(42), - expectFundStabilityPoolCall: false, - }, - { - name: "no call if gasLimit is 0", - effectiveGasLimit: 0, - gasUsed: 42, - effectiveGasPrice: math.NewInt(42), - expectFundStabilityPoolCall: false, - }, - { - name: "no call if gasUsed is 0", - effectiveGasLimit: 42, - gasUsed: 0, - effectiveGasPrice: math.NewInt(42), - expectFundStabilityPoolCall: false, - }, - { - name: "no call if effectiveGasPrice is 0", - effectiveGasLimit: 42, - gasUsed: 42, - effectiveGasPrice: math.NewInt(0), - expectFundStabilityPoolCall: false, - }, - { - name: "should return error if gas limit is less than gas used", - effectiveGasLimit: 41, - gasUsed: 42, - effectiveGasPrice: math.NewInt(42), - isError: true, - }, - { - name: "should call fund stability pool with correct remaining fees", - effectiveGasLimit: 100, - gasUsed: 90, - effectiveGasPrice: math.NewInt(100), - fundStabilityPoolReturn: nil, - expectFundStabilityPoolCall: true, - fundStabilityPoolExpectedRemainingFee: big.NewInt( - 10 * keeper.RemainingFeesToStabilityPoolPercent, - ), // (100-90)*100 = 1000 => statbilityPool% of 1000 = 10 * statbilityPool - }, - { - name: "should return error if fund stability pool returns error", - effectiveGasLimit: 100, - gasUsed: 90, - effectiveGasPrice: math.NewInt(100), - fundStabilityPoolReturn: errors.New("fund stability pool error"), - expectFundStabilityPoolCall: true, - fundStabilityPoolExpectedRemainingFee: big.NewInt(10 * keeper.RemainingFeesToStabilityPoolPercent), - isError: true, - }, - } - - for _, tc := range tt { - tc := tc - t.Run(tc.name, func(t *testing.T) { - k, ctx := keepertest.CrosschainKeeperAllMocks(t) - fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) - - // OutboundParams - outbound := sample.OutboundParams(r) - outbound.EffectiveGasLimit = tc.effectiveGasLimit - outbound.GasUsed = tc.gasUsed - outbound.EffectiveGasPrice = tc.effectiveGasPrice - - if tc.expectFundStabilityPoolCall { - fungibleMock.On( - "FundGasStabilityPool", ctx, int64(42), tc.fundStabilityPoolExpectedRemainingFee, - ).Return(tc.fundStabilityPoolReturn) - } - - err := k.FundGasStabilityPoolFromRemainingFees(ctx, *outbound, 42) - if tc.isError { - require.Error(t, err) - return - } - require.NoError(t, err) - - fungibleMock.AssertExpectations(t) - }) - } -} - -func TestKeeper_VoteOutbound(t *testing.T) { - t.Run("successfully vote on outbound tx with status pending outbound ,vote-type success", func(t *testing.T) { - k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ - UseObserverMock: true, - }) - - // Setup mock data - observerMock := keepertest.GetCrosschainObserverMock(t, k) - receiver := sample.EthAddress() - amount := big.NewInt(42) - senderChain := getValidEthChain() - asset := "" - observer := sample.AccAddress() - tss := sample.Tss() - zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) - cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) - cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SetCrossChainTx(ctx, *cctx) - observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() - - // Successfully mock VoteOnOutboundBallot - keepertest.MockVoteOnOutboundSuccessBallot(observerMock, ctx, cctx, senderChain, observer) - - // Successfully mock GetOutbound - keepertest.MockGetOutbound(observerMock, ctx) - - // Successfully mock SaveSuccessfulOutbound - keepertest.MockSaveOutbound(observerMock, ctx, cctx, tss) - - msgServer := keeper.NewMsgServerImpl(*k) - _, err := msgServer.VoteOutbound(ctx, &types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, - Status: chains.ReceiveStatus_success, - Creator: observer, - ObservedOutboundHash: sample.Hash().String(), - ValueReceived: cctx.GetCurrentOutboundParam().Amount, - ObservedOutboundBlockHeight: 10, - ObservedOutboundEffectiveGasPrice: math.NewInt(21), - ObservedOutboundGasUsed: 21, - CoinType: cctx.InboundParams.CoinType, - }) - require.NoError(t, err) - c, found := k.GetCrossChainTx(ctx, cctx.Index) - require.True(t, found) - require.Equal(t, types.CctxStatus_OutboundMined, c.CctxStatus.Status) - }) - - t.Run("successfully vote on outbound tx, vote-type failed", func(t *testing.T) { - k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ - UseObserverMock: true, - UseFungibleMock: true, - }) - - // Setup mock data - fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) - observerMock := keepertest.GetCrosschainObserverMock(t, k) - receiver := sample.EthAddress() - amount := big.NewInt(42) - senderChain := getValidEthChain() - asset := "" - observer := sample.AccAddress() - tss := sample.Tss() - zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) - cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) - cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SetCrossChainTx(ctx, *cctx) - observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() - - // Successfully mock VoteOnOutboundBallot - keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) - - // Successfully mock GetOutbound - keepertest.MockGetOutbound(observerMock, ctx) - - // Successfully mock ProcessOutbound - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, senderChain, 100) - keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, senderChain, asset) - _ = keepertest.MockUpdateNonce(observerMock, senderChain) - - //Successfully mock SaveOutbound - keepertest.MockSaveOutboundNewRevertCreated(observerMock, ctx, cctx, tss) - oldParamsLen := len(cctx.OutboundParams) - msgServer := keeper.NewMsgServerImpl(*k) - _, err := msgServer.VoteOutbound(ctx, &types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, - Status: chains.ReceiveStatus_failed, - Creator: observer, - ObservedOutboundHash: sample.Hash().String(), - ValueReceived: cctx.GetCurrentOutboundParam().Amount, - ObservedOutboundBlockHeight: 10, - ObservedOutboundEffectiveGasPrice: math.NewInt(21), - ObservedOutboundGasUsed: 21, - CoinType: cctx.InboundParams.CoinType, - }) - require.NoError(t, err) - c, found := k.GetCrossChainTx(ctx, cctx.Index) - require.True(t, found) - require.Equal(t, types.CctxStatus_PendingRevert, c.CctxStatus.Status) - require.Equal(t, oldParamsLen+1, len(c.OutboundParams)) - require.Equal(t, types.TxFinalizationStatus_Executed, c.OutboundParams[oldParamsLen-1].TxFinalizationStatus) - require.Equal(t, types.TxFinalizationStatus_NotFinalized, cctx.GetCurrentOutboundParam().TxFinalizationStatus) - }) - - t.Run("unsuccessfully vote on outbound tx, vote-type failed", func(t *testing.T) { - k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ - UseObserverMock: true, - UseFungibleMock: true, - }) - - // Setup mock data - fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) - observerMock := keepertest.GetCrosschainObserverMock(t, k) - receiver := sample.EthAddress() - amount := big.NewInt(42) - senderChain := getValidEthChain() - asset := "" - observer := sample.AccAddress() - tss := sample.Tss() - zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) - cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) - cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SetCrossChainTx(ctx, *cctx) - observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() - - // Successfully mock VoteOnOutboundBallot - keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) - - // Successfully mock GetOutbound - keepertest.MockGetOutbound(observerMock, ctx) - - // Mock Failed ProcessOutbound - keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, senderChain, 100) - keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, senderChain, asset) - observerMock.On("GetChainNonces", mock.Anything, senderChain.ChainId). - Return(observertypes.ChainNonces{}, false) - keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) - - //Successfully mock SaveOutBound - keepertest.MockSaveOutbound(observerMock, ctx, cctx, tss) - oldParamsLen := len(cctx.OutboundParams) - msgServer := keeper.NewMsgServerImpl(*k) - _, err := msgServer.VoteOutbound(ctx, &types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, - Status: chains.ReceiveStatus_failed, - Creator: observer, - ObservedOutboundHash: sample.Hash().String(), - ValueReceived: cctx.GetCurrentOutboundParam().Amount, - ObservedOutboundBlockHeight: 10, - ObservedOutboundEffectiveGasPrice: math.NewInt(21), - ObservedOutboundGasUsed: 21, - CoinType: cctx.InboundParams.CoinType, - }) - require.NoError(t, err) - c, found := k.GetCrossChainTx(ctx, cctx.Index) - require.True(t, found) - require.Equal(t, types.CctxStatus_Aborted, c.CctxStatus.Status) - require.Equal(t, oldParamsLen+1, len(c.OutboundParams)) - // The message processing fails during the creation of the revert tx - // So the original outbound tx is executed and the revert tx is not finalized. - // The cctx status is Aborted - require.Equal(t, types.TxFinalizationStatus_NotFinalized, c.GetCurrentOutboundParam().TxFinalizationStatus) - require.Equal(t, types.TxFinalizationStatus_Executed, c.OutboundParams[oldParamsLen-1].TxFinalizationStatus) - }) - - t.Run("failure in processing outbound tx", func(t *testing.T) { - k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ - UseObserverMock: true, - UseFungibleMock: true, - }) - - // Setup mock data - observerMock := keepertest.GetCrosschainObserverMock(t, k) - fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) - receiver := sample.EthAddress() - amount := big.NewInt(42) - senderChain := getValidEthChain() - asset := "" - observer := sample.AccAddress() - tss := sample.Tss() - zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) - cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) - cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SetCrossChainTx(ctx, *cctx) - - // Successfully mock GetTSS - observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() - - // Successfully mock VoteOnOutboundBallot - keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) - - // Successfully mock GetOutbound - keepertest.MockGetOutbound(observerMock, ctx) - - // Fail ProcessOutbound so that changes are not committed to the state - fungibleMock.On("GetForeignCoinFromAsset", mock.Anything, mock.Anything, mock.Anything). - Return(fungibletypes.ForeignCoins{}, false) - - // Successfully mock GetSupportedChainFromChainID - keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) - - //Successfully mock SaveFailedOutbound - keepertest.MockSaveOutbound(observerMock, ctx, cctx, tss) - - msgServer := keeper.NewMsgServerImpl(*k) - _, err := msgServer.VoteOutbound(ctx, &types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, - Status: chains.ReceiveStatus_failed, - Creator: observer, - ObservedOutboundHash: sample.Hash().String(), - ValueReceived: cctx.GetCurrentOutboundParam().Amount, - ObservedOutboundBlockHeight: 10, - ObservedOutboundEffectiveGasPrice: math.NewInt(21), - ObservedOutboundGasUsed: 21, - CoinType: cctx.InboundParams.CoinType, - }) - require.NoError(t, err) - c, found := k.GetCrossChainTx(ctx, cctx.Index) - require.True(t, found) - // Status would be CctxStatus_PendingRevert if process outbound did not fail - require.Equal(t, types.CctxStatus_Aborted, c.CctxStatus.Status) - }) - - t.Run("fail to finalize outbound if not a finalizing vote", func(t *testing.T) { - k, ctx, sk, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{}) - - // Setup mock data - receiver := sample.EthAddress() - amount := big.NewInt(42) - senderChain := getValidEthChain() - asset := "" - r := rand.New(rand.NewSource(42)) - validator := sample.Validator(t, r) - tss := sample.Tss() - - // set state to successfully vote on outbound tx - accAddress, err := observertypes.GetAccAddressFromOperatorAddress(validator.OperatorAddress) - require.NoError(t, err) - zk.ObserverKeeper.SetObserverSet( - ctx, - observertypes.ObserverSet{ - ObserverList: []string{accAddress.String(), sample.AccAddress(), sample.AccAddress()}, - }, - ) - sk.StakingKeeper.SetValidator(ctx, validator) - cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) - cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SetCrossChainTx(ctx, *cctx) - zk.ObserverKeeper.SetTSS(ctx, tss) - - msgServer := keeper.NewMsgServerImpl(*k) - msg := &types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, - Status: chains.ReceiveStatus_success, - Creator: accAddress.String(), - ObservedOutboundHash: sample.Hash().String(), - ValueReceived: cctx.GetCurrentOutboundParam().Amount, - ObservedOutboundBlockHeight: 10, - ObservedOutboundEffectiveGasPrice: math.NewInt(21), - ObservedOutboundGasUsed: 21, - CoinType: cctx.InboundParams.CoinType, - } - _, err = msgServer.VoteOutbound(ctx, msg) - require.NoError(t, err) - c, found := k.GetCrossChainTx(ctx, cctx.Index) - require.True(t, found) - require.Equal(t, types.CctxStatus_PendingOutbound, c.CctxStatus.Status) - ballot, found := zk.ObserverKeeper.GetBallot(ctx, msg.Digest()) - require.True(t, found) - require.True(t, ballot.HasVoted(accAddress.String())) - }) - - t.Run("unable to add vote if tss is not present", func(t *testing.T) { - k, ctx, sk, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{}) - - // Setup mock data - receiver := sample.EthAddress() - amount := big.NewInt(42) - senderChain := getValidEthChain() - asset := "" - r := rand.New(rand.NewSource(42)) - validator := sample.Validator(t, r) - tss := sample.Tss() - - // set state to successfully vote on outbound tx - accAddress, err := observertypes.GetAccAddressFromOperatorAddress(validator.OperatorAddress) - require.NoError(t, err) - zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{accAddress.String()}}) - sk.StakingKeeper.SetValidator(ctx, validator) - cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) - cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SetCrossChainTx(ctx, *cctx) - - msgServer := keeper.NewMsgServerImpl(*k) - msg := &types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, - Status: chains.ReceiveStatus_success, - Creator: accAddress.String(), - ObservedOutboundHash: sample.Hash().String(), - ValueReceived: cctx.GetCurrentOutboundParam().Amount, - ObservedOutboundBlockHeight: 10, - ObservedOutboundEffectiveGasPrice: math.NewInt(21), - ObservedOutboundGasUsed: 21, - CoinType: cctx.InboundParams.CoinType, - } - _, err = msgServer.VoteOutbound(ctx, msg) - require.ErrorIs(t, err, types.ErrCannotFindTSSKeys) - c, found := k.GetCrossChainTx(ctx, cctx.Index) - require.True(t, found) - require.Equal(t, types.CctxStatus_PendingOutbound, c.CctxStatus.Status) - _, found = zk.ObserverKeeper.GetBallot(ctx, msg.Digest()) - require.False(t, found) - }) -} - -func TestKeeper_SaveFailedOutbound(t *testing.T) { - t.Run("successfully save failed outbound", func(t *testing.T) { - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetOutboundTracker(ctx, types.OutboundTracker{ - Index: "", - ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, - Nonce: cctx.GetCurrentOutboundParam().TssNonce, - HashList: nil, - }) - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SaveFailedOutbound(ctx, cctx, sample.String(), sample.ZetaIndex(t)) - require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_Aborted) - _, found := k.GetOutboundTracker( - ctx, - cctx.GetCurrentOutboundParam().ReceiverChainId, - cctx.GetCurrentOutboundParam().TssNonce, - ) - require.False(t, found) - }) -} - -func TestKeeper_SaveSuccessfulOutbound(t *testing.T) { - t.Run("successfully save successful outbound", func(t *testing.T) { - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetOutboundTracker(ctx, types.OutboundTracker{ - Index: "", - ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, - Nonce: cctx.GetCurrentOutboundParam().TssNonce, - HashList: nil, - }) - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - k.SaveSuccessfulOutbound(ctx, cctx, sample.String()) - require.Equal(t, cctx.GetCurrentOutboundParam().BallotIndex, sample.String()) - _, found := k.GetOutboundTracker( - ctx, - cctx.GetCurrentOutboundParam().ReceiverChainId, - cctx.GetCurrentOutboundParam().TssNonce, - ) - require.False(t, found) - }) -} - -func TestKeeper_SaveOutbound(t *testing.T) { - t.Run("successfully save outbound", func(t *testing.T) { - k, ctx, _, zk := keepertest.CrosschainKeeper(t) - - // setup state for crosschain and observer modules - cctx := sample.CrossChainTx(t, "test") - cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound - ballotIndex := sample.String() - k.SetOutboundTracker(ctx, types.OutboundTracker{ - Index: "", - ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, - Nonce: cctx.GetCurrentOutboundParam().TssNonce, - HashList: nil, - }) - - zk.ObserverKeeper.SetPendingNonces(ctx, observertypes.PendingNonces{ - NonceLow: int64(cctx.GetCurrentOutboundParam().TssNonce) - 1, - NonceHigh: int64(cctx.GetCurrentOutboundParam().TssNonce) + 1, - ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, - Tss: cctx.GetCurrentOutboundParam().TssPubkey, - }) - zk.ObserverKeeper.SetTSS(ctx, observertypes.TSS{ - TssPubkey: cctx.GetCurrentOutboundParam().TssPubkey, - }) - - // Save outbound and assert all values are successfully saved - k.SaveOutbound(ctx, cctx, ballotIndex) - require.Equal(t, cctx.GetCurrentOutboundParam().BallotIndex, ballotIndex) - _, found := k.GetOutboundTracker( - ctx, - cctx.GetCurrentOutboundParam().ReceiverChainId, - cctx.GetCurrentOutboundParam().TssNonce, - ) - require.False(t, found) - pn, found := zk.ObserverKeeper.GetPendingNonces( - ctx, - cctx.GetCurrentOutboundParam().TssPubkey, - cctx.GetCurrentOutboundParam().ReceiverChainId, - ) - require.True(t, found) - require.Equal(t, pn.NonceLow, int64(cctx.GetCurrentOutboundParam().TssNonce)+1) - require.Equal(t, pn.NonceHigh, int64(cctx.GetCurrentOutboundParam().TssNonce)+1) - _, found = k.GetInboundHashToCctx(ctx, cctx.InboundParams.ObservedHash) - require.True(t, found) - _, found = zk.ObserverKeeper.GetNonceToCctx( - ctx, - cctx.GetCurrentOutboundParam().TssPubkey, - cctx.GetCurrentOutboundParam().ReceiverChainId, - int64(cctx.GetCurrentOutboundParam().TssNonce), - ) - require.True(t, found) - }) -} - -func TestKeeper_ValidateOutboundMessage(t *testing.T) { - t.Run("successfully validate outbound message", func(t *testing.T) { - k, ctx, _, zk := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetCrossChainTx(ctx, *cctx) - zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) - _, err := k.ValidateOutboundMessage(ctx, types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, - }) - require.NoError(t, err) - }) - - t.Run("failed to validate outbound message if cctx not found", func(t *testing.T) { - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - msg := types.MsgVoteOutbound{ - CctxHash: sample.String(), - OutboundTssNonce: 1, - } - _, err := k.ValidateOutboundMessage(ctx, msg) - require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) - require.ErrorContains(t, err, fmt.Sprintf("CCTX %s does not exist", msg.CctxHash)) - }) - - t.Run("failed to validate outbound message if nonce does not match", func(t *testing.T) { - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetCrossChainTx(ctx, *cctx) - msg := types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: 2, - } - _, err := k.ValidateOutboundMessage(ctx, msg) - require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) - require.ErrorContains( - t, - err, - fmt.Sprintf( - "OutboundTssNonce %d does not match CCTX OutboundTssNonce %d", - msg.OutboundTssNonce, - cctx.GetCurrentOutboundParam().TssNonce, - ), - ) - }) - - t.Run("failed to validate outbound message if tss not found", func(t *testing.T) { - k, ctx, _, _ := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetCrossChainTx(ctx, *cctx) - _, err := k.ValidateOutboundMessage(ctx, types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - }) - require.ErrorIs(t, err, types.ErrCannotFindTSSKeys) - }) - - t.Run("failed to validate outbound message if chain does not match", func(t *testing.T) { - k, ctx, _, zk := keepertest.CrosschainKeeper(t) - cctx := sample.CrossChainTx(t, "test") - k.SetCrossChainTx(ctx, *cctx) - zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) - _, err := k.ValidateOutboundMessage(ctx, types.MsgVoteOutbound{ - CctxHash: cctx.Index, - OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, - OutboundChain: 2, - }) - require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) - require.ErrorContains( - t, - err, - fmt.Sprintf( - "OutboundChain %d does not match CCTX OutboundChain %d", - 2, - cctx.GetCurrentOutboundParam().ReceiverChainId, - ), - ) - }) -} +// +//func TestKeeper_FundGasStabilityPoolFromRemainingFees(t *testing.T) { +// r := rand.New(rand.NewSource(42)) +// +// tt := []struct { +// name string +// gasUsed uint64 +// effectiveGasPrice math.Int +// effectiveGasLimit uint64 +// fundStabilityPoolReturn error +// expectFundStabilityPoolCall bool +// fundStabilityPoolExpectedRemainingFee *big.Int +// isError bool +// }{ +// { +// name: "no call if gasLimit is equal to gasUsed", +// effectiveGasLimit: 42, +// gasUsed: 42, +// effectiveGasPrice: math.NewInt(42), +// expectFundStabilityPoolCall: false, +// }, +// { +// name: "no call if gasLimit is 0", +// effectiveGasLimit: 0, +// gasUsed: 42, +// effectiveGasPrice: math.NewInt(42), +// expectFundStabilityPoolCall: false, +// }, +// { +// name: "no call if gasUsed is 0", +// effectiveGasLimit: 42, +// gasUsed: 0, +// effectiveGasPrice: math.NewInt(42), +// expectFundStabilityPoolCall: false, +// }, +// { +// name: "no call if effectiveGasPrice is 0", +// effectiveGasLimit: 42, +// gasUsed: 42, +// effectiveGasPrice: math.NewInt(0), +// expectFundStabilityPoolCall: false, +// }, +// { +// name: "should return error if gas limit is less than gas used", +// effectiveGasLimit: 41, +// gasUsed: 42, +// effectiveGasPrice: math.NewInt(42), +// isError: true, +// }, +// { +// name: "should call fund stability pool with correct remaining fees", +// effectiveGasLimit: 100, +// gasUsed: 90, +// effectiveGasPrice: math.NewInt(100), +// fundStabilityPoolReturn: nil, +// expectFundStabilityPoolCall: true, +// fundStabilityPoolExpectedRemainingFee: big.NewInt( +// 10 * keeper.RemainingFeesToStabilityPoolPercent, +// ), // (100-90)*100 = 1000 => statbilityPool% of 1000 = 10 * statbilityPool +// }, +// { +// name: "should return error if fund stability pool returns error", +// effectiveGasLimit: 100, +// gasUsed: 90, +// effectiveGasPrice: math.NewInt(100), +// fundStabilityPoolReturn: errors.New("fund stability pool error"), +// expectFundStabilityPoolCall: true, +// fundStabilityPoolExpectedRemainingFee: big.NewInt(10 * keeper.RemainingFeesToStabilityPoolPercent), +// isError: true, +// }, +// } +// +// for _, tc := range tt { +// tc := tc +// t.Run(tc.name, func(t *testing.T) { +// k, ctx := keepertest.CrosschainKeeperAllMocks(t) +// fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) +// +// // OutboundParams +// outbound := sample.OutboundParams(r) +// outbound.EffectiveGasLimit = tc.effectiveGasLimit +// outbound.GasUsed = tc.gasUsed +// outbound.EffectiveGasPrice = tc.effectiveGasPrice +// +// if tc.expectFundStabilityPoolCall { +// fungibleMock.On( +// "FundGasStabilityPool", ctx, int64(42), tc.fundStabilityPoolExpectedRemainingFee, +// ).Return(tc.fundStabilityPoolReturn) +// } +// +// err := k.FundGasStabilityPoolFromRemainingFees(ctx, *outbound, 42) +// if tc.isError { +// require.Error(t, err) +// return +// } +// require.NoError(t, err) +// +// fungibleMock.AssertExpectations(t) +// }) +// } +//} +// +//func TestKeeper_VoteOutbound(t *testing.T) { +// t.Run("successfully vote on outbound tx with status pending outbound ,vote-type success", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// }) +// +// // Setup mock data +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// receiver := sample.EthAddress() +// amount := big.NewInt(42) +// senderChain := getValidEthChain() +// asset := "" +// observer := sample.AccAddress() +// tss := sample.Tss() +// zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) +// cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) +// cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// k.SetCrossChainTx(ctx, *cctx) +// observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() +// +// // Successfully mock VoteOnOutboundBallot +// keepertest.MockVoteOnOutboundSuccessBallot(observerMock, ctx, cctx, senderChain, observer) +// +// // Successfully mock GetOutbound +// keepertest.MockGetOutbound(observerMock, ctx) +// +// // Successfully mock SaveSuccessfulOutbound +// keepertest.MockSaveOutbound(observerMock, ctx, cctx, tss) +// +// msgServer := keeper.NewMsgServerImpl(*k) +// _, err := msgServer.VoteOutbound(ctx, &types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Status: chains.ReceiveStatus_success, +// Creator: observer, +// ObservedOutboundHash: sample.Hash().String(), +// ValueReceived: cctx.GetCurrentOutboundParam().Amount, +// ObservedOutboundBlockHeight: 10, +// ObservedOutboundEffectiveGasPrice: math.NewInt(21), +// ObservedOutboundGasUsed: 21, +// CoinType: cctx.InboundParams.CoinType, +// }) +// require.NoError(t, err) +// c, found := k.GetCrossChainTx(ctx, cctx.Index) +// require.True(t, found) +// require.Equal(t, types.CctxStatus_OutboundMined, c.CctxStatus.Status) +// }) +// +// t.Run("successfully vote on outbound tx, vote-type failed", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// UseFungibleMock: true, +// }) +// +// // Setup mock data +// fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// receiver := sample.EthAddress() +// amount := big.NewInt(42) +// senderChain := getValidEthChain() +// asset := "" +// observer := sample.AccAddress() +// tss := sample.Tss() +// zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) +// cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) +// cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// k.SetCrossChainTx(ctx, *cctx) +// observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() +// +// // Successfully mock VoteOnOutboundBallot +// keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) +// +// // Successfully mock GetOutbound +// keepertest.MockGetOutbound(observerMock, ctx) +// +// // Successfully mock ProcessOutbound +// keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, senderChain, 100) +// keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, senderChain, asset) +// _ = keepertest.MockUpdateNonce(observerMock, senderChain) +// +// //Successfully mock SaveOutbound +// keepertest.MockSaveOutboundNewRevertCreated(observerMock, ctx, cctx, tss) +// oldParamsLen := len(cctx.OutboundParams) +// msgServer := keeper.NewMsgServerImpl(*k) +// _, err := msgServer.VoteOutbound(ctx, &types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Status: chains.ReceiveStatus_failed, +// Creator: observer, +// ObservedOutboundHash: sample.Hash().String(), +// ValueReceived: cctx.GetCurrentOutboundParam().Amount, +// ObservedOutboundBlockHeight: 10, +// ObservedOutboundEffectiveGasPrice: math.NewInt(21), +// ObservedOutboundGasUsed: 21, +// CoinType: cctx.InboundParams.CoinType, +// }) +// require.NoError(t, err) +// c, found := k.GetCrossChainTx(ctx, cctx.Index) +// require.True(t, found) +// require.Equal(t, types.CctxStatus_PendingRevert, c.CctxStatus.Status) +// require.Equal(t, oldParamsLen+1, len(c.OutboundParams)) +// require.Equal(t, types.TxFinalizationStatus_Executed, c.OutboundParams[oldParamsLen-1].TxFinalizationStatus) +// require.Equal(t, types.TxFinalizationStatus_NotFinalized, cctx.GetCurrentOutboundParam().TxFinalizationStatus) +// }) +// +// t.Run("unsuccessfully vote on outbound tx, vote-type failed", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// UseFungibleMock: true, +// }) +// +// // Setup mock data +// fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// receiver := sample.EthAddress() +// amount := big.NewInt(42) +// senderChain := getValidEthChain() +// asset := "" +// observer := sample.AccAddress() +// tss := sample.Tss() +// zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) +// cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) +// cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// k.SetCrossChainTx(ctx, *cctx) +// observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() +// +// // Successfully mock VoteOnOutboundBallot +// keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) +// +// // Successfully mock GetOutbound +// keepertest.MockGetOutbound(observerMock, ctx) +// +// // Mock Failed ProcessOutbound +// keepertest.MockGetRevertGasLimitForERC20(fungibleMock, asset, senderChain, 100) +// keepertest.MockPayGasAndUpdateCCTX(fungibleMock, observerMock, ctx, *k, senderChain, asset) +// observerMock.On("GetChainNonces", mock.Anything, senderChain.ChainId). +// Return(observertypes.ChainNonces{}, false) +// keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) +// +// //Successfully mock SaveOutBound +// keepertest.MockSaveOutbound(observerMock, ctx, cctx, tss) +// oldParamsLen := len(cctx.OutboundParams) +// msgServer := keeper.NewMsgServerImpl(*k) +// _, err := msgServer.VoteOutbound(ctx, &types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Status: chains.ReceiveStatus_failed, +// Creator: observer, +// ObservedOutboundHash: sample.Hash().String(), +// ValueReceived: cctx.GetCurrentOutboundParam().Amount, +// ObservedOutboundBlockHeight: 10, +// ObservedOutboundEffectiveGasPrice: math.NewInt(21), +// ObservedOutboundGasUsed: 21, +// CoinType: cctx.InboundParams.CoinType, +// }) +// require.NoError(t, err) +// c, found := k.GetCrossChainTx(ctx, cctx.Index) +// require.True(t, found) +// require.Equal(t, types.CctxStatus_Aborted, c.CctxStatus.Status) +// require.Equal(t, oldParamsLen+1, len(c.OutboundParams)) +// // The message processing fails during the creation of the revert tx +// // So the original outbound tx is executed and the revert tx is not finalized. +// // The cctx status is Aborted +// require.Equal(t, types.TxFinalizationStatus_NotFinalized, c.GetCurrentOutboundParam().TxFinalizationStatus) +// require.Equal(t, types.TxFinalizationStatus_Executed, c.OutboundParams[oldParamsLen-1].TxFinalizationStatus) +// }) +// +// t.Run("failure in processing outbound tx", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ +// UseObserverMock: true, +// UseFungibleMock: true, +// }) +// +// // Setup mock data +// observerMock := keepertest.GetCrosschainObserverMock(t, k) +// fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) +// receiver := sample.EthAddress() +// amount := big.NewInt(42) +// senderChain := getValidEthChain() +// asset := "" +// observer := sample.AccAddress() +// tss := sample.Tss() +// zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{observer}}) +// cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) +// cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// k.SetCrossChainTx(ctx, *cctx) +// +// // Successfully mock GetTSS +// observerMock.On("GetTSS", ctx).Return(observertypes.TSS{}, true).Once() +// +// // Successfully mock VoteOnOutboundBallot +// keepertest.MockVoteOnOutboundFailedBallot(observerMock, ctx, cctx, senderChain, observer) +// +// // Successfully mock GetOutbound +// keepertest.MockGetOutbound(observerMock, ctx) +// +// // Fail ProcessOutbound so that changes are not committed to the state +// fungibleMock.On("GetForeignCoinFromAsset", mock.Anything, mock.Anything, mock.Anything). +// Return(fungibletypes.ForeignCoins{}, false) +// +// // Successfully mock GetSupportedChainFromChainID +// keepertest.MockGetSupportedChainFromChainID(observerMock, senderChain) +// +// //Successfully mock SaveFailedOutbound +// keepertest.MockSaveOutbound(observerMock, ctx, cctx, tss) +// +// msgServer := keeper.NewMsgServerImpl(*k) +// _, err := msgServer.VoteOutbound(ctx, &types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Status: chains.ReceiveStatus_failed, +// Creator: observer, +// ObservedOutboundHash: sample.Hash().String(), +// ValueReceived: cctx.GetCurrentOutboundParam().Amount, +// ObservedOutboundBlockHeight: 10, +// ObservedOutboundEffectiveGasPrice: math.NewInt(21), +// ObservedOutboundGasUsed: 21, +// CoinType: cctx.InboundParams.CoinType, +// }) +// require.NoError(t, err) +// c, found := k.GetCrossChainTx(ctx, cctx.Index) +// require.True(t, found) +// // Status would be CctxStatus_PendingRevert if process outbound did not fail +// require.Equal(t, types.CctxStatus_Aborted, c.CctxStatus.Status) +// }) +// +// t.Run("fail to finalize outbound if not a finalizing vote", func(t *testing.T) { +// k, ctx, sk, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{}) +// +// // Setup mock data +// receiver := sample.EthAddress() +// amount := big.NewInt(42) +// senderChain := getValidEthChain() +// asset := "" +// r := rand.New(rand.NewSource(42)) +// validator := sample.Validator(t, r) +// tss := sample.Tss() +// +// // set state to successfully vote on outbound tx +// accAddress, err := observertypes.GetAccAddressFromOperatorAddress(validator.OperatorAddress) +// require.NoError(t, err) +// zk.ObserverKeeper.SetObserverSet( +// ctx, +// observertypes.ObserverSet{ +// ObserverList: []string{accAddress.String(), sample.AccAddress(), sample.AccAddress()}, +// }, +// ) +// sk.StakingKeeper.SetValidator(ctx, validator) +// cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) +// cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// k.SetCrossChainTx(ctx, *cctx) +// zk.ObserverKeeper.SetTSS(ctx, tss) +// +// msgServer := keeper.NewMsgServerImpl(*k) +// msg := &types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Status: chains.ReceiveStatus_success, +// Creator: accAddress.String(), +// ObservedOutboundHash: sample.Hash().String(), +// ValueReceived: cctx.GetCurrentOutboundParam().Amount, +// ObservedOutboundBlockHeight: 10, +// ObservedOutboundEffectiveGasPrice: math.NewInt(21), +// ObservedOutboundGasUsed: 21, +// CoinType: cctx.InboundParams.CoinType, +// } +// _, err = msgServer.VoteOutbound(ctx, msg) +// require.NoError(t, err) +// c, found := k.GetCrossChainTx(ctx, cctx.Index) +// require.True(t, found) +// require.Equal(t, types.CctxStatus_PendingOutbound, c.CctxStatus.Status) +// ballot, found := zk.ObserverKeeper.GetBallot(ctx, msg.Digest()) +// require.True(t, found) +// require.True(t, ballot.HasVoted(accAddress.String())) +// }) +// +// t.Run("unable to add vote if tss is not present", func(t *testing.T) { +// k, ctx, sk, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{}) +// +// // Setup mock data +// receiver := sample.EthAddress() +// amount := big.NewInt(42) +// senderChain := getValidEthChain() +// asset := "" +// r := rand.New(rand.NewSource(42)) +// validator := sample.Validator(t, r) +// tss := sample.Tss() +// +// // set state to successfully vote on outbound tx +// accAddress, err := observertypes.GetAccAddressFromOperatorAddress(validator.OperatorAddress) +// require.NoError(t, err) +// zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{ObserverList: []string{accAddress.String()}}) +// sk.StakingKeeper.SetValidator(ctx, validator) +// cctx := GetERC20Cctx(t, receiver, senderChain, asset, amount) +// cctx.GetCurrentOutboundParam().TssPubkey = tss.TssPubkey +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// k.SetCrossChainTx(ctx, *cctx) +// +// msgServer := keeper.NewMsgServerImpl(*k) +// msg := &types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Status: chains.ReceiveStatus_success, +// Creator: accAddress.String(), +// ObservedOutboundHash: sample.Hash().String(), +// ValueReceived: cctx.GetCurrentOutboundParam().Amount, +// ObservedOutboundBlockHeight: 10, +// ObservedOutboundEffectiveGasPrice: math.NewInt(21), +// ObservedOutboundGasUsed: 21, +// CoinType: cctx.InboundParams.CoinType, +// } +// _, err = msgServer.VoteOutbound(ctx, msg) +// require.ErrorIs(t, err, types.ErrCannotFindTSSKeys) +// c, found := k.GetCrossChainTx(ctx, cctx.Index) +// require.True(t, found) +// require.Equal(t, types.CctxStatus_PendingOutbound, c.CctxStatus.Status) +// _, found = zk.ObserverKeeper.GetBallot(ctx, msg.Digest()) +// require.False(t, found) +// }) +//} +// +//func TestKeeper_SaveFailedOutbound(t *testing.T) { +// t.Run("successfully save failed outbound", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeper(t) +// cctx := sample.CrossChainTx(t, "test") +// k.SetOutboundTracker(ctx, types.OutboundTracker{ +// Index: "", +// ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Nonce: cctx.GetCurrentOutboundParam().TssNonce, +// HashList: nil, +// }) +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// k.SaveFailedOutbound(ctx, cctx, sample.String(), sample.ZetaIndex(t)) +// require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_Aborted) +// _, found := k.GetOutboundTracker( +// ctx, +// cctx.GetCurrentOutboundParam().ReceiverChainId, +// cctx.GetCurrentOutboundParam().TssNonce, +// ) +// require.False(t, found) +// }) +//} + +//func TestKeeper_SaveSuccessfulOutbound(t *testing.T) { +// t.Run("successfully save successful outbound", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeper(t) +// cctx := sample.CrossChainTx(t, "test") +// k.SetOutboundTracker(ctx, types.OutboundTracker{ +// Index: "", +// ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Nonce: cctx.GetCurrentOutboundParam().TssNonce, +// HashList: nil, +// }) +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// k.SaveSuccessfulOutbound(ctx, cctx, sample.String()) +// require.Equal(t, cctx.GetCurrentOutboundParam().BallotIndex, sample.String()) +// _, found := k.GetOutboundTracker( +// ctx, +// cctx.GetCurrentOutboundParam().ReceiverChainId, +// cctx.GetCurrentOutboundParam().TssNonce, +// ) +// require.False(t, found) +// }) +//} + +//func TestKeeper_SaveOutbound(t *testing.T) { +// t.Run("successfully save outbound", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeper(t) +// +// // setup state for crosschain and observer modules +// cctx := sample.CrossChainTx(t, "test") +// cctx.CctxStatus.Status = types.CctxStatus_PendingOutbound +// ballotIndex := sample.String() +// k.SetOutboundTracker(ctx, types.OutboundTracker{ +// Index: "", +// ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Nonce: cctx.GetCurrentOutboundParam().TssNonce, +// HashList: nil, +// }) +// +// zk.ObserverKeeper.SetPendingNonces(ctx, observertypes.PendingNonces{ +// NonceLow: int64(cctx.GetCurrentOutboundParam().TssNonce) - 1, +// NonceHigh: int64(cctx.GetCurrentOutboundParam().TssNonce) + 1, +// ChainId: cctx.GetCurrentOutboundParam().ReceiverChainId, +// Tss: cctx.GetCurrentOutboundParam().TssPubkey, +// }) +// zk.ObserverKeeper.SetTSS(ctx, observertypes.TSS{ +// TssPubkey: cctx.GetCurrentOutboundParam().TssPubkey, +// }) +// +// // Save outbound and assert all values are successfully saved +// k.SaveOutbound(ctx, cctx, ballotIndex) +// require.Equal(t, cctx.GetCurrentOutboundParam().BallotIndex, ballotIndex) +// _, found := k.GetOutboundTracker( +// ctx, +// cctx.GetCurrentOutboundParam().ReceiverChainId, +// cctx.GetCurrentOutboundParam().TssNonce, +// ) +// require.False(t, found) +// pn, found := zk.ObserverKeeper.GetPendingNonces( +// ctx, +// cctx.GetCurrentOutboundParam().TssPubkey, +// cctx.GetCurrentOutboundParam().ReceiverChainId, +// ) +// require.True(t, found) +// require.Equal(t, pn.NonceLow, int64(cctx.GetCurrentOutboundParam().TssNonce)+1) +// require.Equal(t, pn.NonceHigh, int64(cctx.GetCurrentOutboundParam().TssNonce)+1) +// _, found = k.GetInboundHashToCctx(ctx, cctx.InboundParams.ObservedHash) +// require.True(t, found) +// _, found = zk.ObserverKeeper.GetNonceToCctx( +// ctx, +// cctx.GetCurrentOutboundParam().TssPubkey, +// cctx.GetCurrentOutboundParam().ReceiverChainId, +// int64(cctx.GetCurrentOutboundParam().TssNonce), +// ) +// require.True(t, found) +// }) +//} +// +//func TestKeeper_ValidateOutboundMessage(t *testing.T) { +// t.Run("successfully validate outbound message", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeper(t) +// cctx := sample.CrossChainTx(t, "test") +// k.SetCrossChainTx(ctx, *cctx) +// zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) +// _, err := k.ValidateOutboundMessage(ctx, types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// OutboundChain: cctx.GetCurrentOutboundParam().ReceiverChainId, +// }) +// require.NoError(t, err) +// }) +// +// t.Run("failed to validate outbound message if cctx not found", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeper(t) +// msg := types.MsgVoteOutbound{ +// CctxHash: sample.String(), +// OutboundTssNonce: 1, +// } +// _, err := k.ValidateOutboundMessage(ctx, msg) +// require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) +// require.ErrorContains(t, err, fmt.Sprintf("CCTX %s does not exist", msg.CctxHash)) +// }) +// +// t.Run("failed to validate outbound message if nonce does not match", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeper(t) +// cctx := sample.CrossChainTx(t, "test") +// k.SetCrossChainTx(ctx, *cctx) +// msg := types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: 2, +// } +// _, err := k.ValidateOutboundMessage(ctx, msg) +// require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) +// require.ErrorContains( +// t, +// err, +// fmt.Sprintf( +// "OutboundTssNonce %d does not match CCTX OutboundTssNonce %d", +// msg.OutboundTssNonce, +// cctx.GetCurrentOutboundParam().TssNonce, +// ), +// ) +// }) +// +// t.Run("failed to validate outbound message if tss not found", func(t *testing.T) { +// k, ctx, _, _ := keepertest.CrosschainKeeper(t) +// cctx := sample.CrossChainTx(t, "test") +// k.SetCrossChainTx(ctx, *cctx) +// _, err := k.ValidateOutboundMessage(ctx, types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// }) +// require.ErrorIs(t, err, types.ErrCannotFindTSSKeys) +// }) +// +// t.Run("failed to validate outbound message if chain does not match", func(t *testing.T) { +// k, ctx, _, zk := keepertest.CrosschainKeeper(t) +// cctx := sample.CrossChainTx(t, "test") +// k.SetCrossChainTx(ctx, *cctx) +// zk.ObserverKeeper.SetTSS(ctx, sample.Tss()) +// _, err := k.ValidateOutboundMessage(ctx, types.MsgVoteOutbound{ +// CctxHash: cctx.Index, +// OutboundTssNonce: cctx.GetCurrentOutboundParam().TssNonce, +// OutboundChain: 2, +// }) +// require.ErrorIs(t, err, sdkerrors.ErrInvalidRequest) +// require.ErrorContains( +// t, +// err, +// fmt.Sprintf( +// "OutboundChain %d does not match CCTX OutboundChain %d", +// 2, +// cctx.GetCurrentOutboundParam().ReceiverChainId, +// ), +// ) +// }) +//} diff --git a/x/crosschain/keeper/outbound_tracker.go b/x/crosschain/keeper/outbound_tracker.go index dbf8bf3bb5..fd9448db90 100644 --- a/x/crosschain/keeper/outbound_tracker.go +++ b/x/crosschain/keeper/outbound_tracker.go @@ -51,6 +51,7 @@ func (k Keeper) RemoveOutboundTrackerFromStore( ) { index := getOutboundTrackerIndex(chainID, nonce) store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.OutboundTrackerKeyPrefix)) + fmt.Println("Removing outbound tracker ", chainID, nonce) store.Delete(types.OutboundTrackerKey( index, )) diff --git a/zetaclient/chains/evm/signer/outbound_data.go b/zetaclient/chains/evm/signer/outbound_data.go index 2509b79198..d405f4c099 100644 --- a/zetaclient/chains/evm/signer/outbound_data.go +++ b/zetaclient/chains/evm/signer/outbound_data.go @@ -21,7 +21,7 @@ import ( const ( MinGasLimit = 100_000 - MaxGasLimit = 1_000_000 + MaxGasLimit = 1_000_000_0 ) // OutboundData is a data structure containing input fields used to construct each type of transaction. @@ -102,6 +102,18 @@ func (txData *OutboundData) SetupGas( } else { txData.gasPrice = specified } + + fmt.Println("Speficied: ", specified) + suggested, err := client.SuggestGasPrice(context.Background()) + if err != nil { + fmt.Println("Error Getting Gas price: ", err) + } + fmt.Println("Suggested: ", suggested) + + if txData.gasPrice.Cmp(suggested) < 0 { + txData.gasPrice = suggested + } + return nil } diff --git a/zetaclient/chains/evm/signer/signer.go b/zetaclient/chains/evm/signer/signer.go index 7235aa4456..ce8152e58a 100644 --- a/zetaclient/chains/evm/signer/signer.go +++ b/zetaclient/chains/evm/signer/signer.go @@ -165,7 +165,8 @@ func (signer *Signer) Sign( nonce uint64, height uint64, ) (*ethtypes.Transaction, []byte, []byte, error) { - log.Debug().Str("tss.pub_key", signer.TSS().EVMAddress().String()).Msg("Sign: TSS signer") + log.Info().Str("tss.pub_key", signer.TSS().EVMAddress().String()).Msg("Sign: TSS signer") + fmt.Println("Sign: TSS signer", signer.TSS().EVMAddress().String()) // TODO: use EIP-1559 transaction type // https://github.com/zeta-chain/node/issues/1952 @@ -588,6 +589,7 @@ func (signer *Signer) BroadcastOutbound( backOff := broadcastBackoff for i := 0; i < broadcastRetries; i++ { time.Sleep(backOff) + fmt.Println("Broadcasting TX : ", tx.GasPrice(), tx.Gas(), tx.Nonce(), tx.ChainId(), tx.To().String()) err := signer.Broadcast(tx) if err != nil { log.Warn(). diff --git a/zetaclient/zetacore/constant.go b/zetaclient/zetacore/constant.go index 2b4916fa42..e4370e97f5 100644 --- a/zetaclient/zetacore/constant.go +++ b/zetaclient/zetacore/constant.go @@ -13,7 +13,7 @@ const ( PostGasPriceGasLimit = 1_500_000 // PostVoteInboundGasLimit is the gas limit for voting on observed inbound tx (for zetachain itself) - PostVoteInboundGasLimit = 500_000 + PostVoteInboundGasLimit = 1_500_000 // PostVoteInboundExecutionGasLimit is the gas limit for voting on observed inbound tx and executing it PostVoteInboundExecutionGasLimit = 4_000_000 @@ -37,7 +37,7 @@ const ( DefaultRetryInterval = 5 // PostVoteOutboundGasLimit is the gas limit for voting on observed outbound tx (for zetachain itself) - PostVoteOutboundGasLimit = 700_000 + PostVoteOutboundGasLimit = 1_500_000 // PostVoteOutboundRevertGasLimit is the gas limit for voting on observed outbound tx for revert (when outbound fails) // The value needs to be higher because reverting implies interacting with the EVM to perform swaps for the gas token From ea915d4d62ae5456ff4c009c7167b24df352d154 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 6 Aug 2024 19:53:08 -0400 Subject: [PATCH 07/29] rebase develop --- cmd/zetae2e/local/local.go | 50 +++++++++---------- .../keeper/msg_server_vote_outbound_tx.go | 1 - 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index be302e8f06..27b016dda4 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -231,41 +231,41 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestERC20DepositRestrictedName, } zetaTests := []string{ - //e2etests.TestZetaWithdrawName, + e2etests.TestZetaWithdrawName, e2etests.TestMessagePassingExternalChainsName, e2etests.TestMessagePassingRevertFailExternalChainsName, - //e2etests.TestMessagePassingRevertSuccessExternalChainsName, + e2etests.TestMessagePassingRevertSuccessExternalChainsName, + } + zetaAdvancedTests := []string{ + e2etests.TestZetaDepositRestrictedName, + e2etests.TestZetaDepositName, + e2etests.TestZetaDepositNewAddressName, } - //zetaAdvancedTests := []string{ - // e2etests.TestZetaDepositRestrictedName, - // e2etests.TestZetaDepositName, - // e2etests.TestZetaDepositNewAddressName, - //} zevmMPTests := []string{} zevmMPAdvancedTests := []string{ e2etests.TestMessagePassingZEVMToEVMName, e2etests.TestMessagePassingEVMtoZEVMName, e2etests.TestMessagePassingEVMtoZEVMRevertName, - //e2etests.TestMessagePassingZEVMtoEVMRevertName, - //e2etests.TestMessagePassingZEVMtoEVMRevertFailName, - //e2etests.TestMessagePassingEVMtoZEVMRevertFailName, + e2etests.TestMessagePassingZEVMtoEVMRevertName, + e2etests.TestMessagePassingZEVMtoEVMRevertFailName, + e2etests.TestMessagePassingEVMtoZEVMRevertFailName, } bitcoinTests := []string{ - //e2etests.TestBitcoinDepositName, - //e2etests.TestBitcoinDepositRefundName, + e2etests.TestBitcoinDepositName, + e2etests.TestBitcoinDepositRefundName, e2etests.TestBitcoinWithdrawSegWitName, - //e2etests.TestBitcoinWithdrawInvalidAddressName, - //e2etests.TestZetaWithdrawBTCRevertName, + e2etests.TestBitcoinWithdrawInvalidAddressName, + e2etests.TestZetaWithdrawBTCRevertName, //e2etests.TestCrosschainSwapName, } bitcoinAdvancedTests := []string{ - //e2etests.TestBitcoinWithdrawTaprootName, - //e2etests.TestBitcoinWithdrawLegacyName, - //e2etests.TestBitcoinWithdrawMultipleName, - //e2etests.TestBitcoinWithdrawP2SHName, - //e2etests.TestBitcoinWithdrawP2WSHName, - //e2etests.TestBitcoinWithdrawRestrictedName, + e2etests.TestBitcoinWithdrawTaprootName, + e2etests.TestBitcoinWithdrawLegacyName, + e2etests.TestBitcoinWithdrawMultipleName, + e2etests.TestBitcoinWithdrawP2SHName, + e2etests.TestBitcoinWithdrawP2WSHName, + e2etests.TestBitcoinWithdrawRestrictedName, } ethereumTests := []string{ e2etests.TestEtherWithdrawName, @@ -279,7 +279,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if !light { erc20Tests = append(erc20Tests, erc20AdvancedTests...) - //zetaTests = append(zetaTests, zetaAdvancedTests...) + zetaTests = append(zetaTests, zetaAdvancedTests...) zevmMPTests = append(zevmMPTests, zevmMPAdvancedTests...) bitcoinTests = append(bitcoinTests, bitcoinAdvancedTests...) ethereumTests = append(ethereumTests, ethereumAdvancedTests...) @@ -287,13 +287,11 @@ func localE2ETest(cmd *cobra.Command, _ []string) { // skip the header proof test if we run light test or skipHeaderProof is enabled testHeader := !light && !skipHeaderProof - fmt.Println(skipBitcoinSetup) - fmt.Println(testHeader) - //eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) + eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) eg.Go(zetaTestRoutine(conf, deployerRunner, verbose, zetaTests...)) - //eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) + eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose, !skipBitcoinSetup, testHeader, bitcoinTests...)) - //eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) + eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) } if testAdmin { diff --git a/x/crosschain/keeper/msg_server_vote_outbound_tx.go b/x/crosschain/keeper/msg_server_vote_outbound_tx.go index dcc6765e4d..804f92fd82 100644 --- a/x/crosschain/keeper/msg_server_vote_outbound_tx.go +++ b/x/crosschain/keeper/msg_server_vote_outbound_tx.go @@ -122,7 +122,6 @@ func (k msgServer) VoteOutbound( newOutboundAdded := lenOutboundsNew > lenOutbounds k.SaveSuccessfulOutbound(ctx, &cctx, ballotIndex, newOutboundAdded) - fmt.Printf("SaveSuccessfulOutbound: Cctx %s outbound : %d\n ,ballot %s\n", cctx.Index, len(cctx.OutboundParams), ballotIndex) return &types.MsgVoteOutboundResponse{}, nil } From 40683abcf5a84f863f5cfe89df736b6b2fa7b360 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 7 Aug 2024 11:06:49 -0400 Subject: [PATCH 08/29] debug crosschainswap --- cmd/zetae2e/local/local.go | 2 +- e2e/e2etests/test_crosschain_swap.go | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index c75af5d57b..62f830e004 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -225,7 +225,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestERC20WithdrawName, e2etests.TestMultipleERC20WithdrawsName, e2etests.TestERC20DepositAndCallRefundName, - //e2etests.TestZRC20SwapName, + e2etests.TestZRC20SwapName, } erc20AdvancedTests := []string{ e2etests.TestERC20DepositRestrictedName, diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index 798958a652..a25674ffb9 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -21,9 +21,11 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { // https://github.com/zeta-chain/node-private/issues/88 // it is kept as is for now to be consistent with the old implementation // if the tx fails due to already initialized, it will be ignored - _, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.BTCZRC20Addr) + tx, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.BTCZRC20Addr) if err != nil { r.Logger.Print("ℹ️create pair error") + } else { + utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) } txERC20ZRC20Approve, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) From fa403b4239c6f63c4e9a74b11d6a21fe1de51d24 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 7 Aug 2024 12:09:24 -0400 Subject: [PATCH 09/29] debud btc swap --- cmd/zetae2e/local/local.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 62f830e004..701242c622 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -257,7 +257,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestBitcoinWithdrawSegWitName, e2etests.TestBitcoinWithdrawInvalidAddressName, e2etests.TestZetaWithdrawBTCRevertName, - //e2etests.TestCrosschainSwapName, + e2etests.TestCrosschainSwapName, } bitcoinAdvancedTests := []string{ e2etests.TestBitcoinWithdrawTaprootName, From d9d10394078a5e0f1d8d1d6795354c36dcbd8ee3 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 7 Aug 2024 15:34:53 -0400 Subject: [PATCH 10/29] enable deposit btc --- cmd/zetae2e/local/bitcoin.go | 4 +--- cmd/zetae2e/local/local.go | 20 ++++++++++---------- e2e/e2etests/test_crosschain_swap.go | 4 ++-- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/cmd/zetae2e/local/bitcoin.go b/cmd/zetae2e/local/bitcoin.go index ffa73c5c3e..184277d0cc 100644 --- a/cmd/zetae2e/local/bitcoin.go +++ b/cmd/zetae2e/local/bitcoin.go @@ -48,9 +48,7 @@ func bitcoinTestRoutine( bitcoinRunner.WaitForMinedCCTX(txERC20Deposit) bitcoinRunner.SetupBitcoinAccount(initBitcoinNetwork) - if initBitcoinNetwork { - bitcoinRunner.DepositBTC() - } + bitcoinRunner.DepositBTC() // run bitcoin test // Note: due to the extensive block generation in Bitcoin localnet, block header test is run first diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 701242c622..678d2c7b1f 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -260,12 +260,12 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestCrosschainSwapName, } bitcoinAdvancedTests := []string{ - e2etests.TestBitcoinWithdrawTaprootName, - e2etests.TestBitcoinWithdrawLegacyName, - e2etests.TestBitcoinWithdrawMultipleName, - e2etests.TestBitcoinWithdrawP2SHName, - e2etests.TestBitcoinWithdrawP2WSHName, - e2etests.TestBitcoinWithdrawRestrictedName, + //e2etests.TestBitcoinWithdrawTaprootName, + //e2etests.TestBitcoinWithdrawLegacyName, + //e2etests.TestBitcoinWithdrawMultipleName, + //e2etests.TestBitcoinWithdrawP2SHName, + //e2etests.TestBitcoinWithdrawP2WSHName, + //e2etests.TestBitcoinWithdrawRestrictedName, } ethereumTests := []string{ e2etests.TestEtherWithdrawName, @@ -285,11 +285,11 @@ func localE2ETest(cmd *cobra.Command, _ []string) { ethereumTests = append(ethereumTests, ethereumAdvancedTests...) } - eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) - eg.Go(zetaTestRoutine(conf, deployerRunner, verbose, zetaTests...)) - eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) + //eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) + //eg.Go(zetaTestRoutine(conf, deployerRunner, verbose, zetaTests...)) + //eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose, !skipBitcoinSetup, bitcoinTests...)) - eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, ethereumTests...)) + //eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, ethereumTests...)) } if testAdmin { diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index a25674ffb9..ecbfc144a0 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -57,9 +57,9 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.ERC20ZRC20Addr, r.BTCZRC20Addr, big.NewInt(1e8), + big.NewInt(1e7), big.NewInt(1e8), - big.NewInt(1e8), - big.NewInt(1e5), + big.NewInt(1e7), r.EVMAddress(), big.NewInt(time.Now().Add(10*time.Minute).Unix()), ) From 310840f269495327916cda6d639d11a3907a0c45 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 7 Aug 2024 15:34:53 -0400 Subject: [PATCH 11/29] enable deposit btc --- cmd/zetae2e/local/bitcoin.go | 4 +--- cmd/zetae2e/local/local.go | 20 ++++++++++---------- e2e/e2etests/test_crosschain_swap.go | 8 +++----- e2e/utils/evm.go | 2 +- e2e/utils/require.go | 2 ++ x/crosschain/keeper/gas_payment.go | 2 +- zetaclient/zetacore/constant.go | 4 ++-- 7 files changed, 20 insertions(+), 22 deletions(-) diff --git a/cmd/zetae2e/local/bitcoin.go b/cmd/zetae2e/local/bitcoin.go index ffa73c5c3e..184277d0cc 100644 --- a/cmd/zetae2e/local/bitcoin.go +++ b/cmd/zetae2e/local/bitcoin.go @@ -48,9 +48,7 @@ func bitcoinTestRoutine( bitcoinRunner.WaitForMinedCCTX(txERC20Deposit) bitcoinRunner.SetupBitcoinAccount(initBitcoinNetwork) - if initBitcoinNetwork { - bitcoinRunner.DepositBTC() - } + bitcoinRunner.DepositBTC() // run bitcoin test // Note: due to the extensive block generation in Bitcoin localnet, block header test is run first diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 701242c622..678d2c7b1f 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -260,12 +260,12 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestCrosschainSwapName, } bitcoinAdvancedTests := []string{ - e2etests.TestBitcoinWithdrawTaprootName, - e2etests.TestBitcoinWithdrawLegacyName, - e2etests.TestBitcoinWithdrawMultipleName, - e2etests.TestBitcoinWithdrawP2SHName, - e2etests.TestBitcoinWithdrawP2WSHName, - e2etests.TestBitcoinWithdrawRestrictedName, + //e2etests.TestBitcoinWithdrawTaprootName, + //e2etests.TestBitcoinWithdrawLegacyName, + //e2etests.TestBitcoinWithdrawMultipleName, + //e2etests.TestBitcoinWithdrawP2SHName, + //e2etests.TestBitcoinWithdrawP2WSHName, + //e2etests.TestBitcoinWithdrawRestrictedName, } ethereumTests := []string{ e2etests.TestEtherWithdrawName, @@ -285,11 +285,11 @@ func localE2ETest(cmd *cobra.Command, _ []string) { ethereumTests = append(ethereumTests, ethereumAdvancedTests...) } - eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) - eg.Go(zetaTestRoutine(conf, deployerRunner, verbose, zetaTests...)) - eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) + //eg.Go(erc20TestRoutine(conf, deployerRunner, verbose, erc20Tests...)) + //eg.Go(zetaTestRoutine(conf, deployerRunner, verbose, zetaTests...)) + //eg.Go(zevmMPTestRoutine(conf, deployerRunner, verbose, zevmMPTests...)) eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose, !skipBitcoinSetup, bitcoinTests...)) - eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, ethereumTests...)) + //eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, ethereumTests...)) } if testAdmin { diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index a25674ffb9..e1eee7c278 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -21,11 +21,9 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { // https://github.com/zeta-chain/node-private/issues/88 // it is kept as is for now to be consistent with the old implementation // if the tx fails due to already initialized, it will be ignored - tx, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.BTCZRC20Addr) + _, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.BTCZRC20Addr) if err != nil { r.Logger.Print("ℹ️create pair error") - } else { - utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) } txERC20ZRC20Approve, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) @@ -57,9 +55,9 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.ERC20ZRC20Addr, r.BTCZRC20Addr, big.NewInt(1e8), + big.NewInt(1e3), big.NewInt(1e8), - big.NewInt(1e8), - big.NewInt(1e5), + big.NewInt(1e3), r.EVMAddress(), big.NewInt(time.Now().Add(10*time.Minute).Unix()), ) diff --git a/e2e/utils/evm.go b/e2e/utils/evm.go index 7cc611b4d6..45b2a55890 100644 --- a/e2e/utils/evm.go +++ b/e2e/utils/evm.go @@ -15,7 +15,7 @@ import ( ) const ( - DefaultReceiptTimeout = 300 * time.Second + DefaultReceiptTimeout = 30 * time.Second ) func CheckNonce( diff --git a/e2e/utils/require.go b/e2e/utils/require.go index 7471bf9b4e..23fc30c33e 100644 --- a/e2e/utils/require.go +++ b/e2e/utils/require.go @@ -26,6 +26,8 @@ func RequireCCTXStatus( // 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" + fmt.Println("receipt hash:", receipt.TxHash) + fmt.Println("receipt logs:", receipt.Logs) require.Equal(t, ethtypes.ReceiptStatusSuccessful, receipt.Status, msg+errSuffix(msgAndArgs...)) } diff --git a/x/crosschain/keeper/gas_payment.go b/x/crosschain/keeper/gas_payment.go index 8a8d372b4a..a5a9b7d0fd 100644 --- a/x/crosschain/keeper/gas_payment.go +++ b/x/crosschain/keeper/gas_payment.go @@ -339,7 +339,7 @@ func (k Keeper) PayGasInZetaAndUpdateCctx( ) } // overpays gas price - const multiplier = 6 + const multiplier = 2 gasPrice = gasPrice.MulUint64(multiplier) priorityFee = priorityFee.MulUint64(multiplier) diff --git a/zetaclient/zetacore/constant.go b/zetaclient/zetacore/constant.go index e4370e97f5..a5a4e16829 100644 --- a/zetaclient/zetacore/constant.go +++ b/zetaclient/zetacore/constant.go @@ -13,7 +13,7 @@ const ( PostGasPriceGasLimit = 1_500_000 // PostVoteInboundGasLimit is the gas limit for voting on observed inbound tx (for zetachain itself) - PostVoteInboundGasLimit = 1_500_000 + PostVoteInboundGasLimit = 500_000 // PostVoteInboundExecutionGasLimit is the gas limit for voting on observed inbound tx and executing it PostVoteInboundExecutionGasLimit = 4_000_000 @@ -37,7 +37,7 @@ const ( DefaultRetryInterval = 5 // PostVoteOutboundGasLimit is the gas limit for voting on observed outbound tx (for zetachain itself) - PostVoteOutboundGasLimit = 1_500_000 + PostVoteOutboundGasLimit = 500_000 // PostVoteOutboundRevertGasLimit is the gas limit for voting on observed outbound tx for revert (when outbound fails) // The value needs to be higher because reverting implies interacting with the EVM to perform swaps for the gas token From 028bf50e51dd1ee28f82e4cf07245e8845184f34 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 8 Aug 2024 13:56:38 -0400 Subject: [PATCH 12/29] ad changelog --- changelog.md | 2 +- cmd/zetae2e/local/local.go | 77 +------------ ..._message_passing_external_chains_revert.go | 10 +- e2e/runner/setup_evm.go | 1 - e2e/runner/update_contracts.go | 40 +++++++ e2e/utils/zetacore.go | 2 +- testutil/keeper/mocks/crosschain/observer.go | 40 +++++++ .../cctx_orchestrator_validate_outbound.go | 3 - .../keeper/msg_server_add_outbound_tracker.go | 4 - x/crosschain/types/expected_keepers.go | 2 - x/observer/keeper/chain_params.go | 26 ----- x/observer/keeper/chain_params_test.go | 103 ------------------ x/observer/keeper/voting.go | 1 - 13 files changed, 91 insertions(+), 220 deletions(-) create mode 100644 e2e/runner/update_contracts.go diff --git a/changelog.md b/changelog.md index 1ed40aa47d..055ada9c61 100644 --- a/changelog.md +++ b/changelog.md @@ -87,7 +87,6 @@ * [2542](https://github.com/zeta-chain/node/pull/2542) - adjust permissions to be more restrictive * [2556](https://github.com/zeta-chain/node/pull/2556) - refactor migrator length check to use consensus type * [2572](https://github.com/zeta-chain/node/pull/2572) - turn off IBC modules -* [2556](https://github.com/zeta-chain/node/pull/2556) - refactor migrator length check to use consensus type * [2568](https://github.com/zeta-chain/node/pull/2568) - improve AppContext by converging chains, chainParams, enabledChains, and additionalChains into a single zctx.Chain ### Tests @@ -111,6 +110,7 @@ * [2415](https://github.com/zeta-chain/node/pull/2415) - add e2e test for upgrade and test admin functionalities * [2440](https://github.com/zeta-chain/node/pull/2440) - Add e2e test for TSS migration * [2473](https://github.com/zeta-chain/node/pull/2473) - add e2e tests for most used admin transactions +* [2661](https://github.com/zeta-chain/node/pull/2661) - update connector and erc20Custody addresses in tss migration e2e tests ### Fixes diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 701242c622..4b45f41494 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -3,12 +3,10 @@ package local import ( "context" "errors" - "fmt" "os" "path/filepath" "time" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/fatih/color" "github.com/spf13/cobra" "github.com/stretchr/testify/require" @@ -353,7 +351,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("βœ… e2e tests completed in %s", time.Since(testStartTime).String()) if testTSSMigration { - runTSSMigrationTest(deployerRunner, logger, verbose, conf) + runTSSMigration(deployerRunner, logger, verbose, conf) } // Verify that there are no trackers left over after tests complete deployerRunner.EnsureNoTrackers() @@ -408,57 +406,7 @@ func waitKeygenHeight( } } -func updateTssAddressForConnector(runner *runner.E2ERunner) { - - tssAddress, err := runner.ConnectorEth.TssAddress(&bind.CallOpts{Context: runner.Ctx}) - require.NoError(runner, err) - runner.Logger.Print(fmt.Sprintf("TSS Address Before: %s", tssAddress.String())) - - tssUpdater, err := runner.ConnectorEth.TssAddressUpdater(&bind.CallOpts{Context: runner.Ctx}) - require.NoError(runner, err) - runner.Logger.Print(fmt.Sprintf("TSS Updater: %s", tssUpdater.String())) - - runner.Logger.Print("Update TSS") - noError(runner.SetTSSAddresses()) - runner.Logger.Print("TSS Deployer Address: %s", runner.TSSAddress) - - tx, err := runner.ConnectorEth.UpdateTssAddress(runner.EVMAuth, runner.TSSAddress) - require.NoError(runner, err) - runner.Logger.Print(fmt.Sprintf("TSS Address Update Tx: %s", tx.Hash().String())) - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - utils.RequireTxSuccessful(runner, receipt) - - tssAddress, err = runner.ConnectorEth.TssAddress(&bind.CallOpts{Context: runner.Ctx}) - require.NoError(runner, err) - runner.Logger.Print(fmt.Sprintf("TSS Address After: %s", tssAddress.String())) -} - -func updateTssAddressForErc20custody(runner *runner.E2ERunner) { - - tssAddress, err := runner.ERC20Custody.TSSAddress(&bind.CallOpts{Context: runner.Ctx}) - require.NoError(runner, err) - runner.Logger.Print(fmt.Sprintf("TSS ERC20 Address Before: %s", tssAddress.String())) - - tssUpdater, err := runner.ERC20Custody.TSSAddressUpdater(&bind.CallOpts{Context: runner.Ctx}) - require.NoError(runner, err) - runner.Logger.Print(fmt.Sprintf("TSS ERC20 Updater: %s", tssUpdater.String())) - - runner.Logger.Print("Update TSS") - noError(runner.SetTSSAddresses()) - runner.Logger.Print("TSS Deployer Address: %s", runner.TSSAddress) - - tx, err := runner.ERC20Custody.UpdateTSSAddress(runner.EVMAuth, runner.TSSAddress) - require.NoError(runner, err) - runner.Logger.Print(fmt.Sprintf("TSS ERC20 Address Update Tx: %s", tx.Hash().String())) - receipt := utils.MustWaitForTxReceipt(runner.Ctx, runner.EVMClient, tx, runner.Logger, runner.ReceiptTimeout) - utils.RequireTxSuccessful(runner, receipt) - - tssAddress, err = runner.ERC20Custody.TSSAddress(&bind.CallOpts{Context: runner.Ctx}) - require.NoError(runner, err) - runner.Logger.Print(fmt.Sprintf("TSS ERC20 Address After: %s", tssAddress.String())) -} - -func runTSSMigrationTest(deployerRunner *runner.E2ERunner, logger *runner.Logger, verbose bool, conf config.Config) { +func runTSSMigration(deployerRunner *runner.E2ERunner, logger *runner.Logger, verbose bool, conf config.Config) { migrationStartTime := time.Now() logger.Print("🏁 starting tss migration") @@ -483,26 +431,9 @@ func runTSSMigrationTest(deployerRunner *runner.E2ERunner, logger *runner.Logger logger.Print("❌ tss migration failed") os.Exit(1) } - updateTssAddressForConnector(deployerRunner) - updateTssAddressForErc20custody(deployerRunner) + deployerRunner.UpdateTssAddressForConnector() + deployerRunner.UpdateTssAddressForErc20custody() logger.Print("βœ… migration completed in %s ", time.Since(migrationStartTime).String()) - - //logger.Print("🏁 starting post migration tests") - - //tests := []string{ - // e2etests.TestBitcoinWithdrawSegWitName, - // e2etests.TestEtherWithdrawName, - // e2etests.TestZetaWithdrawName, - // e2etests.TestERC20WithdrawName, - //} - //fn = postMigrationTestRoutine(conf, deployerRunner, verbose, tests...) - // - //if err := fn(); err != nil { - // logger.Print("❌ %v", err) - // logger.Print("❌ post migration tests failed") - // os.Exit(1) - //} - } func must[T any](v T, err error) T { diff --git a/e2e/e2etests/test_message_passing_external_chains_revert.go b/e2e/e2etests/test_message_passing_external_chains_revert.go index 37146a4c78..e396a7d95c 100644 --- a/e2e/e2etests/test_message_passing_external_chains_revert.go +++ b/e2e/e2etests/test_message_passing_external_chains_revert.go @@ -62,11 +62,11 @@ func TestMessagePassingRevertSuccessExternalChains(r *runner.E2ERunner, args []s for _, log := range receipt.Logs { event, err := r.ConnectorEth.ParseZetaReverted(*log) if err == nil { - r.Logger.Info("ZetaReverted event: ") - r.Logger.Info(" Dest Addr: %s", ethcommon.BytesToAddress(event.DestinationAddress).Hex()) - r.Logger.Info(" Dest Chain: %d", event.DestinationChainId) - r.Logger.Info(" RemainingZetaValue: %d", event.RemainingZetaValue) - r.Logger.Info(" Message: %x", event.Message) + r.Logger.Print("ZetaReverted event: ") + r.Logger.Print(" Dest Addr: %s", ethcommon.BytesToAddress(event.DestinationAddress).Hex()) + r.Logger.Print(" Dest Chain: %d", event.DestinationChainId) + r.Logger.Print(" RemainingZetaValue: %d", event.RemainingZetaValue) + r.Logger.Print(" Message: %x", event.Message) } } diff --git a/e2e/runner/setup_evm.go b/e2e/runner/setup_evm.go index d998063d1a..7b61d43163 100644 --- a/e2e/runner/setup_evm.go +++ b/e2e/runner/setup_evm.go @@ -77,7 +77,6 @@ func (r *E2ERunner) SetupEVM(contractsDeployed bool, whitelistERC20 bool) { r.Logger.Info("ZetaEth contract address: %s, tx hash: %s", zetaEthAddr.Hex(), zetaEthAddr.Hash().Hex()) r.Logger.Info("Deploying ZetaConnectorEth contract") - r.Logger.Print("Connector constructor args: ZetaETH %s, TSS %s, Updated %s, Pauser %s\n", zetaEthAddr.Hex(), r.TSSAddress.Hex(), r.EVMAddress().Hex(), r.EVMAddress().Hex()) connectorEthAddr, txConnector, ConnectorEth, err := zetaconnectoreth.DeployZetaConnectorEth( r.EVMAuth, r.EVMClient, diff --git a/e2e/runner/update_contracts.go b/e2e/runner/update_contracts.go new file mode 100644 index 0000000000..6d4b184061 --- /dev/null +++ b/e2e/runner/update_contracts.go @@ -0,0 +1,40 @@ +package runner + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/utils" +) + +func (r *E2ERunner) UpdateTssAddressForConnector() { + + require.NoError(r, r.SetTSSAddresses()) + + tx, err := r.ConnectorEth.UpdateTssAddress(r.EVMAuth, r.TSSAddress) + require.NoError(r, err) + r.Logger.Info(fmt.Sprintf("TSS Address Update Tx: %s", tx.Hash().String())) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt) + + tssAddressOnConnector, err := r.ConnectorEth.TssAddress(&bind.CallOpts{Context: r.Ctx}) + require.NoError(r, err) + require.Equal(r, r.TSSAddress, tssAddressOnConnector) + +} + +func (r *E2ERunner) UpdateTssAddressForErc20custody() { + + require.NoError(r, r.SetTSSAddresses()) + + tx, err := r.ERC20Custody.UpdateTSSAddress(r.EVMAuth, r.TSSAddress) + require.NoError(r, err) + r.Logger.Info(fmt.Sprintf("TSS ERC20 Address Update Tx: %s", tx.Hash().String())) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.EVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequireTxSuccessful(r, receipt) + + tssAddressOnCustody, err := r.ERC20Custody.TSSAddress(&bind.CallOpts{Context: r.Ctx}) + require.NoError(r, err) + require.Equal(r, r.TSSAddress, tssAddressOnCustody) +} diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index da3d4fc5d4..a10dc8d68b 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -20,7 +20,7 @@ const ( AdminPolicyName = "admin" OperationalPolicyName = "operational" - DefaultCctxTimeout = 8 * time.Minute + DefaultCctxTimeout = 4 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) diff --git a/testutil/keeper/mocks/crosschain/observer.go b/testutil/keeper/mocks/crosschain/observer.go index c90c15c3a6..63789912ce 100644 --- a/testutil/keeper/mocks/crosschain/observer.go +++ b/testutil/keeper/mocks/crosschain/observer.go @@ -604,6 +604,46 @@ func (_m *CrosschainObserverKeeper) GetSupportedChains(ctx types.Context) []chai return r0 } +// GetSupportedForeignChains provides a mock function with given fields: ctx +func (_m *CrosschainObserverKeeper) GetSupportedForeignChains(ctx types.Context) []chains.Chain { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedForeignChains") + } + + var r0 []chains.Chain + if rf, ok := ret.Get(0).(func(types.Context) []chains.Chain); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]chains.Chain) + } + } + + return r0 +} + +// GetSupportedForeignChainsByConsensus provides a mock function with given fields: ctx, consensus +func (_m *CrosschainObserverKeeper) GetSupportedForeignChainsByConsensus(ctx types.Context, consensus chains.Consensus) []chains.Chain { + ret := _m.Called(ctx, consensus) + + if len(ret) == 0 { + panic("no return value specified for GetSupportedForeignChainsByConsensus") + } + + var r0 []chains.Chain + if rf, ok := ret.Get(0).(func(types.Context, chains.Consensus) []chains.Chain); ok { + r0 = rf(ctx, consensus) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]chains.Chain) + } + } + + return r0 +} + // GetTSS provides a mock function with given fields: ctx func (_m *CrosschainObserverKeeper) GetTSS(ctx types.Context) (observertypes.TSS, bool) { ret := _m.Called(ctx) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go index 983b2c2e49..1391bbaf9d 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_outbound.go @@ -77,7 +77,6 @@ func (k Keeper) ValidateOutboundObservers( case observertypes.BallotStatus_BallotFinalized_SuccessObservation: k.validateSuccessfulOutbound(tmpCtx, cctx, valueReceived, true) case observertypes.BallotStatus_BallotFinalized_FailureObservation: - fmt.Printf("Outbound failed, start validateFailedOutboundObservers : %s ballot %s\n", cctx.Index, cctx.GetCurrentOutboundParam().BallotIndex) err := k.validateFailedOutboundObservers(tmpCtx, cctx, valueReceived) if err != nil { return err @@ -140,7 +139,6 @@ func (k Keeper) validateFailedOutboundObservers(ctx sdk.Context, cctx *types.Cro } } } else { - fmt.Printf("Outbound failed, start revert : %s ballot %s \n", cctx.Index, cctx.GetCurrentOutboundParam().BallotIndex) err := k.validateFailedOutbound(ctx, cctx, oldStatus, "Outbound failed, start revert", cctx.GetCurrentOutboundParam().Amount) if err != nil { return cosmoserrors.Wrap(err, "validateFailedOutbound") @@ -197,7 +195,6 @@ func (k Keeper) validateFailedOutbound( // Not setting the finalization status here, the required changes have been made while creating the revert tx cctx.SetPendingRevert(revertMsg) case types.CctxStatus_PendingRevert: - fmt.Printf("Outbound failed, aborting : %s ballot %s \n", cctx.Index, cctx.GetCurrentOutboundParam().BallotIndex) cctx.GetCurrentOutboundParam().TxFinalizationStatus = types.TxFinalizationStatus_Executed cctx.SetAbort("Outbound failed: revert failed; abort TX") } diff --git a/x/crosschain/keeper/msg_server_add_outbound_tracker.go b/x/crosschain/keeper/msg_server_add_outbound_tracker.go index 85c9f96f90..a7df13ebce 100644 --- a/x/crosschain/keeper/msg_server_add_outbound_tracker.go +++ b/x/crosschain/keeper/msg_server_add_outbound_tracker.go @@ -55,10 +55,6 @@ func (k msgServer) AddOutboundTracker( k.RemoveOutboundTrackerFromStore(ctx, msg.ChainId, msg.Nonce) return &types.MsgAddOutboundTrackerResponse{IsRemoved: true}, nil } - - fmt.Println("Trying to add new tracker :", cctx.CrossChainTx.Index, len(cctx.CrossChainTx.OutboundParams), cctx.CrossChainTx.CctxStatus.Status) - fmt.Println("Tracker Index ", msg.ChainId, msg.Nonce) - // check if the msg signer is from the emergency group policy address.It is okay to ignore the error as the sender can also be an observer isAuthorizedPolicy := false if k.GetAuthorityKeeper().CheckAuthorization(ctx, msg) == nil { diff --git a/x/crosschain/types/expected_keepers.go b/x/crosschain/types/expected_keepers.go index b159f84148..1422538b2f 100644 --- a/x/crosschain/types/expected_keepers.go +++ b/x/crosschain/types/expected_keepers.go @@ -103,8 +103,6 @@ type ObserverKeeper interface { ) (bool, bool, observertypes.Ballot, string, error) GetSupportedChainFromChainID(ctx sdk.Context, chainID int64) (chains.Chain, bool) GetSupportedChains(ctx sdk.Context) []chains.Chain - GetSupportedForeignChains(ctx sdk.Context) []chains.Chain - GetSupportedForeignChainsByConsensus(ctx sdk.Context, consensus chains.Consensus) []chains.Chain } type FungibleKeeper interface { diff --git a/x/observer/keeper/chain_params.go b/x/observer/keeper/chain_params.go index 1c2cf4e7c4..9dc862dd98 100644 --- a/x/observer/keeper/chain_params.go +++ b/x/observer/keeper/chain_params.go @@ -75,29 +75,3 @@ func (k Keeper) GetSupportedChains(ctx sdk.Context) []chains.Chain { } return c } - -// GetSupportedChainsByConsensus returns the list of supported chains by consensus -func (k Keeper) GetSupportedForeignChainsByConsensus(ctx sdk.Context, consensus chains.Consensus) []chains.Chain { - allChains := k.GetSupportedChains(ctx) - - foreignChains := make([]chains.Chain, 0) - for _, chain := range allChains { - if !chain.IsZetaChain() && chain.GetConsensus() == consensus { - foreignChains = append(foreignChains, chain) - } - } - return foreignChains -} - -// GetSupportedForeignChains returns the list of supported foreign chains -func (k Keeper) GetSupportedForeignChains(ctx sdk.Context) []chains.Chain { - allChains := k.GetSupportedChains(ctx) - - foreignChains := make([]chains.Chain, 0) - for _, chain := range allChains { - if !chain.IsZetaChain() { - foreignChains = append(foreignChains, chain) - } - } - return foreignChains -} diff --git a/x/observer/keeper/chain_params_test.go b/x/observer/keeper/chain_params_test.go index f4de631043..733fafc0b8 100644 --- a/x/observer/keeper/chain_params_test.go +++ b/x/observer/keeper/chain_params_test.go @@ -110,106 +110,3 @@ func TestKeeper_GetSupportedChains(t *testing.T) { require.EqualValues(t, supported4.ChainId, supportedChains[3].ChainId) }) } - -func TestKeeper_GetSupportedForeignChainsByConsensus(t *testing.T) { - t.Run("return empty list if not chans are supported", func(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - require.Empty(t, k.GetSupportedForeignChainsByConsensus(ctx, chains.Consensus_ethereum)) - }) - - t.Run("return list of supported chains for ethereum consensus", func(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - chainList := chains.ExternalChainList([]chains.Chain{}) - var chainParamsList types.ChainParamsList - for _, chain := range chainList { - chainParamsList.ChainParams = append( - chainParamsList.ChainParams, - sample.ChainParamsSupported(chain.ChainId), - ) - } - k.SetChainParamsList(ctx, chainParamsList) - consensus := chains.Consensus_ethereum - - supportedChainsList := k.GetSupportedForeignChainsByConsensus(ctx, consensus) - require.NotEmpty(t, supportedChainsList) - - require.ElementsMatch(t, getForeignChains(consensus), supportedChainsList) - }) - - t.Run("return list of supported chains for bitcoin consensus", func(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - chainList := chains.ExternalChainList([]chains.Chain{}) - var chainParamsList types.ChainParamsList - for _, chain := range chainList { - chainParamsList.ChainParams = append( - chainParamsList.ChainParams, - sample.ChainParamsSupported(chain.ChainId), - ) - } - k.SetChainParamsList(ctx, chainParamsList) - consensus := chains.Consensus_bitcoin - - supportedChainsList := k.GetSupportedForeignChainsByConsensus(ctx, consensus) - require.NotEmpty(t, supportedChainsList) - require.ElementsMatch(t, getForeignChains(consensus), supportedChainsList) - }) - - t.Run("return list of supported chains for solana consensus", func(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - chainList := chains.ExternalChainList([]chains.Chain{}) - var chainParamsList types.ChainParamsList - for _, chain := range chainList { - chainParamsList.ChainParams = append( - chainParamsList.ChainParams, - sample.ChainParamsSupported(chain.ChainId), - ) - } - k.SetChainParamsList(ctx, chainParamsList) - consensus := chains.Consensus_solana_consensus - - supportedChainsList := k.GetSupportedForeignChainsByConsensus(ctx, consensus) - require.NotEmpty(t, supportedChainsList) - require.ElementsMatch(t, getForeignChains(consensus), supportedChainsList) - }) -} - -func TestKeeper_GetSupportedForeignChains(t *testing.T) { - t.Run("return empty list if not chans are supported", func(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - require.Empty(t, k.GetSupportedForeignChains(ctx)) - }) - - t.Run("return list of supported chains", func(t *testing.T) { - k, ctx, _, _ := keepertest.ObserverKeeper(t) - chainList := chains.ExternalChainList([]chains.Chain{}) - var chainParamsList types.ChainParamsList - for _, chain := range chainList { - chainParamsList.ChainParams = append( - chainParamsList.ChainParams, - sample.ChainParamsSupported(chain.ChainId), - ) - } - k.SetChainParamsList(ctx, chainParamsList) - - supportedChainsList := k.GetSupportedForeignChains(ctx) - require.NotEmpty(t, supportedChainsList) - - require.ElementsMatch(t, getAllForeignChains(), supportedChainsList) - }) -} - -func getAllForeignChains() []chains.Chain { - return chains.ExternalChainList([]chains.Chain{}) -} - -func getForeignChains(consensus chains.Consensus) []chains.Chain { - evmChains := chains.ChainListByConsensus(consensus, []chains.Chain{}) - foreignEvmChains := make([]chains.Chain, 0) - - for _, chain := range evmChains { - if !chain.IsZetaChain() { - foreignEvmChains = append(foreignEvmChains, chain) - } - } - return foreignEvmChains -} diff --git a/x/observer/keeper/voting.go b/x/observer/keeper/voting.go index 417a5cc470..d340f0bf32 100644 --- a/x/observer/keeper/voting.go +++ b/x/observer/keeper/voting.go @@ -26,7 +26,6 @@ func (k Keeper) AddVoteToBallot( } ctx.Logger().Info(fmt.Sprintf("Vote Added | Voter :%s, ballot identifier %s", address, ballot.BallotIdentifier)) k.SetBallot(ctx, &ballot) - ctx.Logger().Info(fmt.Sprintf("Ballot Updated | Ballot Identifier : %s", ballot.BallotIdentifier)) return ballot, nil } From e964cee442851943d4eb1e678dd58664bb603f96 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 8 Aug 2024 15:48:24 -0400 Subject: [PATCH 13/29] update cctx timeout --- changelog.md | 2 +- cmd/zetae2e/local/local.go | 8 ++++---- cmd/zetae2e/local/migration.go | 4 ++-- contrib/localnet/orchestrator/start-zetae2e.sh | 17 ++++++++--------- e2e/e2etests/test_crosschain_swap.go | 8 +++----- ...st_message_passing_external_chains_revert.go | 10 +++++----- ...ssage_passing_external_chains_revert_fail.go | 9 ++++----- e2e/e2etests/test_zrc20_swap.go | 2 +- e2e/utils/zetacore.go | 2 +- x/crosschain/keeper/outbound_tracker.go | 1 - 10 files changed, 29 insertions(+), 34 deletions(-) diff --git a/changelog.md b/changelog.md index 055ada9c61..c904c5af8d 100644 --- a/changelog.md +++ b/changelog.md @@ -85,8 +85,8 @@ * [2515](https://github.com/zeta-chain/node/pull/2515) - replace chainName by chainID for ChainNonces indexing * [2541](https://github.com/zeta-chain/node/pull/2541) - deprecate ChainName field in Chain object * [2542](https://github.com/zeta-chain/node/pull/2542) - adjust permissions to be more restrictive -* [2556](https://github.com/zeta-chain/node/pull/2556) - refactor migrator length check to use consensus type * [2572](https://github.com/zeta-chain/node/pull/2572) - turn off IBC modules +* [2556](https://github.com/zeta-chain/node/pull/2556) - refactor migrator length check to use consensus type * [2568](https://github.com/zeta-chain/node/pull/2568) - improve AppContext by converging chains, chainParams, enabledChains, and additionalChains into a single zctx.Chain ### Tests diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 4b45f41494..deb9dd112e 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -421,10 +421,10 @@ func runTSSMigration(deployerRunner *runner.E2ERunner, logger *runner.Logger, ve // Generate new TSS waitKeygenHeight(deployerRunner.Ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) - // migration test is a blocking thread, we cannot run other tests in parallel - // The migration test migrates funds to a new TSS and then updates the TSS address on zetacore. - // The necessary restarts are done by the zetaclient supervisor - fn := migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTSSName) + // Run migration + // migrationRoutine runs migration e2e test , which migrates funds from the older TSS to the new one + // The zetaclient restarts required for this process are managed by the background workers in zetaclient (TSSListener) + fn := migrationRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTSSName) if err := fn(); err != nil { logger.Print("❌ %v", err) diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index d6fab1b709..27d9682990 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -11,8 +11,8 @@ import ( "github.com/zeta-chain/zetacore/e2e/runner" ) -// migrationTestRoutine runs migration related e2e tests -func migrationTestRoutine( +// migrationRoutine runs migration related e2e tests +func migrationRoutine( conf config.Config, deployerRunner *runner.E2ERunner, verbose bool, diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index d8e7d04cbb..2cff961772 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -90,8 +90,11 @@ geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: w address=$(yq -r '.additional_accounts.user_migration.evm_address' config.yml) echo "funding migration tester address ${address} with 10000 Ether" geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 +### Run zetae2e command depending on the option passed - +# Mode migrate is used to run the e2e tests before and after the TSS migration +# It runs the e2e tests with the migrate flag which triggers a TSS migration at the end of the tests. Once the migrationis done the first e2e test is complete +# The second e2e test is run after the migration to ensure the network is still working as expected with the new tss address if [ "$LOCALNET_MODE" == "migrate" ]; then if [[ ! -f deployed.yml ]]; then zetae2e local $E2E_ARGS --setup-only --config config.yml --config-out deployed.yml --skip-header-proof @@ -104,8 +107,6 @@ if [ "$LOCALNET_MODE" == "migrate" ]; then fi echo "running e2e test before migrating TSS" - - # Use light flag to ensure tests can complete before the upgrade height zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --skip-header-proof if [ $? -ne 0 ]; then echo "first e2e failed" @@ -116,7 +117,6 @@ if [ "$LOCALNET_MODE" == "migrate" ]; then sleep 10 zetae2e local --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof - ZETAE2E_EXIT_CODE=$? if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then echo "E2E passed after migration" @@ -128,8 +128,9 @@ if [ "$LOCALNET_MODE" == "migrate" ]; then fi -### Run zetae2e command depending on the option passed - +# Mode upgrade is used to run the e2e tests before and after the upgrade +# It runs the e2e tests , waits for the upgrade height to be reached, and then runs the e2e tests again once the ungrade is done. +# The second e2e test is run after the upgrade to ensure the network is still working as expected with the new version if [ "$LOCALNET_MODE" == "upgrade" ]; then # Run the e2e tests, then restart zetaclientd at upgrade height and run the e2e tests again @@ -162,7 +163,6 @@ if [ "$LOCALNET_MODE" == "upgrade" ]; then echo "Waiting for upgrade height..." OLD_VERSION=$(get_zetacored_version) - CURRENT_HEIGHT=0 WAIT_HEIGHT=$(( UPGRADE_HEIGHT - 1 )) # wait for upgrade height @@ -209,8 +209,7 @@ if [ "$LOCALNET_MODE" == "upgrade" ]; then fi else - - # Run the e2e tests normally + # If no mode is passed, run the e2e tests normally echo "running e2e setup..." if [[ ! -f deployed.yml ]]; then diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index faaca5c026..61511b6ddd 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -25,8 +25,8 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { // if the tx fails due to already initialized, it will be ignored _, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.BTCZRC20Addr) if err != nil { - time.Sleep(3 * time.Second) - r.Logger.Print("ℹ️create pair error") + r.Logger.Print("ℹ️ create pair error") + time.Sleep(3 * time.Second) // wait for sometime so that the } txERC20ZRC20Approve, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) @@ -144,10 +144,8 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { r.Logger.Info("memo length %d", len(memo)) amount := 0.1 - - txid := &chainhash.Hash{} utxos, err = r.ListDeployerUTXOs() - txid, err = r.SendToTSSFromDeployerWithMemo(amount, utxos[0:1], memo) + txid, err := r.SendToTSSFromDeployerWithMemo(amount, utxos[0:1], memo) require.NoError(r, err) cctx := utils.WaitCctxMinedByInboundHash(r.Ctx, txid.String(), r.CctxClient, r.Logger, r.CctxTimeout) diff --git a/e2e/e2etests/test_message_passing_external_chains_revert.go b/e2e/e2etests/test_message_passing_external_chains_revert.go index e396a7d95c..37146a4c78 100644 --- a/e2e/e2etests/test_message_passing_external_chains_revert.go +++ b/e2e/e2etests/test_message_passing_external_chains_revert.go @@ -62,11 +62,11 @@ func TestMessagePassingRevertSuccessExternalChains(r *runner.E2ERunner, args []s for _, log := range receipt.Logs { event, err := r.ConnectorEth.ParseZetaReverted(*log) if err == nil { - r.Logger.Print("ZetaReverted event: ") - r.Logger.Print(" Dest Addr: %s", ethcommon.BytesToAddress(event.DestinationAddress).Hex()) - r.Logger.Print(" Dest Chain: %d", event.DestinationChainId) - r.Logger.Print(" RemainingZetaValue: %d", event.RemainingZetaValue) - r.Logger.Print(" Message: %x", event.Message) + r.Logger.Info("ZetaReverted event: ") + r.Logger.Info(" Dest Addr: %s", ethcommon.BytesToAddress(event.DestinationAddress).Hex()) + r.Logger.Info(" Dest Chain: %d", event.DestinationChainId) + r.Logger.Info(" RemainingZetaValue: %d", event.RemainingZetaValue) + r.Logger.Info(" Message: %x", event.Message) } } 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 139dee8f44..699f66b607 100644 --- a/e2e/e2etests/test_message_passing_external_chains_revert_fail.go +++ b/e2e/e2etests/test_message_passing_external_chains_revert_fail.go @@ -59,13 +59,12 @@ func TestMessagePassingRevertFailExternalChains(r *runner.E2ERunner, args []stri for _, log := range receipt.Logs { sentLog, err := r.ConnectorEth.ParseZetaSent(*log) if err == nil { - r.Logger.Print(" Dest Addr: %s", ethcommon.BytesToAddress(sentLog.DestinationAddress).Hex()) - r.Logger.Print(" Dest Chain: %d", sentLog.DestinationChainId) - r.Logger.Print(" Dest Gas: %d", sentLog.DestinationGasLimit) - r.Logger.Print(" 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) } } - r.Logger.Print(" Inbound Tx Hash: %s", receipt.TxHash.String()) // 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)) diff --git a/e2e/e2etests/test_zrc20_swap.go b/e2e/e2etests/test_zrc20_swap.go index 14febbe800..3008904306 100644 --- a/e2e/e2etests/test_zrc20_swap.go +++ b/e2e/e2etests/test_zrc20_swap.go @@ -19,7 +19,7 @@ func TestZRC20Swap(r *runner.E2ERunner, _ []string) { // if the tx fails due to already initialized, it will be ignored tx, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.ETHZRC20Addr) if err != nil { - r.Logger.Print("ℹ️create pair error") + r.Logger.Print("ℹ️ create pair error") } else { utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) } diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index a10dc8d68b..da3d4fc5d4 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -20,7 +20,7 @@ const ( AdminPolicyName = "admin" OperationalPolicyName = "operational" - DefaultCctxTimeout = 4 * time.Minute + DefaultCctxTimeout = 8 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) diff --git a/x/crosschain/keeper/outbound_tracker.go b/x/crosschain/keeper/outbound_tracker.go index fd9448db90..dbf8bf3bb5 100644 --- a/x/crosschain/keeper/outbound_tracker.go +++ b/x/crosschain/keeper/outbound_tracker.go @@ -51,7 +51,6 @@ func (k Keeper) RemoveOutboundTrackerFromStore( ) { index := getOutboundTrackerIndex(chainID, nonce) store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.OutboundTrackerKeyPrefix)) - fmt.Println("Removing outbound tracker ", chainID, nonce) store.Delete(types.OutboundTrackerKey( index, )) From a68a1b39c394b66143ea6238f3633418d1e1d251 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 8 Aug 2024 20:02:33 -0400 Subject: [PATCH 14/29] update cctx timeout --- e2e/utils/zetacore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index da3d4fc5d4..9122860d75 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -20,7 +20,7 @@ const ( AdminPolicyName = "admin" OperationalPolicyName = "operational" - DefaultCctxTimeout = 8 * time.Minute + DefaultCctxTimeout = 6 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) From 865f5650ea1669bbe362fd13370ef98cc2b2d7a3 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 8 Aug 2024 21:22:17 -0400 Subject: [PATCH 15/29] move to unreleased --- changelog.md | 5 ++++- e2e/e2etests/test_crosschain_swap.go | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index c904c5af8d..d90f6157e4 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,10 @@ * [2615](https://github.com/zeta-chain/node/pull/2615) - Refactor cleanup of outbound trackers +### Tests + +* [2661](https://github.com/zeta-chain/node/pull/2661) - update connector and erc20Custody addresses in tss migration e2e tests + ## v19.0.0 ### Breaking Changes @@ -110,7 +114,6 @@ * [2415](https://github.com/zeta-chain/node/pull/2415) - add e2e test for upgrade and test admin functionalities * [2440](https://github.com/zeta-chain/node/pull/2440) - Add e2e test for TSS migration * [2473](https://github.com/zeta-chain/node/pull/2473) - add e2e tests for most used admin transactions -* [2661](https://github.com/zeta-chain/node/pull/2661) - update connector and erc20Custody addresses in tss migration e2e tests ### Fixes diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index 61511b6ddd..a612e609ea 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -26,7 +26,6 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { _, err := r.UniswapV2Factory.CreatePair(r.ZEVMAuth, r.ERC20ZRC20Addr, r.BTCZRC20Addr) if err != nil { r.Logger.Print("ℹ️ create pair error") - time.Sleep(3 * time.Second) // wait for sometime so that the } txERC20ZRC20Approve, err := r.ERC20ZRC20.Approve(r.ZEVMAuth, r.UniswapV2RouterAddr, big.NewInt(1e18)) From 86e292161db92b98d86961cdd4f0dcbd579739ea Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 8 Aug 2024 22:01:02 -0400 Subject: [PATCH 16/29] move to unreleased --- .../test_message_passing_external_chains_revert_fail.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 699f66b607..00a18bb3e2 100644 --- a/e2e/e2etests/test_message_passing_external_chains_revert_fail.go +++ b/e2e/e2etests/test_message_passing_external_chains_revert_fail.go @@ -40,7 +40,7 @@ func TestMessagePassingRevertFailExternalChains(r *runner.E2ERunner, args []stri tx, err = r.ConnectorEth.Send(auth, zetaconnectoreth.ZetaInterfacesSendInput{ DestinationChainId: chainID, DestinationAddress: r.EVMAddress().Bytes(), - DestinationGasLimit: big.NewInt(1800_000), + DestinationGasLimit: big.NewInt(400_000), Message: []byte( "revert", ), // non-empty message will cause revert, because the dest address is not a contract From d223a8f09c34bf6353136320b560e589ed52fc24 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 8 Aug 2024 22:33:34 -0400 Subject: [PATCH 17/29] move to unreleased --- x/crosschain/keeper/msg_server_add_outbound_tracker.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/crosschain/keeper/msg_server_add_outbound_tracker.go b/x/crosschain/keeper/msg_server_add_outbound_tracker.go index a7df13ebce..b82fba7f79 100644 --- a/x/crosschain/keeper/msg_server_add_outbound_tracker.go +++ b/x/crosschain/keeper/msg_server_add_outbound_tracker.go @@ -55,6 +55,7 @@ func (k msgServer) AddOutboundTracker( k.RemoveOutboundTrackerFromStore(ctx, msg.ChainId, msg.Nonce) return &types.MsgAddOutboundTrackerResponse{IsRemoved: true}, nil } + // check if the msg signer is from the emergency group policy address.It is okay to ignore the error as the sender can also be an observer isAuthorizedPolicy := false if k.GetAuthorityKeeper().CheckAuthorization(ctx, msg) == nil { From c2da535e97af3d47276e0afa1b7fe518bd548c01 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 8 Aug 2024 22:42:57 -0400 Subject: [PATCH 18/29] generate --- e2e/e2etests/test_migrate_tss.go | 1 + e2e/runner/update_contracts.go | 4 +- testutil/keeper/mocks/crosschain/observer.go | 40 -------------------- 3 files changed, 2 insertions(+), 43 deletions(-) diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index 8063a2154b..d3ff74cb2f 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -11,6 +11,7 @@ import ( "github.com/btcsuite/btcutil" "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" "github.com/zeta-chain/zetacore/pkg/chains" diff --git a/e2e/runner/update_contracts.go b/e2e/runner/update_contracts.go index 6d4b184061..8b357a01f5 100644 --- a/e2e/runner/update_contracts.go +++ b/e2e/runner/update_contracts.go @@ -5,11 +5,11 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/e2e/utils" ) func (r *E2ERunner) UpdateTssAddressForConnector() { - require.NoError(r, r.SetTSSAddresses()) tx, err := r.ConnectorEth.UpdateTssAddress(r.EVMAuth, r.TSSAddress) @@ -21,11 +21,9 @@ func (r *E2ERunner) UpdateTssAddressForConnector() { tssAddressOnConnector, err := r.ConnectorEth.TssAddress(&bind.CallOpts{Context: r.Ctx}) require.NoError(r, err) require.Equal(r, r.TSSAddress, tssAddressOnConnector) - } func (r *E2ERunner) UpdateTssAddressForErc20custody() { - require.NoError(r, r.SetTSSAddresses()) tx, err := r.ERC20Custody.UpdateTSSAddress(r.EVMAuth, r.TSSAddress) diff --git a/testutil/keeper/mocks/crosschain/observer.go b/testutil/keeper/mocks/crosschain/observer.go index 63789912ce..c90c15c3a6 100644 --- a/testutil/keeper/mocks/crosschain/observer.go +++ b/testutil/keeper/mocks/crosschain/observer.go @@ -604,46 +604,6 @@ func (_m *CrosschainObserverKeeper) GetSupportedChains(ctx types.Context) []chai return r0 } -// GetSupportedForeignChains provides a mock function with given fields: ctx -func (_m *CrosschainObserverKeeper) GetSupportedForeignChains(ctx types.Context) []chains.Chain { - ret := _m.Called(ctx) - - if len(ret) == 0 { - panic("no return value specified for GetSupportedForeignChains") - } - - var r0 []chains.Chain - if rf, ok := ret.Get(0).(func(types.Context) []chains.Chain); ok { - r0 = rf(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]chains.Chain) - } - } - - return r0 -} - -// GetSupportedForeignChainsByConsensus provides a mock function with given fields: ctx, consensus -func (_m *CrosschainObserverKeeper) GetSupportedForeignChainsByConsensus(ctx types.Context, consensus chains.Consensus) []chains.Chain { - ret := _m.Called(ctx, consensus) - - if len(ret) == 0 { - panic("no return value specified for GetSupportedForeignChainsByConsensus") - } - - var r0 []chains.Chain - if rf, ok := ret.Get(0).(func(types.Context, chains.Consensus) []chains.Chain); ok { - r0 = rf(ctx, consensus) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]chains.Chain) - } - } - - return r0 -} - // GetTSS provides a mock function with given fields: ctx func (_m *CrosschainObserverKeeper) GetTSS(ctx types.Context) (observertypes.TSS, bool) { ret := _m.Called(ctx) From 0e6fa1c995731728ae47b26b1f03a76ae54aa22b Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 12 Aug 2024 14:02:39 -0400 Subject: [PATCH 19/29] refactor migration to tss-migration --- Makefile | 4 ++-- contrib/localnet/orchestrator/start-zetae2e.sh | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 1b19573094..dc48463da4 100644 --- a/Makefile +++ b/Makefile @@ -262,8 +262,8 @@ start-stress-test: zetanode cd contrib/localnet/ && $(DOCKER_COMPOSE) --profile stress -f docker-compose.yml up -d start-tss-migration-test: zetanode - @echo "--> Starting migration test" - export LOCALNET_MODE=migrate && \ + @echo "--> Starting tss migration test" + export LOCALNET_MODE=tss-migrate && \ export E2E_ARGS="--test-tss-migration" && \ cd contrib/localnet/ && $(DOCKER_COMPOSE) up -d diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 2cff961772..af1d565ea4 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -4,6 +4,7 @@ # First argument is the command to run the local e2e # A second optional argument can be passed and can have the following value: # upgrade: run the local e2e once, then restart zetaclientd at upgrade height and run the local e2e again +# tss-migrate: run the local e2e once, then trigger a TSS migration and run the local e2e again get_zetacored_version() { retries=10 @@ -95,7 +96,7 @@ geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: w # Mode migrate is used to run the e2e tests before and after the TSS migration # It runs the e2e tests with the migrate flag which triggers a TSS migration at the end of the tests. Once the migrationis done the first e2e test is complete # The second e2e test is run after the migration to ensure the network is still working as expected with the new tss address -if [ "$LOCALNET_MODE" == "migrate" ]; then +if [ "$LOCALNET_MODE" == "tss-migrate" ]; then if [[ ! -f deployed.yml ]]; then zetae2e local $E2E_ARGS --setup-only --config config.yml --config-out deployed.yml --skip-header-proof if [ $? -ne 0 ]; then From a9b72ed8cf82dbd2cc35cfeea83f4d1f5448c51f Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 13 Aug 2024 11:14:56 -0400 Subject: [PATCH 20/29] add issue to track increase in DefaultCctxTimeout --- e2e/utils/zetacore.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index 9122860d75..460ba62ed1 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -19,6 +19,9 @@ const ( EmergencyPolicyName = "emergency" AdminPolicyName = "admin" OperationalPolicyName = "operational" + // The timeout was increased from 4 to 6 , which allows for a higher success in test runs + // However this needs to be researched as to why the increase in timeout was needed. + // https://github.com/zeta-chain/node/issues/2690 DefaultCctxTimeout = 6 * time.Minute ) From 08ecc2273ea95015e67baf0683204c463f311bd9 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 16 Aug 2024 10:50:54 -0400 Subject: [PATCH 21/29] move migration test to a separate file --- cmd/zetae2e/local/local.go | 33 +--------------- cmd/zetae2e/local/post_migration.go | 58 ----------------------------- cmd/zetae2e/local/tss_migration.go | 43 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 90 deletions(-) delete mode 100644 cmd/zetae2e/local/post_migration.go create mode 100644 cmd/zetae2e/local/tss_migration.go diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index deb9dd112e..c2aaa146ee 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -9,7 +9,6 @@ import ( "github.com/fatih/color" "github.com/spf13/cobra" - "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" @@ -351,7 +350,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("βœ… e2e tests completed in %s", time.Since(testStartTime).String()) if testTSSMigration { - runTSSMigration(deployerRunner, logger, verbose, conf) + TSSMigration(deployerRunner, logger, verbose, conf) } // Verify that there are no trackers left over after tests complete deployerRunner.EnsureNoTrackers() @@ -406,36 +405,6 @@ func waitKeygenHeight( } } -func runTSSMigration(deployerRunner *runner.E2ERunner, logger *runner.Logger, verbose bool, conf config.Config) { - migrationStartTime := time.Now() - logger.Print("🏁 starting tss migration") - - response, err := deployerRunner.CctxClient.LastZetaHeight( - deployerRunner.Ctx, - &crosschaintypes.QueryLastZetaHeightRequest{}, - ) - require.NoError(deployerRunner, err) - err = deployerRunner.ZetaTxServer.UpdateKeygen(response.Height) - require.NoError(deployerRunner, err) - - // Generate new TSS - waitKeygenHeight(deployerRunner.Ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) - - // Run migration - // migrationRoutine runs migration e2e test , which migrates funds from the older TSS to the new one - // The zetaclient restarts required for this process are managed by the background workers in zetaclient (TSSListener) - fn := migrationRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTSSName) - - if err := fn(); err != nil { - logger.Print("❌ %v", err) - logger.Print("❌ tss migration failed") - os.Exit(1) - } - deployerRunner.UpdateTssAddressForConnector() - deployerRunner.UpdateTssAddressForErc20custody() - logger.Print("βœ… migration completed in %s ", time.Since(migrationStartTime).String()) -} - func must[T any](v T, err error) T { return testutil.Must(v, err) } diff --git a/cmd/zetae2e/local/post_migration.go b/cmd/zetae2e/local/post_migration.go deleted file mode 100644 index f339ce0bc1..0000000000 --- a/cmd/zetae2e/local/post_migration.go +++ /dev/null @@ -1,58 +0,0 @@ -package local - -import ( - "time" - - "github.com/fatih/color" - "github.com/pkg/errors" - - "github.com/zeta-chain/zetacore/e2e/config" - "github.com/zeta-chain/zetacore/e2e/e2etests" - "github.com/zeta-chain/zetacore/e2e/runner" -) - -// postMigrationTestRoutine runs post migration tests -func postMigrationTestRoutine( - conf config.Config, - deployerRunner *runner.E2ERunner, - verbose bool, - testNames ...string, -) func() error { - return func() (err error) { - account := conf.AdditionalAccounts.UserBitcoin - // initialize runner for post migration test - postMigrationRunner, err := initTestRunner( - "postMigration", - conf, - deployerRunner, - account, - runner.NewLogger(verbose, color.FgMagenta, "postMigrationRunner"), - ) - if err != nil { - return err - } - - postMigrationRunner.Logger.Print("πŸƒ starting postMigration tests") - startTime := time.Now() - - testsToRun, err := postMigrationRunner.GetE2ETestsToRunByName( - e2etests.AllE2ETests, - testNames..., - ) - if err != nil { - return errors.Wrap(err, "postMigrationRunner tests failed") - } - - if err := postMigrationRunner.RunE2ETests(testsToRun); err != nil { - return errors.Wrap(err, "postMigrationRunner tests failed") - } - - if err := postMigrationRunner.CheckBtcTSSBalance(); err != nil { - return err - } - - postMigrationRunner.Logger.Print("🍾 PostMigration tests completed in %s", time.Since(startTime).String()) - - return err - } -} diff --git a/cmd/zetae2e/local/tss_migration.go b/cmd/zetae2e/local/tss_migration.go new file mode 100644 index 0000000000..a7acf80daa --- /dev/null +++ b/cmd/zetae2e/local/tss_migration.go @@ -0,0 +1,43 @@ +package local + +import ( + "os" + "time" + + "github.com/stretchr/testify/require" + + "github.com/zeta-chain/zetacore/e2e/config" + "github.com/zeta-chain/zetacore/e2e/e2etests" + "github.com/zeta-chain/zetacore/e2e/runner" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" +) + +func TSSMigration(deployerRunner *runner.E2ERunner, logger *runner.Logger, verbose bool, conf config.Config) { + migrationStartTime := time.Now() + logger.Print("🏁 starting tss migration") + + response, err := deployerRunner.CctxClient.LastZetaHeight( + deployerRunner.Ctx, + &crosschaintypes.QueryLastZetaHeightRequest{}, + ) + require.NoError(deployerRunner, err) + err = deployerRunner.ZetaTxServer.UpdateKeygen(response.Height) + require.NoError(deployerRunner, err) + + // Generate new TSS + waitKeygenHeight(deployerRunner.Ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) + + // Run migration + // migrationRoutine runs migration e2e test , which migrates funds from the older TSS to the new one + // The zetaclient restarts required for this process are managed by the background workers in zetaclient (TSSListener) + fn := migrationRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTSSName) + + if err := fn(); err != nil { + logger.Print("❌ %v", err) + logger.Print("❌ tss migration failed") + os.Exit(1) + } + deployerRunner.UpdateTssAddressForConnector() + deployerRunner.UpdateTssAddressForErc20custody() + logger.Print("βœ… migration completed in %s ", time.Since(migrationStartTime).String()) +} From d00658534bb246cae893f378eba51b6c630340ca Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 19 Aug 2024 13:22:05 -0400 Subject: [PATCH 22/29] generate files --- x/crosschain/keeper/msg_server_migrate_tss_funds.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds.go b/x/crosschain/keeper/msg_server_migrate_tss_funds.go index b6e31b9f6b..16797187b2 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds.go @@ -110,7 +110,6 @@ func (k Keeper) initiateMigrateTSSFundsCCTX( err = k.SetObserverOutboundInfo(ctx, chainID, &cctx) if err != nil { return errorsmod.Wrap(types.ErrCannotMigrateTssFunds, err.Error()) - } // The migrate funds can be run again to update the migration cctx index if the migration fails From fd6548b89627dc7ad2d48d1aae3e68a0d8c17b4b Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 19 Aug 2024 13:54:43 -0400 Subject: [PATCH 23/29] generate files --- e2e/e2etests/test_crosschain_swap.go | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/e2etests/test_crosschain_swap.go b/e2e/e2etests/test_crosschain_swap.go index a612e609ea..f41d3d8372 100644 --- a/e2e/e2etests/test_crosschain_swap.go +++ b/e2e/e2etests/test_crosschain_swap.go @@ -144,6 +144,7 @@ func TestCrosschainSwap(r *runner.E2ERunner, _ []string) { amount := 0.1 utxos, err = r.ListDeployerUTXOs() + require.NoError(r, err) txid, err := r.SendToTSSFromDeployerWithMemo(amount, utxos[0:1], memo) require.NoError(r, err) From 6e0a3cdf4210f12d8d6fd4a1901722ff2e68c45c Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 19 Aug 2024 15:34:27 -0400 Subject: [PATCH 24/29] increase DefaultCctxTimeout --- e2e/utils/zetacore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index 460ba62ed1..b69d9fbc32 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -23,7 +23,7 @@ const ( // However this needs to be researched as to why the increase in timeout was needed. // https://github.com/zeta-chain/node/issues/2690 - DefaultCctxTimeout = 6 * time.Minute + DefaultCctxTimeout = 8 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) From 6f631317cac5ef4e5935054178004ce1d40efaa2 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 19 Aug 2024 18:09:32 -0400 Subject: [PATCH 25/29] rename to admin evm --- e2e/runner/{update_contracts.go => admin_evm.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename e2e/runner/{update_contracts.go => admin_evm.go} (100%) diff --git a/e2e/runner/update_contracts.go b/e2e/runner/admin_evm.go similarity index 100% rename from e2e/runner/update_contracts.go rename to e2e/runner/admin_evm.go From b66c36812ff17914032318a14de25fa450e1fd76 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 20 Aug 2024 12:07:37 -0400 Subject: [PATCH 26/29] add unit test for failed to set outbound info --- changelog.md | 3 -- .../keeper/msg_server_migrate_tss_funds.go | 2 +- .../msg_server_migrate_tss_funds_test.go | 54 ++++++++++++++----- x/crosschain/types/errors.go | 5 +- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/changelog.md b/changelog.md index 2705b16899..5c6fdc217e 100644 --- a/changelog.md +++ b/changelog.md @@ -22,9 +22,6 @@ ### Tests * [2661](https://github.com/zeta-chain/node/pull/2661) - update connector and erc20Custody addresses in tss migration e2e tests - -### Tests - * [2726](https://github.com/zeta-chain/node/pull/2726) - add e2e tests for deposit and call, deposit and revert ### Fixes diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds.go b/x/crosschain/keeper/msg_server_migrate_tss_funds.go index 16797187b2..f1f625571a 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds.go @@ -109,7 +109,7 @@ func (k Keeper) initiateMigrateTSSFundsCCTX( // Set the CCTX and the nonce for the outbound migration err = k.SetObserverOutboundInfo(ctx, chainID, &cctx) if err != nil { - return errorsmod.Wrap(types.ErrCannotMigrateTssFunds, err.Error()) + return errorsmod.Wrap(types.ErrUnableToSetOutboundInfo, err.Error()) } // The migrate funds can be run again to update the migration cctx index if the migration fails diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go index a715fcf4e6..93e9a8fb98 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go @@ -26,6 +26,7 @@ func setupTssMigrationParams( amount sdkmath.Uint, setNewTss bool, setCurrentTSS bool, + setChainNonces bool, ) (string, string) { zk.ObserverKeeper.SetCrosschainFlags(ctx, observertypes.CrosschainFlags{ IsInboundEnabled: false, @@ -70,10 +71,12 @@ func setupTssMigrationParams( PriorityFees: []uint64{100, 300, 200}, MedianIndex: 1, }) - k.GetObserverKeeper().SetChainNonces(ctx, observertypes.ChainNonces{ - ChainId: chain.ChainId, - Nonce: 1, - }) + if setChainNonces { + k.GetObserverKeeper().SetChainNonces(ctx, observertypes.ChainNonces{ + ChainId: chain.ChainId, + Nonce: 1, + }) + } indexString := crosschaintypes.GetTssMigrationCCTXIndexString( currentTss.TssPubkey, newTss.TssPubkey, @@ -98,7 +101,7 @@ func TestKeeper_MigrateTSSFundsForChain(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) gp, priorityFee, found := k.GetMedianGasValues(ctx, chain.ChainId) require.True(t, found) msg := crosschaintypes.MsgMigrateTssFunds{ @@ -134,7 +137,7 @@ func TestKeeper_MigrateTSSFundsForChain(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) gp, priorityFee, found := k.GetMedianGasValues(ctx, chain.ChainId) require.True(t, found) @@ -373,7 +376,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) msg := crosschaintypes.MsgMigrateTssFunds{ Creator: admin, @@ -405,7 +408,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) msg := crosschaintypes.MsgMigrateTssFunds{ Creator: admin, @@ -433,7 +436,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, false, true) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, false, true, true) msg := crosschaintypes.MsgMigrateTssFunds{ Creator: admin, @@ -460,7 +463,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) k.GetObserverKeeper().SetPendingNonces(ctx, observertypes.PendingNonces{ NonceLow: 1, NonceHigh: 10, @@ -483,7 +486,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { require.False(t, found) }) - t.Run("unable to migrate funds when a pending cctx is presnt in migration info", func(t *testing.T) { + t.Run("unable to migrate funds when a pending cctx is present in migration info", func(t *testing.T) { k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, }) @@ -494,7 +497,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) msgServer := keeper.NewMsgServerImpl(*k) - indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true) + indexString, tssPubkey := setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, true) k.GetObserverKeeper().SetPendingNonces(ctx, observertypes.PendingNonces{ NonceLow: 1, NonceHigh: 1, @@ -541,7 +544,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { msgServer := keeper.NewMsgServerImpl(*k) - indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, false, false) + indexString, _ := setupTssMigrationParams(zk, k, ctx, chain, amount, false, false, true) currentTss, found := k.GetObserverKeeper().GetTSS(ctx) require.True(t, found) newTss := sample.Tss() @@ -565,4 +568,29 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { require.False(t, found) }, ) + + t.Run("unable to process migration if SetObserverOutboundInfo fails", func(t *testing.T) { + k, ctx, _, zk := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + admin := sample.AccAddress() + chain := getValidEthChain() + amount := sdkmath.NewUintFromString("10000000000000000000") + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + + msgServer := keeper.NewMsgServerImpl(*k) + + _, _ = setupTssMigrationParams(zk, k, ctx, chain, amount, true, true, false) + msg := crosschaintypes.MsgMigrateTssFunds{ + Creator: admin, + ChainId: chain.ChainId, + Amount: amount, + } + keepertest.MockCheckAuthorization(&authorityMock.Mock, &msg, nil) + keepertest.MockGetChainListEmpty(&authorityMock.Mock) + + _, err := msgServer.MigrateTssFunds(ctx, &msg) + require.ErrorContains(t, err, crosschaintypes.ErrUnableToSetOutboundInfo.Error()) + }) } diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index 279442d2c7..40182fe313 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -55,6 +55,7 @@ var ( 1156, "migration tx from an old tss address detected", ) - ErrValidatingInbound = errorsmod.Register(ModuleName, 1157, "unable to validate inbound") - ErrInvalidGasLimit = errorsmod.Register(ModuleName, 1158, "invalid gas limit") + ErrValidatingInbound = errorsmod.Register(ModuleName, 1157, "unable to validate inbound") + ErrInvalidGasLimit = errorsmod.Register(ModuleName, 1158, "invalid gas limit") + ErrUnableToSetOutboundInfo = errorsmod.Register(ModuleName, 1159, "unable to set outbound info") ) From c9a49f872ab5b39343abd37f024b309e8dc25065 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 21 Aug 2024 19:48:14 -0400 Subject: [PATCH 27/29] reduce cctx time to try getting CI to run successfully --- e2e/utils/zetacore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index b69d9fbc32..460ba62ed1 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -23,7 +23,7 @@ const ( // However this needs to be researched as to why the increase in timeout was needed. // https://github.com/zeta-chain/node/issues/2690 - DefaultCctxTimeout = 8 * time.Minute + DefaultCctxTimeout = 6 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) From bff9cc1543958bc5ca39380861c4c990583e3712 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 21 Aug 2024 20:55:59 -0400 Subject: [PATCH 28/29] increase cctx timeout --- e2e/utils/zetacore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index 460ba62ed1..b69d9fbc32 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -23,7 +23,7 @@ const ( // However this needs to be researched as to why the increase in timeout was needed. // https://github.com/zeta-chain/node/issues/2690 - DefaultCctxTimeout = 6 * time.Minute + DefaultCctxTimeout = 8 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) From 01587c297da6a81e3bb5355cb67a5e2a55329110 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 22 Aug 2024 10:25:26 -0400 Subject: [PATCH 29/29] increase timeout for tss migration tests --- .github/workflows/e2e.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index f5030b1152..4390bd1ede 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -168,6 +168,7 @@ jobs: - make-target: "start-tss-migration-test" runs-on: ubuntu-20.04 run: ${{ needs.matrix-conditionals.outputs.TSS_MIGRATION_TESTS == 'true' }} + timeout-minutes: 40 - make-target: "start-solana-test" runs-on: ubuntu-20.04 run: ${{ needs.matrix-conditionals.outputs.SOLANA_TESTS == 'true' }}