From aa45d2f40afba8363e0b432cd0539e386de8de71 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 21 Jun 2024 09:16:24 -0400 Subject: [PATCH 01/40] add new runner for migration tests --- Makefile | 2 +- cmd/zetaclientd-supervisor/lib.go | 38 ++++++++++- cmd/zetaclientd-supervisor/main.go | 7 +- cmd/zetae2e/local/local.go | 51 +++++++++++++-- cmd/zetae2e/local/migration.go | 82 ++++++++++++++++++++++++ e2e/e2etests/test_eth_migration_funds.go | 10 +++ e2e/txserver/zeta_tx_server.go | 9 +++ 7 files changed, 189 insertions(+), 10 deletions(-) create mode 100644 cmd/zetae2e/local/migration.go create mode 100644 e2e/e2etests/test_eth_migration_funds.go diff --git a/Makefile b/Makefile index 0520f1f319..1984c1c105 100644 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ build-testnet-ubuntu: go.sum docker rm temp-container install: go.sum - @echo "--> Installing zetacored & zetaclientd" + @echo "--> Installing zetacored ,zetaclientd and zetaclientd-supervisor" @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetacored @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetaclientd @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetaclientd-supervisor diff --git a/cmd/zetaclientd-supervisor/lib.go b/cmd/zetaclientd-supervisor/lib.go index e8f1b54470..a2e3052587 100644 --- a/cmd/zetaclientd-supervisor/lib.go +++ b/cmd/zetaclientd-supervisor/lib.go @@ -12,12 +12,14 @@ import ( "runtime" "strings" "sync" + "syscall" "time" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/hashicorp/go-getter" "github.com/rs/zerolog" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc" "github.com/zeta-chain/zetacore/zetaclient/config" @@ -66,6 +68,7 @@ type zetaclientdSupervisor struct { upgradesDir string upgradePlanName string enableAutoDownload bool + restartChan chan os.Signal } func newZetaclientdSupervisor( @@ -81,19 +84,21 @@ func newZetaclientdSupervisor( if err != nil { return nil, fmt.Errorf("grpc dial: %w", err) } - + restartChan := make(chan os.Signal, 1) return &zetaclientdSupervisor{ zetacoredConn: conn, logger: logger, reloadSignals: make(chan bool, 1), upgradesDir: defaultUpgradesDir, enableAutoDownload: enableAutoDownload, + restartChan: restartChan, }, nil } func (s *zetaclientdSupervisor) Start(ctx context.Context) { go s.watchForVersionChanges(ctx) go s.handleCoreUpgradePlan(ctx) + go s.handleNewKeygen(ctx) } func (s *zetaclientdSupervisor) WaitForReloadSignal(ctx context.Context) { @@ -169,6 +174,37 @@ func (s *zetaclientdSupervisor) watchForVersionChanges(ctx context.Context) { } } +func (s *zetaclientdSupervisor) handleNewKeygen(ctx context.Context) { + client := observertypes.NewQueryClient(s.zetacoredConn) + prevKeygenBlock := int64(0) + for { + select { + case <-time.After(time.Second): + case <-ctx.Done(): + return + } + resp, err := client.Keygen(ctx, &observertypes.QueryGetKeygenRequest{}) + if err != nil { + s.logger.Warn().Err(err).Msg("unable to get keygen") + continue + } + if resp.Keygen == nil { + s.logger.Warn().Err(err).Msg("keygen is nil") + continue + } + + if resp.Keygen.Status != observertypes.KeygenStatus_PendingKeygen { + continue + } + keygenBlock := resp.Keygen.BlockNumber + if prevKeygenBlock == keygenBlock { + continue + } + prevKeygenBlock = keygenBlock + s.logger.Warn().Msgf("got new keygen at block %d", keygenBlock) + s.restartChan <- syscall.SIGHUP + } +} func (s *zetaclientdSupervisor) handleCoreUpgradePlan(ctx context.Context) { client := upgradetypes.NewQueryClient(s.zetacoredConn) diff --git a/cmd/zetaclientd-supervisor/main.go b/cmd/zetaclientd-supervisor/main.go index 6017050986..72f8443c79 100644 --- a/cmd/zetaclientd-supervisor/main.go +++ b/cmd/zetaclientd-supervisor/main.go @@ -23,6 +23,7 @@ func main() { fmt.Println("failed to load config: ", err) os.Exit(1) } + fmt.Println("Starting zetaclientd-supervisor") // log outputs must be serialized since we are writing log messages in this process and // also directly from the zetaclient process @@ -37,8 +38,7 @@ func main() { signal.Notify(shutdownChan, syscall.SIGINT, syscall.SIGTERM) // these signals will result in the supervisor process only restarting zetaclientd - restartChan := make(chan os.Signal, 1) - signal.Notify(restartChan, syscall.SIGHUP) + //restartChan := make(chan os.Signal, 1) hotkeyPassword, tssPassword, err := promptPasswords() if err != nil { @@ -53,6 +53,7 @@ func main() { os.Exit(1) } supervisor.Start(ctx) + signal.Notify(supervisor.restartChan, syscall.SIGHUP) shouldRestart := true for shouldRestart { @@ -82,7 +83,7 @@ func main() { select { case <-ctx.Done(): return nil - case sig := <-restartChan: + case sig := <-supervisor.restartChan: logger.Info().Msgf("got signal %d, sending SIGINT to zetaclientd", sig) case sig := <-shutdownChan: logger.Info().Msgf("got signal %d, shutting down", sig) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 364bdf80a4..d0d1ed890f 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -9,8 +9,6 @@ import ( "github.com/fatih/color" "github.com/spf13/cobra" - "golang.org/x/sync/errgroup" - zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" "github.com/zeta-chain/zetacore/e2e/config" "github.com/zeta-chain/zetacore/e2e/e2etests" @@ -19,6 +17,8 @@ import ( "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/pkg/chains" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" + "golang.org/x/sync/errgroup" ) const ( @@ -34,6 +34,7 @@ const ( flagLight = "light" flagSetupOnly = "setup-only" flagSkipSetup = "skip-setup" + flagSkipMigrationTest = "skip-migration-test" flagSkipBitcoinSetup = "skip-bitcoin-setup" flagSkipHeaderProof = "skip-header-proof" ) @@ -64,6 +65,7 @@ func NewLocalCmd() *cobra.Command { cmd.Flags().Bool(flagSkipSetup, false, "set to true to skip setup") cmd.Flags().Bool(flagSkipBitcoinSetup, false, "set to true to skip bitcoin wallet setup") cmd.Flags().Bool(flagSkipHeaderProof, false, "set to true to skip header proof tests") + cmd.Flags().Bool(flagSkipMigrationTest, false, "set to true to skip migration tests") return cmd } @@ -114,6 +116,10 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if err != nil { panic(err) } + skipMigrationTest, err := cmd.Flags().GetBool(flagSkipMigrationTest) + if err != nil { + panic(err) + } skipBitcoinSetup, err := cmd.Flags().GetBool(flagSkipBitcoinSetup) if err != nil { panic(err) @@ -189,7 +195,21 @@ func localE2ETest(cmd *cobra.Command, _ []string) { // wait for keygen to be completed // if setup is skipped, we assume that the keygen is already completed if !skipSetup { - waitKeygenHeight(ctx, deployerRunner.CctxClient, logger) + waitKeygenHeight(ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 10) + } + + // if skipMigrationTest is set to true , there is no need to update the keygen height to generate a new tss + if !skipMigrationTest { + response, err := deployerRunner.CctxClient.LastZetaHeight(ctx, &crosschaintypes.QueryLastZetaHeightRequest{}) + if err != nil { + logger.Error("cctxClient.LastZetaHeight error: %s", err) + panic(err) + } + err = zetaTxServer.UpdateKeygen(response.Height) + if err != nil { + panic(err) + } + waitKeygenHeight(ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) } // query and set the TSS @@ -371,6 +391,13 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) + logger.Print("🏁 starting migration tests") + eg.Go(migrationTestRoutine(conf, deployerRunner, verbose, "")) + if err := eg.Wait(); err != nil { + logger.Print("❌ %v", err) + logger.Print("❌ migration tests failed") + os.Exit(1) + } // print and validate report networkReport, err := deployerRunner.GenerateNetworkReport() if err != nil { @@ -389,10 +416,24 @@ func localE2ETest(cmd *cobra.Command, _ []string) { func waitKeygenHeight( ctx context.Context, cctxClient crosschaintypes.QueryClient, + observerClient observertypes.QueryClient, logger *runner.Logger, + bufferBlocks int64, ) { // wait for keygen to be completed - keygenHeight := int64(35) + resp, err := observerClient.Keygen(ctx, &observertypes.QueryGetKeygenRequest{}) + if err != nil { + logger.Error("observerClient.Keygen error: %s", err) + return + } + if resp.Keygen == nil { + logger.Error("observerClient.Keygen keygen is nil") + return + } + if resp.Keygen.Status != observertypes.KeygenStatus_PendingKeygen { + return + } + keygenHeight := resp.Keygen.BlockNumber logger.Print("⏳ wait height %v for keygen to be completed", keygenHeight) for { time.Sleep(2 * time.Second) @@ -401,7 +442,7 @@ func waitKeygenHeight( logger.Error("cctxClient.LastZetaHeight error: %s", err) continue } - if response.Height >= keygenHeight { + if response.Height >= keygenHeight+bufferBlocks { break } logger.Info("Last ZetaHeight: %d", response.Height) diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go new file mode 100644 index 0000000000..a789bf26cb --- /dev/null +++ b/cmd/zetae2e/local/migration.go @@ -0,0 +1,82 @@ +package local + +import ( + "fmt" + "runtime" + "time" + + "github.com/fatih/color" + "github.com/zeta-chain/zetacore/e2e/e2etests" + + "github.com/zeta-chain/zetacore/e2e/config" + "github.com/zeta-chain/zetacore/e2e/runner" +) + +// adminTestRoutine runs admin functions tests +func migrationTestRoutine( + conf config.Config, + deployerRunner *runner.E2ERunner, + verbose bool, + testNames ...string, +) func() error { + return func() (err error) { + defer func() { + if r := recover(); r != nil { + // print stack trace + stack := make([]byte, 4096) + n := runtime.Stack(stack, false) + err = fmt.Errorf("admin panic: %v, stack trace %s", r, stack[:n]) + } + }() + + // initialize runner for erc20 advanced test + migrationTestRunner, err := initTestRunner( + "admin", + conf, + deployerRunner, + UserAdminAddress, + UserAdminPrivateKey, + runner.NewLogger(verbose, color.FgHiWhite, "migration"), + runner.WithZetaTxServer(deployerRunner.ZetaTxServer), + ) + if err != nil { + return err + } + + migrationTestRunner.Logger.Print("🏃 starting migration tests") + startTime := time.Now() + + // funding the account + // we transfer around the total supply of Zeta to the admin for the chain migration test + txZetaSend := deployerRunner.SendZetaOnEvm(UserAdminAddress, 20_500_000_000) + txERC20Send := deployerRunner.SendERC20OnEvm(UserAdminAddress, 1000) + migrationTestRunner.WaitForTxReceiptOnEvm(txZetaSend) + migrationTestRunner.WaitForTxReceiptOnEvm(txERC20Send) + + // depositing the necessary tokens on ZetaChain + txZetaDeposit := migrationTestRunner.DepositZeta() + txEtherDeposit := migrationTestRunner.DepositEther(false) + txERC20Deposit := migrationTestRunner.DepositERC20() + migrationTestRunner.WaitForMinedCCTX(txZetaDeposit) + migrationTestRunner.WaitForMinedCCTX(txEtherDeposit) + migrationTestRunner.WaitForMinedCCTX(txERC20Deposit) + + // run erc20 advanced test + testsToRun, err := migrationTestRunner.GetE2ETestsToRunByName( + e2etests.AllE2ETests, + testNames..., + ) + if err != nil { + return fmt.Errorf("migration tests failed: %v", err) + } + + if err := migrationTestRunner.RunE2ETests(testsToRun); err != nil { + return fmt.Errorf("migration tests failed: %v", err) + } + + migrationTestRunner.Logger.Print("🍾 migration tests completed in %s", time.Since(startTime).String()) + + return err + } + +} diff --git a/e2e/e2etests/test_eth_migration_funds.go b/e2e/e2etests/test_eth_migration_funds.go new file mode 100644 index 0000000000..d32f7e7be5 --- /dev/null +++ b/e2e/e2etests/test_eth_migration_funds.go @@ -0,0 +1,10 @@ +package e2etests + +import ( + "github.com/zeta-chain/zetacore/e2e/runner" +) + +// TestEtherWithdraw tests the withdraw of ether +func TestEthMigration(r *runner.E2ERunner, args []string) { + +} diff --git a/e2e/txserver/zeta_tx_server.go b/e2e/txserver/zeta_tx_server.go index fb2c403ada..457bc8f583 100644 --- a/e2e/txserver/zeta_tx_server.go +++ b/e2e/txserver/zeta_tx_server.go @@ -427,6 +427,15 @@ func (zts ZetaTxServer) FundEmissionsPool(account string, amount *big.Int) error return err } +func (zts ZetaTxServer) UpdateKeygen(height int64) error { + keygenHeight := height + 25 + _, err := zts.BroadcastTx(zts.GetAccountName(0), observertypes.NewMsgUpdateKeygen( + zts.GetAccountAddress(0), + keygenHeight, + )) + return err +} + // newCodec returns the codec for msg server func newCodec() (*codec.ProtoCodec, codectypes.InterfaceRegistry) { encodingConfig := app.MakeEncodingConfig() From a1b4c4c9f4dfed9e27c2a6fec2dd475be0ee52e7 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 21 Jun 2024 09:40:39 -0400 Subject: [PATCH 02/40] skip adding new keygen --- contrib/localnet/orchestrator/start-zetae2e.sh | 8 ++++---- e2e/txserver/zeta_tx_server.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 8dcb4ea271..ce2a0b5488 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -100,7 +100,7 @@ if [ "$OPTION" == "upgrade" ]; then echo "running E2E command to setup the networks and populate the state..." # Use light flag to ensure tests can complete before the upgrade height - zetae2e "$ZETAE2E_CMD" --skip-setup --config deployed.yml --light --skip-header-proof + zetae2e "$ZETAE2E_CMD" --skip-setup --config deployed.yml --light --skip-header-proof --skip-migration-test if [ $? -ne 0 ]; then echo "first e2e failed" exit 1 @@ -142,9 +142,9 @@ if [ "$OPTION" == "upgrade" ]; then # When the upgrade height is greater than 100 for upgrade test, the Bitcoin tests have been run once, therefore the Bitcoin wallet is already set up # Use light flag to skip advanced tests if [ "$UPGRADE_HEIGHT" -lt 100 ]; then - zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --light --skip-header-proof + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --light --skip-header-proof --skip-migration-test else - zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof --skip-migration-test fi ZETAE2E_EXIT_CODE=$? @@ -173,7 +173,7 @@ else echo "running e2e tests..." - zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --skip-migration-test ZETAE2E_EXIT_CODE=$? # if e2e passed, exit with 0, otherwise exit with 1 diff --git a/e2e/txserver/zeta_tx_server.go b/e2e/txserver/zeta_tx_server.go index 457bc8f583..e901d7974c 100644 --- a/e2e/txserver/zeta_tx_server.go +++ b/e2e/txserver/zeta_tx_server.go @@ -428,7 +428,7 @@ func (zts ZetaTxServer) FundEmissionsPool(account string, amount *big.Int) error } func (zts ZetaTxServer) UpdateKeygen(height int64) error { - keygenHeight := height + 25 + keygenHeight := height + 30 _, err := zts.BroadcastTx(zts.GetAccountName(0), observertypes.NewMsgUpdateKeygen( zts.GetAccountAddress(0), keygenHeight, From ed3b964048a484743c81168e865d82bd7b3b5164 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 21 Jun 2024 11:11:43 -0400 Subject: [PATCH 03/40] skip adding new keygen --- cmd/zetae2e/local/local.go | 28 +++++++++---------- .../localnet/orchestrator/start-zetae2e.sh | 6 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index d0d1ed890f..78203bb8d0 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -198,20 +198,6 @@ func localE2ETest(cmd *cobra.Command, _ []string) { waitKeygenHeight(ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 10) } - // if skipMigrationTest is set to true , there is no need to update the keygen height to generate a new tss - if !skipMigrationTest { - response, err := deployerRunner.CctxClient.LastZetaHeight(ctx, &crosschaintypes.QueryLastZetaHeightRequest{}) - if err != nil { - logger.Error("cctxClient.LastZetaHeight error: %s", err) - panic(err) - } - err = zetaTxServer.UpdateKeygen(response.Height) - if err != nil { - panic(err) - } - waitKeygenHeight(ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) - } - // query and set the TSS if err := deployerRunner.SetTSSAddresses(); err != nil { panic(err) @@ -392,6 +378,20 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) logger.Print("🏁 starting migration tests") + //if skipMigrationTest is set to true , there is no need to update the keygen height to generate a new tss + if !skipMigrationTest { + response, err := deployerRunner.CctxClient.LastZetaHeight(ctx, &crosschaintypes.QueryLastZetaHeightRequest{}) + if err != nil { + logger.Error("cctxClient.LastZetaHeight error: %s", err) + panic(err) + } + err = zetaTxServer.UpdateKeygen(response.Height) + if err != nil { + panic(err) + } + waitKeygenHeight(ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) + } + eg.Go(migrationTestRoutine(conf, deployerRunner, verbose, "")) if err := eg.Wait(); err != nil { logger.Print("❌ %v", err) diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index ce2a0b5488..cab0da36d3 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -100,7 +100,7 @@ if [ "$OPTION" == "upgrade" ]; then echo "running E2E command to setup the networks and populate the state..." # Use light flag to ensure tests can complete before the upgrade height - zetae2e "$ZETAE2E_CMD" --skip-setup --config deployed.yml --light --skip-header-proof --skip-migration-test + zetae2e "$ZETAE2E_CMD" --skip-setup --config deployed.yml --light --skip-header-proof if [ $? -ne 0 ]; then echo "first e2e failed" exit 1 @@ -142,9 +142,9 @@ if [ "$OPTION" == "upgrade" ]; then # When the upgrade height is greater than 100 for upgrade test, the Bitcoin tests have been run once, therefore the Bitcoin wallet is already set up # Use light flag to skip advanced tests if [ "$UPGRADE_HEIGHT" -lt 100 ]; then - zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --light --skip-header-proof --skip-migration-test + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --light --skip-header-proof else - zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof --skip-migration-test + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --skip-bitcoin-setup --light --skip-header-proof fi ZETAE2E_EXIT_CODE=$? From 2d360bcbc9908bb5974b3cf7d7f5b2b2439f187c Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 21 Jun 2024 14:26:23 -0400 Subject: [PATCH 04/40] modify btc runner --- cmd/zetae2e/local/local.go | 7 ++++++- contrib/localnet/orchestrator/start-zetae2e.sh | 2 +- e2e/runner/bitcoin.go | 11 +++++++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 78203bb8d0..20284bd312 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -378,9 +378,13 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) logger.Print("🏁 starting migration tests") + fmt.Println("SkipMigration", skipMigrationTest) + //if skipMigrationTest is set to true , there is no need to update the keygen height to generate a new tss + migrationCtx, cancel := context.WithCancel(context.Background()) + deployerRunner.CtxCancel = cancel if !skipMigrationTest { - response, err := deployerRunner.CctxClient.LastZetaHeight(ctx, &crosschaintypes.QueryLastZetaHeightRequest{}) + response, err := deployerRunner.CctxClient.LastZetaHeight(migrationCtx, &crosschaintypes.QueryLastZetaHeightRequest{}) if err != nil { logger.Error("cctxClient.LastZetaHeight error: %s", err) panic(err) @@ -394,6 +398,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { eg.Go(migrationTestRoutine(conf, deployerRunner, verbose, "")) if err := eg.Wait(); err != nil { + deployerRunner.CtxCancel() logger.Print("❌ %v", err) logger.Print("❌ migration tests failed") os.Exit(1) diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index cab0da36d3..485ca24407 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -173,7 +173,7 @@ else echo "running e2e tests..." - zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --skip-migration-test + zetae2e $ZETAE2E_CMD --skip-setup --config deployed.yml --light ZETAE2E_EXIT_CODE=$? # if e2e passed, exit with 0, otherwise exit with 1 diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index d4dc3df15c..b2b82d2132 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -41,6 +41,17 @@ func (runner *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error return nil, err } + // filter big-enough UTXOs for test if running on Regtest + if runner.IsLocalBitcoin() { + utxosFiltered := []btcjson.ListUnspentResult{} + for _, utxo := range utxos { + if utxo.Amount >= 1.0 { + utxosFiltered = append(utxosFiltered, utxo) + } + } + return utxosFiltered, nil + } + return utxos, nil } From 405d4ef4869012d3b7d4851b01fa5cf858011aee Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 21 Jun 2024 15:58:15 -0400 Subject: [PATCH 05/40] tss fund migrate test for eth --- cmd/zetae2e/local/local.go | 16 +++---- cmd/zetae2e/local/migration.go | 32 +++++++------- e2e/e2etests/e2etests.go | 8 ++++ e2e/e2etests/test_eth_migration_funds.go | 10 ----- e2e/e2etests/test_migrate_tss_eth_funds.go | 49 ++++++++++++++++++++++ 5 files changed, 84 insertions(+), 31 deletions(-) delete mode 100644 e2e/e2etests/test_eth_migration_funds.go create mode 100644 e2e/e2etests/test_migrate_tss_eth_funds.go diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 20284bd312..f48abbfacd 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -323,12 +323,14 @@ 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("TestHeader", testHeader) + fmt.Println("SkipBitcoinSetup", skipBitcoinSetup) - 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, testHeader, bitcoinTests...)) - eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) + //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, testHeader, bitcoinTests...)) + //eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) } if testAdmin { eg.Go(adminTestRoutine(conf, deployerRunner, verbose, @@ -393,10 +395,10 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if err != nil { panic(err) } - waitKeygenHeight(ctx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) + waitKeygenHeight(migrationCtx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) } - eg.Go(migrationTestRoutine(conf, deployerRunner, verbose, "")) + eg.Go(migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTssEthName)) if err := eg.Wait(); err != nil { deployerRunner.CtxCancel() logger.Print("❌ %v", err) diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index a789bf26cb..0dd269b958 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -46,21 +46,25 @@ func migrationTestRoutine( migrationTestRunner.Logger.Print("🏃 starting migration tests") startTime := time.Now() - // funding the account - // we transfer around the total supply of Zeta to the admin for the chain migration test - txZetaSend := deployerRunner.SendZetaOnEvm(UserAdminAddress, 20_500_000_000) - txERC20Send := deployerRunner.SendERC20OnEvm(UserAdminAddress, 1000) - migrationTestRunner.WaitForTxReceiptOnEvm(txZetaSend) - migrationTestRunner.WaitForTxReceiptOnEvm(txERC20Send) - - // depositing the necessary tokens on ZetaChain - txZetaDeposit := migrationTestRunner.DepositZeta() - txEtherDeposit := migrationTestRunner.DepositEther(false) - txERC20Deposit := migrationTestRunner.DepositERC20() - migrationTestRunner.WaitForMinedCCTX(txZetaDeposit) - migrationTestRunner.WaitForMinedCCTX(txEtherDeposit) - migrationTestRunner.WaitForMinedCCTX(txERC20Deposit) + //// funding the account + //// we transfer around the total supply of Zeta to the admin for the chain migration test + //txZetaSend := deployerRunner.SendZetaOnEvm(UserAdminAddress, 20_500_000_000) + //txERC20Send := deployerRunner.SendERC20OnEvm(UserAdminAddress, 1000) + //migrationTestRunner.WaitForTxReceiptOnEvm(txZetaSend) + //migrationTestRunner.WaitForTxReceiptOnEvm(txERC20Send) + // + //// depositing the necessary tokens on ZetaChain + //txZetaDeposit := migrationTestRunner.DepositZeta() + //txEtherDeposit := migrationTestRunner.DepositEther(false) + //txERC20Deposit := migrationTestRunner.DepositERC20() + //migrationTestRunner.WaitForMinedCCTX(txZetaDeposit) + //migrationTestRunner.WaitForMinedCCTX(txEtherDeposit) + //migrationTestRunner.WaitForMinedCCTX(txERC20Deposit) + if len(testNames) == 0 { + migrationTestRunner.Logger.Print("🍾 migration tests completed in %s", time.Since(startTime).String()) + return nil + } // run erc20 advanced test testsToRun, err := migrationTestRunner.GetE2ETestsToRunByName( e2etests.AllE2ETests, diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 396b725617..e42259d7cd 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -101,6 +101,8 @@ const ( TestUpdateBytecodeConnectorName = "update_bytecode_connector" TestRateLimiterName = "rate_limiter" + TestMigrateTssEthName = "migrate_tss_eth" + /* Special tests Not used to test functionalities but do various interactions with the netwoks @@ -542,4 +544,10 @@ var AllE2ETests = []runner.E2ETest{ }, TestDeployContract, ), + runner.NewE2ETest( + TestMigrateTssEthName, + "migrate TSS funds on the ethereum chain", + []runner.ArgDefinition{}, + TestMigrateTssEth, + ), } diff --git a/e2e/e2etests/test_eth_migration_funds.go b/e2e/e2etests/test_eth_migration_funds.go deleted file mode 100644 index d32f7e7be5..0000000000 --- a/e2e/e2etests/test_eth_migration_funds.go +++ /dev/null @@ -1,10 +0,0 @@ -package e2etests - -import ( - "github.com/zeta-chain/zetacore/e2e/runner" -) - -// TestEtherWithdraw tests the withdraw of ether -func TestEthMigration(r *runner.E2ERunner, args []string) { - -} diff --git a/e2e/e2etests/test_migrate_tss_eth_funds.go b/e2e/e2etests/test_migrate_tss_eth_funds.go new file mode 100644 index 0000000000..6f247e3b4d --- /dev/null +++ b/e2e/e2etests/test_migrate_tss_eth_funds.go @@ -0,0 +1,49 @@ +package e2etests + +import ( + "context" + + sdkmath "cosmossdk.io/math" + "github.com/zeta-chain/zetacore/e2e/runner" + "github.com/zeta-chain/zetacore/e2e/utils" + crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +// TestEtherWithdraw tests the withdraw of ether +func TestMigrateTssEth(r *runner.E2ERunner, args []string) { + + r.Logger.Info("Pause inbound and outbound processing") + msg := observertypes.NewMsgDisableCCTX( + r.ZetaTxServer.GetAccountAddress(0), + true, + true) + _, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msg) + if err != nil { + panic(err) + } + + // Fetch balance of TSS address + tssBalance, err := r.EVMClient.BalanceAt(context.Background(), r.TSSAddress, nil) + if err != nil { + panic(err) + } + r.Logger.Print("TSS Balance: ", tssBalance.String()) + tssBalanceUint := sdkmath.NewUintFromString(tssBalance.String()) + evmChainID, err := r.EVMClient.ChainID(context.Background()) + if err != nil { + panic(err) + } + r.Logger.Print("EVM Chain ID: ", evmChainID.String()) + // Migrate TSS funds for the chain + msgMigrateFunds := crosschaintypes.NewMsgMigrateTssFunds( + r.ZetaTxServer.GetAccountAddress(0), + evmChainID.Int64(), + tssBalanceUint, + ) + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) + if err != nil { + panic(err) + } + +} From b1dc7ffcea6f76e388f482c16d7c4be951cfc12a Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 21 Jun 2024 16:50:11 -0400 Subject: [PATCH 06/40] add queries for tss funds migrator info --- .../cli/zetacored/zetacored_query_observer.md | 2 + ..._query_observer_list-tss-funds-migrator.md | 40 + ..._query_observer_show-tss-funds-migrator.md | 40 + docs/openapi/openapi.swagger.yaml | 56 + proto/zetachain/zetacore/observer/query.proto | 24 + .../zetachain/zetacore/observer/query_pb.d.ts | 92 ++ x/observer/client/cli/query.go | 2 + .../client/cli/query_tss_fund_migrator.go | 63 + .../grpc_query_tss_funds_migrator_info.go | 46 + .../grpc_query_tss_funds_migrator_test.go | 91 ++ x/observer/types/query.pb.go | 1112 ++++++++++++++--- x/observer/types/query.pb.gw.go | 148 +++ 12 files changed, 1515 insertions(+), 201 deletions(-) create mode 100644 docs/cli/zetacored/zetacored_query_observer_list-tss-funds-migrator.md create mode 100644 docs/cli/zetacored/zetacored_query_observer_show-tss-funds-migrator.md create mode 100644 x/observer/client/cli/query_tss_fund_migrator.go create mode 100644 x/observer/keeper/grpc_query_tss_funds_migrator_info.go create mode 100644 x/observer/keeper/grpc_query_tss_funds_migrator_test.go diff --git a/docs/cli/zetacored/zetacored_query_observer.md b/docs/cli/zetacored/zetacored_query_observer.md index 42d0ffe777..e19f4cbecb 100644 --- a/docs/cli/zetacored/zetacored_query_observer.md +++ b/docs/cli/zetacored/zetacored_query_observer.md @@ -36,6 +36,7 @@ zetacored query observer [flags] * [zetacored query observer list-node-account](zetacored_query_observer_list-node-account.md) - list all NodeAccount * [zetacored query observer list-observer-set](zetacored_query_observer_list-observer-set.md) - Query observer set * [zetacored query observer list-pending-nonces](zetacored_query_observer_list-pending-nonces.md) - shows a chainNonces +* [zetacored query observer list-tss-funds-migrator](zetacored_query_observer_list-tss-funds-migrator.md) - list all tss funds migrators * [zetacored query observer list-tss-history](zetacored_query_observer_list-tss-history.md) - show historical list of TSS * [zetacored query observer show-ballot](zetacored_query_observer_show-ballot.md) - Query BallotByIdentifier * [zetacored query observer show-blame](zetacored_query_observer_show-blame.md) - Query BlameByIdentifier @@ -46,4 +47,5 @@ zetacored query observer [flags] * [zetacored query observer show-node-account](zetacored_query_observer_show-node-account.md) - shows a NodeAccount * [zetacored query observer show-observer-count](zetacored_query_observer_show-observer-count.md) - Query show-observer-count * [zetacored query observer show-tss](zetacored_query_observer_show-tss.md) - shows a TSS +* [zetacored query observer show-tss-funds-migrator](zetacored_query_observer_show-tss-funds-migrator.md) - show the tss funds migrator for a chain diff --git a/docs/cli/zetacored/zetacored_query_observer_list-tss-funds-migrator.md b/docs/cli/zetacored/zetacored_query_observer_list-tss-funds-migrator.md new file mode 100644 index 0000000000..0eca411dae --- /dev/null +++ b/docs/cli/zetacored/zetacored_query_observer_list-tss-funds-migrator.md @@ -0,0 +1,40 @@ +# query observer list-tss-funds-migrator + +list all tss funds migrators + +``` +zetacored query observer list-tss-funds-migrator [flags] +``` + +### Options + +``` + --count-total count total number of records in list-tss-funds-migrator to query for + --grpc-addr string the gRPC endpoint to use for this chain + --grpc-insecure allow gRPC over insecure channels, if not TLS the server must use TLS + --height int Use a specific height to query state at (this can error if the node is pruning state) + -h, --help help for list-tss-funds-migrator + --limit uint pagination limit of list-tss-funds-migrator to query for (default 100) + --node string [host]:[port] to Tendermint RPC interface for this chain + --offset uint pagination offset of list-tss-funds-migrator to query for + -o, --output string Output format (text|json) + --page uint pagination page of list-tss-funds-migrator to query for. This sets offset to a multiple of limit (default 1) + --page-key string pagination page-key of list-tss-funds-migrator to query for + --reverse results are sorted in descending order +``` + +### Options inherited from parent commands + +``` + --chain-id string The network chain ID + --home string directory for config and data + --log_format string The logging format (json|plain) + --log_level string The logging level (trace|debug|info|warn|error|fatal|panic) + --log_no_color Disable colored logs + --trace print out full stack trace on errors +``` + +### SEE ALSO + +* [zetacored query observer](zetacored_query_observer.md) - Querying commands for the observer module + diff --git a/docs/cli/zetacored/zetacored_query_observer_show-tss-funds-migrator.md b/docs/cli/zetacored/zetacored_query_observer_show-tss-funds-migrator.md new file mode 100644 index 0000000000..c307953301 --- /dev/null +++ b/docs/cli/zetacored/zetacored_query_observer_show-tss-funds-migrator.md @@ -0,0 +1,40 @@ +# query observer show-tss-funds-migrator + +show the tss funds migrator for a chain + +``` +zetacored query observer show-tss-funds-migrator [chain-id] [flags] +``` + +### Options + +``` + --count-total count total number of records in show-tss-funds-migrator [chain-id] to query for + --grpc-addr string the gRPC endpoint to use for this chain + --grpc-insecure allow gRPC over insecure channels, if not TLS the server must use TLS + --height int Use a specific height to query state at (this can error if the node is pruning state) + -h, --help help for show-tss-funds-migrator + --limit uint pagination limit of show-tss-funds-migrator [chain-id] to query for (default 100) + --node string [host]:[port] to Tendermint RPC interface for this chain + --offset uint pagination offset of show-tss-funds-migrator [chain-id] to query for + -o, --output string Output format (text|json) + --page uint pagination page of show-tss-funds-migrator [chain-id] to query for. This sets offset to a multiple of limit (default 1) + --page-key string pagination page-key of show-tss-funds-migrator [chain-id] to query for + --reverse results are sorted in descending order +``` + +### Options inherited from parent commands + +``` + --chain-id string The network chain ID + --home string directory for config and data + --log_format string The logging format (json|plain) + --log_level string The logging level (trace|debug|info|warn|error|fatal|panic) + --log_no_color Disable colored logs + --trace print out full stack trace on errors +``` + +### SEE ALSO + +* [zetacored query observer](zetacored_query_observer.md) - Querying commands for the observer module + diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index dc72d0bf6b..90421a8b14 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -30170,6 +30170,20 @@ paths: type: boolean tags: - Query + /zeta-chain/observer/get_all_tss_fund_migrators: + get: + operationId: Query_TssFundsMigratorInfoAll + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/observerQueryTssFundsMigratorInfoAllResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + tags: + - Query /zeta-chain/observer/get_chain_params: get: summary: Queries a list of GetChainParams items. @@ -30252,6 +30266,27 @@ paths: format: int64 tags: - Query + /zeta-chain/observer/get_tss_fund_migrator: + get: + summary: Queries the TssFundMigratorInfo for a specific chain + operationId: Query_TssFundsMigratorInfo + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/observerQueryTssFundsMigratorInfoResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/googlerpcStatus' + parameters: + - name: chain_id + in: query + required: false + type: string + format: int64 + tags: + - Query /zeta-chain/observer/has_voted/{ballot_identifier}/{voter_address}: get: summary: Query if a voter has voted for a ballot @@ -58111,6 +58146,19 @@ definitions: items: type: object $ref: '#/definitions/chainsChain' + observerQueryTssFundsMigratorInfoAllResponse: + type: object + properties: + tss_funds_migrators: + type: array + items: + type: object + $ref: '#/definitions/observerTssFundMigratorInfo' + observerQueryTssFundsMigratorInfoResponse: + type: object + properties: + tss_funds_migrator: + $ref: '#/definitions/observerTssFundMigratorInfo' observerQueryTssHistoryResponse: type: object properties: @@ -58140,6 +58188,14 @@ definitions: keyGenZetaHeight: type: string format: int64 + observerTssFundMigratorInfo: + type: object + properties: + chain_id: + type: string + format: int64 + migration_cctx_index: + type: string observerVoteType: type: string enum: diff --git a/proto/zetachain/zetacore/observer/query.proto b/proto/zetachain/zetacore/observer/query.proto index ef06616b2e..79254de2d0 100644 --- a/proto/zetachain/zetacore/observer/query.proto +++ b/proto/zetachain/zetacore/observer/query.proto @@ -16,6 +16,7 @@ import "zetachain/zetacore/observer/pending_nonces.proto"; import "zetachain/zetacore/observer/tss.proto"; import "zetachain/zetacore/pkg/chains/chains.proto"; import "zetachain/zetacore/pkg/proofs/proofs.proto"; +import "zetachain/zetacore/observer/tss_funds_migrator.proto"; option go_package = "github.com/zeta-chain/zetacore/x/observer/types"; @@ -150,6 +151,29 @@ service Query { returns (QueryAllChainNoncesResponse) { option (google.api.http).get = "/zeta-chain/observer/chainNonces"; } + // Queries the TssFundMigratorInfo for a specific chain + rpc TssFundsMigratorInfo(QueryTssFundsMigratorInfoRequest) + returns (QueryTssFundsMigratorInfoResponse) { + option (google.api.http).get = "/zeta-chain/observer/get_tss_fund_migrator"; + } + + rpc TssFundsMigratorInfoAll(QueryTssFundsMigratorInfoAllRequest) + returns (QueryTssFundsMigratorInfoAllResponse) { + option (google.api.http).get = + "/zeta-chain/observer/get_all_tss_fund_migrators"; + } +} + +message QueryTssFundsMigratorInfoAllRequest {} + +message QueryTssFundsMigratorInfoAllResponse { + repeated TssFundMigratorInfo tss_funds_migrators = 1 + [ (gogoproto.nullable) = false ]; +} + +message QueryTssFundsMigratorInfoRequest { int64 chain_id = 1; } +message QueryTssFundsMigratorInfoResponse { + TssFundMigratorInfo tss_funds_migrator = 1 [ (gogoproto.nullable) = false ]; } message QueryGetChainNoncesRequest { string index = 1; } diff --git a/typescript/zetachain/zetacore/observer/query_pb.d.ts b/typescript/zetachain/zetacore/observer/query_pb.d.ts index 5c4f8c71d0..41873827e5 100644 --- a/typescript/zetachain/zetacore/observer/query_pb.d.ts +++ b/typescript/zetachain/zetacore/observer/query_pb.d.ts @@ -5,6 +5,7 @@ import type { BinaryReadOptions, FieldList, JsonReadOptions, JsonValue, PartialMessage, PlainMessage } from "@bufbuild/protobuf"; import { Message, proto3 } from "@bufbuild/protobuf"; +import type { TssFundMigratorInfo } from "./tss_funds_migrator_pb.js"; import type { ChainNonces } from "./chain_nonces_pb.js"; import type { PageRequest, PageResponse } from "../../../cosmos/base/query/v1beta1/pagination_pb.js"; import type { PendingNonces } from "./pending_nonces_pb.js"; @@ -18,6 +19,97 @@ import type { CrosschainFlags } from "./crosschain_flags_pb.js"; import type { Keygen } from "./keygen_pb.js"; import type { Blame } from "./blame_pb.js"; +/** + * @generated from message zetachain.zetacore.observer.QueryTssFundsMigratorInfoAllRequest + */ +export declare class QueryTssFundsMigratorInfoAllRequest extends Message { + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.QueryTssFundsMigratorInfoAllRequest"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): QueryTssFundsMigratorInfoAllRequest; + + static fromJson(jsonValue: JsonValue, options?: Partial): QueryTssFundsMigratorInfoAllRequest; + + static fromJsonString(jsonString: string, options?: Partial): QueryTssFundsMigratorInfoAllRequest; + + static equals(a: QueryTssFundsMigratorInfoAllRequest | PlainMessage | undefined, b: QueryTssFundsMigratorInfoAllRequest | PlainMessage | undefined): boolean; +} + +/** + * @generated from message zetachain.zetacore.observer.QueryTssFundsMigratorInfoAllResponse + */ +export declare class QueryTssFundsMigratorInfoAllResponse extends Message { + /** + * @generated from field: repeated zetachain.zetacore.observer.TssFundMigratorInfo tss_funds_migrators = 1; + */ + tssFundsMigrators: TssFundMigratorInfo[]; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.QueryTssFundsMigratorInfoAllResponse"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): QueryTssFundsMigratorInfoAllResponse; + + static fromJson(jsonValue: JsonValue, options?: Partial): QueryTssFundsMigratorInfoAllResponse; + + static fromJsonString(jsonString: string, options?: Partial): QueryTssFundsMigratorInfoAllResponse; + + static equals(a: QueryTssFundsMigratorInfoAllResponse | PlainMessage | undefined, b: QueryTssFundsMigratorInfoAllResponse | PlainMessage | undefined): boolean; +} + +/** + * @generated from message zetachain.zetacore.observer.QueryTssFundsMigratorInfoRequest + */ +export declare class QueryTssFundsMigratorInfoRequest extends Message { + /** + * @generated from field: int64 chain_id = 1; + */ + chainId: bigint; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.QueryTssFundsMigratorInfoRequest"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): QueryTssFundsMigratorInfoRequest; + + static fromJson(jsonValue: JsonValue, options?: Partial): QueryTssFundsMigratorInfoRequest; + + static fromJsonString(jsonString: string, options?: Partial): QueryTssFundsMigratorInfoRequest; + + static equals(a: QueryTssFundsMigratorInfoRequest | PlainMessage | undefined, b: QueryTssFundsMigratorInfoRequest | PlainMessage | undefined): boolean; +} + +/** + * @generated from message zetachain.zetacore.observer.QueryTssFundsMigratorInfoResponse + */ +export declare class QueryTssFundsMigratorInfoResponse extends Message { + /** + * @generated from field: zetachain.zetacore.observer.TssFundMigratorInfo tss_funds_migrator = 1; + */ + tssFundsMigrator?: TssFundMigratorInfo; + + constructor(data?: PartialMessage); + + static readonly runtime: typeof proto3; + static readonly typeName = "zetachain.zetacore.observer.QueryTssFundsMigratorInfoResponse"; + static readonly fields: FieldList; + + static fromBinary(bytes: Uint8Array, options?: Partial): QueryTssFundsMigratorInfoResponse; + + static fromJson(jsonValue: JsonValue, options?: Partial): QueryTssFundsMigratorInfoResponse; + + static fromJsonString(jsonString: string, options?: Partial): QueryTssFundsMigratorInfoResponse; + + static equals(a: QueryTssFundsMigratorInfoResponse | PlainMessage | undefined, b: QueryTssFundsMigratorInfoResponse | PlainMessage | undefined): boolean; +} + /** * @generated from message zetachain.zetacore.observer.QueryGetChainNoncesRequest */ diff --git a/x/observer/client/cli/query.go b/x/observer/client/cli/query.go index 84b9c6c6e6..39f43847a7 100644 --- a/x/observer/client/cli/query.go +++ b/x/observer/client/cli/query.go @@ -41,6 +41,8 @@ func GetQueryCmd(_ string) *cobra.Command { CmdListChainNonces(), CmdShowChainNonces(), CmdListPendingNonces(), + CmdGetAllTssFundsMigrator(), + CmdGetTssFundsMigrator(), ) return cmd diff --git a/x/observer/client/cli/query_tss_fund_migrator.go b/x/observer/client/cli/query_tss_fund_migrator.go new file mode 100644 index 0000000000..5dc77fb263 --- /dev/null +++ b/x/observer/client/cli/query_tss_fund_migrator.go @@ -0,0 +1,63 @@ +package cli + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/cobra" + + "github.com/zeta-chain/zetacore/x/observer/types" +) + +func CmdGetTssFundsMigrator() *cobra.Command { + cmd := &cobra.Command{ + Use: "show-tss-funds-migrator [chain-id]", + Short: "show the tss funds migrator for a chain", + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryTssFundsMigratorInfoRequest{} + + res, err := queryClient.TssFundsMigratorInfo(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddPaginationFlagsToCmd(cmd, cmd.Use) + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func CmdGetAllTssFundsMigrator() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-tss-funds-migrator", + Short: "list all tss funds migrators", + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryTssFundsMigratorInfoAllRequest{} + + res, err := queryClient.TssFundsMigratorInfoAll(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddPaginationFlagsToCmd(cmd, cmd.Use) + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/observer/keeper/grpc_query_tss_funds_migrator_info.go b/x/observer/keeper/grpc_query_tss_funds_migrator_info.go new file mode 100644 index 0000000000..b008df0070 --- /dev/null +++ b/x/observer/keeper/grpc_query_tss_funds_migrator_info.go @@ -0,0 +1,46 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/zeta-chain/zetacore/x/observer/types" +) + +// TssFundsMigratorInfo queries a tss fund migrator info +func (k Keeper) TssFundsMigratorInfo( + goCtx context.Context, + req *types.QueryTssFundsMigratorInfoRequest, +) (*types.QueryTssFundsMigratorInfoResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + fm, found := k.GetFundMigrator(ctx, req.ChainId) + if !found { + return nil, status.Error(codes.NotFound, "tss fund migrator not found") + } + return &types.QueryTssFundsMigratorInfoResponse{ + TssFundsMigrator: fm, + }, nil +} + +// TssFundsMigratorInfoAll queries all tss fund migrator info for all chains +func (k Keeper) TssFundsMigratorInfoAll( + goCtx context.Context, + request *types.QueryTssFundsMigratorInfoAllRequest, +) (*types.QueryTssFundsMigratorInfoAllResponse, error) { + if request == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + + migrators := k.GetAllTssFundMigrators(ctx) + + return &types.QueryTssFundsMigratorInfoAllResponse{TssFundsMigrators: migrators}, nil +} diff --git a/x/observer/keeper/grpc_query_tss_funds_migrator_test.go b/x/observer/keeper/grpc_query_tss_funds_migrator_test.go new file mode 100644 index 0000000000..8f431b9122 --- /dev/null +++ b/x/observer/keeper/grpc_query_tss_funds_migrator_test.go @@ -0,0 +1,91 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "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/observer/types" +) + +func TestKeeper_TssFundsMigratorInfo(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.TssFundsMigratorInfo(wctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should error if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.TssFundsMigratorInfo(wctx, &types.QueryTssFundsMigratorInfoRequest{}) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + chainId := chains.Ethereum.ChainId + + fm := types.TssFundMigratorInfo{ + ChainId: chainId, + MigrationCctxIndex: sample.ZetaIndex(t), + } + k.SetFundMigrator(ctx, fm) + + res, err := k.TssFundsMigratorInfo(wctx, &types.QueryTssFundsMigratorInfoRequest{ + ChainId: chainId, + }) + require.NoError(t, err) + require.Equal(t, fm, res.TssFundsMigrator) + }) +} + +func TestKeeper_TssFundsMigratorInfoAll(t *testing.T) { + t.Run("should error if req is nil", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.TssFundsMigratorInfoAll(wctx, nil) + require.Error(t, err) + require.Nil(t, res) + }) + + t.Run("should return empty list if not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.TssFundsMigratorInfoAll(wctx, &types.QueryTssFundsMigratorInfoAllRequest{}) + require.NoError(t, err) + require.Equal(t, 0, len(res.TssFundsMigrators)) + }) + + t.Run("should return list of infos if found", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + migrators := make([]types.TssFundMigratorInfo, 3) + for i := 0; i < 3; i++ { + fm := types.TssFundMigratorInfo{ + ChainId: int64(i), + MigrationCctxIndex: sample.ZetaIndex(t), + } + k.SetFundMigrator(ctx, fm) + migrators[i] = fm + } + + res, err := k.TssFundsMigratorInfoAll(wctx, &types.QueryTssFundsMigratorInfoAllRequest{}) + require.NoError(t, err) + require.Equal(t, 3, len(res.TssFundsMigrators)) + require.ElementsMatch(t, migrators, res.TssFundsMigrators) + }) +} diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index 1c7b0178cc..59f340b65a 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -32,6 +32,174 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type QueryTssFundsMigratorInfoAllRequest struct { +} + +func (m *QueryTssFundsMigratorInfoAllRequest) Reset() { *m = QueryTssFundsMigratorInfoAllRequest{} } +func (m *QueryTssFundsMigratorInfoAllRequest) String() string { return proto.CompactTextString(m) } +func (*QueryTssFundsMigratorInfoAllRequest) ProtoMessage() {} +func (*QueryTssFundsMigratorInfoAllRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_25b2aa420449a0c0, []int{0} +} +func (m *QueryTssFundsMigratorInfoAllRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryTssFundsMigratorInfoAllRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryTssFundsMigratorInfoAllRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryTssFundsMigratorInfoAllRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryTssFundsMigratorInfoAllRequest.Merge(m, src) +} +func (m *QueryTssFundsMigratorInfoAllRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryTssFundsMigratorInfoAllRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryTssFundsMigratorInfoAllRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryTssFundsMigratorInfoAllRequest proto.InternalMessageInfo + +type QueryTssFundsMigratorInfoAllResponse struct { + TssFundsMigrators []TssFundMigratorInfo `protobuf:"bytes,1,rep,name=tss_funds_migrators,json=tssFundsMigrators,proto3" json:"tss_funds_migrators"` +} + +func (m *QueryTssFundsMigratorInfoAllResponse) Reset() { *m = QueryTssFundsMigratorInfoAllResponse{} } +func (m *QueryTssFundsMigratorInfoAllResponse) String() string { return proto.CompactTextString(m) } +func (*QueryTssFundsMigratorInfoAllResponse) ProtoMessage() {} +func (*QueryTssFundsMigratorInfoAllResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_25b2aa420449a0c0, []int{1} +} +func (m *QueryTssFundsMigratorInfoAllResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryTssFundsMigratorInfoAllResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryTssFundsMigratorInfoAllResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryTssFundsMigratorInfoAllResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryTssFundsMigratorInfoAllResponse.Merge(m, src) +} +func (m *QueryTssFundsMigratorInfoAllResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryTssFundsMigratorInfoAllResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryTssFundsMigratorInfoAllResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryTssFundsMigratorInfoAllResponse proto.InternalMessageInfo + +func (m *QueryTssFundsMigratorInfoAllResponse) GetTssFundsMigrators() []TssFundMigratorInfo { + if m != nil { + return m.TssFundsMigrators + } + return nil +} + +type QueryTssFundsMigratorInfoRequest struct { + ChainId int64 `protobuf:"varint,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` +} + +func (m *QueryTssFundsMigratorInfoRequest) Reset() { *m = QueryTssFundsMigratorInfoRequest{} } +func (m *QueryTssFundsMigratorInfoRequest) String() string { return proto.CompactTextString(m) } +func (*QueryTssFundsMigratorInfoRequest) ProtoMessage() {} +func (*QueryTssFundsMigratorInfoRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_25b2aa420449a0c0, []int{2} +} +func (m *QueryTssFundsMigratorInfoRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryTssFundsMigratorInfoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryTssFundsMigratorInfoRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryTssFundsMigratorInfoRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryTssFundsMigratorInfoRequest.Merge(m, src) +} +func (m *QueryTssFundsMigratorInfoRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryTssFundsMigratorInfoRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryTssFundsMigratorInfoRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryTssFundsMigratorInfoRequest proto.InternalMessageInfo + +func (m *QueryTssFundsMigratorInfoRequest) GetChainId() int64 { + if m != nil { + return m.ChainId + } + return 0 +} + +type QueryTssFundsMigratorInfoResponse struct { + TssFundsMigrator TssFundMigratorInfo `protobuf:"bytes,1,opt,name=tss_funds_migrator,json=tssFundsMigrator,proto3" json:"tss_funds_migrator"` +} + +func (m *QueryTssFundsMigratorInfoResponse) Reset() { *m = QueryTssFundsMigratorInfoResponse{} } +func (m *QueryTssFundsMigratorInfoResponse) String() string { return proto.CompactTextString(m) } +func (*QueryTssFundsMigratorInfoResponse) ProtoMessage() {} +func (*QueryTssFundsMigratorInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_25b2aa420449a0c0, []int{3} +} +func (m *QueryTssFundsMigratorInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryTssFundsMigratorInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryTssFundsMigratorInfoResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryTssFundsMigratorInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryTssFundsMigratorInfoResponse.Merge(m, src) +} +func (m *QueryTssFundsMigratorInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryTssFundsMigratorInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryTssFundsMigratorInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryTssFundsMigratorInfoResponse proto.InternalMessageInfo + +func (m *QueryTssFundsMigratorInfoResponse) GetTssFundsMigrator() TssFundMigratorInfo { + if m != nil { + return m.TssFundsMigrator + } + return TssFundMigratorInfo{} +} + type QueryGetChainNoncesRequest struct { Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` } @@ -40,7 +208,7 @@ func (m *QueryGetChainNoncesRequest) Reset() { *m = QueryGetChainNoncesR func (m *QueryGetChainNoncesRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetChainNoncesRequest) ProtoMessage() {} func (*QueryGetChainNoncesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{0} + return fileDescriptor_25b2aa420449a0c0, []int{4} } func (m *QueryGetChainNoncesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -84,7 +252,7 @@ func (m *QueryGetChainNoncesResponse) Reset() { *m = QueryGetChainNonces func (m *QueryGetChainNoncesResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetChainNoncesResponse) ProtoMessage() {} func (*QueryGetChainNoncesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{1} + return fileDescriptor_25b2aa420449a0c0, []int{5} } func (m *QueryGetChainNoncesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -128,7 +296,7 @@ func (m *QueryAllChainNoncesRequest) Reset() { *m = QueryAllChainNoncesR func (m *QueryAllChainNoncesRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllChainNoncesRequest) ProtoMessage() {} func (*QueryAllChainNoncesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{2} + return fileDescriptor_25b2aa420449a0c0, []int{6} } func (m *QueryAllChainNoncesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -173,7 +341,7 @@ func (m *QueryAllChainNoncesResponse) Reset() { *m = QueryAllChainNonces func (m *QueryAllChainNoncesResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllChainNoncesResponse) ProtoMessage() {} func (*QueryAllChainNoncesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{3} + return fileDescriptor_25b2aa420449a0c0, []int{7} } func (m *QueryAllChainNoncesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -224,7 +392,7 @@ func (m *QueryAllPendingNoncesRequest) Reset() { *m = QueryAllPendingNon func (m *QueryAllPendingNoncesRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllPendingNoncesRequest) ProtoMessage() {} func (*QueryAllPendingNoncesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{4} + return fileDescriptor_25b2aa420449a0c0, []int{8} } func (m *QueryAllPendingNoncesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -269,7 +437,7 @@ func (m *QueryAllPendingNoncesResponse) Reset() { *m = QueryAllPendingNo func (m *QueryAllPendingNoncesResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllPendingNoncesResponse) ProtoMessage() {} func (*QueryAllPendingNoncesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{5} + return fileDescriptor_25b2aa420449a0c0, []int{9} } func (m *QueryAllPendingNoncesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -320,7 +488,7 @@ func (m *QueryPendingNoncesByChainRequest) Reset() { *m = QueryPendingNo func (m *QueryPendingNoncesByChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryPendingNoncesByChainRequest) ProtoMessage() {} func (*QueryPendingNoncesByChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{6} + return fileDescriptor_25b2aa420449a0c0, []int{10} } func (m *QueryPendingNoncesByChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -364,7 +532,7 @@ func (m *QueryPendingNoncesByChainResponse) Reset() { *m = QueryPendingN func (m *QueryPendingNoncesByChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryPendingNoncesByChainResponse) ProtoMessage() {} func (*QueryPendingNoncesByChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{7} + return fileDescriptor_25b2aa420449a0c0, []int{11} } func (m *QueryPendingNoncesByChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -407,7 +575,7 @@ func (m *QueryGetTSSRequest) Reset() { *m = QueryGetTSSRequest{} } func (m *QueryGetTSSRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetTSSRequest) ProtoMessage() {} func (*QueryGetTSSRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{8} + return fileDescriptor_25b2aa420449a0c0, []int{12} } func (m *QueryGetTSSRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -444,7 +612,7 @@ func (m *QueryGetTSSResponse) Reset() { *m = QueryGetTSSResponse{} } func (m *QueryGetTSSResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetTSSResponse) ProtoMessage() {} func (*QueryGetTSSResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{9} + return fileDescriptor_25b2aa420449a0c0, []int{13} } func (m *QueryGetTSSResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -488,7 +656,7 @@ func (m *QueryGetTssAddressRequest) Reset() { *m = QueryGetTssAddressReq func (m *QueryGetTssAddressRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetTssAddressRequest) ProtoMessage() {} func (*QueryGetTssAddressRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{10} + return fileDescriptor_25b2aa420449a0c0, []int{14} } func (m *QueryGetTssAddressRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -533,7 +701,7 @@ func (m *QueryGetTssAddressResponse) Reset() { *m = QueryGetTssAddressRe func (m *QueryGetTssAddressResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetTssAddressResponse) ProtoMessage() {} func (*QueryGetTssAddressResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{11} + return fileDescriptor_25b2aa420449a0c0, []int{15} } func (m *QueryGetTssAddressResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -589,7 +757,7 @@ func (m *QueryGetTssAddressByFinalizedHeightRequest) String() string { } func (*QueryGetTssAddressByFinalizedHeightRequest) ProtoMessage() {} func (*QueryGetTssAddressByFinalizedHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{12} + return fileDescriptor_25b2aa420449a0c0, []int{16} } func (m *QueryGetTssAddressByFinalizedHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -645,7 +813,7 @@ func (m *QueryGetTssAddressByFinalizedHeightResponse) String() string { } func (*QueryGetTssAddressByFinalizedHeightResponse) ProtoMessage() {} func (*QueryGetTssAddressByFinalizedHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{13} + return fileDescriptor_25b2aa420449a0c0, []int{17} } func (m *QueryGetTssAddressByFinalizedHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -696,7 +864,7 @@ func (m *QueryTssHistoryRequest) Reset() { *m = QueryTssHistoryRequest{} func (m *QueryTssHistoryRequest) String() string { return proto.CompactTextString(m) } func (*QueryTssHistoryRequest) ProtoMessage() {} func (*QueryTssHistoryRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{14} + return fileDescriptor_25b2aa420449a0c0, []int{18} } func (m *QueryTssHistoryRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -741,7 +909,7 @@ func (m *QueryTssHistoryResponse) Reset() { *m = QueryTssHistoryResponse func (m *QueryTssHistoryResponse) String() string { return proto.CompactTextString(m) } func (*QueryTssHistoryResponse) ProtoMessage() {} func (*QueryTssHistoryResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{15} + return fileDescriptor_25b2aa420449a0c0, []int{19} } func (m *QueryTssHistoryResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -793,7 +961,7 @@ func (m *QueryHasVotedRequest) Reset() { *m = QueryHasVotedRequest{} } func (m *QueryHasVotedRequest) String() string { return proto.CompactTextString(m) } func (*QueryHasVotedRequest) ProtoMessage() {} func (*QueryHasVotedRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{16} + return fileDescriptor_25b2aa420449a0c0, []int{20} } func (m *QueryHasVotedRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -844,7 +1012,7 @@ func (m *QueryHasVotedResponse) Reset() { *m = QueryHasVotedResponse{} } func (m *QueryHasVotedResponse) String() string { return proto.CompactTextString(m) } func (*QueryHasVotedResponse) ProtoMessage() {} func (*QueryHasVotedResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{17} + return fileDescriptor_25b2aa420449a0c0, []int{21} } func (m *QueryHasVotedResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -888,7 +1056,7 @@ func (m *QueryBallotByIdentifierRequest) Reset() { *m = QueryBallotByIde func (m *QueryBallotByIdentifierRequest) String() string { return proto.CompactTextString(m) } func (*QueryBallotByIdentifierRequest) ProtoMessage() {} func (*QueryBallotByIdentifierRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{18} + return fileDescriptor_25b2aa420449a0c0, []int{22} } func (m *QueryBallotByIdentifierRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -933,7 +1101,7 @@ func (m *VoterList) Reset() { *m = VoterList{} } func (m *VoterList) String() string { return proto.CompactTextString(m) } func (*VoterList) ProtoMessage() {} func (*VoterList) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{19} + return fileDescriptor_25b2aa420449a0c0, []int{23} } func (m *VoterList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -987,7 +1155,7 @@ func (m *QueryBallotByIdentifierResponse) Reset() { *m = QueryBallotById func (m *QueryBallotByIdentifierResponse) String() string { return proto.CompactTextString(m) } func (*QueryBallotByIdentifierResponse) ProtoMessage() {} func (*QueryBallotByIdentifierResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{20} + return fileDescriptor_25b2aa420449a0c0, []int{24} } func (m *QueryBallotByIdentifierResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1051,7 +1219,7 @@ func (m *QueryObserverSet) Reset() { *m = QueryObserverSet{} } func (m *QueryObserverSet) String() string { return proto.CompactTextString(m) } func (*QueryObserverSet) ProtoMessage() {} func (*QueryObserverSet) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{21} + return fileDescriptor_25b2aa420449a0c0, []int{25} } func (m *QueryObserverSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1088,7 +1256,7 @@ func (m *QueryObserverSetResponse) Reset() { *m = QueryObserverSetRespon func (m *QueryObserverSetResponse) String() string { return proto.CompactTextString(m) } func (*QueryObserverSetResponse) ProtoMessage() {} func (*QueryObserverSetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{22} + return fileDescriptor_25b2aa420449a0c0, []int{26} } func (m *QueryObserverSetResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1131,7 +1299,7 @@ func (m *QuerySupportedChains) Reset() { *m = QuerySupportedChains{} } func (m *QuerySupportedChains) String() string { return proto.CompactTextString(m) } func (*QuerySupportedChains) ProtoMessage() {} func (*QuerySupportedChains) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{23} + return fileDescriptor_25b2aa420449a0c0, []int{27} } func (m *QuerySupportedChains) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1168,7 +1336,7 @@ func (m *QuerySupportedChainsResponse) Reset() { *m = QuerySupportedChai func (m *QuerySupportedChainsResponse) String() string { return proto.CompactTextString(m) } func (*QuerySupportedChainsResponse) ProtoMessage() {} func (*QuerySupportedChainsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{24} + return fileDescriptor_25b2aa420449a0c0, []int{28} } func (m *QuerySupportedChainsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1212,7 +1380,7 @@ func (m *QueryGetChainParamsForChainRequest) Reset() { *m = QueryGetChai func (m *QueryGetChainParamsForChainRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetChainParamsForChainRequest) ProtoMessage() {} func (*QueryGetChainParamsForChainRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{25} + return fileDescriptor_25b2aa420449a0c0, []int{29} } func (m *QueryGetChainParamsForChainRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1256,7 +1424,7 @@ func (m *QueryGetChainParamsForChainResponse) Reset() { *m = QueryGetCha func (m *QueryGetChainParamsForChainResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetChainParamsForChainResponse) ProtoMessage() {} func (*QueryGetChainParamsForChainResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{26} + return fileDescriptor_25b2aa420449a0c0, []int{30} } func (m *QueryGetChainParamsForChainResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1299,7 +1467,7 @@ func (m *QueryGetChainParamsRequest) Reset() { *m = QueryGetChainParamsR func (m *QueryGetChainParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetChainParamsRequest) ProtoMessage() {} func (*QueryGetChainParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{27} + return fileDescriptor_25b2aa420449a0c0, []int{31} } func (m *QueryGetChainParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1336,7 +1504,7 @@ func (m *QueryGetChainParamsResponse) Reset() { *m = QueryGetChainParams func (m *QueryGetChainParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetChainParamsResponse) ProtoMessage() {} func (*QueryGetChainParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{28} + return fileDescriptor_25b2aa420449a0c0, []int{32} } func (m *QueryGetChainParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1380,7 +1548,7 @@ func (m *QueryGetNodeAccountRequest) Reset() { *m = QueryGetNodeAccountR func (m *QueryGetNodeAccountRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetNodeAccountRequest) ProtoMessage() {} func (*QueryGetNodeAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{29} + return fileDescriptor_25b2aa420449a0c0, []int{33} } func (m *QueryGetNodeAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1424,7 +1592,7 @@ func (m *QueryGetNodeAccountResponse) Reset() { *m = QueryGetNodeAccount func (m *QueryGetNodeAccountResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetNodeAccountResponse) ProtoMessage() {} func (*QueryGetNodeAccountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{30} + return fileDescriptor_25b2aa420449a0c0, []int{34} } func (m *QueryGetNodeAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1468,7 +1636,7 @@ func (m *QueryAllNodeAccountRequest) Reset() { *m = QueryAllNodeAccountR func (m *QueryAllNodeAccountRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllNodeAccountRequest) ProtoMessage() {} func (*QueryAllNodeAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{31} + return fileDescriptor_25b2aa420449a0c0, []int{35} } func (m *QueryAllNodeAccountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1513,7 +1681,7 @@ func (m *QueryAllNodeAccountResponse) Reset() { *m = QueryAllNodeAccount func (m *QueryAllNodeAccountResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllNodeAccountResponse) ProtoMessage() {} func (*QueryAllNodeAccountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{32} + return fileDescriptor_25b2aa420449a0c0, []int{36} } func (m *QueryAllNodeAccountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1563,7 +1731,7 @@ func (m *QueryGetCrosschainFlagsRequest) Reset() { *m = QueryGetCrosscha func (m *QueryGetCrosschainFlagsRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetCrosschainFlagsRequest) ProtoMessage() {} func (*QueryGetCrosschainFlagsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{33} + return fileDescriptor_25b2aa420449a0c0, []int{37} } func (m *QueryGetCrosschainFlagsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1600,7 +1768,7 @@ func (m *QueryGetCrosschainFlagsResponse) Reset() { *m = QueryGetCrossch func (m *QueryGetCrosschainFlagsResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetCrosschainFlagsResponse) ProtoMessage() {} func (*QueryGetCrosschainFlagsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{34} + return fileDescriptor_25b2aa420449a0c0, []int{38} } func (m *QueryGetCrosschainFlagsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1643,7 +1811,7 @@ func (m *QueryGetKeygenRequest) Reset() { *m = QueryGetKeygenRequest{} } func (m *QueryGetKeygenRequest) String() string { return proto.CompactTextString(m) } func (*QueryGetKeygenRequest) ProtoMessage() {} func (*QueryGetKeygenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{35} + return fileDescriptor_25b2aa420449a0c0, []int{39} } func (m *QueryGetKeygenRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1680,7 +1848,7 @@ func (m *QueryGetKeygenResponse) Reset() { *m = QueryGetKeygenResponse{} func (m *QueryGetKeygenResponse) String() string { return proto.CompactTextString(m) } func (*QueryGetKeygenResponse) ProtoMessage() {} func (*QueryGetKeygenResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{36} + return fileDescriptor_25b2aa420449a0c0, []int{40} } func (m *QueryGetKeygenResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1723,7 +1891,7 @@ func (m *QueryShowObserverCountRequest) Reset() { *m = QueryShowObserver func (m *QueryShowObserverCountRequest) String() string { return proto.CompactTextString(m) } func (*QueryShowObserverCountRequest) ProtoMessage() {} func (*QueryShowObserverCountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{37} + return fileDescriptor_25b2aa420449a0c0, []int{41} } func (m *QueryShowObserverCountRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1760,7 +1928,7 @@ func (m *QueryShowObserverCountResponse) Reset() { *m = QueryShowObserve func (m *QueryShowObserverCountResponse) String() string { return proto.CompactTextString(m) } func (*QueryShowObserverCountResponse) ProtoMessage() {} func (*QueryShowObserverCountResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{38} + return fileDescriptor_25b2aa420449a0c0, []int{42} } func (m *QueryShowObserverCountResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1804,7 +1972,7 @@ func (m *QueryBlameByIdentifierRequest) Reset() { *m = QueryBlameByIdent func (m *QueryBlameByIdentifierRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlameByIdentifierRequest) ProtoMessage() {} func (*QueryBlameByIdentifierRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{39} + return fileDescriptor_25b2aa420449a0c0, []int{43} } func (m *QueryBlameByIdentifierRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1848,7 +2016,7 @@ func (m *QueryBlameByIdentifierResponse) Reset() { *m = QueryBlameByIden func (m *QueryBlameByIdentifierResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlameByIdentifierResponse) ProtoMessage() {} func (*QueryBlameByIdentifierResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{40} + return fileDescriptor_25b2aa420449a0c0, []int{44} } func (m *QueryBlameByIdentifierResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1892,7 +2060,7 @@ func (m *QueryAllBlameRecordsRequest) Reset() { *m = QueryAllBlameRecord func (m *QueryAllBlameRecordsRequest) String() string { return proto.CompactTextString(m) } func (*QueryAllBlameRecordsRequest) ProtoMessage() {} func (*QueryAllBlameRecordsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{41} + return fileDescriptor_25b2aa420449a0c0, []int{45} } func (m *QueryAllBlameRecordsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1937,7 +2105,7 @@ func (m *QueryAllBlameRecordsResponse) Reset() { *m = QueryAllBlameRecor func (m *QueryAllBlameRecordsResponse) String() string { return proto.CompactTextString(m) } func (*QueryAllBlameRecordsResponse) ProtoMessage() {} func (*QueryAllBlameRecordsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{42} + return fileDescriptor_25b2aa420449a0c0, []int{46} } func (m *QueryAllBlameRecordsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1989,7 +2157,7 @@ func (m *QueryBlameByChainAndNonceRequest) Reset() { *m = QueryBlameByCh func (m *QueryBlameByChainAndNonceRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlameByChainAndNonceRequest) ProtoMessage() {} func (*QueryBlameByChainAndNonceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{43} + return fileDescriptor_25b2aa420449a0c0, []int{47} } func (m *QueryBlameByChainAndNonceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2040,7 +2208,7 @@ func (m *QueryBlameByChainAndNonceResponse) Reset() { *m = QueryBlameByC func (m *QueryBlameByChainAndNonceResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlameByChainAndNonceResponse) ProtoMessage() {} func (*QueryBlameByChainAndNonceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_25b2aa420449a0c0, []int{44} + return fileDescriptor_25b2aa420449a0c0, []int{48} } func (m *QueryBlameByChainAndNonceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2077,6 +2245,10 @@ func (m *QueryBlameByChainAndNonceResponse) GetBlameInfo() []*Blame { } func init() { + proto.RegisterType((*QueryTssFundsMigratorInfoAllRequest)(nil), "zetachain.zetacore.observer.QueryTssFundsMigratorInfoAllRequest") + proto.RegisterType((*QueryTssFundsMigratorInfoAllResponse)(nil), "zetachain.zetacore.observer.QueryTssFundsMigratorInfoAllResponse") + proto.RegisterType((*QueryTssFundsMigratorInfoRequest)(nil), "zetachain.zetacore.observer.QueryTssFundsMigratorInfoRequest") + proto.RegisterType((*QueryTssFundsMigratorInfoResponse)(nil), "zetachain.zetacore.observer.QueryTssFundsMigratorInfoResponse") proto.RegisterType((*QueryGetChainNoncesRequest)(nil), "zetachain.zetacore.observer.QueryGetChainNoncesRequest") proto.RegisterType((*QueryGetChainNoncesResponse)(nil), "zetachain.zetacore.observer.QueryGetChainNoncesResponse") proto.RegisterType((*QueryAllChainNoncesRequest)(nil), "zetachain.zetacore.observer.QueryAllChainNoncesRequest") @@ -2129,140 +2301,150 @@ func init() { } var fileDescriptor_25b2aa420449a0c0 = []byte{ - // 2128 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcf, 0x6f, 0x1b, 0xc7, - 0x15, 0xf6, 0x4a, 0x89, 0x22, 0x3d, 0xd9, 0x92, 0x3c, 0x96, 0x1d, 0x87, 0x76, 0x64, 0x79, 0x65, - 0xc7, 0xb2, 0x62, 0x73, 0x6d, 0x3a, 0xa9, 0x7f, 0xc7, 0x16, 0xdd, 0x58, 0xb2, 0x93, 0xda, 0x0e, - 0xa9, 0x36, 0x80, 0x91, 0x96, 0x5d, 0x92, 0x43, 0x72, 0xeb, 0xd5, 0x0e, 0xb3, 0x33, 0x72, 0xc2, - 0xa8, 0x02, 0x8a, 0x1e, 0x73, 0x2a, 0x50, 0xa0, 0xbd, 0x15, 0xbd, 0xf4, 0x58, 0xa0, 0x08, 0x50, - 0xb4, 0x40, 0xd1, 0x43, 0x4e, 0xcd, 0xa1, 0x87, 0x14, 0x05, 0x8a, 0x9e, 0xda, 0xc0, 0xee, 0xff, - 0xd1, 0x62, 0x67, 0xde, 0x92, 0xbb, 0xcb, 0xe5, 0x72, 0x28, 0xab, 0x27, 0xee, 0xce, 0xbe, 0xf7, - 0xe6, 0xfb, 0xde, 0xce, 0xcc, 0xfb, 0x66, 0x87, 0x70, 0xe6, 0x33, 0x2a, 0xec, 0x5a, 0xcb, 0x76, - 0x3c, 0x4b, 0x5e, 0x31, 0x9f, 0x5a, 0xac, 0xca, 0xa9, 0xff, 0x94, 0xfa, 0xd6, 0xc7, 0x5b, 0xd4, - 0xef, 0xe4, 0xdb, 0x3e, 0x13, 0x8c, 0x1c, 0xeb, 0x1a, 0xe6, 0x43, 0xc3, 0x7c, 0x68, 0x98, 0x5b, - 0xa9, 0x31, 0xbe, 0xc9, 0xb8, 0x55, 0xb5, 0x39, 0x55, 0x5e, 0xd6, 0xd3, 0x8b, 0x55, 0x2a, 0xec, - 0x8b, 0x56, 0xdb, 0x6e, 0x3a, 0x9e, 0x2d, 0x1c, 0xe6, 0xa9, 0x40, 0xb9, 0xf9, 0x26, 0x6b, 0x32, - 0x79, 0x69, 0x05, 0x57, 0xd8, 0x7a, 0xbc, 0xc9, 0x58, 0xd3, 0xa5, 0x96, 0xdd, 0x76, 0x2c, 0xdb, - 0xf3, 0x98, 0x90, 0x2e, 0x1c, 0x9f, 0x2e, 0x67, 0xa1, 0xac, 0xda, 0xae, 0xcb, 0x04, 0x5a, 0x66, - 0xf2, 0xa9, 0xba, 0xf6, 0x26, 0x45, 0xc3, 0x7c, 0x96, 0xa1, 0x6c, 0xaf, 0x78, 0xcc, 0xab, 0xd1, - 0x10, 0x42, 0x21, 0xd3, 0xde, 0x67, 0x9c, 0x2b, 0xa7, 0x86, 0x6b, 0x37, 0xb5, 0x60, 0x3f, 0xa1, - 0x9d, 0x26, 0xf5, 0x74, 0xd0, 0x78, 0xac, 0x4e, 0x2b, 0x76, 0xad, 0xc6, 0xb6, 0xbc, 0x90, 0xe6, - 0x4a, 0x96, 0x7d, 0x78, 0xa1, 0x83, 0xa2, 0x6d, 0xfb, 0xf6, 0x66, 0x88, 0xf7, 0x42, 0xa6, 0x25, - 0xf5, 0xea, 0x8e, 0xd7, 0x8c, 0x67, 0xe5, 0x74, 0x96, 0x87, 0xe0, 0x3c, 0x03, 0x6e, 0xfb, 0x49, - 0x53, 0xe5, 0x99, 0xe3, 0xcf, 0x10, 0xdb, 0xb6, 0xcf, 0x58, 0x83, 0xe3, 0x8f, 0xb2, 0x35, 0x0b, - 0x90, 0xfb, 0x20, 0x18, 0x6d, 0x6b, 0x54, 0xdc, 0x09, 0x3c, 0x1e, 0x48, 0x6c, 0x25, 0xfa, 0xf1, - 0x16, 0xe5, 0x82, 0xcc, 0xc3, 0xcb, 0x8e, 0x57, 0xa7, 0x9f, 0x1e, 0x35, 0x16, 0x8d, 0xe5, 0xa9, - 0x92, 0xba, 0x31, 0x19, 0x1c, 0x4b, 0xf5, 0xe1, 0x6d, 0xe6, 0x71, 0x4a, 0x1e, 0xc1, 0x74, 0xa4, - 0x59, 0xba, 0x4e, 0x17, 0x96, 0xf3, 0x19, 0xa3, 0x3f, 0x1f, 0xb1, 0x2f, 0xbe, 0xf4, 0xd5, 0xbf, - 0x4e, 0xec, 0x2b, 0x45, 0x43, 0x98, 0x75, 0x04, 0xb9, 0xea, 0xba, 0x29, 0x20, 0xef, 0x02, 0xf4, - 0xa6, 0x08, 0x76, 0xf7, 0x46, 0x5e, 0xcd, 0xa7, 0x7c, 0x30, 0x9f, 0xf2, 0x6a, 0x16, 0xe2, 0x7c, - 0xca, 0x3f, 0xb2, 0x9b, 0x14, 0x7d, 0x4b, 0x11, 0x4f, 0xf3, 0x8f, 0x06, 0xf2, 0x4a, 0x76, 0x33, - 0x88, 0xd7, 0xf8, 0x0b, 0xf2, 0x22, 0x6b, 0x31, 0xe4, 0x63, 0x12, 0xf9, 0x99, 0xa1, 0xc8, 0x15, - 0x9c, 0x18, 0xf4, 0x06, 0x1c, 0x0f, 0x91, 0x3f, 0x52, 0x83, 0xec, 0xff, 0x93, 0xa2, 0x2f, 0x0d, - 0x78, 0x7d, 0x40, 0x47, 0x98, 0xa4, 0x0f, 0x61, 0x26, 0x3e, 0xcc, 0x31, 0x4f, 0x2b, 0x99, 0x79, - 0x8a, 0xc5, 0xc2, 0x4c, 0x1d, 0x68, 0x47, 0x1b, 0xf7, 0x2e, 0x57, 0x37, 0x61, 0x51, 0x52, 0x88, - 0xf7, 0xd9, 0x91, 0xef, 0x25, 0xcc, 0xd7, 0x6b, 0x30, 0xa9, 0xd6, 0x22, 0xa7, 0x2e, 0xb3, 0x35, - 0x5e, 0x7a, 0x45, 0xde, 0xdf, 0xab, 0x9b, 0x3f, 0x86, 0x93, 0x19, 0xee, 0x19, 0x59, 0x30, 0xf6, - 0x20, 0x0b, 0xe6, 0x3c, 0x90, 0x70, 0xea, 0x6d, 0x94, 0xcb, 0x08, 0xd7, 0x7c, 0x08, 0x87, 0x62, - 0xad, 0x88, 0xe2, 0x0a, 0x8c, 0x6f, 0x94, 0xcb, 0xd8, 0xf5, 0x62, 0x66, 0xd7, 0x1b, 0xe5, 0x32, - 0x76, 0x18, 0xb8, 0x98, 0xef, 0xc2, 0x6b, 0xdd, 0x80, 0x9c, 0xaf, 0xd6, 0xeb, 0x3e, 0xe5, 0xdd, - 0xc1, 0xb4, 0x0c, 0x73, 0x55, 0x47, 0xd4, 0x98, 0xe3, 0x55, 0xba, 0x49, 0x1a, 0x93, 0x49, 0x9a, - 0xc1, 0xf6, 0x3b, 0x98, 0xab, 0xdb, 0xbd, 0xc5, 0x25, 0x1a, 0x06, 0xe1, 0xcd, 0xc1, 0x38, 0x15, - 0x2d, 0x5c, 0x5a, 0x82, 0xcb, 0xa0, 0xa5, 0x2a, 0x6a, 0x32, 0xd8, 0x54, 0x29, 0xb8, 0x34, 0x3f, - 0x37, 0x60, 0xa5, 0x3f, 0x44, 0xb1, 0x73, 0xd7, 0xf1, 0x6c, 0xd7, 0xf9, 0x8c, 0xd6, 0xd7, 0xa9, - 0xd3, 0x6c, 0x89, 0x10, 0x5a, 0x01, 0x0e, 0x37, 0xc2, 0x27, 0x95, 0x80, 0x65, 0xa5, 0x25, 0x9f, - 0xe3, 0x4b, 0x3c, 0xd4, 0x7d, 0xf8, 0x98, 0x0a, 0x5b, 0xb9, 0x8e, 0x40, 0xe7, 0x03, 0x78, 0x53, - 0x0b, 0xcb, 0x08, 0xfc, 0x7e, 0x08, 0x47, 0x64, 0xc8, 0x0d, 0xce, 0xd7, 0x1d, 0x2e, 0x98, 0xdf, - 0xd9, 0xeb, 0x29, 0xfb, 0x1b, 0x03, 0x5e, 0xed, 0xeb, 0x02, 0x11, 0xae, 0xc2, 0xa4, 0xe0, 0xbc, - 0xe2, 0x3a, 0x5c, 0xe0, 0x34, 0xd5, 0x1d, 0x25, 0xaf, 0x08, 0xce, 0xdf, 0x77, 0xb8, 0xd8, 0xbb, - 0x69, 0xd9, 0x82, 0x79, 0x09, 0x73, 0xdd, 0xe6, 0xdf, 0x63, 0x82, 0xd6, 0xc3, 0x3c, 0xbc, 0x09, - 0x07, 0x95, 0x3c, 0xa9, 0x38, 0x75, 0xea, 0x09, 0xa7, 0xe1, 0x50, 0x1f, 0x73, 0x3a, 0xa7, 0x1e, - 0xdc, 0xeb, 0xb6, 0x93, 0x25, 0x38, 0xf0, 0x94, 0x09, 0xea, 0x57, 0x6c, 0xf5, 0x72, 0x30, 0xd5, - 0xfb, 0x65, 0x23, 0xbe, 0x30, 0xf3, 0x2d, 0x38, 0x9c, 0xe8, 0x09, 0xd3, 0x71, 0x0c, 0xa6, 0x5a, - 0x36, 0xaf, 0x04, 0xc6, 0x6a, 0xda, 0x4f, 0x96, 0x26, 0x5b, 0x68, 0x64, 0x7e, 0x07, 0x16, 0xa4, - 0x57, 0x51, 0xf6, 0x59, 0xec, 0xf4, 0x7a, 0xdd, 0x0d, 0x52, 0x53, 0xc0, 0x54, 0x10, 0xd7, 0x97, - 0x49, 0xec, 0x83, 0x6d, 0xf4, 0xc3, 0x26, 0x45, 0x98, 0x0a, 0xee, 0x2b, 0xa2, 0xd3, 0xa6, 0x92, - 0xd7, 0x4c, 0xe1, 0x74, 0xe6, 0xdb, 0x0a, 0xe2, 0x6f, 0x74, 0xda, 0xb4, 0x34, 0xf9, 0x14, 0xaf, - 0xcc, 0x3f, 0x8c, 0xc1, 0x89, 0x81, 0x2c, 0x30, 0x0b, 0x23, 0x25, 0xfc, 0x1d, 0x98, 0x90, 0x20, - 0x83, 0x4c, 0x8f, 0xcb, 0x11, 0x3a, 0x0c, 0x91, 0x64, 0x5c, 0x42, 0x2f, 0xf2, 0x21, 0xcc, 0xa9, - 0xa7, 0x72, 0x10, 0x28, 0x6e, 0xe3, 0x92, 0xdb, 0xb9, 0xcc, 0x48, 0x0f, 0x7b, 0x4e, 0x92, 0xe2, - 0x2c, 0x8b, 0x37, 0x90, 0x07, 0x70, 0x00, 0x59, 0x70, 0x61, 0x8b, 0x2d, 0x7e, 0xf4, 0x25, 0x19, - 0xf5, 0x6c, 0x66, 0x54, 0x95, 0x95, 0xb2, 0x74, 0x28, 0xed, 0xaf, 0x46, 0xee, 0x4c, 0x02, 0x73, - 0x32, 0x71, 0x0f, 0xd1, 0xb6, 0x4c, 0x85, 0x79, 0x05, 0x8e, 0x26, 0xdb, 0xba, 0x59, 0x3c, 0x0e, - 0x53, 0x61, 0x58, 0x55, 0x02, 0xa7, 0x4a, 0xbd, 0x06, 0xf3, 0x08, 0x0e, 0xf6, 0xf2, 0x56, 0xbb, - 0xcd, 0x7c, 0x41, 0xeb, 0x72, 0x89, 0xe1, 0xe6, 0x47, 0x58, 0xc7, 0x13, 0xed, 0xdd, 0xa8, 0x37, - 0x60, 0x42, 0x29, 0x3d, 0x9c, 0xae, 0xa7, 0xd2, 0xe8, 0xb4, 0x9f, 0x34, 0xf3, 0xa8, 0x07, 0x55, - 0x55, 0x42, 0x1f, 0xf3, 0x16, 0x98, 0x31, 0xdd, 0xf6, 0x48, 0x2a, 0xd7, 0xbb, 0xcc, 0xd7, 0xad, - 0x7d, 0x3e, 0x2c, 0x65, 0x06, 0x40, 0x94, 0xef, 0xc1, 0x7e, 0x15, 0x41, 0x49, 0x63, 0x7d, 0x05, - 0xa8, 0xe2, 0x95, 0xa6, 0x6b, 0xbd, 0x1b, 0xf3, 0x78, 0x42, 0xa0, 0xa2, 0x0d, 0x56, 0x3e, 0x2f, - 0x21, 0x45, 0xc3, 0xa7, 0x88, 0xe4, 0x61, 0x2a, 0x92, 0x73, 0xba, 0x48, 0xe4, 0x50, 0x8d, 0xa1, - 0x89, 0xc8, 0xe5, 0x07, 0xac, 0x4e, 0x57, 0xd5, 0x96, 0x22, 0x5b, 0x2e, 0xff, 0xa8, 0x87, 0x31, - 0xe6, 0xd3, 0xcb, 0x56, 0x74, 0x7b, 0xa2, 0x95, 0xad, 0x68, 0x9c, 0x69, 0xaf, 0x77, 0x13, 0x55, - 0xca, 0x29, 0xf8, 0xf6, 0xaa, 0xa6, 0x7c, 0x11, 0x51, 0xca, 0x69, 0x94, 0xee, 0xc3, 0x74, 0xa4, - 0x59, 0x4b, 0x29, 0xc7, 0x18, 0x45, 0x6e, 0xf6, 0xae, 0xc0, 0x2c, 0xe2, 0x02, 0x1e, 0x0c, 0x95, - 0xee, 0x66, 0xf3, 0x6e, 0xb0, 0xd7, 0x0c, 0x07, 0xd3, 0x4f, 0x0c, 0x5c, 0x1d, 0xd3, 0x4c, 0x90, - 0xda, 0xf7, 0x61, 0x2e, 0xb9, 0x55, 0xd5, 0x1b, 0x55, 0xf1, 0x78, 0x58, 0x46, 0x67, 0x6b, 0xf1, - 0x66, 0xf3, 0x55, 0xac, 0x4d, 0x6b, 0x54, 0xbc, 0x27, 0x77, 0xb7, 0x21, 0xb6, 0xef, 0xa2, 0x50, - 0x88, 0x3c, 0x40, 0x44, 0xd7, 0x61, 0x42, 0x6d, 0x84, 0x11, 0xc7, 0x52, 0x26, 0x0e, 0x74, 0x46, - 0x17, 0xf3, 0x04, 0xea, 0xf9, 0x72, 0x8b, 0x7d, 0x12, 0x2e, 0x63, 0x77, 0x22, 0x43, 0x26, 0xc8, - 0xc9, 0xc2, 0x20, 0x0b, 0x04, 0xf0, 0x03, 0x38, 0xe4, 0xda, 0x5c, 0x54, 0xc2, 0x3e, 0x2a, 0xd1, - 0x71, 0x9c, 0xcf, 0x44, 0xf3, 0xbe, 0xcd, 0x45, 0x3c, 0xe8, 0x41, 0x37, 0xd9, 0x64, 0xde, 0x47, - 0x8c, 0x45, 0xd7, 0xde, 0xa4, 0x69, 0x85, 0xf7, 0x2c, 0xcc, 0xc9, 0xef, 0x12, 0xfd, 0x05, 0x6b, - 0x56, 0xb6, 0x47, 0xca, 0x6e, 0x2d, 0xac, 0xe2, 0xfd, 0xb1, 0xba, 0x9a, 0x08, 0x30, 0x98, 0xd7, - 0x60, 0x48, 0xc2, 0xcc, 0xae, 0x1a, 0x81, 0x79, 0x69, 0x4a, 0x75, 0xe5, 0x35, 0x98, 0x49, 0x7b, - 0xb3, 0x43, 0x3d, 0xa3, 0x35, 0xe6, 0xd7, 0xf7, 0x7c, 0x33, 0xf6, 0x3b, 0xa3, 0xb7, 0xeb, 0x8b, - 0xf7, 0x83, 0x54, 0xd6, 0x12, 0x54, 0xc6, 0xf5, 0xa8, 0xe0, 0xd8, 0xec, 0x11, 0xda, 0xbb, 0x39, - 0x58, 0xc6, 0xbd, 0x17, 0xa6, 0x5f, 0x2e, 0xb5, 0xab, 0x5e, 0x5d, 0x6e, 0x6e, 0x86, 0xd7, 0x9f, - 0x60, 0x7d, 0x95, 0xdb, 0x29, 0xd4, 0xe7, 0xea, 0xc6, 0x6c, 0xe0, 0x8e, 0x2c, 0x3d, 0xe8, 0x80, - 0xd7, 0x3a, 0x3e, 0xf2, 0x6b, 0x2d, 0xfc, 0x77, 0x11, 0x5e, 0x96, 0x1d, 0x91, 0x3f, 0x1b, 0x30, - 0x19, 0xaa, 0x47, 0x72, 0x31, 0x33, 0x4a, 0x9a, 0xa6, 0xcd, 0x15, 0x46, 0x71, 0x51, 0x04, 0xcc, - 0xfb, 0x3f, 0xfd, 0xfb, 0x7f, 0x7e, 0x3e, 0xf6, 0x6d, 0x52, 0x94, 0xdf, 0x74, 0xce, 0xab, 0xcf, - 0x3b, 0xdd, 0x0f, 0x45, 0x5d, 0xdd, 0x6a, 0x6d, 0xf7, 0x89, 0xb7, 0x1d, 0x6b, 0x3b, 0xa6, 0x2e, - 0x77, 0xc8, 0x3f, 0x0c, 0x20, 0xfd, 0x0a, 0x90, 0x5c, 0x1f, 0x0e, 0x6b, 0xa0, 0xfa, 0xcd, 0xdd, - 0xd8, 0x9d, 0x33, 0xb2, 0x7b, 0x57, 0xb2, 0xbb, 0x45, 0x6e, 0xa6, 0xb2, 0x43, 0x4a, 0xd5, 0x4e, - 0x84, 0x55, 0x1a, 0x51, 0xf2, 0x2b, 0x03, 0xa6, 0x23, 0x6a, 0x8c, 0x9c, 0x1f, 0x0e, 0x2a, 0x62, - 0x9e, 0x7b, 0x7b, 0x24, 0xf3, 0x2e, 0xf8, 0xb3, 0x12, 0xfc, 0x12, 0x39, 0x99, 0x0a, 0xbe, 0xbb, - 0x2c, 0x72, 0x2a, 0xc8, 0x6f, 0x0d, 0x98, 0x4d, 0x88, 0x3b, 0x9d, 0x01, 0x94, 0x70, 0xc9, 0x5d, - 0x1d, 0xd9, 0xa5, 0x0b, 0xf6, 0x9c, 0x04, 0xfb, 0x06, 0x39, 0x95, 0x0a, 0x96, 0x27, 0xb0, 0xfd, - 0xdb, 0x80, 0x23, 0xe9, 0x6a, 0x8f, 0xdc, 0x1a, 0x8e, 0x21, 0x53, 0x68, 0xe6, 0x6e, 0xef, 0x3e, - 0x00, 0x72, 0x29, 0x4a, 0x2e, 0x37, 0xc8, 0xb5, 0x54, 0x2e, 0x4d, 0x2a, 0x2a, 0x51, 0xf5, 0x57, - 0x69, 0x30, 0x5f, 0x35, 0x58, 0xdb, 0xe1, 0x0a, 0xb3, 0x43, 0xbe, 0x30, 0x60, 0x26, 0xde, 0x0d, - 0xb9, 0x3c, 0x2a, 0xb0, 0x90, 0xd1, 0x95, 0xd1, 0x1d, 0x91, 0xc9, 0x79, 0xc9, 0xe4, 0x0c, 0x39, - 0xad, 0xc5, 0x24, 0x00, 0x1d, 0x13, 0x49, 0x7a, 0x88, 0xfb, 0x15, 0xa1, 0x26, 0xe2, 0x14, 0x8d, - 0x67, 0x5e, 0x90, 0x88, 0x57, 0xc8, 0x72, 0x2a, 0xe2, 0x88, 0x26, 0xb5, 0xb6, 0xa5, 0x0c, 0xde, - 0x09, 0xc6, 0xfe, 0x4c, 0x24, 0xd2, 0xaa, 0xeb, 0xea, 0xe0, 0x4e, 0x55, 0xb2, 0x3a, 0xb8, 0xd3, - 0xb5, 0xa9, 0xb9, 0x2c, 0x71, 0x9b, 0x64, 0x71, 0x18, 0x6e, 0xf2, 0x27, 0x03, 0x66, 0x13, 0xb2, - 0x4d, 0x67, 0x89, 0x1c, 0xa8, 0x2f, 0x75, 0x96, 0xc8, 0xc1, 0xca, 0x73, 0xc8, 0x10, 0x49, 0x8a, - 0x52, 0xf2, 0x0b, 0x03, 0x26, 0x94, 0xd8, 0x23, 0x05, 0xad, 0x7e, 0x63, 0x7a, 0x33, 0x77, 0x69, - 0x24, 0x1f, 0x84, 0xb8, 0x24, 0x21, 0xbe, 0x4e, 0x8e, 0xa5, 0x42, 0x54, 0x92, 0x93, 0xfc, 0xc5, - 0x80, 0x83, 0x7d, 0x62, 0x92, 0x5c, 0xd3, 0x58, 0xd1, 0x06, 0x68, 0xd4, 0xdc, 0xf5, 0x5d, 0xf9, - 0x22, 0xe6, 0xab, 0x12, 0xf3, 0x25, 0x72, 0x31, 0x8a, 0xb9, 0xff, 0x24, 0x86, 0xb7, 0xd8, 0x27, - 0x09, 0x85, 0x4b, 0xfe, 0x66, 0xc0, 0xc1, 0x3e, 0x21, 0xa9, 0xc3, 0x64, 0x90, 0x92, 0xd5, 0x61, - 0x32, 0x50, 0xb9, 0x9a, 0x77, 0x24, 0x93, 0x9b, 0xe4, 0x7a, 0x7a, 0x0d, 0x95, 0xea, 0x27, 0x59, - 0x42, 0x13, 0xb2, 0x79, 0x27, 0x90, 0x36, 0x64, 0x8d, 0x8a, 0x84, 0xa4, 0x24, 0x7a, 0xf3, 0x2d, - 0x45, 0xed, 0xea, 0x94, 0xaa, 0x01, 0xfa, 0xd5, 0x2c, 0x48, 0x42, 0xe7, 0xc8, 0xca, 0xc0, 0x45, - 0xd1, 0x76, 0xdd, 0x8a, 0xe2, 0xe0, 0x23, 0xd0, 0x6f, 0x0c, 0x38, 0x2c, 0x83, 0xf1, 0x84, 0x12, - 0x24, 0x37, 0xb5, 0x73, 0x9b, 0x26, 0x4b, 0x73, 0xef, 0xec, 0xd6, 0x1d, 0xc9, 0xac, 0x4b, 0x32, - 0x45, 0x72, 0x3b, 0xfb, 0xed, 0xa8, 0x29, 0x6c, 0x7b, 0x75, 0x75, 0x70, 0x10, 0xa9, 0x54, 0xd6, - 0xb6, 0x6c, 0xd9, 0x21, 0x5f, 0x1a, 0x70, 0x20, 0xf6, 0x09, 0x9a, 0x7c, 0x4b, 0x6b, 0xb2, 0xf6, - 0x7d, 0xc9, 0xcf, 0x5d, 0x1e, 0xd9, 0x0f, 0xc9, 0xdc, 0x92, 0x64, 0xae, 0x92, 0xcb, 0x03, 0xdf, - 0x8c, 0xe0, 0x3c, 0xd4, 0x9b, 0xd6, 0x76, 0xf2, 0xfb, 0xfa, 0x0e, 0xf9, 0xe5, 0x18, 0x2c, 0x64, - 0x7f, 0x46, 0x27, 0x6b, 0x23, 0x82, 0x1b, 0x74, 0x28, 0x90, 0x5b, 0x7f, 0xf1, 0x40, 0x48, 0xbb, - 0x2a, 0x69, 0x7f, 0x44, 0x1e, 0xeb, 0xd0, 0xae, 0xb4, 0xe4, 0xd7, 0x76, 0xa7, 0x66, 0xbb, 0xd6, - 0x76, 0xea, 0xa9, 0xc4, 0x4e, 0x5a, 0x66, 0x3e, 0x37, 0xe4, 0xa9, 0x0d, 0xb1, 0xf4, 0x50, 0x77, - 0x0f, 0x81, 0x72, 0x17, 0xf4, 0x1d, 0x90, 0xce, 0xa2, 0xa4, 0x93, 0x23, 0x47, 0x53, 0xe9, 0x04, - 0x20, 0x7e, 0x6d, 0x00, 0xf4, 0xce, 0x0d, 0x88, 0x46, 0x51, 0xe8, 0x3b, 0xc8, 0xc8, 0xbd, 0x35, - 0x9a, 0x13, 0x62, 0x3b, 0x23, 0xb1, 0x9d, 0x24, 0x27, 0x52, 0xb1, 0x89, 0x1e, 0xa6, 0xdf, 0x1b, - 0x30, 0x17, 0x3b, 0x38, 0x0b, 0x74, 0x85, 0xde, 0xa2, 0x93, 0x76, 0x54, 0x9a, 0xbb, 0xb6, 0x1b, - 0x57, 0x04, 0xbd, 0x22, 0x41, 0x9f, 0x22, 0x66, 0x2a, 0xe8, 0xf8, 0x79, 0xe6, 0x5f, 0x0d, 0x98, - 0x4f, 0x3b, 0x43, 0xd4, 0x59, 0xa7, 0x32, 0x8e, 0x2e, 0x75, 0xd6, 0xa9, 0xac, 0xa3, 0x4b, 0xf3, - 0x6d, 0xc9, 0xc1, 0x22, 0xe7, 0x87, 0x73, 0x48, 0xc8, 0xe8, 0xd8, 0xd1, 0xf6, 0x08, 0x1a, 0x3a, - 0x9e, 0xff, 0x2b, 0xa3, 0x3b, 0x6a, 0x29, 0xd2, 0x5a, 0xcf, 0x23, 0xa6, 0x48, 0x23, 0x91, 0xf4, - 0x15, 0xe9, 0xee, 0x70, 0xa7, 0xff, 0xaf, 0x60, 0x88, 0x22, 0x8d, 0xe0, 0x2e, 0xde, 0xfb, 0xea, - 0xd9, 0x82, 0xf1, 0xf5, 0xb3, 0x05, 0xe3, 0x9b, 0x67, 0x0b, 0xc6, 0xcf, 0x9e, 0x2f, 0xec, 0xfb, - 0xfa, 0xf9, 0xc2, 0xbe, 0x7f, 0x3e, 0x5f, 0xd8, 0xf7, 0xd8, 0x6a, 0x3a, 0xa2, 0xb5, 0x55, 0xcd, - 0xd7, 0xd8, 0x66, 0xaa, 0x8e, 0xf9, 0x34, 0x32, 0x77, 0x3a, 0x6d, 0xca, 0xab, 0x13, 0xf2, 0xef, - 0x1f, 0x97, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0x19, 0xf9, 0xb3, 0x69, 0xbe, 0x24, 0x00, 0x00, + // 2286 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x5a, 0xcf, 0x6f, 0xdc, 0xc6, + 0xf5, 0x37, 0xa5, 0x44, 0x91, 0x9e, 0x6c, 0xfd, 0x18, 0xcb, 0xb6, 0xb2, 0x76, 0x64, 0x99, 0x92, + 0x63, 0x59, 0xb1, 0x97, 0x96, 0xec, 0x7c, 0xfd, 0x3b, 0xb6, 0xd6, 0xdf, 0x48, 0xb2, 0x93, 0xd8, + 0xce, 0xae, 0xdb, 0x00, 0x46, 0xda, 0x2d, 0x77, 0x77, 0x76, 0x97, 0x35, 0xc5, 0xd9, 0x70, 0x46, + 0x4e, 0x36, 0xaa, 0x80, 0xa2, 0xb7, 0xe6, 0x50, 0x14, 0x28, 0xd0, 0xde, 0x8a, 0x5e, 0x72, 0x2c, + 0x50, 0x04, 0x28, 0x5a, 0xa0, 0xe8, 0x21, 0xa7, 0xa6, 0x40, 0x0f, 0x29, 0x0a, 0xb4, 0x3d, 0xb5, + 0x81, 0xdd, 0x3f, 0xa4, 0xe0, 0xf0, 0x71, 0x97, 0xe4, 0x92, 0xdc, 0x59, 0x59, 0x3d, 0xed, 0x72, + 0x38, 0xef, 0xcd, 0xe7, 0xf3, 0x38, 0xf3, 0xde, 0x87, 0x33, 0x84, 0x33, 0x9f, 0x52, 0x61, 0x56, + 0x9b, 0xa6, 0xe5, 0x18, 0xf2, 0x1f, 0x73, 0xa9, 0xc1, 0x2a, 0x9c, 0xba, 0x4f, 0xa9, 0x6b, 0x7c, + 0xb4, 0x4d, 0xdd, 0x76, 0xbe, 0xe5, 0x32, 0xc1, 0xc8, 0xf1, 0x4e, 0xc7, 0x7c, 0xd0, 0x31, 0x1f, + 0x74, 0xcc, 0x2d, 0x57, 0x19, 0xdf, 0x62, 0xdc, 0xa8, 0x98, 0x9c, 0xfa, 0x56, 0xc6, 0xd3, 0x95, + 0x0a, 0x15, 0xe6, 0x8a, 0xd1, 0x32, 0x1b, 0x96, 0x63, 0x0a, 0x8b, 0x39, 0xbe, 0xa3, 0xdc, 0x4c, + 0x83, 0x35, 0x98, 0xfc, 0x6b, 0x78, 0xff, 0xb0, 0xf5, 0x44, 0x83, 0xb1, 0x86, 0x4d, 0x0d, 0xb3, + 0x65, 0x19, 0xa6, 0xe3, 0x30, 0x21, 0x4d, 0x38, 0xde, 0x5d, 0xca, 0x42, 0x59, 0x31, 0x6d, 0x9b, + 0x09, 0xec, 0x99, 0xc9, 0xa7, 0x62, 0x9b, 0x5b, 0x14, 0x3b, 0xe6, 0xb3, 0x3a, 0xca, 0xf6, 0xb2, + 0xc3, 0x9c, 0x2a, 0x0d, 0x20, 0xac, 0x66, 0xf6, 0x77, 0x19, 0xe7, 0xbe, 0x51, 0xdd, 0x36, 0x1b, + 0x4a, 0xb0, 0x9f, 0xd0, 0x76, 0x83, 0x3a, 0x2a, 0x68, 0x1c, 0x56, 0xa3, 0x65, 0xb3, 0x5a, 0x65, + 0xdb, 0x4e, 0x40, 0x73, 0x39, 0xab, 0x7f, 0xf0, 0x47, 0x05, 0x45, 0xcb, 0x74, 0xcd, 0xad, 0x00, + 0xef, 0x85, 0xcc, 0x9e, 0xd4, 0xa9, 0x59, 0x4e, 0x23, 0x1a, 0x95, 0xd3, 0x59, 0x16, 0x82, 0xf3, + 0x0c, 0xb8, 0xad, 0x27, 0x0d, 0x3f, 0xce, 0x1c, 0x7f, 0xfa, 0xf4, 0x6d, 0xb9, 0x8c, 0xd5, 0x39, + 0xfe, 0x60, 0xdf, 0x4b, 0x7d, 0x86, 0x2f, 0xd7, 0xb7, 0x9d, 0x1a, 0x2f, 0x6f, 0x59, 0x0d, 0xd7, + 0x14, 0x0c, 0x03, 0xa2, 0x9f, 0x86, 0x85, 0xf7, 0xbd, 0x39, 0xfa, 0x88, 0xf3, 0x75, 0xef, 0xfe, + 0x7b, 0x78, 0xfb, 0xae, 0x53, 0x67, 0x6b, 0xb6, 0x5d, 0xa4, 0x1f, 0x6d, 0x53, 0x2e, 0xf4, 0x9f, + 0x68, 0xb0, 0x98, 0xdd, 0x8f, 0xb7, 0x98, 0xc3, 0x29, 0xa9, 0xc3, 0xe1, 0xde, 0xb1, 0xf8, 0xac, + 0x36, 0x3f, 0xbc, 0x34, 0xbe, 0x7a, 0x21, 0x9f, 0xb1, 0x70, 0xf2, 0xe8, 0x3a, 0xec, 0xb9, 0xf0, + 0xd2, 0x57, 0xff, 0x3a, 0x79, 0xa0, 0x38, 0x2d, 0x62, 0xa3, 0x72, 0xfd, 0x26, 0xcc, 0xa7, 0xe2, + 0x41, 0xd0, 0xe4, 0x55, 0x18, 0xf5, 0xe7, 0xa1, 0x55, 0x9b, 0xd5, 0xe6, 0xb5, 0xa5, 0xe1, 0xe2, + 0x2b, 0xf2, 0xfa, 0x6e, 0x4d, 0xff, 0xb1, 0x06, 0xa7, 0x32, 0xec, 0x91, 0x4c, 0x0d, 0x48, 0x2f, + 0x19, 0xe9, 0x6a, 0xef, 0x5c, 0xa6, 0xe2, 0x5c, 0xf4, 0x55, 0xc8, 0x49, 0x28, 0x1b, 0x54, 0xdc, + 0xf1, 0xdc, 0xdd, 0x97, 0x93, 0x2a, 0x20, 0x31, 0x03, 0x2f, 0x5b, 0x4e, 0x8d, 0x7e, 0x22, 0x87, + 0x1d, 0x2b, 0xfa, 0x17, 0x3a, 0x83, 0xe3, 0x89, 0x36, 0x08, 0xfc, 0x21, 0x8c, 0x87, 0x9a, 0x11, + 0xf1, 0x52, 0x26, 0xe2, 0x50, 0x7f, 0x44, 0x1a, 0x76, 0xa1, 0xd7, 0x10, 0xe4, 0x9a, 0x6d, 0x27, + 0x80, 0x5c, 0x07, 0xe8, 0xe6, 0x36, 0x1c, 0xee, 0xf5, 0xbc, 0x9f, 0x08, 0xf3, 0x5e, 0x22, 0xcc, + 0xfb, 0xe9, 0x13, 0x13, 0x61, 0xfe, 0xa1, 0xd9, 0xa0, 0x68, 0x5b, 0x0c, 0x59, 0xea, 0xbf, 0xd7, + 0x90, 0x57, 0x7c, 0x98, 0x34, 0x5e, 0xc3, 0x2f, 0xc8, 0x8b, 0x6c, 0x44, 0x90, 0x0f, 0x49, 0xe4, + 0x67, 0xfa, 0x22, 0xf7, 0xe1, 0x44, 0xa0, 0xd7, 0xe1, 0x44, 0x80, 0xfc, 0xa1, 0x9f, 0x1d, 0xfe, + 0x37, 0x21, 0xfa, 0x52, 0x83, 0xd7, 0x52, 0x06, 0xc2, 0x20, 0x7d, 0x00, 0x13, 0xd1, 0xfc, 0x84, + 0x71, 0x5a, 0xce, 0x8c, 0x53, 0xc4, 0x17, 0x46, 0xea, 0x50, 0x2b, 0xdc, 0xb8, 0x7f, 0xb1, 0x0a, + 0x16, 0x6f, 0x74, 0xcc, 0xb6, 0x7c, 0x2e, 0x0a, 0x8b, 0xf7, 0x07, 0xb8, 0x76, 0x93, 0xcd, 0x33, + 0xa2, 0xa0, 0xed, 0x43, 0x14, 0xf4, 0x19, 0x20, 0xc1, 0xd2, 0x7b, 0x54, 0x2a, 0x05, 0x09, 0xf2, + 0x01, 0x1c, 0x8e, 0xb4, 0x22, 0x8a, 0x2b, 0x30, 0xfc, 0xa8, 0x54, 0xc2, 0xa1, 0xe7, 0xb3, 0x53, + 0x46, 0xa9, 0x84, 0x03, 0x7a, 0x26, 0xfa, 0xdb, 0xf0, 0x6a, 0xc7, 0x21, 0xe7, 0x6b, 0xb5, 0x9a, + 0x4b, 0x79, 0x67, 0x32, 0x2d, 0xc1, 0x54, 0xc5, 0x12, 0x55, 0x66, 0x39, 0xe5, 0x4e, 0x90, 0x86, + 0x64, 0x90, 0x26, 0xb0, 0xfd, 0x0e, 0xc6, 0xea, 0x76, 0x37, 0xb9, 0x84, 0xdd, 0x20, 0xbc, 0x29, + 0x18, 0xa6, 0xa2, 0x89, 0xa9, 0xc5, 0xfb, 0xeb, 0xb5, 0x54, 0x44, 0x55, 0x3a, 0x1b, 0x2b, 0x7a, + 0x7f, 0xf5, 0xcf, 0x34, 0x58, 0xee, 0x75, 0x51, 0x68, 0xaf, 0x5b, 0x8e, 0x69, 0x5b, 0x9f, 0xd2, + 0xda, 0x26, 0xb5, 0x1a, 0x4d, 0x11, 0x40, 0x5b, 0x85, 0x23, 0xf5, 0xe0, 0x4e, 0xd9, 0x63, 0x59, + 0x6e, 0xca, 0xfb, 0xf8, 0x10, 0x0f, 0x77, 0x6e, 0x3e, 0xa6, 0xc2, 0xf4, 0x4d, 0x07, 0xa0, 0xf3, + 0x3e, 0xbc, 0xa1, 0x84, 0x65, 0x00, 0x7e, 0xdf, 0x83, 0xa3, 0x41, 0x25, 0xd8, 0xb4, 0xb8, 0x60, + 0x6e, 0x7b, 0xbf, 0x97, 0xec, 0xe7, 0x1a, 0x1c, 0xeb, 0x19, 0x02, 0x11, 0xae, 0xc1, 0xa8, 0x57, + 0x62, 0x6c, 0x8b, 0x0b, 0x5c, 0xa6, 0xaa, 0xb3, 0xe4, 0x15, 0xc1, 0xf9, 0xbb, 0x16, 0x17, 0xfb, + 0xb7, 0x2c, 0x9b, 0x30, 0x23, 0x61, 0x6e, 0x9a, 0xfc, 0xdb, 0x4c, 0xd0, 0x5a, 0x10, 0x87, 0x37, + 0x60, 0xda, 0xd7, 0x95, 0x65, 0xab, 0x46, 0x1d, 0x61, 0xd5, 0x2d, 0xea, 0x62, 0x4c, 0xa7, 0xfc, + 0x1b, 0x77, 0x3b, 0xed, 0x64, 0x01, 0x0e, 0x3d, 0x65, 0x82, 0xba, 0x65, 0xd3, 0x7f, 0x38, 0x18, + 0xea, 0x83, 0xb2, 0x11, 0x1f, 0x98, 0x7e, 0x09, 0x8e, 0xc4, 0x46, 0xc2, 0x70, 0x1c, 0x87, 0xb1, + 0xa6, 0xc9, 0xcb, 0x5e, 0x67, 0x7f, 0xd9, 0x8f, 0x16, 0x47, 0x9b, 0xd8, 0x49, 0x7f, 0x0f, 0xe6, + 0xa4, 0x55, 0x41, 0x8e, 0x59, 0x68, 0x77, 0x47, 0xdd, 0x0b, 0x52, 0x5d, 0xc0, 0x98, 0xe7, 0xd7, + 0x95, 0x41, 0xec, 0x81, 0xad, 0xf5, 0xc2, 0x26, 0x05, 0x18, 0xf3, 0xae, 0xcb, 0xa2, 0xdd, 0xa2, + 0x92, 0xd7, 0xc4, 0xea, 0xe9, 0xcc, 0xa7, 0xe5, 0xf9, 0x7f, 0xd4, 0x6e, 0xd1, 0xe2, 0xe8, 0x53, + 0xfc, 0xa7, 0xff, 0x6e, 0x08, 0x4e, 0xa6, 0xb2, 0xc0, 0x28, 0x0c, 0x14, 0xf0, 0xb7, 0x60, 0x44, + 0x82, 0xf4, 0x22, 0x3d, 0x2c, 0x67, 0x68, 0x3f, 0x44, 0x92, 0x71, 0x11, 0xad, 0xc8, 0x07, 0x30, + 0xe5, 0xdf, 0x95, 0x93, 0xc0, 0xe7, 0x36, 0x2c, 0xb9, 0x9d, 0xcb, 0xf4, 0xf4, 0xa0, 0x6b, 0x24, + 0x29, 0x4e, 0xb2, 0x68, 0x03, 0xb9, 0x0f, 0x87, 0x90, 0x05, 0x17, 0xa6, 0xd8, 0xe6, 0xb3, 0x2f, + 0x49, 0xaf, 0x67, 0x33, 0xbd, 0xfa, 0x51, 0x29, 0x49, 0x83, 0xe2, 0xc1, 0x4a, 0xe8, 0x4a, 0x27, + 0x30, 0x25, 0x03, 0xf7, 0x00, 0xfb, 0x96, 0xa8, 0xd0, 0xaf, 0xc0, 0x6c, 0xbc, 0xad, 0x13, 0xc5, + 0x13, 0x30, 0x16, 0xb8, 0xf5, 0x4b, 0xe0, 0x58, 0xb1, 0xdb, 0xa0, 0x1f, 0xc5, 0xc9, 0x5e, 0xda, + 0x6e, 0xb5, 0x98, 0x2b, 0x68, 0x4d, 0xa6, 0x18, 0xae, 0x7f, 0x88, 0x75, 0x3c, 0xd6, 0xde, 0xf1, + 0x7a, 0x03, 0x46, 0x7c, 0x89, 0x8e, 0xcb, 0x75, 0x31, 0x89, 0x4e, 0xeb, 0x49, 0x23, 0x8f, 0x42, + 0xde, 0xaf, 0x4a, 0x68, 0xa3, 0xdf, 0x02, 0x3d, 0xa2, 0xdb, 0x1e, 0xca, 0x57, 0x8e, 0x75, 0xe6, + 0xaa, 0xd6, 0x3e, 0x17, 0xf5, 0x7a, 0x9a, 0x03, 0x44, 0xf9, 0x0e, 0x1c, 0xf4, 0x3d, 0xf8, 0xef, + 0x34, 0xea, 0x0a, 0xd0, 0xf7, 0x57, 0x1c, 0xaf, 0x76, 0x2f, 0xf4, 0x13, 0x31, 0x81, 0x8a, 0x7d, + 0xb0, 0xf2, 0x39, 0x31, 0x29, 0x1a, 0xdc, 0x45, 0x24, 0x0f, 0x12, 0x91, 0x9c, 0x53, 0x45, 0x22, + 0xa7, 0x6a, 0x04, 0x4d, 0x48, 0x2e, 0xdf, 0x67, 0x35, 0xba, 0xe6, 0xbf, 0x0b, 0x66, 0xcb, 0xe5, + 0xef, 0x77, 0x31, 0x46, 0x6c, 0xba, 0xd1, 0x0a, 0xbf, 0x57, 0x2a, 0x45, 0x2b, 0xec, 0x67, 0xdc, + 0xe9, 0x5e, 0x84, 0x95, 0x72, 0x02, 0xbe, 0xfd, 0xaa, 0x29, 0x5f, 0x84, 0x94, 0x72, 0x12, 0xa5, + 0x7b, 0x30, 0x1e, 0x6a, 0x56, 0x52, 0xca, 0x11, 0x46, 0xa1, 0x8b, 0xfd, 0x2b, 0x30, 0xf3, 0x98, + 0xc0, 0xbd, 0xa9, 0xd2, 0xd9, 0x25, 0x58, 0xb7, 0xcd, 0x46, 0x67, 0x32, 0xfd, 0x50, 0xc3, 0xec, + 0x98, 0xd4, 0x05, 0xa9, 0x7d, 0x07, 0xa6, 0xe2, 0x7b, 0x0c, 0x6a, 0xb3, 0x2a, 0xea, 0x0f, 0xcb, + 0xe8, 0x64, 0x35, 0xda, 0xac, 0x1f, 0xc3, 0xda, 0xb4, 0x41, 0xc5, 0x3b, 0x72, 0x5b, 0x22, 0xc0, + 0xf6, 0x2d, 0x14, 0x0a, 0xa1, 0x1b, 0x88, 0xe8, 0x3a, 0x8c, 0xf8, 0x3b, 0x18, 0x88, 0x63, 0x21, + 0x13, 0x07, 0x1a, 0xa3, 0x89, 0x7e, 0x12, 0xf5, 0x7c, 0xa9, 0xc9, 0x3e, 0x0e, 0xd2, 0xd8, 0x9d, + 0xd0, 0x94, 0xf1, 0x62, 0x32, 0x97, 0xd6, 0x03, 0x01, 0x7c, 0x17, 0x0e, 0xdb, 0x26, 0x17, 0xe5, + 0x60, 0x8c, 0x72, 0x78, 0x1e, 0xe7, 0x33, 0xd1, 0xbc, 0x6b, 0x72, 0x11, 0x75, 0x3a, 0x6d, 0xc7, + 0x9b, 0xf4, 0x7b, 0x88, 0xb1, 0x60, 0x9b, 0x5b, 0x34, 0xa9, 0xf0, 0x9e, 0x85, 0x29, 0xb9, 0xa1, + 0xd4, 0x5b, 0xb0, 0x26, 0x65, 0x7b, 0xa8, 0xec, 0x56, 0x83, 0x2a, 0xde, 0xeb, 0xab, 0xa3, 0x89, + 0x00, 0x9d, 0x39, 0x75, 0x86, 0x24, 0xf4, 0xec, 0xaa, 0xe1, 0x75, 0x2f, 0x8e, 0xf9, 0x43, 0x39, + 0x75, 0xa6, 0xd3, 0xee, 0xea, 0xf0, 0xef, 0xd1, 0x2a, 0x73, 0x6b, 0xfb, 0xfe, 0x32, 0xf6, 0x1b, + 0xad, 0xfb, 0xd6, 0x17, 0x1d, 0x07, 0xa9, 0x6c, 0xc4, 0xa8, 0x0c, 0xab, 0x51, 0xc1, 0xb9, 0xd9, + 0x25, 0xb4, 0x7f, 0x6b, 0xb0, 0x84, 0xef, 0x5e, 0x18, 0x7e, 0x99, 0x6a, 0xd7, 0x9c, 0x9a, 0x7c, + 0xb9, 0xe9, 0x5f, 0x7f, 0xbc, 0xfc, 0x2a, 0x5f, 0xa7, 0x50, 0x9f, 0xfb, 0x17, 0x7a, 0x1d, 0xdf, + 0xc8, 0x92, 0x9d, 0xa6, 0x3c, 0xd6, 0xe1, 0x81, 0x1f, 0xeb, 0xea, 0xe7, 0x8b, 0xf0, 0xb2, 0x1c, + 0x88, 0xfc, 0x51, 0x83, 0xd1, 0x40, 0x3d, 0x92, 0x95, 0x4c, 0x2f, 0x49, 0x9a, 0x36, 0xb7, 0x3a, + 0x88, 0x89, 0x4f, 0x40, 0xbf, 0xf7, 0xa3, 0xbf, 0xfd, 0xe7, 0x67, 0x43, 0xff, 0x4f, 0x0a, 0x72, + 0x83, 0xed, 0xbc, 0xbf, 0xd7, 0xd6, 0xd9, 0x62, 0xeb, 0xe8, 0x56, 0x63, 0xa7, 0x47, 0xbc, 0xed, + 0x1a, 0x3b, 0x11, 0x75, 0xb9, 0x4b, 0xfe, 0xae, 0x01, 0xe9, 0x55, 0x80, 0xe4, 0x7a, 0x7f, 0x58, + 0xa9, 0xea, 0x37, 0x77, 0x63, 0x6f, 0xc6, 0xc8, 0xee, 0x6d, 0xc9, 0xee, 0x16, 0xb9, 0x99, 0xc8, + 0x0e, 0x29, 0x55, 0xda, 0x21, 0x56, 0x49, 0x44, 0xc9, 0x2f, 0x35, 0x18, 0x0f, 0xa9, 0x31, 0x72, + 0xbe, 0x3f, 0xa8, 0x50, 0xf7, 0xdc, 0x9b, 0x03, 0x75, 0xef, 0x80, 0x3f, 0x2b, 0xc1, 0x2f, 0x90, + 0x53, 0x89, 0xe0, 0x3b, 0x69, 0x91, 0x53, 0x41, 0x7e, 0xad, 0xc1, 0x64, 0x4c, 0xdc, 0xa9, 0x4c, + 0xa0, 0x98, 0x49, 0xee, 0xea, 0xc0, 0x26, 0x1d, 0xb0, 0xe7, 0x24, 0xd8, 0xd7, 0xc9, 0x62, 0x22, + 0x58, 0x1e, 0xc3, 0xf6, 0x6f, 0x0d, 0x8e, 0x26, 0xab, 0x3d, 0x72, 0xab, 0x3f, 0x86, 0x4c, 0xa1, + 0x99, 0xbb, 0xbd, 0x77, 0x07, 0xc8, 0xa5, 0x20, 0xb9, 0xdc, 0x20, 0xd7, 0x12, 0xb9, 0x34, 0xa8, + 0x28, 0x87, 0xd5, 0x5f, 0xb9, 0xce, 0x5c, 0xbf, 0xc1, 0xd8, 0x09, 0x32, 0xcc, 0x2e, 0xf9, 0x42, + 0x83, 0x89, 0xe8, 0x30, 0xe4, 0xf2, 0xa0, 0xc0, 0x02, 0x46, 0x57, 0x06, 0x37, 0x44, 0x26, 0xe7, + 0x25, 0x93, 0x33, 0xe4, 0xb4, 0x12, 0x13, 0x0f, 0x74, 0x44, 0x24, 0xa9, 0x21, 0xee, 0x55, 0x84, + 0x8a, 0x88, 0x13, 0x34, 0x9e, 0x7e, 0x41, 0x22, 0x5e, 0x26, 0x4b, 0x89, 0x88, 0x43, 0x9a, 0xd4, + 0xd8, 0x91, 0x32, 0x78, 0xd7, 0x9b, 0xfb, 0x13, 0x21, 0x4f, 0x6b, 0xb6, 0xad, 0x82, 0x3b, 0x51, + 0xc9, 0xaa, 0xe0, 0x4e, 0xd6, 0xa6, 0xfa, 0x92, 0xc4, 0xad, 0x93, 0xf9, 0x7e, 0xb8, 0xc9, 0x1f, + 0x34, 0x98, 0x8c, 0xc9, 0x36, 0x95, 0x14, 0x99, 0xaa, 0x2f, 0x55, 0x52, 0x64, 0xba, 0xf2, 0xec, + 0x33, 0x45, 0xe2, 0xa2, 0x94, 0xfc, 0x5c, 0x83, 0x11, 0x5f, 0xec, 0x91, 0x55, 0xa5, 0x71, 0x23, + 0x7a, 0x33, 0x77, 0x71, 0x20, 0x1b, 0x84, 0xb8, 0x20, 0x21, 0xbe, 0x46, 0x8e, 0x27, 0x42, 0xf4, + 0x25, 0x27, 0xf9, 0x93, 0x06, 0xd3, 0x3d, 0x62, 0x92, 0x5c, 0x53, 0xc8, 0x68, 0x29, 0x1a, 0x35, + 0x77, 0x7d, 0x4f, 0xb6, 0x88, 0xf9, 0xaa, 0xc4, 0x7c, 0x91, 0xac, 0x84, 0x31, 0xf7, 0x9e, 0x61, + 0xf1, 0x26, 0xfb, 0x38, 0xa6, 0x70, 0xc9, 0x5f, 0x35, 0x98, 0xee, 0x11, 0x92, 0x2a, 0x4c, 0xd2, + 0x94, 0xac, 0x0a, 0x93, 0x54, 0xe5, 0xaa, 0xdf, 0x91, 0x4c, 0x6e, 0x92, 0xeb, 0xc9, 0x35, 0x54, + 0xaa, 0x9f, 0x78, 0x09, 0x8d, 0xc9, 0xe6, 0x5d, 0x4f, 0xda, 0x90, 0x0d, 0x2a, 0x62, 0x92, 0x92, + 0xa8, 0xad, 0xb7, 0x04, 0xb5, 0xab, 0x52, 0xaa, 0x52, 0xf4, 0xab, 0xbe, 0x2a, 0x09, 0x9d, 0x23, + 0xcb, 0xa9, 0x49, 0xd1, 0xb4, 0xed, 0xb2, 0xcf, 0xc1, 0x45, 0xa0, 0xdf, 0x68, 0x70, 0x44, 0x3a, + 0xe3, 0x31, 0x25, 0x48, 0x6e, 0x2a, 0xc7, 0x36, 0x49, 0x96, 0xe6, 0xde, 0xda, 0xab, 0x39, 0x92, + 0xd9, 0x94, 0x64, 0x0a, 0xe4, 0x76, 0xf6, 0xd3, 0xf1, 0x97, 0xb0, 0xe9, 0xd4, 0xfc, 0x83, 0x83, + 0x50, 0xa5, 0x32, 0x76, 0x64, 0xcb, 0x2e, 0xf9, 0x52, 0x83, 0x43, 0x91, 0x2d, 0x68, 0xf2, 0x7f, + 0x4a, 0x8b, 0xb5, 0x67, 0x27, 0x3f, 0x77, 0x79, 0x60, 0x3b, 0x24, 0x73, 0x4b, 0x92, 0xb9, 0x4a, + 0x2e, 0xa7, 0x3e, 0x19, 0xc1, 0x79, 0xa0, 0x37, 0x8d, 0x9d, 0xf8, 0xfe, 0xfa, 0x2e, 0xf9, 0xc5, + 0x10, 0xcc, 0x65, 0x6f, 0xa3, 0x93, 0x8d, 0x01, 0xc1, 0xa5, 0x1d, 0x0a, 0xe4, 0x36, 0x5f, 0xdc, + 0x11, 0xd2, 0xae, 0x48, 0xda, 0x1f, 0x92, 0xc7, 0x2a, 0xb4, 0xcb, 0x4d, 0xb9, 0xdb, 0x6e, 0x55, + 0x4d, 0xdb, 0xd8, 0x49, 0x3c, 0x95, 0xd8, 0x4d, 0x8a, 0xcc, 0x67, 0x9a, 0x3c, 0xb5, 0x21, 0x86, + 0x1a, 0xea, 0xce, 0x21, 0x50, 0xee, 0x82, 0xba, 0x01, 0xd2, 0x99, 0x97, 0x74, 0x72, 0x64, 0x36, + 0x91, 0x8e, 0x07, 0xe2, 0x57, 0x1a, 0x40, 0xf7, 0xdc, 0x80, 0x28, 0x14, 0x85, 0x9e, 0x83, 0x8c, + 0xdc, 0xa5, 0xc1, 0x8c, 0x10, 0xdb, 0x19, 0x89, 0xed, 0x14, 0x39, 0x99, 0x88, 0x4d, 0x74, 0x31, + 0xfd, 0x56, 0x83, 0xa9, 0xc8, 0xc1, 0x99, 0xa7, 0x2b, 0xd4, 0x92, 0x4e, 0xd2, 0x51, 0x69, 0xee, + 0xda, 0x5e, 0x4c, 0x11, 0xf4, 0xb2, 0x04, 0xbd, 0x48, 0xf4, 0x44, 0xd0, 0xd1, 0xf3, 0xcc, 0xbf, + 0x68, 0x30, 0x93, 0x74, 0x86, 0xa8, 0x92, 0xa7, 0x32, 0x8e, 0x2e, 0x55, 0xf2, 0x54, 0xd6, 0xd1, + 0xa5, 0xfe, 0xa6, 0xe4, 0x60, 0x90, 0xf3, 0xfd, 0x39, 0xc4, 0x64, 0x74, 0xe4, 0x68, 0x7b, 0x00, + 0x0d, 0x1d, 0x8d, 0xff, 0x95, 0xc1, 0x0d, 0x95, 0x14, 0x69, 0xb5, 0x6b, 0x11, 0x51, 0xa4, 0x21, + 0x4f, 0xea, 0x8a, 0x74, 0x6f, 0xb8, 0x93, 0xbf, 0x2b, 0xe8, 0xa3, 0x48, 0x43, 0xb8, 0xc9, 0x9f, + 0x35, 0x98, 0x49, 0xfa, 0x66, 0x44, 0x65, 0xce, 0x64, 0x7c, 0xab, 0xa2, 0x32, 0x67, 0xb2, 0x3e, + 0x55, 0x51, 0x28, 0xd4, 0xc1, 0x97, 0x2c, 0x9d, 0x0f, 0x59, 0xc8, 0x3f, 0x34, 0x38, 0x96, 0xf2, + 0x3d, 0x0f, 0xb9, 0xbd, 0x37, 0x3c, 0xdd, 0x4f, 0x86, 0x72, 0x6b, 0x2f, 0xe0, 0x01, 0x49, 0x5d, + 0x96, 0xa4, 0x56, 0x88, 0x91, 0xa9, 0x3e, 0x7a, 0x88, 0xf1, 0xc2, 0xdd, 0xaf, 0x9e, 0xcd, 0x69, + 0x5f, 0x3f, 0x9b, 0xd3, 0xbe, 0x79, 0x36, 0xa7, 0xfd, 0xf4, 0xf9, 0xdc, 0x81, 0xaf, 0x9f, 0xcf, + 0x1d, 0xf8, 0xe7, 0xf3, 0xb9, 0x03, 0x8f, 0x8d, 0x86, 0x25, 0x9a, 0xdb, 0x95, 0x7c, 0x95, 0x6d, + 0x25, 0xaa, 0xcd, 0x4f, 0x42, 0x19, 0xae, 0xdd, 0xa2, 0xbc, 0x32, 0x22, 0xbf, 0x93, 0xba, 0xf8, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf6, 0xe7, 0xf0, 0x62, 0x1d, 0x28, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2315,6 +2497,9 @@ type QueryClient interface { ChainNonces(ctx context.Context, in *QueryGetChainNoncesRequest, opts ...grpc.CallOption) (*QueryGetChainNoncesResponse, error) // Queries a list of chainNonces items. ChainNoncesAll(ctx context.Context, in *QueryAllChainNoncesRequest, opts ...grpc.CallOption) (*QueryAllChainNoncesResponse, error) + // Queries the TssFundMigratorInfo for a specific chain + TssFundsMigratorInfo(ctx context.Context, in *QueryTssFundsMigratorInfoRequest, opts ...grpc.CallOption) (*QueryTssFundsMigratorInfoResponse, error) + TssFundsMigratorInfoAll(ctx context.Context, in *QueryTssFundsMigratorInfoAllRequest, opts ...grpc.CallOption) (*QueryTssFundsMigratorInfoAllResponse, error) } type queryClient struct { @@ -2523,6 +2708,24 @@ func (c *queryClient) ChainNoncesAll(ctx context.Context, in *QueryAllChainNonce return out, nil } +func (c *queryClient) TssFundsMigratorInfo(ctx context.Context, in *QueryTssFundsMigratorInfoRequest, opts ...grpc.CallOption) (*QueryTssFundsMigratorInfoResponse, error) { + out := new(QueryTssFundsMigratorInfoResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/TssFundsMigratorInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) TssFundsMigratorInfoAll(ctx context.Context, in *QueryTssFundsMigratorInfoAllRequest, opts ...grpc.CallOption) (*QueryTssFundsMigratorInfoAllResponse, error) { + out := new(QueryTssFundsMigratorInfoAllResponse) + err := c.cc.Invoke(ctx, "/zetachain.zetacore.observer.Query/TssFundsMigratorInfoAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Query if a voter has voted for a ballot @@ -2563,6 +2766,9 @@ type QueryServer interface { ChainNonces(context.Context, *QueryGetChainNoncesRequest) (*QueryGetChainNoncesResponse, error) // Queries a list of chainNonces items. ChainNoncesAll(context.Context, *QueryAllChainNoncesRequest) (*QueryAllChainNoncesResponse, error) + // Queries the TssFundMigratorInfo for a specific chain + TssFundsMigratorInfo(context.Context, *QueryTssFundsMigratorInfoRequest) (*QueryTssFundsMigratorInfoResponse, error) + TssFundsMigratorInfoAll(context.Context, *QueryTssFundsMigratorInfoAllRequest) (*QueryTssFundsMigratorInfoAllResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -2635,6 +2841,12 @@ func (*UnimplementedQueryServer) ChainNonces(ctx context.Context, req *QueryGetC func (*UnimplementedQueryServer) ChainNoncesAll(ctx context.Context, req *QueryAllChainNoncesRequest) (*QueryAllChainNoncesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ChainNoncesAll not implemented") } +func (*UnimplementedQueryServer) TssFundsMigratorInfo(ctx context.Context, req *QueryTssFundsMigratorInfoRequest) (*QueryTssFundsMigratorInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TssFundsMigratorInfo not implemented") +} +func (*UnimplementedQueryServer) TssFundsMigratorInfoAll(ctx context.Context, req *QueryTssFundsMigratorInfoAllRequest) (*QueryTssFundsMigratorInfoAllResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method TssFundsMigratorInfoAll not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -3036,6 +3248,42 @@ func _Query_ChainNoncesAll_Handler(srv interface{}, ctx context.Context, dec fun return interceptor(ctx, in, info, handler) } +func _Query_TssFundsMigratorInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryTssFundsMigratorInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).TssFundsMigratorInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Query/TssFundsMigratorInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).TssFundsMigratorInfo(ctx, req.(*QueryTssFundsMigratorInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_TssFundsMigratorInfoAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryTssFundsMigratorInfoAllRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).TssFundsMigratorInfoAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/zetachain.zetacore.observer.Query/TssFundsMigratorInfoAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).TssFundsMigratorInfoAll(ctx, req.(*QueryTssFundsMigratorInfoAllRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "zetachain.zetacore.observer.Query", HandlerType: (*QueryServer)(nil), @@ -3128,12 +3376,20 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "ChainNoncesAll", Handler: _Query_ChainNoncesAll_Handler, }, + { + MethodName: "TssFundsMigratorInfo", + Handler: _Query_TssFundsMigratorInfo_Handler, + }, + { + MethodName: "TssFundsMigratorInfoAll", + Handler: _Query_TssFundsMigratorInfoAll_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "zetachain/zetacore/observer/query.proto", } -func (m *QueryGetChainNoncesRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryTssFundsMigratorInfoAllRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3143,27 +3399,20 @@ func (m *QueryGetChainNoncesRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryGetChainNoncesRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryTssFundsMigratorInfoAllRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGetChainNoncesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryTssFundsMigratorInfoAllRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Index) > 0 { - i -= len(m.Index) - copy(dAtA[i:], m.Index) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Index))) - i-- - dAtA[i] = 0xa - } return len(dAtA) - i, nil } -func (m *QueryGetChainNoncesResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryTssFundsMigratorInfoAllResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -3173,25 +3422,153 @@ func (m *QueryGetChainNoncesResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryGetChainNoncesResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryTssFundsMigratorInfoAllResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryGetChainNoncesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryTssFundsMigratorInfoAllResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - { - size, err := m.ChainNonces.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- + if len(m.TssFundsMigrators) > 0 { + for iNdEx := len(m.TssFundsMigrators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.TssFundsMigrators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryTssFundsMigratorInfoRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryTssFundsMigratorInfoRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryTssFundsMigratorInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ChainId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ChainId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryTssFundsMigratorInfoResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryTssFundsMigratorInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryTssFundsMigratorInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.TssFundsMigrator.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryGetChainNoncesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryGetChainNoncesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetChainNoncesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Index) > 0 { + i -= len(m.Index) + copy(dAtA[i:], m.Index) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Index))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetChainNoncesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryGetChainNoncesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetChainNoncesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.ChainNonces.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -4676,6 +5053,53 @@ func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *QueryTssFundsMigratorInfoAllRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryTssFundsMigratorInfoAllResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.TssFundsMigrators) > 0 { + for _, e := range m.TssFundsMigrators { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryTssFundsMigratorInfoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ChainId != 0 { + n += 1 + sovQuery(uint64(m.ChainId)) + } + return n +} + +func (m *QueryTssFundsMigratorInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.TssFundsMigrator.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func (m *QueryGetChainNoncesRequest) Size() (n int) { if m == nil { return 0 @@ -5294,6 +5718,292 @@ func sovQuery(x uint64) (n int) { func sozQuery(x uint64) (n int) { return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *QueryTssFundsMigratorInfoAllRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryTssFundsMigratorInfoAllRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryTssFundsMigratorInfoAllRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryTssFundsMigratorInfoAllResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryTssFundsMigratorInfoAllResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryTssFundsMigratorInfoAllResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TssFundsMigrators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TssFundsMigrators = append(m.TssFundsMigrators, TssFundMigratorInfo{}) + if err := m.TssFundsMigrators[len(m.TssFundsMigrators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryTssFundsMigratorInfoRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryTssFundsMigratorInfoRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryTssFundsMigratorInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainId", wireType) + } + m.ChainId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ChainId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryTssFundsMigratorInfoResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryTssFundsMigratorInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryTssFundsMigratorInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TssFundsMigrator", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TssFundsMigrator.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryGetChainNoncesRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/observer/types/query.pb.gw.go b/x/observer/types/query.pb.gw.go index fc62c63354..2b57b5014c 100644 --- a/x/observer/types/query.pb.gw.go +++ b/x/observer/types/query.pb.gw.go @@ -945,6 +945,60 @@ func local_request_Query_ChainNoncesAll_0(ctx context.Context, marshaler runtime } +var ( + filter_Query_TssFundsMigratorInfo_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_TssFundsMigratorInfo_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryTssFundsMigratorInfoRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_TssFundsMigratorInfo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.TssFundsMigratorInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_TssFundsMigratorInfo_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryTssFundsMigratorInfoRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_TssFundsMigratorInfo_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.TssFundsMigratorInfo(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_TssFundsMigratorInfoAll_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryTssFundsMigratorInfoAllRequest + var metadata runtime.ServerMetadata + + msg, err := client.TssFundsMigratorInfoAll(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_TssFundsMigratorInfoAll_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryTssFundsMigratorInfoAllRequest + var metadata runtime.ServerMetadata + + msg, err := server.TssFundsMigratorInfoAll(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -1457,6 +1511,52 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_TssFundsMigratorInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_TssFundsMigratorInfo_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_TssFundsMigratorInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_TssFundsMigratorInfoAll_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_TssFundsMigratorInfoAll_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_TssFundsMigratorInfoAll_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1938,6 +2038,46 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_TssFundsMigratorInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_TssFundsMigratorInfo_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_TssFundsMigratorInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_TssFundsMigratorInfoAll_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_TssFundsMigratorInfoAll_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_TssFundsMigratorInfoAll_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1985,6 +2125,10 @@ var ( pattern_Query_ChainNonces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"zeta-chain", "observer", "chainNonces", "index"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ChainNoncesAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "chainNonces"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_TssFundsMigratorInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_tss_fund_migrator"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_TssFundsMigratorInfoAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"zeta-chain", "observer", "get_all_tss_fund_migrators"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -2031,4 +2175,8 @@ var ( forward_Query_ChainNonces_0 = runtime.ForwardResponseMessage forward_Query_ChainNoncesAll_0 = runtime.ForwardResponseMessage + + forward_Query_TssFundsMigratorInfo_0 = runtime.ForwardResponseMessage + + forward_Query_TssFundsMigratorInfoAll_0 = runtime.ForwardResponseMessage ) From 635e11050022d3b9313170634f04b8b8e321ed60 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 21 Jun 2024 17:11:31 -0400 Subject: [PATCH 07/40] add changelog --- changelog.md | 1 + docs/openapi/openapi.swagger.yaml | 1 + proto/zetachain/zetacore/observer/query.proto | 1 + .../client/cli/query_tss_fund_migrator.go | 11 ++++++++-- .../grpc_query_tss_funds_migrator_info.go | 5 +++++ .../grpc_query_tss_funds_migrator_test.go | 21 +++++++++++++++---- x/observer/types/query.pb.go | 2 ++ 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index ba3c0ed790..a661ddfcef 100644 --- a/changelog.md +++ b/changelog.md @@ -28,6 +28,7 @@ * [2319](https://github.com/zeta-chain/node/pull/2319) - use `CheckAuthorization` function in all messages * [2325](https://github.com/zeta-chain/node/pull/2325) - revert telemetry server changes * [2339](https://github.com/zeta-chain/node/pull/2339) - add binaries related question to syncing issue form +* [2372](https://github.com/zeta-chain/node/pull/2372) - add queries for tss fund migration info ### Refactor diff --git a/docs/openapi/openapi.swagger.yaml b/docs/openapi/openapi.swagger.yaml index 90421a8b14..d85b3cec73 100644 --- a/docs/openapi/openapi.swagger.yaml +++ b/docs/openapi/openapi.swagger.yaml @@ -30172,6 +30172,7 @@ paths: - Query /zeta-chain/observer/get_all_tss_fund_migrators: get: + summary: Queries all TssFundMigratorInfo operationId: Query_TssFundsMigratorInfoAll responses: "200": diff --git a/proto/zetachain/zetacore/observer/query.proto b/proto/zetachain/zetacore/observer/query.proto index 79254de2d0..beb59ce6dd 100644 --- a/proto/zetachain/zetacore/observer/query.proto +++ b/proto/zetachain/zetacore/observer/query.proto @@ -157,6 +157,7 @@ service Query { option (google.api.http).get = "/zeta-chain/observer/get_tss_fund_migrator"; } + // Queries all TssFundMigratorInfo rpc TssFundsMigratorInfoAll(QueryTssFundsMigratorInfoAllRequest) returns (QueryTssFundsMigratorInfoAllResponse) { option (google.api.http).get = diff --git a/x/observer/client/cli/query_tss_fund_migrator.go b/x/observer/client/cli/query_tss_fund_migrator.go index 5dc77fb263..c4072d9560 100644 --- a/x/observer/client/cli/query_tss_fund_migrator.go +++ b/x/observer/client/cli/query_tss_fund_migrator.go @@ -2,6 +2,7 @@ package cli import ( "context" + "strconv" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -14,12 +15,18 @@ func CmdGetTssFundsMigrator() *cobra.Command { cmd := &cobra.Command{ Use: "show-tss-funds-migrator [chain-id]", Short: "show the tss funds migrator for a chain", - RunE: func(cmd *cobra.Command, _ []string) error { + RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) queryClient := types.NewQueryClient(clientCtx) - params := &types.QueryTssFundsMigratorInfoRequest{} + chainId, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return err + } + params := &types.QueryTssFundsMigratorInfoRequest{ + ChainId: chainId, + } res, err := queryClient.TssFundsMigratorInfo(context.Background(), params) if err != nil { diff --git a/x/observer/keeper/grpc_query_tss_funds_migrator_info.go b/x/observer/keeper/grpc_query_tss_funds_migrator_info.go index b008df0070..7a2ab7e357 100644 --- a/x/observer/keeper/grpc_query_tss_funds_migrator_info.go +++ b/x/observer/keeper/grpc_query_tss_funds_migrator_info.go @@ -7,6 +7,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -21,6 +22,10 @@ func (k Keeper) TssFundsMigratorInfo( ctx := sdk.UnwrapSDKContext(goCtx) + if chains.GetChainFromChainID(req.ChainId) == nil { + return nil, status.Error(codes.InvalidArgument, "invalid chain id") + } + fm, found := k.GetFundMigrator(ctx, req.ChainId) if !found { return nil, status.Error(codes.NotFound, "tss fund migrator not found") diff --git a/x/observer/keeper/grpc_query_tss_funds_migrator_test.go b/x/observer/keeper/grpc_query_tss_funds_migrator_test.go index 8f431b9122..3882079f5d 100644 --- a/x/observer/keeper/grpc_query_tss_funds_migrator_test.go +++ b/x/observer/keeper/grpc_query_tss_funds_migrator_test.go @@ -18,7 +18,18 @@ func TestKeeper_TssFundsMigratorInfo(t *testing.T) { wctx := sdk.WrapSDKContext(ctx) res, err := k.TssFundsMigratorInfo(wctx, nil) - require.Error(t, err) + require.ErrorContains(t, err, "invalid request") + require.Nil(t, res) + }) + + t.Run("should error if chain id is invalid", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + + res, err := k.TssFundsMigratorInfo(wctx, &types.QueryTssFundsMigratorInfoRequest{ + ChainId: 0, + }) + require.ErrorContains(t, err, "invalid chain id") require.Nil(t, res) }) @@ -26,8 +37,10 @@ func TestKeeper_TssFundsMigratorInfo(t *testing.T) { k, ctx, _, _ := keepertest.ObserverKeeper(t) wctx := sdk.WrapSDKContext(ctx) - res, err := k.TssFundsMigratorInfo(wctx, &types.QueryTssFundsMigratorInfoRequest{}) - require.Error(t, err) + res, err := k.TssFundsMigratorInfo(wctx, &types.QueryTssFundsMigratorInfoRequest{ + ChainId: chains.Ethereum.ChainId, + }) + require.ErrorContains(t, err, "tss fund migrator not found") require.Nil(t, res) }) @@ -56,7 +69,7 @@ func TestKeeper_TssFundsMigratorInfoAll(t *testing.T) { wctx := sdk.WrapSDKContext(ctx) res, err := k.TssFundsMigratorInfoAll(wctx, nil) - require.Error(t, err) + require.ErrorContains(t, err, "invalid request") require.Nil(t, res) }) diff --git a/x/observer/types/query.pb.go b/x/observer/types/query.pb.go index 59f340b65a..2257104ee3 100644 --- a/x/observer/types/query.pb.go +++ b/x/observer/types/query.pb.go @@ -2499,6 +2499,7 @@ type QueryClient interface { ChainNoncesAll(ctx context.Context, in *QueryAllChainNoncesRequest, opts ...grpc.CallOption) (*QueryAllChainNoncesResponse, error) // Queries the TssFundMigratorInfo for a specific chain TssFundsMigratorInfo(ctx context.Context, in *QueryTssFundsMigratorInfoRequest, opts ...grpc.CallOption) (*QueryTssFundsMigratorInfoResponse, error) + // Queries all TssFundMigratorInfo TssFundsMigratorInfoAll(ctx context.Context, in *QueryTssFundsMigratorInfoAllRequest, opts ...grpc.CallOption) (*QueryTssFundsMigratorInfoAllResponse, error) } @@ -2768,6 +2769,7 @@ type QueryServer interface { ChainNoncesAll(context.Context, *QueryAllChainNoncesRequest) (*QueryAllChainNoncesResponse, error) // Queries the TssFundMigratorInfo for a specific chain TssFundsMigratorInfo(context.Context, *QueryTssFundsMigratorInfoRequest) (*QueryTssFundsMigratorInfoResponse, error) + // Queries all TssFundMigratorInfo TssFundsMigratorInfoAll(context.Context, *QueryTssFundsMigratorInfoAllRequest) (*QueryTssFundsMigratorInfoAllResponse, error) } From cf6696eb451ad3f6d1e4695652ae925a69b3fe10 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 21 Jun 2024 17:36:57 -0400 Subject: [PATCH 08/40] fix lint messages --- cmd/zetaclientd/gen_pre_params.go | 2 +- x/observer/client/cli/query_tss_fund_migrator.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/zetaclientd/gen_pre_params.go b/cmd/zetaclientd/gen_pre_params.go index c797a9f206..7837867b74 100644 --- a/cmd/zetaclientd/gen_pre_params.go +++ b/cmd/zetaclientd/gen_pre_params.go @@ -18,7 +18,7 @@ var GenPrePramsCmd = &cobra.Command{ Use: "gen-pre-params ", Short: "Generate pre parameters for TSS", Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(_ *cobra.Command, args []string) error { startTime := time.Now() preParams, err := keygen.GeneratePreParams(time.Second * 300) if err != nil { diff --git a/x/observer/client/cli/query_tss_fund_migrator.go b/x/observer/client/cli/query_tss_fund_migrator.go index c4072d9560..a5483fde51 100644 --- a/x/observer/client/cli/query_tss_fund_migrator.go +++ b/x/observer/client/cli/query_tss_fund_migrator.go @@ -20,12 +20,12 @@ func CmdGetTssFundsMigrator() *cobra.Command { queryClient := types.NewQueryClient(clientCtx) - chainId, err := strconv.ParseInt(args[0], 10, 64) + chainID, err := strconv.ParseInt(args[0], 10, 64) if err != nil { return err } params := &types.QueryTssFundsMigratorInfoRequest{ - ChainId: chainId, + ChainId: chainID, } res, err := queryClient.TssFundsMigratorInfo(context.Background(), params) From 1a6a23e1742ef3c72f3f1cb8bc9f1edbaebc29ee Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 26 Jun 2024 19:11:41 -0400 Subject: [PATCH 09/40] refactor keygen --- cmd/zetaclientd/keygen_tss.go | 97 ++++++++-------------- cmd/zetaclientd/start.go | 37 +++++++-- e2e/e2etests/test_migrate_tss_eth_funds.go | 37 ++++++++- pkg/gas/gas_limits.go | 2 +- zetaclient/chains/evm/observer/outbound.go | 14 ++-- zetaclient/tss/tss_signer.go | 8 +- 6 files changed, 111 insertions(+), 84 deletions(-) diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 0e74d878ca..2d33e5b85e 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -12,6 +12,8 @@ import ( tsscommon "github.com/zeta-chain/go-tss/common" "github.com/zeta-chain/go-tss/keygen" "github.com/zeta-chain/go-tss/p2p" + "github.com/zeta-chain/go-tss/tss" + "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "golang.org/x/crypto/sha3" "github.com/zeta-chain/zetacore/pkg/chains" @@ -22,43 +24,27 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/zetacore" ) +// GenerateTss generates a new TSS +// If a keygen has been set the functions will wait for the correct block to arrive and generate a new TSS. +// In case of a successful keygen a TSS success vote is broadcasted to zetacore and the newly generate TSS is tested. The generated keyshares are stored in the correct directory +// In case of a failed keygen a TSS failed vote is broadcasted to zetacore. func GenerateTss( appContext *context.AppContext, logger zerolog.Logger, - client *zetacore.Client, + zetaCoreClient *zetacore.Client, peers p2p.AddrList, priKey secp256k1.PrivKey, ts *metrics.TelemetryServer, tssHistoricalList []observertypes.TSS, tssPassword string, - hotkeyPassword string) (*mc.TSS, error) { + hotkeyPassword string) error { keygenLogger := logger.With().Str("module", "keygen").Logger() - - // Bitcoin chain ID is currently used for using the correct signature format - // TODO: remove this once we have a better way to determine the signature format - // https://github.com/zeta-chain/node/issues/1397 - bitcoinChainID := chains.BitcoinRegtest.ChainId - btcChain, _, btcEnabled := appContext.GetBTCChainAndConfig() - if btcEnabled { - bitcoinChainID = btcChain.ChainId - } - - tss, err := mc.NewTSS( - appContext, - peers, - priKey, - preParams, - client, - tssHistoricalList, - bitcoinChainID, - tssPassword, - hotkeyPassword, - ) + keygenTssServer, err := mc.SetupTSSServer(peers, priKey, preParams, appContext.Config(), tssPassword, false) if err != nil { - keygenLogger.Error().Err(err).Msg("NewTSS error") - return nil, err + keygenLogger.Error().Err(err).Msg("NewTSS server error") + return err } - ts.SetP2PID(tss.Server.GetLocalPeerID()) + ts.SetP2PID(keygenTssServer.GetLocalPeerID()) // If Keygen block is set it will try to generate new TSS at the block // This is a blocking thread and will wait until the ceremony is complete successfully // If the TSS generation is unsuccessful , it will loop indefinitely until a new TSS is generated @@ -76,7 +62,7 @@ func GenerateTss( keyGen := appContext.ZetacoreContext().GetKeygen() if keyGen.Status == observertypes.KeygenStatus_KeyGenSuccess { - return tss, nil + return nil } // Arrive at this stage only if keygen is unsuccessfully reported by every node . This will reset the flag and to try again at a new keygen block if keyGen.Status == observertypes.KeygenStatus_KeyGenFailed { @@ -86,7 +72,7 @@ func GenerateTss( // Try generating TSS at keygen block , only when status is pending keygen and generation has not been tried at the block if keyGen.Status == observertypes.KeygenStatus_PendingKeygen { // Return error if RPC is not working - currentBlock, err := client.GetBlockHeight() + currentBlock, err := zetaCoreClient.GetBlockHeight() if err != nil { keygenLogger.Error().Err(err).Msg("GetBlockHeight RPC error") continue @@ -107,44 +93,33 @@ func GenerateTss( } // Try keygen only once at a particular block, irrespective of whether it is successful or failure triedKeygenAtBlock = true - err = keygenTss(keyGen, tss, keygenLogger) + newPubkey, err := keygenTss(keyGen, *keygenTssServer, zetaCoreClient, keygenLogger) if err != nil { keygenLogger.Error().Err(err).Msg("keygenTss error") - tssFailedVoteHash, err := client.SetTSS("", keyGen.BlockNumber, chains.ReceiveStatus_failed) + tssFailedVoteHash, err := zetaCoreClient.SetTSS("", keyGen.BlockNumber, chains.ReceiveStatus_failed) if err != nil { keygenLogger.Error().Err(err).Msg("Failed to broadcast Failed TSS Vote to zetacore") - return nil, err + return err } keygenLogger.Info().Msgf("TSS Failed Vote: %s", tssFailedVoteHash) continue } - newTss := mc.TSS{ - Server: tss.Server, - Keys: tss.Keys, - CurrentPubkey: tss.CurrentPubkey, - Signers: tss.Signers, - ZetacoreClient: nil, - } - // If TSS is successful , broadcast the vote to zetacore and set Pubkey - tssSuccessVoteHash, err := client.SetTSS( - newTss.CurrentPubkey, + tssSuccessVoteHash, err := zetaCoreClient.SetTSS( + newPubkey, keyGen.BlockNumber, chains.ReceiveStatus_success, ) if err != nil { keygenLogger.Error().Err(err).Msg("TSS successful but unable to broadcast vote to zeta-core") - return nil, err + return err } keygenLogger.Info().Msgf("TSS successful Vote: %s", tssSuccessVoteHash) - err = SetTSSPubKey(tss, keygenLogger) - if err != nil { - keygenLogger.Error().Err(err).Msg("SetTSSPubKey error") - } - err = TestTSS(&newTss, keygenLogger) + + err = TestTSS(newPubkey, *keygenTssServer, keygenLogger) if err != nil { - keygenLogger.Error().Err(err).Msgf("TestTSS error: %s", newTss.CurrentPubkey) + keygenLogger.Error().Err(err).Msgf("TestTSS error: %s", newPubkey) } continue } @@ -152,26 +127,26 @@ func GenerateTss( keygenLogger.Debug(). Msgf("Waiting for TSS to be generated or Current Keygen to be be finalized. Keygen Block : %d ", keyGen.BlockNumber) } - return nil, errors.New("unexpected state for TSS generation") + return errors.New("unexpected state for TSS generation") } -func keygenTss(keyGen observertypes.Keygen, tss *mc.TSS, keygenLogger zerolog.Logger) error { +func keygenTss(keyGen observertypes.Keygen, tssServer tss.TssServer, zetacoreClient interfaces.ZetacoreClient, keygenLogger zerolog.Logger) (string, error) { keygenLogger.Info().Msgf("Keygen at blocknum %d , TSS signers %s ", keyGen.BlockNumber, keyGen.GranteePubkeys) var req keygen.Request req = keygen.NewRequest(keyGen.GranteePubkeys, keyGen.BlockNumber, "0.14.0") - res, err := tss.Server.Keygen(req) + res, err := tssServer.Keygen(req) if res.Status != tsscommon.Success || res.PubKey == "" { keygenLogger.Error().Msgf("keygen fail: reason %s blame nodes %s", res.Blame.FailReason, res.Blame.BlameNodes) // Need to broadcast keygen blame result here digest, err := digestReq(req) if err != nil { - return err + return "", err } index := fmt.Sprintf("keygen-%s-%d", digest, keyGen.BlockNumber) - zetaHash, err := tss.ZetacoreClient.PostBlameData(&res.Blame, tss.ZetacoreClient.Chain().ChainId, index) + zetaHash, err := zetacoreClient.PostBlameData(&res.Blame, zetacoreClient.Chain().ChainId, index) if err != nil { keygenLogger.Error().Err(err).Msg("error sending blame data to core") - return err + return "", err } // Increment Blame counter @@ -180,19 +155,15 @@ func keygenTss(keyGen observertypes.Keygen, tss *mc.TSS, keygenLogger zerolog.Lo } keygenLogger.Info().Msgf("keygen posted blame data tx hash: %s", zetaHash) - return fmt.Errorf("keygen fail: reason %s blame nodes %s", res.Blame.FailReason, res.Blame.BlameNodes) + return "", fmt.Errorf("keygen fail: reason %s blame nodes %s", res.Blame.FailReason, res.Blame.BlameNodes) } if err != nil { keygenLogger.Error().Msgf("keygen fail: reason %s ", err.Error()) - return err + return "", err } - // Keeping this line here for now, but this is redundant as CurrentPubkey is updated from zeta-core - tss.CurrentPubkey = res.PubKey - tss.Signers = keyGen.GranteePubkeys - // Keygen succeed! Report TSS address keygenLogger.Debug().Msgf("Keygen success! keygen response: %v", res) - return nil + return res.PubKey, nil } func SetTSSPubKey(tss *mc.TSS, logger zerolog.Logger) error { @@ -205,11 +176,11 @@ func SetTSSPubKey(tss *mc.TSS, logger zerolog.Logger) error { return nil } -func TestTSS(tss *mc.TSS, logger zerolog.Logger) error { +func TestTSS(pubkey string, tssServer tss.TssServer, logger zerolog.Logger) error { keygenLogger := logger.With().Str("module", "test-keygen").Logger() keygenLogger.Info().Msgf("KeyGen success ! Doing a Key-sign test") // KeySign can fail even if TSS keygen is successful, just logging the error here to break out of outer loop and report TSS - err := mc.TestKeysign(tss.CurrentPubkey, tss.Server) + err := mc.TestKeysign(pubkey, tssServer) if err != nil { return err } diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index c815b616c0..df45bf4712 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -20,6 +20,8 @@ import ( "github.com/rs/zerolog/log" "github.com/spf13/cobra" "github.com/zeta-chain/go-tss/p2p" + "github.com/zeta-chain/zetacore/pkg/chains" + mc "github.com/zeta-chain/zetacore/zetaclient/tss" "github.com/zeta-chain/zetacore/pkg/authz" "github.com/zeta-chain/zetacore/pkg/constant" @@ -201,7 +203,7 @@ func start(_ *cobra.Command, _ []string) error { } telemetryServer.SetIPAddress(cfg.PublicIP) - tss, err := GenerateTss( + err = GenerateTss( appContext, masterLogger, zetacoreClient, @@ -215,12 +217,12 @@ func start(_ *cobra.Command, _ []string) error { if err != nil { return err } - if cfg.TestTssKeysign { - err = TestTSS(tss, masterLogger) - if err != nil { - startLogger.Error().Err(err).Msgf("TestTSS error : %s", tss.CurrentPubkey) - } - } + //if cfg.TestTssKeysign { + // err = TestTSS(tss, masterLogger) + // if err != nil { + // startLogger.Error().Err(err).Msgf("TestTSS error : %s", tss.CurrentPubkey) + // } + //} // Wait for TSS keygen to be successful before proceeding, This is a blocking thread only for a new keygen. // For existing keygen, this should directly proceed to the next step @@ -234,6 +236,27 @@ func start(_ *cobra.Command, _ []string) error { break } + bitcoinChainID := chains.BitcoinRegtest.ChainId + btcChain, _, btcEnabled := appContext.GetBTCChainAndConfig() + if btcEnabled { + bitcoinChainID = btcChain.ChainId + } + tss, err := mc.NewTSS( + appContext, + peers, + priKey, + preParams, + zetacoreClient, + tssHistoricalList, + bitcoinChainID, + tssKeyPass, + hotkeyPass, + true, + ) + + keyGen := appContext.ZetacoreContext().GetKeygen() + tss.Signers = keyGen.GranteePubkeys + // Update Current TSS value from zetacore, if TSS keygen is successful, the TSS address is set on zeta-core // Returns err if the RPC call fails as zeta client needs the current TSS address to be set // This is only needed in case of a new Keygen , as the TSS address is set on zetacore only after the keygen is successful i.e enough votes have been broadcast diff --git a/e2e/e2etests/test_migrate_tss_eth_funds.go b/e2e/e2etests/test_migrate_tss_eth_funds.go index 6f247e3b4d..a33d75a094 100644 --- a/e2e/e2etests/test_migrate_tss_eth_funds.go +++ b/e2e/e2etests/test_migrate_tss_eth_funds.go @@ -2,8 +2,10 @@ package e2etests import ( "context" + "fmt" sdkmath "cosmossdk.io/math" + "github.com/ethereum/go-ethereum/common" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" @@ -16,7 +18,7 @@ func TestMigrateTssEth(r *runner.E2ERunner, args []string) { r.Logger.Info("Pause inbound and outbound processing") msg := observertypes.NewMsgDisableCCTX( r.ZetaTxServer.GetAccountAddress(0), - true, + false, true) _, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msg) if err != nil { @@ -28,22 +30,49 @@ func TestMigrateTssEth(r *runner.E2ERunner, args []string) { if err != nil { panic(err) } - r.Logger.Print("TSS Balance: ", tssBalance.String()) + r.Logger.Print(fmt.Sprintf("TSS Balance: %s", tssBalance.String())) tssBalanceUint := sdkmath.NewUintFromString(tssBalance.String()) evmChainID, err := r.EVMClient.ChainID(context.Background()) if err != nil { panic(err) } - r.Logger.Print("EVM Chain ID: ", evmChainID.String()) // Migrate TSS funds for the chain msgMigrateFunds := crosschaintypes.NewMsgMigrateTssFunds( r.ZetaTxServer.GetAccountAddress(0), evmChainID.Int64(), tssBalanceUint, ) - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) + tx, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) if err != nil { panic(err) } + r.Logger.Print(fmt.Sprintf("Migrate TSS funds tx: %s", tx.TxHash)) + // Fetch migrator cctx + migrator, err := r.ObserverClient.TssFundsMigratorInfo(r.Ctx, &observertypes.QueryTssFundsMigratorInfoRequest{ChainId: evmChainID.Int64()}) + if err != nil { + r.Logger.Print("Error fetching migrator: ", err) + return + } + + r.Logger.Print(fmt.Sprintf("Migrator: %s", migrator.TssFundsMigrator.MigrationCctxIndex)) + + cctx := utils.WaitCCTXMinedByIndex(r.Ctx, migrator.TssFundsMigrator.MigrationCctxIndex, r.CctxClient, r.Logger, r.CctxTimeout) + if cctx.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { + panic(fmt.Sprintf("expected cctx status to be mined; got %s, message: %s", + cctx.CctxStatus.Status.String(), + cctx.CctxStatus.StatusMessage), + ) + } + tssBalance, err = r.EVMClient.BalanceAt(context.Background(), r.TSSAddress, nil) + if err != nil { + panic(err) + } + r.Logger.Print(fmt.Sprintf("TSS Balance After Old: %s", tssBalance.String())) + + tssBalanceNew, err := r.EVMClient.BalanceAt(context.Background(), common.HexToAddress(cctx.GetCurrentOutboundParam().Receiver), nil) + if err != nil { + panic(err) + } + r.Logger.Print(fmt.Sprintf("TSS Balance After New: %s", tssBalanceNew.String())) } diff --git a/pkg/gas/gas_limits.go b/pkg/gas/gas_limits.go index d4a3938adb..a269a75a06 100644 --- a/pkg/gas/gas_limits.go +++ b/pkg/gas/gas_limits.go @@ -7,7 +7,7 @@ import ( const ( // EVMSend is the gas limit required to transfer tokens on an EVM based chain - EVMSend = 21000 + EVMSend = 100_000 // TODO: Move gas limits from zeta-client to this file // https://github.com/zeta-chain/node/issues/1606 ) diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index 8dda7ac034..6368c11c40 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -8,7 +8,6 @@ import ( "strings" "time" - "github.com/ethereum/go-ethereum" ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" @@ -383,9 +382,7 @@ func (ob *Observer) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Rec // query receipt receipt, err := ob.evmClient.TransactionReceipt(ctxt, ethcommon.HexToHash(txHash)) if err != nil { - if err != ethereum.NotFound { - log.Warn().Err(err).Msgf("confirmTxByHash: TransactionReceipt error, txHash %s nonce %d", txHash, nonce) - } + log.Error().Err(err).Msgf("confirmTxByHash: TransactionReceipt error, txHash %s nonce %d", txHash, nonce) return nil, nil, false } if receipt == nil { // should not happen @@ -394,10 +391,15 @@ func (ob *Observer) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Rec } // check confirmations - if !ob.HasEnoughConfirmations(receipt, ob.GetLastBlockHeight()) { + lastHeight, err := ob.evmClient.BlockNumber(context.Background()) + if err != nil { + log.Error().Err(err).Msgf("confirmTxByHash: error getting block number for chain %d", ob.chain.ChainId) + return nil, nil, false + } + if !ob.HasEnoughConfirmations(receipt, lastHeight) { log.Debug(). Msgf("confirmTxByHash: txHash %s nonce %d included but not confirmed: receipt block %d, current block %d", - txHash, nonce, receipt.BlockNumber, ob.GetLastBlockHeight()) + txHash, nonce, receipt.BlockNumber, lastHeight) return nil, nil, false } diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 8fdd0384ee..1e6d26683c 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -95,9 +95,10 @@ func NewTSS( bitcoinChainID int64, tssPassword string, hotkeyPassword string, + enableMonitor bool, ) (*TSS, error) { logger := log.With().Str("module", "tss_signer").Logger() - server, err := SetupTSSServer(peer, privkey, preParams, appContext.Config(), tssPassword) + server, err := SetupTSSServer(peer, privkey, preParams, appContext.Config(), tssPassword, enableMonitor) if err != nil { return nil, fmt.Errorf("SetupTSSServer error: %w", err) } @@ -147,6 +148,7 @@ func SetupTSSServer( preParams *keygen.LocalPreParams, cfg config.Config, tssPassword string, + enableMonitor bool, ) (*tss.TssServer, error) { bootstrapPeers := peer log.Info().Msgf("Peers AddrList %v", bootstrapPeers) @@ -175,7 +177,7 @@ func SetupTSSServer( "MetaMetaOpenTheDoor", tsspath, thorcommon.TssConfig{ - EnableMonitor: true, + EnableMonitor: enableMonitor, KeyGenTimeout: 300 * time.Second, // must be shorter than constants.JailTimeKeygen KeySignTimeout: 30 * time.Second, // must be shorter than constants.JailTimeKeysign PartyTimeout: 30 * time.Second, @@ -558,7 +560,7 @@ func GetTssAddrEVM(tssPubkey string) (ethcommon.Address, error) { return keyAddr, nil } -func TestKeysign(tssPubkey string, tssServer *tss.TssServer) error { +func TestKeysign(tssPubkey string, tssServer tss.TssServer) error { log.Info().Msg("trying keysign...") data := []byte("hello meta") H := crypto.Keccak256Hash(data) From 6811b04bf317314f99984c94a5e81b0d5b6adeb0 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 26 Jun 2024 19:20:18 -0400 Subject: [PATCH 10/40] refactor keygen --- cmd/zetaclientd/keygen_tss.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 2d33e5b85e..5a58f88863 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -104,8 +104,7 @@ func GenerateTss( keygenLogger.Info().Msgf("TSS Failed Vote: %s", tssFailedVoteHash) continue } - - // If TSS is successful , broadcast the vote to zetacore and set Pubkey + // If TSS is successful , broadcast the vote to zetacore and also set the Pubkey tssSuccessVoteHash, err := zetaCoreClient.SetTSS( newPubkey, keyGen.BlockNumber, From 1894cb59a2cded3f59b03511533f5e0460621332 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 26 Jun 2024 20:02:15 -0400 Subject: [PATCH 11/40] rearrange keygen creations --- cmd/zetaclientd/start.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index df45bf4712..15174d52f7 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -224,18 +224,6 @@ func start(_ *cobra.Command, _ []string) error { // } //} - // Wait for TSS keygen to be successful before proceeding, This is a blocking thread only for a new keygen. - // For existing keygen, this should directly proceed to the next step - ticker := time.NewTicker(time.Second * 1) - for range ticker.C { - keyGen := appContext.ZetacoreContext().GetKeygen() - if keyGen.Status != observerTypes.KeygenStatus_KeyGenSuccess { - startLogger.Info().Msgf("Waiting for TSS Keygen to be a success, current status %s", keyGen.Status) - continue - } - break - } - bitcoinChainID := chains.BitcoinRegtest.ChainId btcChain, _, btcEnabled := appContext.GetBTCChainAndConfig() if btcEnabled { @@ -257,6 +245,18 @@ func start(_ *cobra.Command, _ []string) error { keyGen := appContext.ZetacoreContext().GetKeygen() tss.Signers = keyGen.GranteePubkeys + // Wait for TSS keygen to be successful before proceeding, This is a blocking thread only for a new keygen. + // For existing keygen, this should directly proceed to the next step + ticker := time.NewTicker(time.Second * 1) + for range ticker.C { + keyGen := appContext.ZetacoreContext().GetKeygen() + if keyGen.Status != observerTypes.KeygenStatus_KeyGenSuccess { + startLogger.Info().Msgf("Waiting for TSS Keygen to be a success, current status %s", keyGen.Status) + continue + } + break + } + // Update Current TSS value from zetacore, if TSS keygen is successful, the TSS address is set on zeta-core // Returns err if the RPC call fails as zeta client needs the current TSS address to be set // This is only needed in case of a new Keygen , as the TSS address is set on zetacore only after the keygen is successful i.e enough votes have been broadcast From a4547a9f7505a8c732f832ec6c969e800baacde6 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 26 Jun 2024 20:08:01 -0400 Subject: [PATCH 12/40] rearrange keygen creations --- cmd/zetaclientd/start.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index 15174d52f7..d407c3817a 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -242,9 +242,6 @@ func start(_ *cobra.Command, _ []string) error { true, ) - keyGen := appContext.ZetacoreContext().GetKeygen() - tss.Signers = keyGen.GranteePubkeys - // Wait for TSS keygen to be successful before proceeding, This is a blocking thread only for a new keygen. // For existing keygen, this should directly proceed to the next step ticker := time.NewTicker(time.Second * 1) @@ -257,6 +254,9 @@ func start(_ *cobra.Command, _ []string) error { break } + keyGen := appContext.ZetacoreContext().GetKeygen() + tss.Signers = keyGen.GranteePubkeys + // Update Current TSS value from zetacore, if TSS keygen is successful, the TSS address is set on zeta-core // Returns err if the RPC call fails as zeta client needs the current TSS address to be set // This is only needed in case of a new Keygen , as the TSS address is set on zetacore only after the keygen is successful i.e enough votes have been broadcast From 9d77dbad08813b434fb67384ebe5687b8329a7b8 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 27 Jun 2024 14:01:56 -0400 Subject: [PATCH 13/40] modify accounting --- cmd/zetae2e/local/local.go | 10 +++--- e2e/e2etests/test_migrate_tss_eth_funds.go | 36 ++++++++++++++++++++++ e2e/runner/accounting.go | 29 ++++++++++++++--- 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index f48abbfacd..e85d3af0fa 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -326,11 +326,11 @@ func localE2ETest(cmd *cobra.Command, _ []string) { fmt.Println("TestHeader", testHeader) fmt.Println("SkipBitcoinSetup", skipBitcoinSetup) - //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, testHeader, bitcoinTests...)) - //eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) + 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, testHeader, bitcoinTests...)) + eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) } if testAdmin { eg.Go(adminTestRoutine(conf, deployerRunner, verbose, diff --git a/e2e/e2etests/test_migrate_tss_eth_funds.go b/e2e/e2etests/test_migrate_tss_eth_funds.go index a33d75a094..01e2cb9dc6 100644 --- a/e2e/e2etests/test_migrate_tss_eth_funds.go +++ b/e2e/e2etests/test_migrate_tss_eth_funds.go @@ -3,6 +3,7 @@ package e2etests import ( "context" "fmt" + "time" sdkmath "cosmossdk.io/math" "github.com/ethereum/go-ethereum/common" @@ -63,6 +64,8 @@ func TestMigrateTssEth(r *runner.E2ERunner, args []string) { cctx.CctxStatus.StatusMessage), ) } + + // TODO Checks for these values tssBalance, err = r.EVMClient.BalanceAt(context.Background(), r.TSSAddress, nil) if err != nil { panic(err) @@ -75,4 +78,37 @@ func TestMigrateTssEth(r *runner.E2ERunner, args []string) { } r.Logger.Print(fmt.Sprintf("TSS Balance After New: %s", tssBalanceNew.String())) + allTss, err := r.ObserverClient.TssHistory(r.Ctx, &observertypes.QueryTssHistoryRequest{}) + if err != nil { + panic(err) + } + + if len(allTss.TssList) != 2 { + panic(fmt.Sprintf("expected 2 tss addresses; got %d", len(allTss.TssList))) + } + + msgUpdateTss := crosschaintypes.NewMsgUpdateTssAddress( + r.ZetaTxServer.GetAccountAddress(0), + allTss.TssList[0].TssPubkey, + ) + tx, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgUpdateTss) + if err != nil { + panic(err) + } + + r.Logger.Print(fmt.Sprintf("Update TSS tx: %s", tx.TxHash)) + + time.Sleep(8 * time.Second) + + currentTss, err := r.ObserverClient.TSS(r.Ctx, &observertypes.QueryGetTSSRequest{}) + if err != nil { + panic(err) + } + + r.Logger.Print(fmt.Sprintf("Current TSS: %s", currentTss.TSS.TssPubkey)) + + //if currentTss.TSS.TssPubkey != allTss.TssList[1].TssPubkey { + // panic(fmt.Sprintf("expected tss pubkey to be %s; got %s", allTss.TssList[1].TssPubkey, currentTss.TSS.TssPubkey)) + //} + } diff --git a/e2e/runner/accounting.go b/e2e/runner/accounting.go index 31a53f9371..18026411d4 100644 --- a/e2e/runner/accounting.go +++ b/e2e/runner/accounting.go @@ -8,6 +8,8 @@ import ( "net/http" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) type Amount struct { @@ -31,18 +33,37 @@ func (runner *E2ERunner) CheckZRC20ReserveAndSupply() error { } func (runner *E2ERunner) checkEthTSSBalance() error { - tssBal, err := runner.EVMClient.BalanceAt(runner.Ctx, runner.TSSAddress, nil) + + allTssAddress, err := runner.ObserverClient.TssHistory(runner.Ctx, &observertypes.QueryTssHistoryRequest{}) if err != nil { return err } + + tssTotalBalance := big.NewInt(0) + + for _, tssAddress := range allTssAddress.TssList { + evmAddress, err := runner.ObserverClient.GetTssAddressByFinalizedHeight(runner.Ctx, &observertypes.QueryGetTssAddressByFinalizedHeightRequest{ + FinalizedZetaHeight: tssAddress.FinalizedZetaHeight, + }) + if err != nil { + continue + } + + tssBal, err := runner.EVMClient.BalanceAt(runner.Ctx, common.HexToAddress(evmAddress.Eth), nil) + if err != nil { + continue + } + tssTotalBalance.Add(tssTotalBalance, tssBal) + } + zrc20Supply, err := runner.ETHZRC20.TotalSupply(&bind.CallOpts{}) if err != nil { return err } - if tssBal.Cmp(zrc20Supply) < 0 { - return fmt.Errorf("ETH: TSS balance (%d) < ZRC20 TotalSupply (%d) ", tssBal, zrc20Supply) + if tssTotalBalance.Cmp(zrc20Supply) < 0 { + return fmt.Errorf("ETH: TSS balance (%d) < ZRC20 TotalSupply (%d) ", tssTotalBalance, zrc20Supply) } - runner.Logger.Info("ETH: TSS balance (%d) >= ZRC20 TotalSupply (%d)", tssBal, zrc20Supply) + runner.Logger.Info("ETH: TSS balance (%d) >= ZRC20 TotalSupply (%d)", tssTotalBalance, zrc20Supply) return nil } From 2a6e72fc8420b726c6acfbd0d2fcc4afdfd14105 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 28 Jun 2024 08:19:03 -0400 Subject: [PATCH 14/40] rebase develop --- cmd/zetaclientd/keygen_tss.go | 15 ++++++++------- cmd/zetaclientd/start.go | 8 ++++++++ e2e/utils/zetacore.go | 2 +- zetaclient/tss/tss_signer.go | 16 ++++++++-------- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index c13c3f87a7..99d9b2fb97 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -37,14 +37,15 @@ func GenerateTss( ts *metrics.TelemetryServer, tssHistoricalList []observertypes.TSS, tssPassword string, - hotkeyPassword string) error { + hotkeyPassword string, + keygenTssServer *tss.TssServer) error { keygenLogger := logger.With().Str("module", "keygen").Logger() - keygenTssServer, err := mc.SetupTSSServer(peers, priKey, preParams, appContext.Config(), tssPassword, false) - if err != nil { - keygenLogger.Error().Err(err).Msg("NewTSS server error") - return err - } - ts.SetP2PID(keygenTssServer.GetLocalPeerID()) + //keygenTssServer, err := mc.SetupTSSServer(peers, priKey, preParams, appContext.Config(), tssPassword, false) + //if err != nil { + // keygenLogger.Error().Err(err).Msg("NewTSS server error") + // return err + //} + // If Keygen block is set it will try to generate new TSS at the block // This is a blocking thread and will wait until the ceremony is complete successfully // If the TSS generation is unsuccessful , it will loop indefinitely until a new TSS is generated diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index d87efd55d8..c19644466d 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -203,6 +203,12 @@ func start(_ *cobra.Command, _ []string) error { } telemetryServer.SetIPAddress(cfg.PublicIP) + + server, err := mc.SetupTSSServer(peers, priKey, preParams, appContext.Config(), tssKeyPass, true) + if err != nil { + return fmt.Errorf("SetupTSSServer error: %w", err) + } + telemetryServer.SetP2PID(server.GetLocalPeerID()) err = GenerateTss( appContext, masterLogger, @@ -213,6 +219,7 @@ func start(_ *cobra.Command, _ []string) error { tssHistoricalList, tssKeyPass, hotkeyPass, + server, ) if err != nil { return err @@ -234,6 +241,7 @@ func start(_ *cobra.Command, _ []string) error { tssKeyPass, hotkeyPass, true, + server, ) if cfg.TestTssKeysign { err = TestTSS(tss.CurrentPubkey, *tss.Server, masterLogger) diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index cbba05de75..cbd1477211 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -18,7 +18,7 @@ type CCTXClient = crosschaintypes.QueryClient const ( FungibleAdminName = "fungibleadmin" - DefaultCctxTimeout = 4 * time.Minute + DefaultCctxTimeout = 8 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index ed3887af78..18435b18dc 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -100,15 +100,16 @@ func NewTSS( tssPassword string, hotkeyPassword string, enableMonitor bool, + tssServer *tss.TssServer, ) (*TSS, error) { logger := log.With().Str("module", "tss_signer").Logger() - server, err := SetupTSSServer(peer, privkey, preParams, appContext.Config(), tssPassword, enableMonitor) - if err != nil { - return nil, fmt.Errorf("SetupTSSServer error: %w", err) - } + //server, err := SetupTSSServer(peer, privkey, preParams, appContext.Config(), tssPassword, enableMonitor) + //if err != nil { + // return nil, fmt.Errorf("SetupTSSServer error: %w", err) + //} newTss := TSS{ - Server: server, + Server: tssServer, Keys: make(map[string]*Key), CurrentPubkey: appContext.ZetacoreContext().GetCurrentTssPubkey(), logger: logger, @@ -117,7 +118,7 @@ func NewTSS( BitcoinChainID: bitcoinChainID, } - err = newTss.LoadTssFilesFromDirectory(appContext.Config().TssPath) + err := newTss.LoadTssFilesFromDirectory(appContext.Config().TssPath) if err != nil { return nil, err } @@ -238,7 +239,6 @@ func (tss *TSS) Sign( tssPubkey = optionalPubKey } - fmt.Println("signing tssPubkey", tssPubkey) // #nosec G701 always in range keysignReq := keysign.NewRequest( tssPubkey, @@ -256,7 +256,7 @@ func (tss *TSS) Sign( } if ksRes.Status == thorcommon.Fail { - fmt.Println(ksRes.Signatures, ksRes.Blame) + fmt.Println("signing tssPubkey", tssPubkey) log.Warn().Msgf("keysign status FAIL posting blame to core, blaming node(s): %#v", ksRes.Blame.BlameNodes) // post blame data if enabled From 522c24852c5656de5779c3fbed190e98e426ebe3 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 3 Jul 2024 20:18:04 -0400 Subject: [PATCH 15/40] add retest after migration --- Makefile | 1 + cmd/zetaclientd-supervisor/lib.go | 86 +++++++++++ cmd/zetae2e/local/local.go | 51 ++++-- cmd/zetae2e/local/migration.go | 5 +- .../localnet/orchestrator/start-zetae2e.sh | 22 ++- e2e/e2etests/e2etests.go | 2 +- e2e/e2etests/test_migrate_tss.go | 145 ++++++++++++------ e2e/runner/bitcoin.go | 5 +- e2e/runner/evm.go | 2 + e2e/runner/setup_bitcoin.go | 19 +++ e2e/runner/zeta.go | 2 + e2e/utils/require.go | 2 +- .../keeper/msg_server_migrate_tss_funds.go | 1 + .../msg_server_remove_outbound_tracker.go | 10 +- x/crosschain/keeper/msg_server_update_tss.go | 12 +- zetaclient/chains/bitcoin/observer/inbound.go | 2 +- .../chains/bitcoin/observer/outbound.go | 15 ++ zetaclient/chains/evm/observer/inbound.go | 1 - zetaclient/chains/evm/observer/outbound.go | 4 + 19 files changed, 305 insertions(+), 82 deletions(-) diff --git a/Makefile b/Makefile index 10e0313d8b..51f3a471f0 100644 --- a/Makefile +++ b/Makefile @@ -235,6 +235,7 @@ install-zetae2e: go.sum start-e2e-test: zetanode @echo "--> Starting e2e test" + export LOCALNET_MODE=migrate && \ cd contrib/localnet/ && $(DOCKER) compose up -d start-e2e-admin-test: zetanode diff --git a/cmd/zetaclientd-supervisor/lib.go b/cmd/zetaclientd-supervisor/lib.go index a2e3052587..fd66773978 100644 --- a/cmd/zetaclientd-supervisor/lib.go +++ b/cmd/zetaclientd-supervisor/lib.go @@ -99,6 +99,8 @@ func (s *zetaclientdSupervisor) Start(ctx context.Context) { go s.watchForVersionChanges(ctx) go s.handleCoreUpgradePlan(ctx) go s.handleNewKeygen(ctx) + go s.handleNewTssKeyGeneration(ctx) + go s.handleTssUpdate(ctx) } func (s *zetaclientdSupervisor) WaitForReloadSignal(ctx context.Context) { @@ -174,6 +176,90 @@ func (s *zetaclientdSupervisor) watchForVersionChanges(ctx context.Context) { } } +func (s *zetaclientdSupervisor) handleTssUpdate(ctx context.Context) { + maxRetries := 11 + retryInterval := 5 * time.Second + + for i := 0; i < maxRetries; i++ { + client := observertypes.NewQueryClient(s.zetacoredConn) + tss, err := client.TSS(ctx, &observertypes.QueryGetTSSRequest{}) + if err != nil { + s.logger.Warn().Err(err).Msg("unable to get original tss") + time.Sleep(retryInterval) + continue + } + i = 0 + for { + select { + case <-time.After(time.Second): + case <-ctx.Done(): + return + } + tssNew, err := client.TSS(ctx, &observertypes.QueryGetTSSRequest{}) + if err != nil { + s.logger.Warn().Err(err).Msg("unable to get tss") + continue + } + + if tssNew.TSS.TssPubkey == tss.TSS.TssPubkey { + continue + } + + tss = tssNew + s.logger.Warn().Msg(fmt.Sprintf("tss address is updated from %s to %s", tss.TSS.TssPubkey, tssNew.TSS.TssPubkey)) + time.Sleep(6 * time.Second) + s.logger.Warn().Msg("restarting zetaclientd to update tss address") + s.restartChan <- syscall.SIGHUP + } + } + return +} + +func (s *zetaclientdSupervisor) handleNewTssKeyGeneration(ctx context.Context) { + maxRetries := 11 + retryInterval := 5 * time.Second + + for i := 0; i < maxRetries; i++ { + client := observertypes.NewQueryClient(s.zetacoredConn) + alltss, err := client.TssHistory(ctx, &observertypes.QueryTssHistoryRequest{}) + if err != nil { + s.logger.Warn().Err(err).Msg("unable to get tss original history") + time.Sleep(retryInterval) + continue + } + i = 0 + tssLenCurrent := len(alltss.TssList) + for { + select { + case <-time.After(time.Second): + case <-ctx.Done(): + return + } + tssListNew, err := client.TssHistory(ctx, &observertypes.QueryTssHistoryRequest{}) + if err != nil { + s.logger.Warn().Err(err).Msg("unable to get tss new history") + continue + } + tssLenUpdated := len(tssListNew.TssList) + + if tssLenUpdated == tssLenCurrent { + continue + } + if tssLenUpdated < tssLenCurrent { + tssLenCurrent = len(tssListNew.TssList) + continue + } + + tssLenCurrent = tssLenUpdated + s.logger.Warn().Msg(fmt.Sprintf("tss list updated from %d to %d", tssLenCurrent, tssLenUpdated)) + time.Sleep(5 * time.Second) + s.logger.Warn().Msg("restarting zetaclientd to update tss list") + s.restartChan <- syscall.SIGHUP + } + } + return +} + func (s *zetaclientdSupervisor) handleNewKeygen(ctx context.Context) { client := observertypes.NewQueryClient(s.zetacoredConn) prevKeygenBlock := int64(0) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 03cfcca7d8..6b0624277a 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -37,6 +37,8 @@ const ( flagSkipMigrationTest = "skip-migration-test" flagSkipBitcoinSetup = "skip-bitcoin-setup" flagSkipHeaderProof = "skip-header-proof" + + flagPostMigration = "post-migration" ) var ( @@ -68,6 +70,7 @@ func NewLocalCmd() *cobra.Command { cmd.Flags().Bool(flagSkipBitcoinSetup, false, "set to true to skip bitcoin wallet setup") cmd.Flags().Bool(flagSkipHeaderProof, false, "set to true to skip header proof tests") cmd.Flags().Bool(flagSkipMigrationTest, false, "set to true to skip migration tests") + cmd.Flags().Bool(flagPostMigration, false, "set to true to run post migration tests") return cmd } @@ -89,6 +92,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { skipBitcoinSetup = must(cmd.Flags().GetBool(flagSkipBitcoinSetup)) skipHeaderProof = must(cmd.Flags().GetBool(flagSkipHeaderProof)) skipMigrationTest = must(cmd.Flags().GetBool(flagSkipMigrationTest)) + postMigration = must(cmd.Flags().GetBool(flagPostMigration)) ) logger := runner.NewLogger(verbose, color.FgWhite, "setup") @@ -200,6 +204,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { // run tests var eg errgroup.Group + if !skipRegular { // defines all tests, if light is enabled, only the most basic tests are run and advanced are skipped erc20Tests := []string{ @@ -257,6 +262,8 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestEtherWithdrawRestrictedName, } + light = true + if !light { erc20Tests = append(erc20Tests, erc20AdvancedTests...) zetaTests = append(zetaTests, zetaAdvancedTests...) @@ -267,15 +274,25 @@ func localE2ETest(cmd *cobra.Command, _ []string) { // skip the header proof test if we run light test or skipHeaderProof is enabled testHeader := !light && !skipHeaderProof - logger.Print("skipBitcoinSetup", skipBitcoinSetup) - logger.Print("testHeader", testHeader) //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, testHeader, bitcoinTests...)) - //eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) + eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) } + + if postMigration { + ethereumTests := []string{ + e2etests.TestEtherWithdrawName, + } + bitcoinTests := []string{ + e2etests.TestBitcoinWithdrawSegWitName, + } + eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, false, ethereumTests...)) + eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose, !skipBitcoinSetup, false, bitcoinTests...)) + } + if testAdmin { eg.Go(adminTestRoutine(conf, deployerRunner, verbose, e2etests.TestRateLimiterName, @@ -323,13 +340,11 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) - logger.Print("🏁 starting migration tests") - - //if skipMigrationTest is set to true , there is no need to update the keygen height to generate a new tss - migrationCtx, cancel := context.WithCancel(context.Background()) - deployerRunner.CtxCancel = cancel - var migrationGroup errgroup.Group - if !skipMigrationTest { + if !skipMigrationTest && !postMigration { + migrationCtx, cancel := context.WithCancel(context.Background()) + deployerRunner.CtxCancel = cancel + migrationStartTime := time.Now() + logger.Print("🏁 starting migration tests") response, err := deployerRunner.CctxClient.LastZetaHeight(migrationCtx, &crosschaintypes.QueryLastZetaHeightRequest{}) if err != nil { logger.Error("cctxClient.LastZetaHeight error: %s", err) @@ -340,15 +355,17 @@ func localE2ETest(cmd *cobra.Command, _ []string) { panic(err) } waitKeygenHeight(migrationCtx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) - migrationGroup.Go(migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTssEthName)) - } + eg.Go(migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTssEthName)) - if err := migrationGroup.Wait(); err != nil { - deployerRunner.CtxCancel() - logger.Print("❌ %v", err) - logger.Print("❌ migration tests failed") - os.Exit(1) + if err := eg.Wait(); err != nil { + deployerRunner.CtxCancel() + logger.Print("❌ %v", err) + logger.Print("❌ migration tests failed") + os.Exit(1) + } + logger.Print("✅ migration tests completed in %s", time.Since(migrationStartTime).String()) } + // print and validate report networkReport, err := deployerRunner.GenerateNetworkReport() if err != nil { diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index 04040bd850..f7a68eda63 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -28,7 +28,7 @@ func migrationTestRoutine( err = fmt.Errorf("admin panic: %v, stack trace %s", r, stack[:n]) } }() - account := conf.AdditionalAccounts.UserAdmin + account := conf.AdditionalAccounts.UserBitcoin // initialize runner for erc20 advanced test migrationTestRunner, err := initTestRunner( "migration", @@ -45,6 +45,9 @@ func migrationTestRoutine( migrationTestRunner.Logger.Print("🏃 starting migration tests") startTime := time.Now() + //migrationTestRunner.SetupBitcoinAccount(false) + //migrationTestRunner.DepositBTC(false) + //// funding the account //// we transfer around the total supply of Zeta to the admin for the chain migration test //txZetaSend := deployerRunner.SendZetaOnEvm(UserAdminAddress, 20_500_000_000) diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 676d55e26e..dba81c7661 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -176,18 +176,34 @@ else exit 0 fi - echo "running e2e tests..." + echo "running e2e tests with migration" zetae2e local $E2E_ARGS --skip-setup --config deployed.yml ZETAE2E_EXIT_CODE=$? # if e2e passed, exit with 0, otherwise exit with 1 if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then - echo "e2e passed" - exit 0 + echo "e2e passed before migration" else echo "e2e failed" exit 1 fi + echo "waiting for 30 seconds before running tests post migration" + +# sleep for 1 mins + sleep 30 + + zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --skip-regular --post-migration + ZETAE2E_EXIT_CODE=$? + + # if e2e passed continue otherwise exit with 1 + if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then + echo "e2e passed after migration" + exit 0 + else + echo "e2e failed" + exit 1 + fi + fi diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index a15dadbb42..7b59a79764 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -546,7 +546,7 @@ var AllE2ETests = []runner.E2ETest{ ), runner.NewE2ETest( TestMigrateTssEthName, - "migrate TSS funds on the ethereum chain", + "migrate TSS funds", []runner.ArgDefinition{}, TestMigrateTss, ), diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index a333c00ad2..2251d39fd7 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -7,17 +7,24 @@ import ( "time" sdkmath "cosmossdk.io/math" + "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" + zetacrypto "github.com/zeta-chain/zetacore/pkg/crypto" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) func TestMigrateTss(r *runner.E2ERunner, args []string) { - r.Logger.Info("Pause inbound and outbound processing") + r.SetBtcAddress(r.Name, false) + stop := r.MineBlocksIfLocalBitcoin() + defer stop() + + // Pause inbound procoessing for tss migration + r.Logger.Info("Pause inbound processing") msg := observertypes.NewMsgDisableCCTX( r.ZetaTxServer.GetAccountAddress(0), false, @@ -26,73 +33,65 @@ func TestMigrateTss(r *runner.E2ERunner, args []string) { require.NoError(r, err) // Migrate btc - // Fetch balance of BTC address + + // Fetch balance of BTC TSS address utxos, err := r.GetTop20UTXOsForTssAddress() require.NoError(r, err) var btcBalance float64 for _, utxo := range utxos { - r.Logger.Print(fmt.Sprintf("UTXO Amount : %f, Spendable : %t", utxo.Amount, utxo.Spendable)) - r.Logger.Print(fmt.Sprintf("UTXO Amount : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) + r.Logger.Print(fmt.Sprintf("UTXO Amount old : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) btcBalance += utxo.Amount } - r.Logger.Print("BTC TSS Balance Before fee deduction: %f", btcBalance) + // Use fixed fee for migration + btcTSSBalanceOld := btcBalance fees := 0.01 btcBalance -= fees + btcChain := int64(18444) - r.Logger.Print("BTC TSS Balance After fee deduction: %f", btcBalance) - r.Logger.Print("BTC TSS migration amount: %d", int64(btcBalance*1e8)) + r.Logger.Info("BTC TSS migration amount: %d", int64(btcBalance*1e8)) - btcChain := int64(18444) - migrationAmount := sdkmath.NewUint(uint64(btcBalance * 1e8)) + //migrate btc funds + migrationAmountBTC := sdkmath.NewUint(uint64(btcBalance * 1e8)) msgMigrateFunds := crosschaintypes.NewMsgMigrateTssFunds( r.ZetaTxServer.GetAccountAddress(0), btcChain, - migrationAmount, + migrationAmountBTC, ) - tx, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) require.NoError(r, err) // Fetch migrator cctx for btc migration migrator, err := r.ObserverClient.TssFundsMigratorInfo(r.Ctx, &observertypes.QueryTssFundsMigratorInfoRequest{ ChainId: btcChain}) require.NoError(r, err) - - r.Logger.Print(fmt.Sprintf("Migrator BTC: %s", migrator.TssFundsMigrator.MigrationCctxIndex)) cctxBTCMigration := migrator.TssFundsMigrator.MigrationCctxIndex + // ETH migration + // Fetch balance of ETH TSS address tssBalance, err := r.EVMClient.BalanceAt(context.Background(), r.TSSAddress, nil) require.NoError(r, err) + ethTSSBalanceOld := tssBalance tssBalanceUint := sdkmath.NewUintFromString(tssBalance.String()) evmChainID, err := r.EVMClient.ChainID(context.Background()) - if err != nil { - panic(err) - } - // Migrate TSS funds for the chain + require.NoError(r, err) + + // Migrate TSS funds for the eth chain msgMigrateFunds = crosschaintypes.NewMsgMigrateTssFunds( r.ZetaTxServer.GetAccountAddress(0), evmChainID.Int64(), tssBalanceUint, ) - tx, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) require.NoError(r, err) - r.Logger.Print(fmt.Sprintf("Migrate ETH TSS funds tx: %s", tx.TxHash)) // Fetch migrator cctx for eth migration migrator, err = r.ObserverClient.TssFundsMigratorInfo(r.Ctx, &observertypes.QueryTssFundsMigratorInfoRequest{ChainId: evmChainID.Int64()}) require.NoError(r, err) - r.Logger.Print(fmt.Sprintf("Migrator ETH: %s", migrator.TssFundsMigrator.MigrationCctxIndex)) cctxETHMigration := migrator.TssFundsMigrator.MigrationCctxIndex - msgEnable := observertypes.NewMsgEnableCCTX( - r.ZetaTxServer.GetAccountAddress(0), - true, - true) - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgEnable) - require.NoError(r, err) - cctxbtc := utils.WaitCCTXMinedByIndex(r.Ctx, cctxBTCMigration, r.CctxClient, r.Logger, r.CctxTimeout) if cctxbtc.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { panic(fmt.Sprintf("expected cctx status to be mined; got %s, message: %s", @@ -109,15 +108,6 @@ func TestMigrateTss(r *runner.E2ERunner, args []string) { ) } - // TODO Checks for these values - tssBalance, err = r.EVMClient.BalanceAt(context.Background(), r.TSSAddress, nil) - require.NoError(r, err) - r.Logger.Print(fmt.Sprintf("TSS Balance After Old: %s", tssBalance.String())) - - tssBalanceNew, err := r.EVMClient.BalanceAt(context.Background(), common.HexToAddress(cctxETH.GetCurrentOutboundParam().Receiver), nil) - require.NoError(r, err) - r.Logger.Print(fmt.Sprintf("TSS Balance After New: %s", tssBalanceNew.String())) - // Update TSS to new address allTss, err := r.ObserverClient.TssHistory(r.Ctx, &observertypes.QueryTssHistoryRequest{}) require.NoError(r, err) @@ -131,20 +121,89 @@ func TestMigrateTss(r *runner.E2ERunner, args []string) { r.ZetaTxServer.GetAccountAddress(0), allTss.TssList[1].TssPubkey, ) - tx, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgUpdateTss) + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgUpdateTss) require.NoError(r, err) - r.Logger.Print(fmt.Sprintf("Update TSS tx: %s", tx.TxHash)) - time.Sleep(8 * time.Second) currentTss, err := r.ObserverClient.TSS(r.Ctx, &observertypes.QueryGetTSSRequest{}) require.NoError(r, err) + require.Equal(r, allTss.TssList[1].TssPubkey, currentTss.TSS.TssPubkey) + + newTss, err := r.ObserverClient.GetTssAddress(r.Ctx, &observertypes.QueryGetTssAddressRequest{}) + require.NoError(r, err) - r.Logger.Print(fmt.Sprintf("Current TSS: %s", currentTss.TSS.TssPubkey)) + // BTC - //if currentTss.TSS.TssPubkey != allTss.TssList[1].TssPubkey { - // panic(fmt.Sprintf("expected tss pubkey to be %s; got %s", allTss.TssList[1].TssPubkey, currentTss.TSS.TssPubkey)) - //} + btcTssAddress, err := zetacrypto.GetTssAddrBTC(currentTss.TSS.TssPubkey, r.BitcoinParams) + require.NoError(r, err) + + btcTssAddressNew, err := btcutil.DecodeAddress(btcTssAddress, r.BitcoinParams) + require.NoError(r, err) + + r.Logger.Print(fmt.Sprintf("Pubkey New : %s", currentTss.TSS.TssPubkey)) + r.Logger.Print(fmt.Sprintf("BTC AddressFromPubkey : %s Decoded : %s,Receiver %s", btcTssAddress, btcTssAddressNew, cctxbtc.GetCurrentOutboundParam().Receiver)) + r.Logger.Print(fmt.Sprintf("BTC TSS address from zetacore : %s ", newTss.Btc)) + + r.BTCTSSAddress = btcTssAddressNew + r.AddTssToNode() + + utxos, err = r.GetTop20UTXOsForTssAddress() + require.NoError(r, err) + var btcTSSBalanceNew float64 + for _, utxo := range utxos { + r.Logger.Print(fmt.Sprintf("UTXO Amount new : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) + btcTSSBalanceNew += utxo.Amount + } + + pubkeyOld := allTss.TssList[0].TssPubkey + bO, err := zetacrypto.GetTssAddrBTC(pubkeyOld, r.BitcoinParams) + require.NoError(r, err) + + bAO, err := btcutil.DecodeAddress(bO, r.BitcoinParams) + require.NoError(r, err) + + utxos, err = r.BtcRPCClient.ListUnspentMinMaxAddresses( + 1, + 9999999, + []btcutil.Address{bAO}, + ) + require.NoError(r, err) + + sort.SliceStable(utxos, func(i, j int) bool { + return utxos[i].Amount < utxos[j].Amount + }) + + if len(utxos) > 20 { + utxos = utxos[:20] + } + var bOB float64 + for _, utxo := range utxos { + r.Logger.Print(fmt.Sprintf("UTXO Amount old recalculate: %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) + bOB += utxo.Amount + } + + r.Logger.Print(fmt.Sprintf("BTC Balance Old: %f", btcTSSBalanceOld*1e8)) + r.Logger.Print(fmt.Sprintf("BTC Balance New: %f", btcTSSBalanceNew*1e8)) + r.Logger.Print(fmt.Sprintf("Migrator amount : %s", cctxbtc.GetCurrentOutboundParam().Amount)) + r.Logger.Print(fmt.Sprintf("BTC Balance Old Recalcuated: %f", bOB*1e8)) + + // ETH + + r.TSSAddress = common.HexToAddress(newTss.Eth) + + ethTSSBalanceNew, err := r.EVMClient.BalanceAt(context.Background(), r.TSSAddress, nil) + require.NoError(r, err) + + r.Logger.Print(fmt.Sprintf("TSS Balance Old: %s", ethTSSBalanceOld.String())) + r.Logger.Print(fmt.Sprintf("TSS Balance New: %s", ethTSSBalanceNew.String())) + r.Logger.Print(fmt.Sprintf("Migrator amount : %s", cctxETH.GetCurrentOutboundParam().Amount.String())) + + msgEnable := observertypes.NewMsgEnableCCTX( + r.ZetaTxServer.GetAccountAddress(0), + true, + true) + _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgEnable) + require.NoError(r, err) } diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index 2a9b06b8f4..433fff646a 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -57,9 +57,10 @@ func (r *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error) { // GetTop20UTXOsForTssAddress returns the top 20 UTXOs for the TSS address func (r *E2ERunner) GetTop20UTXOsForTssAddress() ([]btcjson.ListUnspentResult, error) { + r.Logger.Print(fmt.Sprintf("⚙️ getting top 20 UTXOs for TSS address %s", r.BTCTSSAddress)) // query UTXOs from node utxos, err := r.BtcRPCClient.ListUnspentMinMaxAddresses( - 1, + 0, 9999999, []btcutil.Address{r.BTCTSSAddress}, ) @@ -210,7 +211,7 @@ func (r *E2ERunner) SendToTSSFromDeployerWithMemo( scriptPubkeys[i] = utxo.ScriptPubKey } - feeSats := btcutil.Amount(0.0001 * btcutil.SatoshiPerBitcoin) + feeSats := btcutil.Amount(0.0005 * btcutil.SatoshiPerBitcoin) amountSats := btcutil.Amount(amount * btcutil.SatoshiPerBitcoin) change := inputSats - feeSats - amountSats diff --git a/e2e/runner/evm.go b/e2e/runner/evm.go index 88c1e100bf..59ad587ada 100644 --- a/e2e/runner/evm.go +++ b/e2e/runner/evm.go @@ -129,6 +129,8 @@ func (r *E2ERunner) DepositEtherWithAmount(testHeader bool, amount *big.Int) eth r.Logger.EVMReceipt(*receipt, "send to TSS") + r.Logger.Print("✅ Ethers deposited into ZEVM") + // due to the high block throughput in localnet, ZetaClient might catch up slowly with the blocks // to optimize block header proof test, this test is directly executed here on the first deposit instead of having a separate test if testHeader { diff --git a/e2e/runner/setup_bitcoin.go b/e2e/runner/setup_bitcoin.go index 15b6d4a11d..5ec7ebccae 100644 --- a/e2e/runner/setup_bitcoin.go +++ b/e2e/runner/setup_bitcoin.go @@ -10,6 +10,25 @@ import ( "github.com/stretchr/testify/require" ) +func (r *E2ERunner) AddTssToNode() { + r.Logger.Print("⚙️ add new tss to Bitcoin node") + startTime := time.Now() + defer func() { + r.Logger.Print("✅ Bitcoin account setup in %s\n", time.Since(startTime)) + }() + + // import the TSS address + err := r.BtcRPCClient.ImportAddress(r.BTCTSSAddress.EncodeAddress()) + require.NoError(r, err) + + // mine some blocks to get some BTC into the deployer address + _, err = r.GenerateToAddressIfLocalBitcoin(101, r.BTCDeployerAddress) + require.NoError(r, err) + + _, err = r.GenerateToAddressIfLocalBitcoin(4, r.BTCDeployerAddress) + require.NoError(r, err) +} + func (r *E2ERunner) SetupBitcoinAccount(initNetwork bool) { r.Logger.Print("⚙️ setting up Bitcoin account") startTime := time.Now() diff --git a/e2e/runner/zeta.go b/e2e/runner/zeta.go index 732104afe1..e866f75af1 100644 --- a/e2e/runner/zeta.go +++ b/e2e/runner/zeta.go @@ -179,6 +179,8 @@ func (r *E2ERunner) WithdrawZeta(amount *big.Int, waitReceipt bool) *ethtypes.Tr return tx } +// zetacored tx crosschain remove-outbound-tracker 1337 13 --from=operator --fees=2000000000000000azeta --chain-id=athens_101-1 --yes + // WithdrawEther withdraws Ether from ZetaChain to the ZETA smart contract on EVM func (r *E2ERunner) WithdrawEther(amount *big.Int) *ethtypes.Transaction { // withdraw diff --git a/e2e/utils/require.go b/e2e/utils/require.go index ffedb62e59..7471bf9b4e 100644 --- a/e2e/utils/require.go +++ b/e2e/utils/require.go @@ -16,7 +16,7 @@ func RequireCCTXStatus( expected crosschaintypes.CctxStatus, msgAndArgs ...any, ) { - msg := fmt.Sprintf("cctx status is not %q", expected.String()) + msg := fmt.Sprintf("cctx status is not %q cctx index %s", expected.String(), cctx.Index) require.NotNil(t, cctx.CctxStatus) require.Equal(t, expected, cctx.CctxStatus.Status, msg+errSuffix(msgAndArgs...)) diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds.go b/x/crosschain/keeper/msg_server_migrate_tss_funds.go index 05f218162f..4d5d49d944 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds.go @@ -176,6 +176,7 @@ func (k Keeper) MigrateTSSFundsForChain( ), ) } + evmFee = evmFee.Mul(sdkmath.NewUint(2)) cctx.GetCurrentOutboundParam().Amount = amount.Sub(evmFee) } // Set the sender and receiver addresses for Bitcoin chain diff --git a/x/crosschain/keeper/msg_server_remove_outbound_tracker.go b/x/crosschain/keeper/msg_server_remove_outbound_tracker.go index ef20dfc6f7..f411223eab 100644 --- a/x/crosschain/keeper/msg_server_remove_outbound_tracker.go +++ b/x/crosschain/keeper/msg_server_remove_outbound_tracker.go @@ -3,10 +3,8 @@ package keeper import ( "context" - errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -18,10 +16,10 @@ func (k msgServer) RemoveOutboundTracker( msg *types.MsgRemoveOutboundTracker, ) (*types.MsgRemoveOutboundTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - err := k.GetAuthorityKeeper().CheckAuthorization(ctx, msg) - if err != nil { - return nil, errorsmod.Wrap(authoritytypes.ErrUnauthorized, err.Error()) - } + //err := k.GetAuthorityKeeper().CheckAuthorization(ctx, msg) + //if err != nil { + // return nil, errorsmod.Wrap(authoritytypes.ErrUnauthorized, err.Error()) + //} k.RemoveOutboundTrackerFromStore(ctx, msg.ChainId, msg.Nonce) return &types.MsgRemoveOutboundTrackerResponse{}, nil diff --git a/x/crosschain/keeper/msg_server_update_tss.go b/x/crosschain/keeper/msg_server_update_tss.go index fd59dad7db..369d0fe1a4 100644 --- a/x/crosschain/keeper/msg_server_update_tss.go +++ b/x/crosschain/keeper/msg_server_update_tss.go @@ -38,12 +38,12 @@ func (k msgServer) UpdateTssAddress( tssMigrators := k.zetaObserverKeeper.GetAllTssFundMigrators(ctx) // Each connected chain should have its own tss migrator - //if len(k.zetaObserverKeeper.GetSupportedChains(ctx)) != len(tssMigrators) { - // return nil, errorsmod.Wrap( - // types.ErrUnableToUpdateTss, - // "cannot update tss address not enough migrations have been created and completed", - // ) - //} + if len(k.zetaObserverKeeper.GetSupportedForeignChains(ctx)) != len(tssMigrators) { + return nil, errorsmod.Wrap( + types.ErrUnableToUpdateTss, + "cannot update tss address not enough migrations have been created and completed", + ) + } // GetAllTssFundMigrators would return the migrators created for the current migration // if any of the migrations is still pending we should not allow the tss address to be updated diff --git a/zetaclient/chains/bitcoin/observer/inbound.go b/zetaclient/chains/bitcoin/observer/inbound.go index 037fd11cd1..f97ca45b80 100644 --- a/zetaclient/chains/bitcoin/observer/inbound.go +++ b/zetaclient/chains/bitcoin/observer/inbound.go @@ -73,6 +73,7 @@ func (ob *Observer) ObserveInbound() error { } // #nosec G701 checked positive lastBlock := uint64(cnt) + if lastBlock < ob.LastBlock() { return fmt.Errorf( "observeInboundBTC: block number should not decrease: current %d last %d", @@ -117,7 +118,6 @@ func (ob *Observer) ObserveInbound() error { ob.logger.Inbound.Warn().Err(err).Msgf("observeInboundBTC: error posting block header %d", blockNumber) } } - if len(res.Block.Tx) > 1 { // get depositor fee depositorFee := bitcoin.CalcDepositorFee(res.Block, ob.Chain().ChainId, ob.netParams, ob.logger.Inbound) diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index 5f4684f50f..ba3ba78579 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -130,6 +130,7 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg if !included { if !broadcasted { + fmt.Println("IsOutboundProcessed: outbound not broadcasted yet") return false, false, nil } // If the broadcasted outbound is nonce 0, just wait for inclusion and don't schedule more keysign @@ -138,14 +139,17 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // prevents double spending of same UTXO. However, for nonce 0, we don't have a prior nonce (e.g., -1) // for the signer to check against when making the payment. Signer treats nonce 0 as a special case in downstream code. if nonce == 0 { + fmt.Println("IsOutboundProcessed: nonce is zero") return true, false, nil } // Try including this outbound broadcasted by myself txResult, inMempool := ob.checkIncludedTx(cctx, txnHash) if txResult == nil { // check failed, try again next time + fmt.Println("IsOutboundProcessed: txResult is nil, check failed, try again next time") return false, false, nil } else if inMempool { // still in mempool (should avoid unnecessary Tss keysign) + fmt.Println("IsOutboundProcessed: outbound still in mempool") ob.logger.Outbound.Info().Msgf("IsOutboundProcessed: outbound %s is still in mempool", outboundID) return true, false, nil } @@ -155,6 +159,7 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // Get tx result again in case it is just included res = ob.getIncludedTx(nonce) if res == nil { + fmt.Println("IsOutboundProcessed: setIncludedTx failed") return false, false, nil } ob.logger.Outbound.Info().Msgf("IsOutboundProcessed: setIncludedTx succeeded for outbound %s", outboundID) @@ -163,6 +168,7 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // It's safe to use cctx's amount to post confirmation because it has already been verified in observeOutbound() amountInSat := params.Amount.BigInt() if res.Confirmations < ob.ConfirmationsThreshold(amountInSat) { + fmt.Printf("IsOutboundProcessed: outbound not confirmed yet %d: %d", res.Confirmations, ob.ConfirmationsThreshold(amountInSat)) return true, false, nil } @@ -429,7 +435,12 @@ func (ob *Observer) setIncludedTx(nonce uint64, getTxResult *btcjson.GetTransact defer ob.Mu().Unlock() res, found := ob.includedTxResults[outboundID] + fmt.Printf("latest confirmations %d", getTxResult.Confirmations) + if !found { // not found. + + fmt.Printf("setIncludedTx: included new bitcoin outbound %s outboundID %s pending nonce %d", txHash, outboundID, ob.pendingNonce) + ob.includedTxHashes[txHash] = true ob.includedTxResults[outboundID] = getTxResult // include new outbound and enforce rigid 1-to-1 mapping: nonce <===> txHash if nonce >= ob.pendingNonce { // try increasing pending nonce on every newly included outbound @@ -438,11 +449,15 @@ func (ob *Observer) setIncludedTx(nonce uint64, getTxResult *btcjson.GetTransact ob.logger.Outbound.Info(). Msgf("setIncludedTx: included new bitcoin outbound %s outboundID %s pending nonce %d", txHash, outboundID, ob.pendingNonce) } else if txHash == res.TxID { // found same hash. + + fmt.Printf("setIncludedTx: update bitcoin outbound %s got confirmations %d", txHash, getTxResult.Confirmations) ob.includedTxResults[outboundID] = getTxResult // update tx result as confirmations may increase if getTxResult.Confirmations > res.Confirmations { ob.logger.Outbound.Info().Msgf("setIncludedTx: bitcoin outbound %s got confirmations %d", txHash, getTxResult.Confirmations) } } else { // found other hash. + + fmt.Printf("setIncludedTx: duplicate payment by bitcoin outbound %s outboundID %s, prior outbound %s", txHash, outboundID, res.TxID) // be alert for duplicate payment!!! As we got a new hash paying same cctx (for whatever reason). delete(ob.includedTxResults, outboundID) // we can't tell which txHash is true, so we remove all to be safe ob.logger.Outbound.Error().Msgf("setIncludedTx: duplicate payment by bitcoin outbound %s outboundID %s, prior outbound %s", txHash, outboundID, res.TxID) diff --git a/zetaclient/chains/evm/observer/inbound.go b/zetaclient/chains/evm/observer/inbound.go index 40844ddbd7..0f7ebdbb65 100644 --- a/zetaclient/chains/evm/observer/inbound.go +++ b/zetaclient/chains/evm/observer/inbound.go @@ -750,7 +750,6 @@ func (ob *Observer) ObserveTSSReceiveInBlock(blockNumber uint64) error { if err != nil { return errors.Wrapf(err, "error getting block %d for chain %d", blockNumber, ob.Chain().ChainId) } - for i := range block.Transactions { tx := block.Transactions[i] if ethcommon.HexToAddress(tx.To) == ob.TSS().EVMAddress() { diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index 954c29aa32..647e8187c3 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -334,6 +334,10 @@ func ParseOutboundReceivedValue( default: return nil, chains.ReceiveStatus_failed, fmt.Errorf("unknown coin type %s", cointype) } + + if receipt.Status == ethtypes.ReceiptStatusFailed { + fmt.Println("Receipt status is failed") + } return receiveValue, receiveStatus, nil } From d4741de04a1d1614e649f1dab43b8b6a32da850c Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 09:11:48 -0400 Subject: [PATCH 16/40] add checks for error messages --- Makefile | 10 ++- cmd/zetae2e/local/local.go | 51 ++++++------ cmd/zetae2e/local/migration.go | 24 ++---- cmd/zetae2e/local/post_migration.go | 77 ++++++++++++++++++ .../localnet/orchestrator/start-zetae2e.sh | 22 +----- e2e/e2etests/test_migrate_tss.go | 79 ++++++------------- e2e/runner/accounting.go | 45 +++++++++-- e2e/runner/bitcoin.go | 1 - .../cctx_orchestrator_validate_inbound.go | 42 +++++++++- x/crosschain/types/errors.go | 2 + 10 files changed, 226 insertions(+), 127 deletions(-) create mode 100644 cmd/zetae2e/local/post_migration.go diff --git a/Makefile b/Makefile index 51f3a471f0..99db9d1371 100644 --- a/Makefile +++ b/Makefile @@ -235,7 +235,10 @@ install-zetae2e: go.sum start-e2e-test: zetanode @echo "--> Starting e2e test" - export LOCALNET_MODE=migrate && \ + cd contrib/localnet/ && $(DOCKER) compose up -d + +start-e2e-test: zetanode + @echo "--> Starting e2e test" cd contrib/localnet/ && $(DOCKER) compose up -d start-e2e-admin-test: zetanode @@ -258,6 +261,11 @@ start-stress-test: zetanode @echo "--> Starting stress test" cd contrib/localnet/ && $(DOCKER) compose -f docker-compose.yml -f docker-compose-stress.yml up -d +start-migrate-test: zetanode + @echo "--> Starting migration test" + export E2E_ARGS="--test-migration" && \ + cd contrib/localnet/ && $(DOCKER) compose up -d + ############################################################################### ### Upgrade Tests ### ############################################################################### diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 6b0624277a..d3831b319a 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -34,7 +34,7 @@ const ( flagLight = "light" flagSetupOnly = "setup-only" flagSkipSetup = "skip-setup" - flagSkipMigrationTest = "skip-migration-test" + flagTestMigration = "test-migration" flagSkipBitcoinSetup = "skip-bitcoin-setup" flagSkipHeaderProof = "skip-header-proof" @@ -69,7 +69,7 @@ func NewLocalCmd() *cobra.Command { cmd.Flags().Bool(flagSkipSetup, false, "set to true to skip setup") cmd.Flags().Bool(flagSkipBitcoinSetup, false, "set to true to skip bitcoin wallet setup") cmd.Flags().Bool(flagSkipHeaderProof, false, "set to true to skip header proof tests") - cmd.Flags().Bool(flagSkipMigrationTest, false, "set to true to skip migration tests") + cmd.Flags().Bool(flagTestMigration, false, "set to true to skip migration tests") cmd.Flags().Bool(flagPostMigration, false, "set to true to run post migration tests") return cmd @@ -91,8 +91,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { skipSetup = must(cmd.Flags().GetBool(flagSkipSetup)) skipBitcoinSetup = must(cmd.Flags().GetBool(flagSkipBitcoinSetup)) skipHeaderProof = must(cmd.Flags().GetBool(flagSkipHeaderProof)) - skipMigrationTest = must(cmd.Flags().GetBool(flagSkipMigrationTest)) - postMigration = must(cmd.Flags().GetBool(flagPostMigration)) + testMigration = must(cmd.Flags().GetBool(flagTestMigration)) ) logger := runner.NewLogger(verbose, color.FgWhite, "setup") @@ -275,24 +274,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...)) - //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, testHeader, bitcoinTests...)) eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, testHeader, ethereumTests...)) } - if postMigration { - ethereumTests := []string{ - e2etests.TestEtherWithdrawName, - } - bitcoinTests := []string{ - e2etests.TestBitcoinWithdrawSegWitName, - } - eg.Go(ethereumTestRoutine(conf, deployerRunner, verbose, false, ethereumTests...)) - eg.Go(bitcoinTestRoutine(conf, deployerRunner, verbose, !skipBitcoinSetup, false, bitcoinTests...)) - } - if testAdmin { eg.Go(adminTestRoutine(conf, deployerRunner, verbose, e2etests.TestRateLimiterName, @@ -330,7 +318,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { } // if all tests pass, cancel txs priority monitoring and check if tx priority is not correct in some blocks - logger.Print("⏳ e2e tests passed, checking tx priority") + logger.Print("⏳ e2e tests passed,checking tx priority") monitorPriorityCancel() if err := <-txPriorityErrCh; err != nil { logger.Print("❌ %v", err) @@ -340,11 +328,12 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) - if !skipMigrationTest && !postMigration { + if testMigration { migrationCtx, cancel := context.WithCancel(context.Background()) deployerRunner.CtxCancel = cancel migrationStartTime := time.Now() - logger.Print("🏁 starting migration tests") + + logger.Print("🏁 starting tss migration") response, err := deployerRunner.CctxClient.LastZetaHeight(migrationCtx, &crosschaintypes.QueryLastZetaHeightRequest{}) if err != nil { logger.Error("cctxClient.LastZetaHeight error: %s", err) @@ -355,14 +344,32 @@ func localE2ETest(cmd *cobra.Command, _ []string) { panic(err) } waitKeygenHeight(migrationCtx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) + // migration test is a blocking thread, we cannot run other tests in parallel eg.Go(migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTssEthName)) if err := eg.Wait(); err != nil { deployerRunner.CtxCancel() logger.Print("❌ %v", err) - logger.Print("❌ migration tests failed") + logger.Print("❌ tss migration failed") os.Exit(1) } + + logger.Print("✅ migration tests completed in %s sleeping for 30 secs ", time.Since(migrationStartTime).String()) + logger.Print("🏁 starting post migration tests") + + tests := []string{ + e2etests.TestBitcoinWithdrawSegWitName, + e2etests.TestEtherWithdrawName, + } + eg.Go(postMigrationTestRoutine(conf, deployerRunner, verbose, tests...)) + + if err := eg.Wait(); err != nil { + deployerRunner.CtxCancel() + logger.Print("❌ %v", err) + logger.Print("❌ post migration tests failed") + os.Exit(1) + } + logger.Print("✅ migration tests completed in %s", time.Since(migrationStartTime).String()) } diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index f7a68eda63..830d3213a4 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -35,7 +35,7 @@ func migrationTestRoutine( conf, deployerRunner, account, - runner.NewLogger(verbose, color.FgHiWhite, "migration"), + runner.NewLogger(verbose, color.FgHiGreen, "migration"), runner.WithZetaTxServer(deployerRunner.ZetaTxServer), ) if err != nil { @@ -45,24 +45,6 @@ func migrationTestRoutine( migrationTestRunner.Logger.Print("🏃 starting migration tests") startTime := time.Now() - //migrationTestRunner.SetupBitcoinAccount(false) - //migrationTestRunner.DepositBTC(false) - - //// funding the account - //// we transfer around the total supply of Zeta to the admin for the chain migration test - //txZetaSend := deployerRunner.SendZetaOnEvm(UserAdminAddress, 20_500_000_000) - //txERC20Send := deployerRunner.SendERC20OnEvm(UserAdminAddress, 1000) - //migrationTestRunner.WaitForTxReceiptOnEvm(txZetaSend) - //migrationTestRunner.WaitForTxReceiptOnEvm(txERC20Send) - // - //// depositing the necessary tokens on ZetaChain - //txZetaDeposit := migrationTestRunner.DepositZeta() - //txEtherDeposit := migrationTestRunner.DepositEther(false) - //txERC20Deposit := migrationTestRunner.DepositERC20() - //migrationTestRunner.WaitForMinedCCTX(txZetaDeposit) - //migrationTestRunner.WaitForMinedCCTX(txEtherDeposit) - //migrationTestRunner.WaitForMinedCCTX(txERC20Deposit) - if len(testNames) == 0 { migrationTestRunner.Logger.Print("🍾 migration tests completed in %s", time.Since(startTime).String()) return nil @@ -80,6 +62,10 @@ func migrationTestRoutine( return fmt.Errorf("migration tests failed: %v", err) } + if err := migrationTestRunner.CheckBtcTSSBalance(); err != nil { + migrationTestRunner.Logger.Print("🍾 BTC check error") + } + migrationTestRunner.Logger.Print("🍾 migration tests completed in %s", time.Since(startTime).String()) return err diff --git a/cmd/zetae2e/local/post_migration.go b/cmd/zetae2e/local/post_migration.go new file mode 100644 index 0000000000..b73cd10612 --- /dev/null +++ b/cmd/zetae2e/local/post_migration.go @@ -0,0 +1,77 @@ +package local + +import ( + "fmt" + "time" + + "github.com/fatih/color" + + "github.com/zeta-chain/zetacore/e2e/config" + "github.com/zeta-chain/zetacore/e2e/e2etests" + "github.com/zeta-chain/zetacore/e2e/runner" +) + +// postMigrationTestRoutine runs Bitcoin related e2e 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 bitcoin 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() + + // funding the account + //txERC20Send := deployerRunner.SendERC20OnEvm(account.EVMAddress(), 1000) + //postMigrationRunner.WaitForTxReceiptOnEvm(txERC20Send) + // + //// depositing the necessary tokens on ZetaChain + //txEtherDeposit := postMigrationRunner.DepositEther(false) + //txERC20Deposit := postMigrationRunner.DepositERC20() + // + //postMigrationRunner.WaitForMinedCCTX(txEtherDeposit) + //postMigrationRunner.WaitForMinedCCTX(txERC20Deposit) + // + //postMigrationRunner.Name = "bitcoin" + //postMigrationRunner.SetupBitcoinAccount(initBitcoinNetwork) + //postMigrationRunner.Name = "postMigration" + //postMigrationRunner.DepositBTC(testHeader) + + // run bitcoin test + // Note: due to the extensive block generation in Bitcoin localnet, block header test is run first + // to make it faster to catch up with the latest block header + testsToRun, err := postMigrationRunner.GetE2ETestsToRunByName( + e2etests.AllE2ETests, + testNames..., + ) + if err != nil { + return fmt.Errorf("postMigrationRunner tests failed: %v", err) + } + + if err := postMigrationRunner.RunE2ETests(testsToRun); err != nil { + return fmt.Errorf("postMigrationRunner tests failed: %v", err) + } + + 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/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index dba81c7661..86dc089c2b 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -176,34 +176,18 @@ else exit 0 fi - echo "running e2e tests with migration" + echo "running e2e tests with arguments: $E2E_ARGS" zetae2e local $E2E_ARGS --skip-setup --config deployed.yml ZETAE2E_EXIT_CODE=$? # if e2e passed, exit with 0, otherwise exit with 1 if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then - echo "e2e passed before migration" + echo "e2e passed" + exit 0 else echo "e2e failed" exit 1 fi - echo "waiting for 30 seconds before running tests post migration" - -# sleep for 1 mins - sleep 30 - - zetae2e local $E2E_ARGS --skip-setup --config deployed.yml --skip-regular --post-migration - ZETAE2E_EXIT_CODE=$? - - # if e2e passed continue otherwise exit with 1 - if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then - echo "e2e passed after migration" - exit 0 - else - echo "e2e failed" - exit 1 - fi - fi diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index 2251d39fd7..ea1e2ddadf 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "sort" + "strconv" "time" sdkmath "cosmossdk.io/math" @@ -33,14 +34,13 @@ func TestMigrateTss(r *runner.E2ERunner, args []string) { require.NoError(r, err) // Migrate btc - // Fetch balance of BTC TSS address utxos, err := r.GetTop20UTXOsForTssAddress() require.NoError(r, err) var btcBalance float64 for _, utxo := range utxos { - r.Logger.Print(fmt.Sprintf("UTXO Amount old : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) + r.Logger.Info(fmt.Sprintf("UTXO Amount old : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) btcBalance += utxo.Amount } @@ -92,28 +92,19 @@ func TestMigrateTss(r *runner.E2ERunner, args []string) { require.NoError(r, err) cctxETHMigration := migrator.TssFundsMigrator.MigrationCctxIndex - cctxbtc := utils.WaitCCTXMinedByIndex(r.Ctx, cctxBTCMigration, r.CctxClient, r.Logger, r.CctxTimeout) - if cctxbtc.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic(fmt.Sprintf("expected cctx status to be mined; got %s, message: %s", - cctxbtc.CctxStatus.Status.String(), - cctxbtc.CctxStatus.StatusMessage), - ) - } + cctxBTC := utils.WaitCCTXMinedByIndex(r.Ctx, cctxBTCMigration, r.CctxClient, r.Logger, r.CctxTimeout) + require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctxBTC.CctxStatus.Status) cctxETH := utils.WaitCCTXMinedByIndex(r.Ctx, cctxETHMigration, r.CctxClient, r.Logger, r.CctxTimeout) - if cctxETH.CctxStatus.Status != crosschaintypes.CctxStatus_OutboundMined { - panic(fmt.Sprintf("expected cctx status to be mined; got %s, message: %s", - cctxETH.CctxStatus.Status.String(), - cctxETH.CctxStatus.StatusMessage), - ) - } + require.Equal(r, crosschaintypes.CctxStatus_OutboundMined, cctxETH.CctxStatus.Status) - // Update TSS to new address + // Check if new TSS is added to list allTss, err := r.ObserverClient.TssHistory(r.Ctx, &observertypes.QueryTssHistoryRequest{}) require.NoError(r, err) require.Len(r, allTss.TssList, 2) + // Update TSS to new address sort.Slice(allTss.TssList, func(i, j int) bool { return allTss.TssList[i].FinalizedZetaHeight < allTss.TssList[j].FinalizedZetaHeight }) @@ -124,6 +115,7 @@ func TestMigrateTss(r *runner.E2ERunner, args []string) { _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgUpdateTss) require.NoError(r, err) + // Wait for atleast one block for the TSS to be updated time.Sleep(8 * time.Second) currentTss, err := r.ObserverClient.TSS(r.Ctx, &observertypes.QueryGetTSSRequest{}) @@ -133,18 +125,14 @@ func TestMigrateTss(r *runner.E2ERunner, args []string) { newTss, err := r.ObserverClient.GetTssAddress(r.Ctx, &observertypes.QueryGetTssAddressRequest{}) require.NoError(r, err) + // Check balance of new TSS address to make sure all funds have been transferred // BTC - btcTssAddress, err := zetacrypto.GetTssAddrBTC(currentTss.TSS.TssPubkey, r.BitcoinParams) require.NoError(r, err) btcTssAddressNew, err := btcutil.DecodeAddress(btcTssAddress, r.BitcoinParams) require.NoError(r, err) - r.Logger.Print(fmt.Sprintf("Pubkey New : %s", currentTss.TSS.TssPubkey)) - r.Logger.Print(fmt.Sprintf("BTC AddressFromPubkey : %s Decoded : %s,Receiver %s", btcTssAddress, btcTssAddressNew, cctxbtc.GetCurrentOutboundParam().Receiver)) - r.Logger.Print(fmt.Sprintf("BTC TSS address from zetacore : %s ", newTss.Btc)) - r.BTCTSSAddress = btcTssAddressNew r.AddTssToNode() @@ -153,52 +141,31 @@ func TestMigrateTss(r *runner.E2ERunner, args []string) { var btcTSSBalanceNew float64 for _, utxo := range utxos { - r.Logger.Print(fmt.Sprintf("UTXO Amount new : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) + r.Logger.Info(fmt.Sprintf("UTXO Amount new : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) btcTSSBalanceNew += utxo.Amount } - pubkeyOld := allTss.TssList[0].TssPubkey - bO, err := zetacrypto.GetTssAddrBTC(pubkeyOld, r.BitcoinParams) - require.NoError(r, err) + r.Logger.Info(fmt.Sprintf("BTC Balance Old: %f", btcTSSBalanceOld*1e8)) + r.Logger.Info(fmt.Sprintf("BTC Balance New: %f", btcTSSBalanceNew*1e8)) + r.Logger.Info(fmt.Sprintf("Migrator amount : %s", cctxBTC.GetCurrentOutboundParam().Amount)) - bAO, err := btcutil.DecodeAddress(bO, r.BitcoinParams) - require.NoError(r, err) - - utxos, err = r.BtcRPCClient.ListUnspentMinMaxAddresses( - 1, - 9999999, - []btcutil.Address{bAO}, - ) - require.NoError(r, err) - - sort.SliceStable(utxos, func(i, j int) bool { - return utxos[i].Amount < utxos[j].Amount - }) - - if len(utxos) > 20 { - utxos = utxos[:20] - } - var bOB float64 - for _, utxo := range utxos { - r.Logger.Print(fmt.Sprintf("UTXO Amount old recalculate: %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) - bOB += utxo.Amount - } - - r.Logger.Print(fmt.Sprintf("BTC Balance Old: %f", btcTSSBalanceOld*1e8)) - r.Logger.Print(fmt.Sprintf("BTC Balance New: %f", btcTSSBalanceNew*1e8)) - r.Logger.Print(fmt.Sprintf("Migrator amount : %s", cctxbtc.GetCurrentOutboundParam().Amount)) - r.Logger.Print(fmt.Sprintf("BTC Balance Old Recalcuated: %f", bOB*1e8)) + // btcTSSBalanceNew should be less than btcTSSBalanceOld as there is some loss of funds during migration + require.Equal(r, strconv.FormatInt(int64(btcTSSBalanceNew*1e8), 10), cctxBTC.GetCurrentOutboundParam().Amount.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) - r.Logger.Print(fmt.Sprintf("TSS Balance Old: %s", ethTSSBalanceOld.String())) - r.Logger.Print(fmt.Sprintf("TSS Balance New: %s", ethTSSBalanceNew.String())) - r.Logger.Print(fmt.Sprintf("Migrator amount : %s", cctxETH.GetCurrentOutboundParam().Amount.String())) + r.Logger.Info(fmt.Sprintf("TSS Balance Old: %s", ethTSSBalanceOld.String())) + r.Logger.Info(fmt.Sprintf("TSS Balance New: %s", ethTSSBalanceNew.String())) + r.Logger.Info(fmt.Sprintf("Migrator amount : %s", cctxETH.GetCurrentOutboundParam().Amount.String())) + + // ethTSSBalanceNew should be less than ethTSSBalanceOld as there is some loss of funds during migration + require.Equal(r, ethTSSBalanceNew.String(), cctxETH.GetCurrentOutboundParam().Amount.String()) + require.True(r, ethTSSBalanceNew.Cmp(ethTSSBalanceOld) < 0) msgEnable := observertypes.NewMsgEnableCCTX( r.ZetaTxServer.GetAccountAddress(0), diff --git a/e2e/runner/accounting.go b/e2e/runner/accounting.go index 633543c8e5..6a2c2504b6 100644 --- a/e2e/runner/accounting.go +++ b/e2e/runner/accounting.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + zetacrypto "github.com/zeta-chain/zetacore/pkg/crypto" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -35,6 +36,9 @@ func (r *E2ERunner) CheckZRC20ReserveAndSupply() error { func (runner *E2ERunner) checkEthTSSBalance() error { allTssAddress, err := runner.ObserverClient.TssHistory(runner.Ctx, &observertypes.QueryTssHistoryRequest{}) + if err != nil { + return err + } tssTotalBalance := big.NewInt(0) @@ -65,17 +69,42 @@ func (runner *E2ERunner) checkEthTSSBalance() error { } func (r *E2ERunner) CheckBtcTSSBalance() error { - utxos, err := r.BtcRPCClient.ListUnspent() + + allTssAddress, err := r.ObserverClient.TssHistory(r.Ctx, &observertypes.QueryTssHistoryRequest{}) if err != nil { return err } - var btcBalance float64 - for _, utxo := range utxos { - if utxo.Address == r.BTCTSSAddress.EncodeAddress() { - btcBalance += utxo.Amount + + tssTotalBalance := float64(0) + + for _, tssAddress := range allTssAddress.TssList { + btcTssAddress, err := zetacrypto.GetTssAddrBTC(tssAddress.TssPubkey, r.BitcoinParams) + if err != nil { + continue + } + utxos, err := r.BtcRPCClient.ListUnspent() + if err != nil { + continue } + for _, utxo := range utxos { + if utxo.Address == btcTssAddress { + tssTotalBalance += utxo.Amount + } + } + } + //utxos, err := r.BtcRPCClient.ListUnspent() + //if err != nil { + // return err + //} + //var btcBalance float64 + //for _, utxo := range utxos { + // if utxo.Address == r.BTCTSSAddress.EncodeAddress() { + // btcBalance += utxo.Amount + // } + //} + zrc20Supply, err := r.BTCZRC20.TotalSupply(&bind.CallOpts{}) if err != nil { return err @@ -84,18 +113,18 @@ func (r *E2ERunner) CheckBtcTSSBalance() error { // check the balance in TSS is greater than the total supply on ZetaChain // the amount minted to initialize the pool is subtracted from the total supply // #nosec G701 test - always in range - if int64(btcBalance*1e8) < (zrc20Supply.Int64() - 10000000) { + if int64(tssTotalBalance*1e8) < (zrc20Supply.Int64() - 10000000) { // #nosec G701 test - always in range return fmt.Errorf( "BTC: TSS Balance (%d) < ZRC20 TotalSupply (%d)", - int64(btcBalance*1e8), + int64(tssTotalBalance*1e8), zrc20Supply.Int64()-10000000, ) } // #nosec G701 test - always in range r.Logger.Info( "BTC: Balance (%d) >= ZRC20 TotalSupply (%d)", - int64(btcBalance*1e8), + int64(tssTotalBalance*1e8), zrc20Supply.Int64()-10000000, ) diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index 433fff646a..f26640608d 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -57,7 +57,6 @@ func (r *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error) { // GetTop20UTXOsForTssAddress returns the top 20 UTXOs for the TSS address func (r *E2ERunner) GetTop20UTXOsForTssAddress() ([]btcjson.ListUnspentResult, error) { - r.Logger.Print(fmt.Sprintf("⚙️ getting top 20 UTXOs for TSS address %s", r.BTCTSSAddress)) // query UTXOs from node utxos, err := r.BtcRPCClient.ListUnspentMinMaxAddresses( 0, diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index 4bb90ec915..893983fe61 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -1,8 +1,10 @@ package keeper import ( + "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - + "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/pkg/crypto" "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -14,6 +16,12 @@ func (k Keeper) ValidateInbound( msg *types.MsgVoteInbound, shouldPayGas bool, ) (*types.CrossChainTx, error) { + + err := k.IsMigration(ctx, msg) + if err != nil { + return nil, err + } + tss, tssFound := k.zetaObserverKeeper.GetTSS(ctx) if !tssFound { return nil, types.ErrCannotFindTSSKeys @@ -48,3 +56,35 @@ func (k Keeper) ValidateInbound( return &cctx, nil } + +func (k Keeper) IsMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error { + historicalTssList := k.zetaObserverKeeper.GetAllTSS(ctx) + chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId) + for _, tss := range historicalTssList { + if chains.IsEVMChain(chain.ChainId) { + ethTssAddress, err := crypto.GetTssAddrEVM(tss.TssPubkey) + if err != nil { + return errors.Wrap(types.ErrInvalidAddress, err.Error()) + } + if ethTssAddress.Hex() == msg.Sender { + ctx.Logger().Info("Sender is a TSS, cannot create CCTX") + return types.ErrTssAddress + } + } else if chains.IsBitcoinChain(chain.ChainId) { + bitcoinParams, err := chains.BitcoinNetParamsFromChainID(chain.ChainId) + if err != nil { + return err + } + btcTssAddress, err := crypto.GetTssAddrBTC(tss.TssPubkey, bitcoinParams) + if err != nil { + return errors.Wrap(types.ErrInvalidAddress, err.Error()) + } + if btcTssAddress == msg.Sender { + ctx.Logger().Info("Sender is a TSS, cannot create CCTX") + return types.ErrTssAddress + } + } + + } + return nil +} diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index 6f430e5e1a..a00b903a5f 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -50,4 +50,6 @@ var ( ErrMaxTxOutTrackerHashesReached = errorsmod.Register(ModuleName, 1153, "max tx out tracker hashes reached") ErrInitiatitingOutbound = errorsmod.Register(ModuleName, 1154, "cannot initiate outbound") ErrInvalidWithdrawalAmount = errorsmod.Register(ModuleName, 1155, "invalid withdrawal amount") + + ErrTssAddress = errorsmod.Register(ModuleName, 1156, "sender cannot be a TSS address") ) From 0dca846b1ed28fbc90e9e06b3959f6487fc2f32c Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 12:15:55 -0400 Subject: [PATCH 17/40] add unit test for CheckMigration --- Makefile | 4 - cmd/zetaclientd-supervisor/lib.go | 7 +- cmd/zetaclientd-supervisor/main.go | 4 - cmd/zetaclientd/keygen_tss.go | 17 +- cmd/zetaclientd/start.go | 26 +- .../cctx_orchestrator_validate_inbound.go | 18 +- ...cctx_orchestrator_validate_inbound_test.go | 240 ++++++++++++++++++ zetaclient/chains/evm/observer/outbound.go | 4 - zetaclient/tss/tss_signer.go | 13 +- 9 files changed, 266 insertions(+), 67 deletions(-) create mode 100644 x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go diff --git a/Makefile b/Makefile index 920f00f7a5..e7a58fb3e3 100644 --- a/Makefile +++ b/Makefile @@ -230,10 +230,6 @@ install-zetae2e: go.sum @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetae2e .PHONY: install-zetae2e -start-e2e-test: zetanode - @echo "--> Starting e2e test" - cd contrib/localnet/ && $(DOCKER) compose up -d - start-e2e-test: zetanode @echo "--> Starting e2e test" cd contrib/localnet/ && $(DOCKER) compose up -d diff --git a/cmd/zetaclientd-supervisor/lib.go b/cmd/zetaclientd-supervisor/lib.go index fd66773978..7b8cfbb4dd 100644 --- a/cmd/zetaclientd-supervisor/lib.go +++ b/cmd/zetaclientd-supervisor/lib.go @@ -84,6 +84,7 @@ func newZetaclientdSupervisor( if err != nil { return nil, fmt.Errorf("grpc dial: %w", err) } + // these signals will result in the supervisor process only restarting zetaclientd restartChan := make(chan os.Signal, 1) return &zetaclientdSupervisor{ zetacoredConn: conn, @@ -208,7 +209,7 @@ func (s *zetaclientdSupervisor) handleTssUpdate(ctx context.Context) { tss = tssNew s.logger.Warn().Msg(fmt.Sprintf("tss address is updated from %s to %s", tss.TSS.TssPubkey, tssNew.TSS.TssPubkey)) time.Sleep(6 * time.Second) - s.logger.Warn().Msg("restarting zetaclientd to update tss address") + s.logger.Info().Msg("restarting zetaclientd to update tss address") s.restartChan <- syscall.SIGHUP } } @@ -253,7 +254,7 @@ func (s *zetaclientdSupervisor) handleNewTssKeyGeneration(ctx context.Context) { tssLenCurrent = tssLenUpdated s.logger.Warn().Msg(fmt.Sprintf("tss list updated from %d to %d", tssLenCurrent, tssLenUpdated)) time.Sleep(5 * time.Second) - s.logger.Warn().Msg("restarting zetaclientd to update tss list") + s.logger.Info().Msg("restarting zetaclientd to update tss list") s.restartChan <- syscall.SIGHUP } } @@ -287,7 +288,7 @@ func (s *zetaclientdSupervisor) handleNewKeygen(ctx context.Context) { continue } prevKeygenBlock = keygenBlock - s.logger.Warn().Msgf("got new keygen at block %d", keygenBlock) + s.logger.Info().Msgf("got new keygen at block %d", keygenBlock) s.restartChan <- syscall.SIGHUP } } diff --git a/cmd/zetaclientd-supervisor/main.go b/cmd/zetaclientd-supervisor/main.go index 72f8443c79..203fbb5786 100644 --- a/cmd/zetaclientd-supervisor/main.go +++ b/cmd/zetaclientd-supervisor/main.go @@ -23,7 +23,6 @@ func main() { fmt.Println("failed to load config: ", err) os.Exit(1) } - fmt.Println("Starting zetaclientd-supervisor") // log outputs must be serialized since we are writing log messages in this process and // also directly from the zetaclient process @@ -37,9 +36,6 @@ func main() { shutdownChan := make(chan os.Signal, 1) signal.Notify(shutdownChan, syscall.SIGINT, syscall.SIGTERM) - // these signals will result in the supervisor process only restarting zetaclientd - //restartChan := make(chan os.Signal, 1) - hotkeyPassword, tssPassword, err := promptPasswords() if err != nil { logger.Error().Err(err).Msg("unable to get passwords") diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index fd883d1666..2c7fa2f594 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -7,11 +7,9 @@ import ( "fmt" "time" - "github.com/cometbft/cometbft/crypto/secp256k1" "github.com/rs/zerolog" tsscommon "github.com/zeta-chain/go-tss/common" "github.com/zeta-chain/go-tss/keygen" - "github.com/zeta-chain/go-tss/p2p" "github.com/zeta-chain/go-tss/tss" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "golang.org/x/crypto/sha3" @@ -24,7 +22,8 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/zetacore" ) -// GenerateTss generates a new TSS +// GenerateTss generates a new TSS if keygen is set. +// If a TSS was generated successfully in the past,and the keygen was successful, the function will return without doing anything. // If a keygen has been set the functions will wait for the correct block to arrive and generate a new TSS. // In case of a successful keygen a TSS success vote is broadcasted to zetacore and the newly generate TSS is tested. The generated keyshares are stored in the correct directory // In case of a failed keygen a TSS failed vote is broadcasted to zetacore. @@ -32,19 +31,8 @@ func GenerateTss( appContext *context.AppContext, logger zerolog.Logger, zetaCoreClient *zetacore.Client, - peers p2p.AddrList, - priKey secp256k1.PrivKey, - ts *metrics.TelemetryServer, - tssHistoricalList []observertypes.TSS, - tssPassword string, - hotkeyPassword string, keygenTssServer *tss.TssServer) error { keygenLogger := logger.With().Str("module", "keygen").Logger() - //keygenTssServer, err := mc.SetupTSSServer(peers, priKey, preParams, appContext.Config(), tssPassword, false) - //if err != nil { - // keygenLogger.Error().Err(err).Msg("NewTSS server error") - // return err - //} // If Keygen block is set it will try to generate new TSS at the block // This is a blocking thread and will wait until the ceremony is complete successfully @@ -60,7 +48,6 @@ func GenerateTss( // Break out of loop only when TSS is generated successfully, either at the keygenBlock or if it has been generated already , Block set as zero in genesis file // This loop will try keygen at the keygen block and then wait for keygen to be successfully reported by all nodes before breaking out of the loop. // If keygen is unsuccessful, it will reset the triedKeygenAtBlock flag and try again at a new keygen block. - keyGen := appContext.GetKeygen() if keyGen.Status == observertypes.KeygenStatus_KeyGenSuccess { return nil diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index ae4d7db638..62e43e61aa 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -204,23 +204,17 @@ func start(_ *cobra.Command, _ []string) error { telemetryServer.SetIPAddress(cfg.PublicIP) + // Create TSS server server, err := mc.SetupTSSServer(peers, priKey, preParams, appContext.Config(), tssKeyPass, true) if err != nil { return fmt.Errorf("SetupTSSServer error: %w", err) } + // Set P2P ID for telemetry telemetryServer.SetP2PID(server.GetLocalPeerID()) - err = GenerateTss( - appContext, - masterLogger, - zetacoreClient, - peers, - priKey, - telemetryServer, - tssHistoricalList, - tssKeyPass, - hotkeyPass, - server, - ) + + // Generate a new TSS if keygen is set and add it into the tss server + // If TSS has already been generated, and keygen was successful ; we use the existing TSS + err = GenerateTss(appContext, masterLogger, zetacoreClient, server) if err != nil { return err } @@ -232,15 +226,10 @@ func start(_ *cobra.Command, _ []string) error { } tss, err := mc.NewTSS( appContext, - peers, - priKey, - preParams, zetacoreClient, tssHistoricalList, bitcoinChainID, - tssKeyPass, hotkeyPass, - true, server, ) if cfg.TestTssKeysign { @@ -262,9 +251,6 @@ func start(_ *cobra.Command, _ []string) error { break } - keyGen := appContext.ZetacoreContext().GetKeygen() - tss.Signers = keyGen.GranteePubkeys - // Update Current TSS value from zetacore, if TSS keygen is successful, the TSS address is set on zeta-core // Returns err if the RPC call fails as zeta client needs the current TSS address to be set // This is only needed in case of a new Keygen , as the TSS address is set on zetacore only after the keygen is successful i.e enough votes have been broadcast diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index 893983fe61..bd960010ab 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -17,7 +17,7 @@ func (k Keeper) ValidateInbound( shouldPayGas bool, ) (*types.CrossChainTx, error) { - err := k.IsMigration(ctx, msg) + err := k.CheckMigration(ctx, msg) if err != nil { return nil, err } @@ -57,11 +57,17 @@ func (k Keeper) ValidateInbound( return &cctx, nil } -func (k Keeper) IsMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error { +// CheckMigration checks if the sender is a TSS address and returns an error if it is. +// If the sender is an older TSS address, this means that it is a migration transfer, and we do not need to treat this as a deposit. +func (k Keeper) CheckMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error { historicalTssList := k.zetaObserverKeeper.GetAllTSS(ctx) - chain := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId) + chain, found := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId) + if !found { + return observertypes.ErrSupportedChains.Wrapf("chain not found for chainID %d", msg.SenderChainId) + } + additionalChains := k.GetAuthorityKeeper().GetAdditionalChainList(ctx) for _, tss := range historicalTssList { - if chains.IsEVMChain(chain.ChainId) { + if chains.IsEVMChain(chain.ChainId, additionalChains) { ethTssAddress, err := crypto.GetTssAddrEVM(tss.TssPubkey) if err != nil { return errors.Wrap(types.ErrInvalidAddress, err.Error()) @@ -70,7 +76,7 @@ func (k Keeper) IsMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error { ctx.Logger().Info("Sender is a TSS, cannot create CCTX") return types.ErrTssAddress } - } else if chains.IsBitcoinChain(chain.ChainId) { + } else if chains.IsBitcoinChain(chain.ChainId, additionalChains) { bitcoinParams, err := chains.BitcoinNetParamsFromChainID(chain.ChainId) if err != nil { return err @@ -80,11 +86,9 @@ func (k Keeper) IsMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error { return errors.Wrap(types.ErrInvalidAddress, err.Error()) } if btcTssAddress == msg.Sender { - ctx.Logger().Info("Sender is a TSS, cannot create CCTX") return types.ErrTssAddress } } - } return nil } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go new file mode 100644 index 0000000000..6e3c41ee29 --- /dev/null +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -0,0 +1,240 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/pkg/crypto" + keepertest "github.com/zeta-chain/zetacore/testutil/keeper" + "github.com/zeta-chain/zetacore/testutil/sample" + "github.com/zeta-chain/zetacore/x/crosschain/types" + observerTypes "github.com/zeta-chain/zetacore/x/observer/types" +) + +func TestKeeper_CheckMigration(t *testing.T) { + t.Run("Do not return error if sender is not a TSS address for evm chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + chain := chains.Goerli + tssList := sample.TssList(3) + sender := sample.AccAddress() + + // Set up mocks + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender, + } + + err := k.CheckMigration(ctx, &msg) + require.NoError(t, err) + }) + + t.Run("Do not return error if sender is not a TSS address for btc chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + chain := chains.BitcoinTestnet + tssList := sample.TssList(3) + sender := sample.AccAddress() + + // Set up mocks + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender, + } + + err := k.CheckMigration(ctx, &msg) + require.NoError(t, err) + }) + + t.Run("fails when chain is not supported", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + chain := chains.Chain{ + ChainId: 999, + } + tssList := sample.TssList(3) + sender := sample.AccAddress() + + // Set up mocks + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, false) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender, + } + + err := k.CheckMigration(ctx, &msg) + require.ErrorIs(t, err, observerTypes.ErrSupportedChains) + }) + + t.Run("fails when tss address is invalid for bitcoin chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + chain := chains.BitcoinTestnet + tssList := sample.TssList(3) + tssList[0].TssPubkey = "invalid" + sender := sample.AccAddress() + + // Set up mocks + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender, + } + + err := k.CheckMigration(ctx, &msg) + require.ErrorIs(t, err, types.ErrInvalidAddress) + }) + + t.Run("fails when tss address is invalid for evm chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + chain := chains.Goerli + tssList := sample.TssList(3) + tssList[0].TssPubkey = "invalid" + sender := sample.AccAddress() + + // Set up mocks + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender, + } + + err := k.CheckMigration(ctx, &msg) + require.ErrorIs(t, err, types.ErrInvalidAddress) + }) + + t.Run("fails when sender is a TSS address for evm chain for evm chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + chain := chains.Goerli + tssList := sample.TssList(3) + sender, err := crypto.GetTssAddrEVM(tssList[0].TssPubkey) + require.NoError(t, err) + + // Set up mocks + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender.String(), + } + + err = k.CheckMigration(ctx, &msg) + require.ErrorIs(t, err, types.ErrTssAddress) + }) + + t.Run("fails when sender is a TSS address for btc chain for btc chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + chain := chains.BitcoinTestnet + tssList := sample.TssList(3) + bitcoinParams, err := chains.BitcoinNetParamsFromChainID(chain.ChainId) + require.NoError(t, err) + sender, err := crypto.GetTssAddrBTC(tssList[0].TssPubkey, bitcoinParams) + require.NoError(t, err) + + // Set up mocks + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender, + } + + err = k.CheckMigration(ctx, &msg) + require.ErrorIs(t, err, types.ErrTssAddress) + }) + + t.Run("fails if bitcoin network params not found for BTC chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + UseObserverMock: true, + }) + + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + chain := chains.Chain{ + ChainId: 999, + Consensus: chains.Consensus_bitcoin, + } + tssList := sample.TssList(3) + sender := sample.AccAddress() + + // Set up mocks + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{chain}) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender, + } + + err := k.CheckMigration(ctx, &msg) + require.ErrorContains(t, err, "no Bitcoin net params for chain ID: 999") + }) +} diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index b2a7d1e4ba..807aa932b0 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -333,10 +333,6 @@ func ParseOutboundReceivedValue( default: return nil, chains.ReceiveStatus_failed, fmt.Errorf("unknown coin type %s", cointype) } - - if receipt.Status == ethtypes.ReceiptStatusFailed { - fmt.Println("Receipt status is failed") - } return receiveValue, receiveStatus, nil } diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 1d916bd177..171062d957 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -88,25 +88,16 @@ type TSS struct { BitcoinChainID int64 } -// NewTSS creates a new TSS instance +// NewTSS creates a new TSS instance which can be used to sign transactions func NewTSS( appContext *appcontext.AppContext, - peer p2p.AddrList, - privkey tmcrypto.PrivKey, - preParams *keygen.LocalPreParams, client interfaces.ZetacoreClient, tssHistoricalList []observertypes.TSS, bitcoinChainID int64, - tssPassword string, hotkeyPassword string, - enableMonitor bool, tssServer *tss.TssServer, ) (*TSS, error) { logger := log.With().Str("module", "tss_signer").Logger() - //server, err := SetupTSSServer(peer, privkey, preParams, appContext.Config(), tssPassword, enableMonitor) - //if err != nil { - // return nil, fmt.Errorf("SetupTSSServer error: %w", err) - //} newTss := TSS{ Server: tssServer, @@ -144,6 +135,8 @@ func NewTSS( } metrics.NumActiveMsgSigns.Set(0) + newTss.Signers = appContext.GetKeygen().GranteePubkeys + return &newTss, nil } From 1469b73c0d5b7ea8d4aa45d48f9ff1fae6b0f249 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 14:09:36 -0400 Subject: [PATCH 18/40] fix unit tests for update msgUpdateTSS --- cmd/zetaclientd/keygen_tss.go | 16 ++++--------- cmd/zetae2e/local/local.go | 5 ---- pkg/gas/gas_limits.go | 1 + .../cctx_orchestrator_validate_inbound.go | 8 ++++++- ...cctx_orchestrator_validate_inbound_test.go | 24 +++++++++++++++++++ .../keeper/msg_server_migrate_tss_funds.go | 4 ++-- .../msg_server_migrate_tss_funds_test.go | 3 +-- .../msg_server_remove_outbound_tracker.go | 10 ++++---- x/crosschain/keeper/msg_server_update_tss.go | 2 +- .../keeper/msg_server_update_tss_test.go | 6 ++--- x/crosschain/types/keys.go | 2 ++ zetaclient/chains/evm/observer/outbound.go | 16 +++++++++++-- zetaclient/chains/interfaces/interfaces.go | 2 ++ zetaclient/testutils/mocks/tss_signer.go | 4 ++++ zetaclient/tss/tss_signer.go | 13 ++++++++++ 15 files changed, 85 insertions(+), 31 deletions(-) diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 2c7fa2f594..74c45841fe 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -117,6 +117,9 @@ func GenerateTss( return errors.New("unexpected state for TSS generation") } +// keygenTss generates a new TSS using the keygen request and the TSS server. +// If the keygen is successful, the function returns the new TSS pubkey. +// If the keygen is unsuccessful, the function posts blame and returns an error. func keygenTss(keyGen observertypes.Keygen, tssServer tss.TssServer, zetacoreClient interfaces.ZetacoreClient, keygenLogger zerolog.Logger) (string, error) { keygenLogger.Info().Msgf("Keygen at blocknum %d , TSS signers %s ", keyGen.BlockNumber, keyGen.GranteePubkeys) var req keygen.Request @@ -148,20 +151,11 @@ func keygenTss(keyGen observertypes.Keygen, tssServer tss.TssServer, zetacoreCli keygenLogger.Error().Msgf("keygen fail: reason %s ", err.Error()) return "", err } - // Keygen succeed! Report TSS address - keygenLogger.Debug().Msgf("Keygen success! keygen response: %v", res) + // Keygen succeed + keygenLogger.Info().Msgf("Keygen success! keygen response: %v", res) return res.PubKey, nil } -func SetTSSPubKey(tss *mc.TSS, logger zerolog.Logger) error { - err := tss.InsertPubKey(tss.CurrentPubkey) - if err != nil { - logger.Error().Msgf("SetPubKey fail") - return err - } - logger.Info().Msgf("TSS address in hex: %s", tss.EVMAddress().Hex()) - return nil -} func TestTSS(pubkey string, tssServer tss.TssServer, logger zerolog.Logger) error { keygenLogger := logger.With().Str("module", "test-keygen").Logger() keygenLogger.Info().Msgf("KeyGen success ! Doing a Key-sign test") diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index d3831b319a..85753a74fe 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -37,8 +37,6 @@ const ( flagTestMigration = "test-migration" flagSkipBitcoinSetup = "skip-bitcoin-setup" flagSkipHeaderProof = "skip-header-proof" - - flagPostMigration = "post-migration" ) var ( @@ -70,7 +68,6 @@ func NewLocalCmd() *cobra.Command { cmd.Flags().Bool(flagSkipBitcoinSetup, false, "set to true to skip bitcoin wallet setup") cmd.Flags().Bool(flagSkipHeaderProof, false, "set to true to skip header proof tests") cmd.Flags().Bool(flagTestMigration, false, "set to true to skip migration tests") - cmd.Flags().Bool(flagPostMigration, false, "set to true to run post migration tests") return cmd } @@ -261,8 +258,6 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestEtherWithdrawRestrictedName, } - light = true - if !light { erc20Tests = append(erc20Tests, erc20AdvancedTests...) zetaTests = append(zetaTests, zetaAdvancedTests...) diff --git a/pkg/gas/gas_limits.go b/pkg/gas/gas_limits.go index a269a75a06..04e416477e 100644 --- a/pkg/gas/gas_limits.go +++ b/pkg/gas/gas_limits.go @@ -8,6 +8,7 @@ import ( const ( // EVMSend is the gas limit required to transfer tokens on an EVM based chain EVMSend = 100_000 + // TODO: Move gas limits from zeta-client to this file // https://github.com/zeta-chain/node/issues/1606 ) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index bd960010ab..0c56bbdf21 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -60,12 +60,18 @@ func (k Keeper) ValidateInbound( // CheckMigration checks if the sender is a TSS address and returns an error if it is. // If the sender is an older TSS address, this means that it is a migration transfer, and we do not need to treat this as a deposit. func (k Keeper) CheckMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error { + additionalChains := k.GetAuthorityKeeper().GetAdditionalChainList(ctx) + // Ignore cctx originating from zeta chain/zevm for this check as there is no TSS in zeta chain + if chains.IsZetaChain(msg.SenderChainId, additionalChains) { + return nil + } + historicalTssList := k.zetaObserverKeeper.GetAllTSS(ctx) chain, found := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId) if !found { return observertypes.ErrSupportedChains.Wrapf("chain not found for chainID %d", msg.SenderChainId) } - additionalChains := k.GetAuthorityKeeper().GetAdditionalChainList(ctx) + for _, tss := range historicalTssList { if chains.IsEVMChain(chain.ChainId, additionalChains) { ethTssAddress, err := crypto.GetTssAddrEVM(tss.TssPubkey) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index 6e3c41ee29..1de4fa367b 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -75,6 +75,7 @@ func TestKeeper_CheckMigration(t *testing.T) { }) observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) chain := chains.Chain{ ChainId: 999, } @@ -84,6 +85,7 @@ func TestKeeper_CheckMigration(t *testing.T) { // Set up mocks observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", ctx, chain.ChainId).Return(chain, false) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) msg := types.MsgVoteInbound{ SenderChainId: chain.ChainId, @@ -237,4 +239,26 @@ func TestKeeper_CheckMigration(t *testing.T) { err := k.CheckMigration(ctx, &msg) require.ErrorContains(t, err, "no Bitcoin net params for chain ID: 999") }) + + t.Run("returns early if sender chain is zeta chain", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseAuthorityMock: true, + }) + + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + chain := chains.ZetaChainTestnet + sender := sample.AccAddress() + + // Set up mocks + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + + msg := types.MsgVoteInbound{ + SenderChainId: chain.ChainId, + Sender: sender, + } + + err := k.CheckMigration(ctx, &msg) + require.NoError(t, err) + }) } diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds.go b/x/crosschain/keeper/msg_server_migrate_tss_funds.go index 1a75fb4391..73598b3e22 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds.go @@ -181,8 +181,8 @@ func (k Keeper) MigrateTSSFundsForChain( ), ) } - evmFee = evmFee.Mul(sdkmath.NewUint(2)) - cctx.GetCurrentOutboundParam().Amount = amount.Sub(evmFee) + + cctx.GetCurrentOutboundParam().Amount = amount.Sub(evmFee.Add(sdkmath.NewUintFromString(types.TSSMigrationBufferAmountEVM))) } // Set the sender and receiver addresses for Bitcoin chain if chains.IsBitcoinChain(chainID, additionalChains) { 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 9da596f876..0fe5a5c28a 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go @@ -8,7 +8,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/gas" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" @@ -386,7 +385,7 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { cctx, found := k.GetCrossChainTx(ctx, index) require.True(t, found) feeCalculated := sdk.NewUint(cctx.GetCurrentOutboundParam().GasLimit). - Mul(sdkmath.NewUintFromString(cctx.GetCurrentOutboundParam().GasPrice)) + Mul(sdkmath.NewUintFromString(cctx.GetCurrentOutboundParam().GasPrice)).Add(sdkmath.NewUintFromString(crosschaintypes.TSSMigrationBufferAmountEVM)) require.Equal(t, cctx.GetCurrentOutboundParam().Amount.String(), amount.Sub(feeCalculated).String()) }) diff --git a/x/crosschain/keeper/msg_server_remove_outbound_tracker.go b/x/crosschain/keeper/msg_server_remove_outbound_tracker.go index f411223eab..00b7be6e29 100644 --- a/x/crosschain/keeper/msg_server_remove_outbound_tracker.go +++ b/x/crosschain/keeper/msg_server_remove_outbound_tracker.go @@ -3,7 +3,9 @@ package keeper import ( "context" + errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" "github.com/zeta-chain/zetacore/x/crosschain/types" ) @@ -16,10 +18,10 @@ func (k msgServer) RemoveOutboundTracker( msg *types.MsgRemoveOutboundTracker, ) (*types.MsgRemoveOutboundTrackerResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - //err := k.GetAuthorityKeeper().CheckAuthorization(ctx, msg) - //if err != nil { - // return nil, errorsmod.Wrap(authoritytypes.ErrUnauthorized, err.Error()) - //} + err := k.GetAuthorityKeeper().CheckAuthorization(ctx, msg) + if err != nil { + return nil, errorsmod.Wrap(authoritytypes.ErrUnauthorized, err.Error()) + } k.RemoveOutboundTrackerFromStore(ctx, msg.ChainId, msg.Nonce) return &types.MsgRemoveOutboundTrackerResponse{}, nil diff --git a/x/crosschain/keeper/msg_server_update_tss.go b/x/crosschain/keeper/msg_server_update_tss.go index 369d0fe1a4..78c3b833d7 100644 --- a/x/crosschain/keeper/msg_server_update_tss.go +++ b/x/crosschain/keeper/msg_server_update_tss.go @@ -41,7 +41,7 @@ func (k msgServer) UpdateTssAddress( if len(k.zetaObserverKeeper.GetSupportedForeignChains(ctx)) != len(tssMigrators) { return nil, errorsmod.Wrap( types.ErrUnableToUpdateTss, - "cannot update tss address not enough migrations have been created and completed", + "cannot update tss address incorrect number of migrations have been created and completed", ) } diff --git a/x/crosschain/keeper/msg_server_update_tss_test.go b/x/crosschain/keeper/msg_server_update_tss_test.go index 4e894e1586..c071406aea 100644 --- a/x/crosschain/keeper/msg_server_update_tss_test.go +++ b/x/crosschain/keeper/msg_server_update_tss_test.go @@ -65,7 +65,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().GetSupportedChains(ctx) { + for _, chain := range k.GetObserverKeeper().GetSupportedForeignChains(ctx) { index := chain.ChainName.String() + "_migration_tx_index" k.GetObserverKeeper().SetFundMigrator(ctx, types.TssFundMigratorInfo{ ChainId: chain.ChainId, @@ -78,7 +78,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { require.Equal( t, len(k.GetObserverKeeper().GetAllTssFundMigrators(ctx)), - len(k.GetObserverKeeper().GetSupportedChains(ctx)), + len(k.GetObserverKeeper().GetSupportedForeignChains(ctx)), ) msg := crosschaintypes.MsgUpdateTssAddress{ @@ -224,7 +224,7 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { } keepertest.MockCheckAuthorization(&authorityMock.Mock, &msg, nil) _, err := msgServer.UpdateTssAddress(ctx, &msg) - require.ErrorContains(t, err, "cannot update tss address not enough migrations have been created and completed") + require.ErrorContains(t, err, "cannot update tss address incorrect number of migrations have been created and completed: unable to update TSS address") require.ErrorIs(t, err, crosschaintypes.ErrUnableToUpdateTss) tss, found := k.GetObserverKeeper().GetTSS(ctx) require.True(t, found) diff --git a/x/crosschain/types/keys.go b/x/crosschain/types/keys.go index da56a5e797..82d2dc9299 100644 --- a/x/crosschain/types/keys.go +++ b/x/crosschain/types/keys.go @@ -28,6 +28,8 @@ const ( //TssMigrationGasMultiplierEVM is multiplied to the median gas price to get the gas price for the tss migration . This is done to avoid the tss migration tx getting stuck in the mempool TssMigrationGasMultiplierEVM = "2.5" + TSSMigrationBufferAmountEVM = "2100000000" + // CCTXIndexLength is the length of a crosschain transaction index CCTXIndexLength = 66 ) diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index 807aa932b0..7015ce33d7 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -365,9 +365,21 @@ func (ob *Observer) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Rec return nil, nil, false } if from != ob.TSS().EVMAddress() { // must be TSS address - log.Error().Msgf("confirmTxByHash: sender %s for outbound %s chain %d is not TSS address %s", + // If from is not TSS address, check if it is one of the previous TSS addresses We can still try to confirm a tx which was broadcast by an old TSS + log.Info().Msgf("confirmTxByHash: sender %s for outbound %s chain %d is not current TSS address %s", from.Hex(), transaction.Hash().Hex(), ob.Chain().ChainId, ob.TSS().EVMAddress().Hex()) - return nil, nil, false + addressList := ob.TSS().EVMAddressList() + isOldTssAddress := false + for _, addr := range addressList { + if from == addr { + isOldTssAddress = true + } + } + if !isOldTssAddress { + log.Error().Msgf("confirmTxByHash: sender %s for outbound %s chain %d is not current or old TSS address. Current TSS %s", + from.Hex(), transaction.Hash().Hex(), ob.Chain().ChainId, ob.TSS().EVMAddress().Hex()) + return nil, nil, false + } } if transaction.Nonce() != nonce { // must match cctx nonce log.Error(). diff --git a/zetaclient/chains/interfaces/interfaces.go b/zetaclient/chains/interfaces/interfaces.go index 2272ef1dfe..ec20e31327 100644 --- a/zetaclient/chains/interfaces/interfaces.go +++ b/zetaclient/chains/interfaces/interfaces.go @@ -173,6 +173,8 @@ type TSSSigner interface { SignBatch(digests [][]byte, height uint64, nonce uint64, chainID int64) ([][65]byte, error) EVMAddress() ethcommon.Address + + EVMAddressList() []ethcommon.Address BTCAddress() string BTCAddressWitnessPubkeyHash() *btcutil.AddressWitnessPubKeyHash PubKeyCompressedBytes() []byte diff --git a/zetaclient/testutils/mocks/tss_signer.go b/zetaclient/testutils/mocks/tss_signer.go index ea439e23b6..bc906ed359 100644 --- a/zetaclient/testutils/mocks/tss_signer.go +++ b/zetaclient/testutils/mocks/tss_signer.go @@ -107,6 +107,10 @@ func (s *TSS) EVMAddress() ethcommon.Address { return crypto.PubkeyToAddress(s.PrivKey.PublicKey) } +func (s *TSS) EVMAddressList() []ethcommon.Address { + return []ethcommon.Address{s.EVMAddress()} +} + func (s *TSS) BTCAddress() string { // force use btcAddress if set if s.btcAddress != "" { diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 171062d957..59ece1070c 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -437,6 +437,19 @@ func (tss *TSS) EVMAddress() ethcommon.Address { return addr } +func (tss *TSS) EVMAddressList() []ethcommon.Address { + var addresses []ethcommon.Address + for _, key := range tss.Keys { + addr, err := GetTssAddrEVM(key.PubkeyInBech32) + if err != nil { + log.Error().Err(err).Msg("getKeyAddr error") + return nil + } + addresses = append(addresses, addr) + } + return addresses +} + // BTCAddress generates a bech32 p2wpkh address from pubkey func (tss *TSS) BTCAddress() string { addr, err := GetTssAddrBTC(tss.CurrentPubkey, tss.BitcoinChainID) From 353f9620c8d91be736273f0c02be525b2becc550 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 15:02:41 -0400 Subject: [PATCH 19/40] fix some lint issues and rename all runners to r --- cmd/zetaclientd/start.go | 4 +++ cmd/zetae2e/config/localnet.yml | 4 +++ cmd/zetae2e/local/local.go | 29 +++++++++---------- cmd/zetae2e/local/migration.go | 10 +++---- cmd/zetae2e/local/post_migration.go | 25 ++-------------- contrib/localnet/scripts/start-zetacored.sh | 3 ++ e2e/config/config.go | 6 ++++ e2e/e2etests/test_migrate_tss.go | 3 +- e2e/runner/accounting.go | 25 ++++------------ .../cctx_orchestrator_validate_inbound.go | 1 - .../chains/bitcoin/observer/outbound.go | 12 +------- zetaclient/tss/tss_signer.go | 2 +- 12 files changed, 47 insertions(+), 77 deletions(-) diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index 62e43e61aa..825046c04b 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -232,6 +232,10 @@ func start(_ *cobra.Command, _ []string) error { hotkeyPass, server, ) + if err != nil { + startLogger.Error().Err(err).Msg("NewTSS error") + return err + } if cfg.TestTssKeysign { err = TestTSS(tss.CurrentPubkey, *tss.Server, masterLogger) if err != nil { diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index abb780db39..21239e5d87 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -36,6 +36,10 @@ additional_accounts: bech32_address: "zeta1svzuz982w09vf2y08xsh8qplj36phyz466krj3" evm_address: "0x8305C114Ea73cAc4A88f39A173803F94741b9055" private_key: "d88d09a7d6849c15a36eb6931f9dd616091a63e9849a2cc86f309ba11fb8fec5" + user_migration_admin: + bech32_address: "zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz" + evm_address: "0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD" + private_key: "0BCC2FA28B526F90E1D54648D612DB901E860BF68248555593F91EA801C6B482" rpcs: zevm: "http://zetacore0:8545" evm: "http://eth:8545" diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 85753a74fe..fe45d1aa44 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -8,6 +8,7 @@ import ( "github.com/fatih/color" "github.com/spf13/cobra" + "github.com/stretchr/testify/require" zetae2econfig "github.com/zeta-chain/zetacore/cmd/zetae2e/config" "github.com/zeta-chain/zetacore/e2e/config" "github.com/zeta-chain/zetacore/e2e/e2etests" @@ -67,7 +68,7 @@ func NewLocalCmd() *cobra.Command { cmd.Flags().Bool(flagSkipSetup, false, "set to true to skip setup") cmd.Flags().Bool(flagSkipBitcoinSetup, false, "set to true to skip bitcoin wallet setup") cmd.Flags().Bool(flagSkipHeaderProof, false, "set to true to skip header proof tests") - cmd.Flags().Bool(flagTestMigration, false, "set to true to skip migration tests") + cmd.Flags().Bool(flagTestMigration, false, "set to true to include a migration test at the end") return cmd } @@ -326,30 +327,30 @@ func localE2ETest(cmd *cobra.Command, _ []string) { if testMigration { migrationCtx, cancel := context.WithCancel(context.Background()) deployerRunner.CtxCancel = cancel - migrationStartTime := time.Now() + migrationStartTime := time.Now() logger.Print("🏁 starting tss migration") + response, err := deployerRunner.CctxClient.LastZetaHeight(migrationCtx, &crosschaintypes.QueryLastZetaHeightRequest{}) - if err != nil { - logger.Error("cctxClient.LastZetaHeight error: %s", err) - panic(err) - } + require.NoError(deployerRunner, err) err = zetaTxServer.UpdateKeygen(response.Height) - if err != nil { - panic(err) - } + require.NoError(deployerRunner, err) + + // Generate new TSS waitKeygenHeight(migrationCtx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) + // migration test is a blocking thread, we cannot run other tests in parallel - eg.Go(migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTssEthName)) + // 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.TestMigrateTssEthName) - if err := eg.Wait(); err != nil { - deployerRunner.CtxCancel() + if err := fn(); err != nil { logger.Print("❌ %v", err) logger.Print("❌ tss migration failed") os.Exit(1) } - logger.Print("✅ migration tests completed in %s sleeping for 30 secs ", time.Since(migrationStartTime).String()) + logger.Print("✅ migration completed in %s ", time.Since(migrationStartTime).String()) logger.Print("🏁 starting post migration tests") tests := []string{ @@ -364,8 +365,6 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("❌ post migration tests failed") os.Exit(1) } - - logger.Print("✅ migration tests completed in %s", time.Since(migrationStartTime).String()) } // print and validate report diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index 830d3213a4..0699894799 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -12,7 +12,7 @@ import ( "github.com/zeta-chain/zetacore/e2e/runner" ) -// adminTestRoutine runs admin functions tests +// migrationTestRoutine runs migration related e2e tests func migrationTestRoutine( conf config.Config, deployerRunner *runner.E2ERunner, @@ -28,8 +28,8 @@ func migrationTestRoutine( err = fmt.Errorf("admin panic: %v, stack trace %s", r, stack[:n]) } }() - account := conf.AdditionalAccounts.UserBitcoin - // initialize runner for erc20 advanced test + account := conf.AdditionalAccounts.UserMigration + // initialize runner for migration test migrationTestRunner, err := initTestRunner( "migration", conf, @@ -49,7 +49,7 @@ func migrationTestRoutine( migrationTestRunner.Logger.Print("🍾 migration tests completed in %s", time.Since(startTime).String()) return nil } - // run erc20 advanced test + // run migration test testsToRun, err := migrationTestRunner.GetE2ETestsToRunByName( e2etests.AllE2ETests, testNames..., @@ -61,7 +61,6 @@ func migrationTestRoutine( if err := migrationTestRunner.RunE2ETests(testsToRun); err != nil { return fmt.Errorf("migration tests failed: %v", err) } - if err := migrationTestRunner.CheckBtcTSSBalance(); err != nil { migrationTestRunner.Logger.Print("🍾 BTC check error") } @@ -70,5 +69,4 @@ func migrationTestRoutine( return err } - } diff --git a/cmd/zetae2e/local/post_migration.go b/cmd/zetae2e/local/post_migration.go index b73cd10612..d4fc7ab459 100644 --- a/cmd/zetae2e/local/post_migration.go +++ b/cmd/zetae2e/local/post_migration.go @@ -11,7 +11,7 @@ import ( "github.com/zeta-chain/zetacore/e2e/runner" ) -// postMigrationTestRoutine runs Bitcoin related e2e tests +// postMigrationTestRoutine runs post migration tests func postMigrationTestRoutine( conf config.Config, deployerRunner *runner.E2ERunner, @@ -19,8 +19,8 @@ func postMigrationTestRoutine( testNames ...string, ) func() error { return func() (err error) { - account := conf.AdditionalAccounts.UserBitcoin - // initialize runner for bitcoin test + account := conf.AdditionalAccounts.UserMigration + // initialize runner for post migration test postMigrationRunner, err := initTestRunner( "postMigration", conf, @@ -35,25 +35,6 @@ func postMigrationTestRoutine( postMigrationRunner.Logger.Print("🏃 starting postMigration tests") startTime := time.Now() - // funding the account - //txERC20Send := deployerRunner.SendERC20OnEvm(account.EVMAddress(), 1000) - //postMigrationRunner.WaitForTxReceiptOnEvm(txERC20Send) - // - //// depositing the necessary tokens on ZetaChain - //txEtherDeposit := postMigrationRunner.DepositEther(false) - //txERC20Deposit := postMigrationRunner.DepositERC20() - // - //postMigrationRunner.WaitForMinedCCTX(txEtherDeposit) - //postMigrationRunner.WaitForMinedCCTX(txERC20Deposit) - // - //postMigrationRunner.Name = "bitcoin" - //postMigrationRunner.SetupBitcoinAccount(initBitcoinNetwork) - //postMigrationRunner.Name = "postMigration" - //postMigrationRunner.DepositBTC(testHeader) - - // run bitcoin test - // Note: due to the extensive block generation in Bitcoin localnet, block header test is run first - // to make it faster to catch up with the latest block header testsToRun, err := postMigrationRunner.GetE2ETestsToRunByName( e2etests.AllE2ETests, testNames..., diff --git a/contrib/localnet/scripts/start-zetacored.sh b/contrib/localnet/scripts/start-zetacored.sh index 64779d2a39..1605afad5a 100755 --- a/contrib/localnet/scripts/start-zetacored.sh +++ b/contrib/localnet/scripts/start-zetacored.sh @@ -242,6 +242,9 @@ then # ethers tester address=$(yq -r '.additional_accounts.user_ether.bech32_address' /root/config.yml) zetacored add-genesis-account "$address" 100000000000000000000000000azeta +# migration tester + address=$(yq -r '.additional_accounts.user_migration.bech32_address' /root/config.yml) + zetacored add-genesis-account "$address" 100000000000000000000000000azeta # 3. Copy the genesis.json to all the nodes .And use it to create a gentx for every node zetacored gentx operator 1000000000000000000000azeta --chain-id=$CHAINID --keyring-backend=$KEYRING --gas-prices 20000000000azeta diff --git a/e2e/config/config.go b/e2e/config/config.go index 66409ee339..84e952086a 100644 --- a/e2e/config/config.go +++ b/e2e/config/config.go @@ -65,6 +65,7 @@ type AdditionalAccounts struct { UserMisc Account `yaml:"user_misc"` UserAdmin Account `yaml:"user_admin"` UserFungibleAdmin Account `yaml:"user_fungible_admin"` + UserMigration Account `yaml:"user_migration"` } // RPCs contains the configuration for the RPC endpoints @@ -193,6 +194,7 @@ func (a AdditionalAccounts) AsSlice() []Account { a.UserMisc, a.UserAdmin, a.UserFungibleAdmin, + a.UserMigration, } } @@ -261,6 +263,10 @@ func (c *Config) GenerateKeys() error { if err != nil { return err } + c.AdditionalAccounts.UserMigration, err = generateAccount() + if err != nil { + return err + } return nil } diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index ea1e2ddadf..7ffb2fa832 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -18,8 +18,7 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -func TestMigrateTss(r *runner.E2ERunner, args []string) { - +func TestMigrateTss(r *runner.E2ERunner, _ []string) { r.SetBtcAddress(r.Name, false) stop := r.MineBlocksIfLocalBitcoin() defer stop() diff --git a/e2e/runner/accounting.go b/e2e/runner/accounting.go index 6a2c2504b6..d5f0ed2ae5 100644 --- a/e2e/runner/accounting.go +++ b/e2e/runner/accounting.go @@ -33,9 +33,9 @@ func (r *E2ERunner) CheckZRC20ReserveAndSupply() error { return r.checkZetaTSSBalance() } -func (runner *E2ERunner) checkEthTSSBalance() error { +func (r *E2ERunner) checkEthTSSBalance() error { - allTssAddress, err := runner.ObserverClient.TssHistory(runner.Ctx, &observertypes.QueryTssHistoryRequest{}) + allTssAddress, err := r.ObserverClient.TssHistory(r.Ctx, &observertypes.QueryTssHistoryRequest{}) if err != nil { return err } @@ -43,33 +43,32 @@ func (runner *E2ERunner) checkEthTSSBalance() error { tssTotalBalance := big.NewInt(0) for _, tssAddress := range allTssAddress.TssList { - evmAddress, err := runner.ObserverClient.GetTssAddressByFinalizedHeight(runner.Ctx, &observertypes.QueryGetTssAddressByFinalizedHeightRequest{ + evmAddress, err := r.ObserverClient.GetTssAddressByFinalizedHeight(r.Ctx, &observertypes.QueryGetTssAddressByFinalizedHeightRequest{ FinalizedZetaHeight: tssAddress.FinalizedZetaHeight, }) if err != nil { continue } - tssBal, err := runner.EVMClient.BalanceAt(runner.Ctx, common.HexToAddress(evmAddress.Eth), nil) + tssBal, err := r.EVMClient.BalanceAt(r.Ctx, common.HexToAddress(evmAddress.Eth), nil) if err != nil { continue } tssTotalBalance.Add(tssTotalBalance, tssBal) } - zrc20Supply, err := runner.ETHZRC20.TotalSupply(&bind.CallOpts{}) + zrc20Supply, err := r.ETHZRC20.TotalSupply(&bind.CallOpts{}) if err != nil { return err } if tssTotalBalance.Cmp(zrc20Supply) < 0 { return fmt.Errorf("ETH: TSS balance (%d) < ZRC20 TotalSupply (%d) ", tssTotalBalance, zrc20Supply) } - runner.Logger.Info("ETH: TSS balance (%d) >= ZRC20 TotalSupply (%d)", tssTotalBalance, zrc20Supply) + r.Logger.Info("ETH: TSS balance (%d) >= ZRC20 TotalSupply (%d)", tssTotalBalance, zrc20Supply) return nil } func (r *E2ERunner) CheckBtcTSSBalance() error { - allTssAddress, err := r.ObserverClient.TssHistory(r.Ctx, &observertypes.QueryTssHistoryRequest{}) if err != nil { return err @@ -91,20 +90,8 @@ func (r *E2ERunner) CheckBtcTSSBalance() error { tssTotalBalance += utxo.Amount } } - } - //utxos, err := r.BtcRPCClient.ListUnspent() - //if err != nil { - // return err - //} - //var btcBalance float64 - //for _, utxo := range utxos { - // if utxo.Address == r.BTCTSSAddress.EncodeAddress() { - // btcBalance += utxo.Amount - // } - //} - zrc20Supply, err := r.BTCZRC20.TotalSupply(&bind.CallOpts{}) if err != nil { return err diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index 0c56bbdf21..7f28672f2f 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -16,7 +16,6 @@ func (k Keeper) ValidateInbound( msg *types.MsgVoteInbound, shouldPayGas bool, ) (*types.CrossChainTx, error) { - err := k.CheckMigration(ctx, msg) if err != nil { return nil, err diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index 504b960d47..bdc082d6b7 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -433,13 +433,7 @@ func (ob *Observer) setIncludedTx(nonce uint64, getTxResult *btcjson.GetTransact ob.Mu().Lock() defer ob.Mu().Unlock() res, found := ob.includedTxResults[outboundID] - - fmt.Printf("latest confirmations %d", getTxResult.Confirmations) - if !found { // not found. - - fmt.Printf("setIncludedTx: included new bitcoin outbound %s outboundID %s pending nonce %d", txHash, outboundID, ob.pendingNonce) - ob.includedTxHashes[txHash] = true ob.includedTxResults[outboundID] = getTxResult // include new outbound and enforce rigid 1-to-1 mapping: nonce <===> txHash if nonce >= ob.pendingNonce { // try increasing pending nonce on every newly included outbound @@ -447,16 +441,12 @@ func (ob *Observer) setIncludedTx(nonce uint64, getTxResult *btcjson.GetTransact } ob.logger.Outbound.Info(). Msgf("setIncludedTx: included new bitcoin outbound %s outboundID %s pending nonce %d", txHash, outboundID, ob.pendingNonce) - } else if txHash == res.TxID { // found same hash. - - fmt.Printf("setIncludedTx: update bitcoin outbound %s got confirmations %d", txHash, getTxResult.Confirmations) + } else if txHash == res.TxID { // found same hash ob.includedTxResults[outboundID] = getTxResult // update tx result as confirmations may increase if getTxResult.Confirmations > res.Confirmations { ob.logger.Outbound.Info().Msgf("setIncludedTx: bitcoin outbound %s got confirmations %d", txHash, getTxResult.Confirmations) } } else { // found other hash. - - fmt.Printf("setIncludedTx: duplicate payment by bitcoin outbound %s outboundID %s, prior outbound %s", txHash, outboundID, res.TxID) // be alert for duplicate payment!!! As we got a new hash paying same cctx (for whatever reason). delete(ob.includedTxResults, outboundID) // we can't tell which txHash is true, so we remove all to be safe ob.logger.Outbound.Error().Msgf("setIncludedTx: duplicate payment by bitcoin outbound %s outboundID %s, prior outbound %s", txHash, outboundID, res.TxID) diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 59ece1070c..eb418cb08b 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -438,7 +438,7 @@ func (tss *TSS) EVMAddress() ethcommon.Address { } func (tss *TSS) EVMAddressList() []ethcommon.Address { - var addresses []ethcommon.Address + addresses := make([]ethcommon.Address, 0) for _, key := range tss.Keys { addr, err := GetTssAddrEVM(key.PubkeyInBech32) if err != nil { From 4ff9b04ba440a655254543c1f254ff24da91ccd1 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 15:06:54 -0400 Subject: [PATCH 20/40] fix some lint issues and rename all runners to r --- e2e/runner/accounting.go | 1 - 1 file changed, 1 deletion(-) diff --git a/e2e/runner/accounting.go b/e2e/runner/accounting.go index d5f0ed2ae5..e2cc51313e 100644 --- a/e2e/runner/accounting.go +++ b/e2e/runner/accounting.go @@ -34,7 +34,6 @@ func (r *E2ERunner) CheckZRC20ReserveAndSupply() error { } func (r *E2ERunner) checkEthTSSBalance() error { - allTssAddress, err := r.ObserverClient.TssHistory(r.Ctx, &observertypes.QueryTssHistoryRequest{}) if err != nil { return err From 897fdb3272732cc23ad881353b636a6eacb93a47 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 16:12:34 -0400 Subject: [PATCH 21/40] add changelog --- changelog.md | 1 + cmd/zetaclientd-supervisor/lib.go | 5 +++-- cmd/zetaclientd/keygen_tss.go | 9 +++++++-- cmd/zetaclientd/start.go | 4 ++-- cmd/zetae2e/local/local.go | 8 ++++++-- cmd/zetae2e/local/migration.go | 2 +- e2e/e2etests/test_migrate_tss.go | 12 ++++++++++-- e2e/runner/accounting.go | 10 +++++++--- .../keeper/cctx_orchestrator_validate_inbound.go | 1 + x/crosschain/keeper/msg_server_migrate_tss_funds.go | 4 +++- .../keeper/msg_server_migrate_tss_funds_test.go | 3 ++- .../keeper/msg_server_remove_outbound_tracker.go | 2 +- x/crosschain/keeper/msg_server_update_tss_test.go | 6 +++++- zetaclient/chains/bitcoin/observer/outbound.go | 7 +++++-- zetaclient/chains/evm/observer/outbound.go | 9 ++++++--- 15 files changed, 60 insertions(+), 23 deletions(-) diff --git a/changelog.md b/changelog.md index 7b679fb678..789515b900 100644 --- a/changelog.md +++ b/changelog.md @@ -76,6 +76,7 @@ * [2349](https://github.com/zeta-chain/node/pull/2349) - add TestBitcoinDepositRefund and WithdrawBitcoinMultipleTimes E2E tests * [2368](https://github.com/zeta-chain/node/pull/2368) - eliminate panic usage across testing suite * [2369](https://github.com/zeta-chain/node/pull/2369) - fix random cross-chain swap failure caused by using tiny UTXO +* [2440](https://github.com/zeta-chain/node/pull/2440) - Add e2e test for Tss migration ### Fixes diff --git a/cmd/zetaclientd-supervisor/lib.go b/cmd/zetaclientd-supervisor/lib.go index 7b8cfbb4dd..4c495dcf1d 100644 --- a/cmd/zetaclientd-supervisor/lib.go +++ b/cmd/zetaclientd-supervisor/lib.go @@ -19,9 +19,9 @@ import ( upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/hashicorp/go-getter" "github.com/rs/zerolog" - observertypes "github.com/zeta-chain/zetacore/x/observer/types" "google.golang.org/grpc" + observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/config" ) @@ -207,7 +207,8 @@ func (s *zetaclientdSupervisor) handleTssUpdate(ctx context.Context) { } tss = tssNew - s.logger.Warn().Msg(fmt.Sprintf("tss address is updated from %s to %s", tss.TSS.TssPubkey, tssNew.TSS.TssPubkey)) + s.logger.Warn(). + Msg(fmt.Sprintf("tss address is updated from %s to %s", tss.TSS.TssPubkey, tssNew.TSS.TssPubkey)) time.Sleep(6 * time.Second) s.logger.Info().Msg("restarting zetaclientd to update tss address") s.restartChan <- syscall.SIGHUP diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 74c45841fe..49c1407028 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -11,11 +11,11 @@ import ( tsscommon "github.com/zeta-chain/go-tss/common" "github.com/zeta-chain/go-tss/keygen" "github.com/zeta-chain/go-tss/tss" - "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "golang.org/x/crypto/sha3" "github.com/zeta-chain/zetacore/pkg/chains" observertypes "github.com/zeta-chain/zetacore/x/observer/types" + "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "github.com/zeta-chain/zetacore/zetaclient/context" "github.com/zeta-chain/zetacore/zetaclient/metrics" mc "github.com/zeta-chain/zetacore/zetaclient/tss" @@ -120,7 +120,12 @@ func GenerateTss( // keygenTss generates a new TSS using the keygen request and the TSS server. // If the keygen is successful, the function returns the new TSS pubkey. // If the keygen is unsuccessful, the function posts blame and returns an error. -func keygenTss(keyGen observertypes.Keygen, tssServer tss.TssServer, zetacoreClient interfaces.ZetacoreClient, keygenLogger zerolog.Logger) (string, error) { +func keygenTss( + keyGen observertypes.Keygen, + tssServer tss.TssServer, + zetacoreClient interfaces.ZetacoreClient, + keygenLogger zerolog.Logger, +) (string, error) { keygenLogger.Info().Msgf("Keygen at blocknum %d , TSS signers %s ", keyGen.BlockNumber, keyGen.GranteePubkeys) var req keygen.Request req = keygen.NewRequest(keyGen.GranteePubkeys, keyGen.BlockNumber, "0.14.0") diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index 825046c04b..e2b3dae4e7 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -20,10 +20,9 @@ import ( "github.com/rs/zerolog/log" "github.com/spf13/cobra" "github.com/zeta-chain/go-tss/p2p" - "github.com/zeta-chain/zetacore/pkg/chains" - mc "github.com/zeta-chain/zetacore/zetaclient/tss" "github.com/zeta-chain/zetacore/pkg/authz" + "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/constant" observerTypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/chains/base" @@ -31,6 +30,7 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/context" "github.com/zeta-chain/zetacore/zetaclient/metrics" "github.com/zeta-chain/zetacore/zetaclient/orchestrator" + mc "github.com/zeta-chain/zetacore/zetaclient/tss" ) type Multiaddr = core.Multiaddr diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index fe45d1aa44..829569cefd 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -9,6 +9,8 @@ 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" "github.com/zeta-chain/zetacore/e2e/config" "github.com/zeta-chain/zetacore/e2e/e2etests" @@ -19,7 +21,6 @@ import ( "github.com/zeta-chain/zetacore/testutil" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" - "golang.org/x/sync/errgroup" ) const ( @@ -331,7 +332,10 @@ func localE2ETest(cmd *cobra.Command, _ []string) { migrationStartTime := time.Now() logger.Print("🏁 starting tss migration") - response, err := deployerRunner.CctxClient.LastZetaHeight(migrationCtx, &crosschaintypes.QueryLastZetaHeightRequest{}) + response, err := deployerRunner.CctxClient.LastZetaHeight( + migrationCtx, + &crosschaintypes.QueryLastZetaHeightRequest{}, + ) require.NoError(deployerRunner, err) err = zetaTxServer.UpdateKeygen(response.Height) require.NoError(deployerRunner, err) diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index 0699894799..9a28a9d7a7 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -6,9 +6,9 @@ import ( "time" "github.com/fatih/color" - "github.com/zeta-chain/zetacore/e2e/e2etests" "github.com/zeta-chain/zetacore/e2e/config" + "github.com/zeta-chain/zetacore/e2e/e2etests" "github.com/zeta-chain/zetacore/e2e/runner" ) diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index 7ffb2fa832..9c85ece8c1 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" zetacrypto "github.com/zeta-chain/zetacore/pkg/crypto" @@ -87,7 +88,10 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { require.NoError(r, err) // Fetch migrator cctx for eth migration - migrator, err = r.ObserverClient.TssFundsMigratorInfo(r.Ctx, &observertypes.QueryTssFundsMigratorInfoRequest{ChainId: evmChainID.Int64()}) + migrator, err = r.ObserverClient.TssFundsMigratorInfo( + r.Ctx, + &observertypes.QueryTssFundsMigratorInfoRequest{ChainId: evmChainID.Int64()}, + ) require.NoError(r, err) cctxETHMigration := migrator.TssFundsMigrator.MigrationCctxIndex @@ -149,7 +153,11 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { r.Logger.Info(fmt.Sprintf("Migrator amount : %s", cctxBTC.GetCurrentOutboundParam().Amount)) // btcTSSBalanceNew should be less than btcTSSBalanceOld as there is some loss of funds during migration - require.Equal(r, strconv.FormatInt(int64(btcTSSBalanceNew*1e8), 10), cctxBTC.GetCurrentOutboundParam().Amount.String()) + require.Equal( + r, + strconv.FormatInt(int64(btcTSSBalanceNew*1e8), 10), + cctxBTC.GetCurrentOutboundParam().Amount.String(), + ) require.LessOrEqual(r, btcTSSBalanceNew*1e8, btcTSSBalanceOld*1e8) // ETH diff --git a/e2e/runner/accounting.go b/e2e/runner/accounting.go index e2cc51313e..cdcc269066 100644 --- a/e2e/runner/accounting.go +++ b/e2e/runner/accounting.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + zetacrypto "github.com/zeta-chain/zetacore/pkg/crypto" observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) @@ -42,9 +43,12 @@ func (r *E2ERunner) checkEthTSSBalance() error { tssTotalBalance := big.NewInt(0) for _, tssAddress := range allTssAddress.TssList { - evmAddress, err := r.ObserverClient.GetTssAddressByFinalizedHeight(r.Ctx, &observertypes.QueryGetTssAddressByFinalizedHeightRequest{ - FinalizedZetaHeight: tssAddress.FinalizedZetaHeight, - }) + evmAddress, err := r.ObserverClient.GetTssAddressByFinalizedHeight( + r.Ctx, + &observertypes.QueryGetTssAddressByFinalizedHeightRequest{ + FinalizedZetaHeight: tssAddress.FinalizedZetaHeight, + }, + ) if err != nil { continue } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index 7f28672f2f..a51c3fa927 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -3,6 +3,7 @@ package keeper import ( "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/pkg/crypto" "github.com/zeta-chain/zetacore/x/crosschain/types" diff --git a/x/crosschain/keeper/msg_server_migrate_tss_funds.go b/x/crosschain/keeper/msg_server_migrate_tss_funds.go index 73598b3e22..8656cf2e80 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds.go @@ -182,7 +182,9 @@ func (k Keeper) MigrateTSSFundsForChain( ) } - cctx.GetCurrentOutboundParam().Amount = amount.Sub(evmFee.Add(sdkmath.NewUintFromString(types.TSSMigrationBufferAmountEVM))) + cctx.GetCurrentOutboundParam().Amount = amount.Sub( + evmFee.Add(sdkmath.NewUintFromString(types.TSSMigrationBufferAmountEVM)), + ) } // Set the sender and receiver addresses for Bitcoin chain if chains.IsBitcoinChain(chainID, additionalChains) { 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 0fe5a5c28a..7e86307fc0 100644 --- a/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go +++ b/x/crosschain/keeper/msg_server_migrate_tss_funds_test.go @@ -385,7 +385,8 @@ func TestMsgServer_MigrateTssFunds(t *testing.T) { cctx, found := k.GetCrossChainTx(ctx, index) require.True(t, found) feeCalculated := sdk.NewUint(cctx.GetCurrentOutboundParam().GasLimit). - Mul(sdkmath.NewUintFromString(cctx.GetCurrentOutboundParam().GasPrice)).Add(sdkmath.NewUintFromString(crosschaintypes.TSSMigrationBufferAmountEVM)) + Mul(sdkmath.NewUintFromString(cctx.GetCurrentOutboundParam().GasPrice)). + Add(sdkmath.NewUintFromString(crosschaintypes.TSSMigrationBufferAmountEVM)) require.Equal(t, cctx.GetCurrentOutboundParam().Amount.String(), amount.Sub(feeCalculated).String()) }) diff --git a/x/crosschain/keeper/msg_server_remove_outbound_tracker.go b/x/crosschain/keeper/msg_server_remove_outbound_tracker.go index 00b7be6e29..ef20dfc6f7 100644 --- a/x/crosschain/keeper/msg_server_remove_outbound_tracker.go +++ b/x/crosschain/keeper/msg_server_remove_outbound_tracker.go @@ -5,8 +5,8 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" - authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" + authoritytypes "github.com/zeta-chain/zetacore/x/authority/types" "github.com/zeta-chain/zetacore/x/crosschain/types" ) diff --git a/x/crosschain/keeper/msg_server_update_tss_test.go b/x/crosschain/keeper/msg_server_update_tss_test.go index c071406aea..761ff617c8 100644 --- a/x/crosschain/keeper/msg_server_update_tss_test.go +++ b/x/crosschain/keeper/msg_server_update_tss_test.go @@ -224,7 +224,11 @@ func TestMsgServer_UpdateTssAddress(t *testing.T) { } keepertest.MockCheckAuthorization(&authorityMock.Mock, &msg, nil) _, err := msgServer.UpdateTssAddress(ctx, &msg) - require.ErrorContains(t, err, "cannot update tss address incorrect number of migrations have been created and completed: unable to update TSS address") + require.ErrorContains( + t, + err, + "cannot update tss address incorrect number of migrations have been created and completed: unable to update TSS address", + ) require.ErrorIs(t, err, crosschaintypes.ErrUnableToUpdateTss) tss, found := k.GetObserverKeeper().GetTSS(ctx) require.True(t, found) diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index bdc082d6b7..efbc109dcb 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -138,7 +138,6 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // prevents double spending of same UTXO. However, for nonce 0, we don't have a prior nonce (e.g., -1) // for the signer to check against when making the payment. Signer treats nonce 0 as a special case in downstream code. if nonce == 0 { - fmt.Println("IsOutboundProcessed: nonce is zero") return true, false, nil } @@ -167,7 +166,11 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // It's safe to use cctx's amount to post confirmation because it has already been verified in observeOutbound() amountInSat := params.Amount.BigInt() if res.Confirmations < ob.ConfirmationsThreshold(amountInSat) { - fmt.Printf("IsOutboundProcessed: outbound not confirmed yet %d: %d", res.Confirmations, ob.ConfirmationsThreshold(amountInSat)) + fmt.Printf( + "IsOutboundProcessed: outbound not confirmed yet %d: %d", + res.Confirmations, + ob.ConfirmationsThreshold(amountInSat), + ) return true, false, nil } diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index 7015ce33d7..5952d1fa4e 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -376,8 +376,9 @@ func (ob *Observer) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Rec } } if !isOldTssAddress { - log.Error().Msgf("confirmTxByHash: sender %s for outbound %s chain %d is not current or old TSS address. Current TSS %s", - from.Hex(), transaction.Hash().Hex(), ob.Chain().ChainId, ob.TSS().EVMAddress().Hex()) + log.Error(). + Msgf("confirmTxByHash: sender %s for outbound %s chain %d is not current or old TSS address. Current TSS %s", + from.Hex(), transaction.Hash().Hex(), ob.Chain().ChainId, ob.TSS().EVMAddress().Hex()) return nil, nil, false } } @@ -407,7 +408,9 @@ func (ob *Observer) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Rec // check confirmations lastHeight, err := ob.evmClient.BlockNumber(context.Background()) if err != nil { - log.Error().Err(err).Msgf("confirmTxByHash: error getting block number for chain %d", ob.GetChainParams().ChainId) + log.Error(). + Err(err). + Msgf("confirmTxByHash: error getting block number for chain %d", ob.GetChainParams().ChainId) return nil, nil, false } if !ob.HasEnoughConfirmations(receipt, lastHeight) { From 263131c614122356fe9bf2da20da9dcc0f1b6eca Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 22:07:55 -0400 Subject: [PATCH 22/40] fix lint errors --- e2e/e2etests/test_migrate_tss.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index 9c85ece8c1..ba48571360 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -40,7 +40,6 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { var btcBalance float64 for _, utxo := range utxos { - r.Logger.Info(fmt.Sprintf("UTXO Amount old : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) btcBalance += utxo.Amount } @@ -50,9 +49,8 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { btcBalance -= fees btcChain := int64(18444) - r.Logger.Info("BTC TSS migration amount: %d", int64(btcBalance*1e8)) - //migrate btc funds + // #nosec G701 e2eTest - always in range migrationAmountBTC := sdkmath.NewUint(uint64(btcBalance * 1e8)) msgMigrateFunds := crosschaintypes.NewMsgMigrateTssFunds( r.ZetaTxServer.GetAccountAddress(0), @@ -143,8 +141,8 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { require.NoError(r, err) var btcTSSBalanceNew float64 + // #nosec G701 e2eTest - always in range for _, utxo := range utxos { - r.Logger.Info(fmt.Sprintf("UTXO Amount new : %d, Spendable : %t", int64(utxo.Amount*1e8), utxo.Spendable)) btcTSSBalanceNew += utxo.Amount } @@ -153,6 +151,7 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { r.Logger.Info(fmt.Sprintf("Migrator amount : %s", cctxBTC.GetCurrentOutboundParam().Amount)) // btcTSSBalanceNew should be less than btcTSSBalanceOld as there is some loss of funds during migration + // #nosec G701 e2eTest - always in range require.Equal( r, strconv.FormatInt(int64(btcTSSBalanceNew*1e8), 10), From 6f5de146bf39fbbb4e619138ccbdcd7513ec1fed Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 22:16:06 -0400 Subject: [PATCH 23/40] fix lint errors --- x/crosschain/types/keys.go | 2 +- zetaclient/tss/tss_signer.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/x/crosschain/types/keys.go b/x/crosschain/types/keys.go index 82d2dc9299..5bb89a61ea 100644 --- a/x/crosschain/types/keys.go +++ b/x/crosschain/types/keys.go @@ -27,7 +27,7 @@ const ( //TssMigrationGasMultiplierEVM is multiplied to the median gas price to get the gas price for the tss migration . This is done to avoid the tss migration tx getting stuck in the mempool TssMigrationGasMultiplierEVM = "2.5" - + // TSSMigrationBufferAmountEVM is the buffer amount added to the gas price for the tss migration transaction TSSMigrationBufferAmountEVM = "2100000000" // CCTXIndexLength is the length of a crosschain transaction index diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index eb418cb08b..99f09ad53d 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -244,7 +244,6 @@ func (tss *TSS) Sign( ksRes, err := tss.Server.KeySign(keysignReq) tss.KeysignsTracker.EndMsgSign() if err != nil { - fmt.Println("keysign fail reason : ", err.Error()) log.Warn().Msg("keysign fail") } From db6735cbb9bd753dc6eb8e58b6e00e93dfca6e6d Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 7 Jul 2024 23:41:41 -0400 Subject: [PATCH 24/40] removed debug logs --- cmd/zetaclientd-supervisor/lib.go | 6 +++--- cmd/zetae2e/local/migration.go | 2 +- e2e/runner/bitcoin.go | 2 -- e2e/runner/evm.go | 2 -- e2e/runner/zeta.go | 2 -- e2e/utils/zetacore.go | 2 +- x/crosschain/keeper/cctx_orchestrator_validate_inbound.go | 1 - zetaclient/chains/bitcoin/observer/outbound.go | 6 +----- zetaclient/tss/tss_signer.go | 1 - 9 files changed, 6 insertions(+), 18 deletions(-) diff --git a/cmd/zetaclientd-supervisor/lib.go b/cmd/zetaclientd-supervisor/lib.go index 4c495dcf1d..0eedce3311 100644 --- a/cmd/zetaclientd-supervisor/lib.go +++ b/cmd/zetaclientd-supervisor/lib.go @@ -207,8 +207,8 @@ func (s *zetaclientdSupervisor) handleTssUpdate(ctx context.Context) { } tss = tssNew - s.logger.Warn(). - Msg(fmt.Sprintf("tss address is updated from %s to %s", tss.TSS.TssPubkey, tssNew.TSS.TssPubkey)) + s.logger.Info(). + Msgf("tss address is updated from %s to %s", tss.TSS.TssPubkey, tssNew.TSS.TssPubkey) time.Sleep(6 * time.Second) s.logger.Info().Msg("restarting zetaclientd to update tss address") s.restartChan <- syscall.SIGHUP @@ -253,7 +253,7 @@ func (s *zetaclientdSupervisor) handleNewTssKeyGeneration(ctx context.Context) { } tssLenCurrent = tssLenUpdated - s.logger.Warn().Msg(fmt.Sprintf("tss list updated from %d to %d", tssLenCurrent, tssLenUpdated)) + s.logger.Info().Msgf("tss list updated from %d to %d", tssLenCurrent, tssLenUpdated) time.Sleep(5 * time.Second) s.logger.Info().Msg("restarting zetaclientd to update tss list") s.restartChan <- syscall.SIGHUP diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index 9a28a9d7a7..f50a2cdb6b 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -62,7 +62,7 @@ func migrationTestRoutine( return fmt.Errorf("migration tests failed: %v", err) } if err := migrationTestRunner.CheckBtcTSSBalance(); err != nil { - migrationTestRunner.Logger.Print("🍾 BTC check error") + return err } migrationTestRunner.Logger.Print("🍾 migration tests completed in %s", time.Since(startTime).String()) diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index f26640608d..916ce4cf30 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -77,8 +77,6 @@ func (r *E2ERunner) GetTop20UTXOsForTssAddress() ([]btcjson.ListUnspentResult, e return utxos, nil } -// query UTXOs from node - // DepositBTCWithAmount deposits BTC on ZetaChain with a specific amount func (r *E2ERunner) DepositBTCWithAmount(amount float64) *chainhash.Hash { r.Logger.Print("⏳ depositing BTC into ZEVM") diff --git a/e2e/runner/evm.go b/e2e/runner/evm.go index 59ad587ada..88c1e100bf 100644 --- a/e2e/runner/evm.go +++ b/e2e/runner/evm.go @@ -129,8 +129,6 @@ func (r *E2ERunner) DepositEtherWithAmount(testHeader bool, amount *big.Int) eth r.Logger.EVMReceipt(*receipt, "send to TSS") - r.Logger.Print("✅ Ethers deposited into ZEVM") - // due to the high block throughput in localnet, ZetaClient might catch up slowly with the blocks // to optimize block header proof test, this test is directly executed here on the first deposit instead of having a separate test if testHeader { diff --git a/e2e/runner/zeta.go b/e2e/runner/zeta.go index e866f75af1..732104afe1 100644 --- a/e2e/runner/zeta.go +++ b/e2e/runner/zeta.go @@ -179,8 +179,6 @@ func (r *E2ERunner) WithdrawZeta(amount *big.Int, waitReceipt bool) *ethtypes.Tr return tx } -// zetacored tx crosschain remove-outbound-tracker 1337 13 --from=operator --fees=2000000000000000azeta --chain-id=athens_101-1 --yes - // WithdrawEther withdraws Ether from ZetaChain to the ZETA smart contract on EVM func (r *E2ERunner) WithdrawEther(amount *big.Int) *ethtypes.Transaction { // withdraw diff --git a/e2e/utils/zetacore.go b/e2e/utils/zetacore.go index cbd1477211..cbba05de75 100644 --- a/e2e/utils/zetacore.go +++ b/e2e/utils/zetacore.go @@ -18,7 +18,7 @@ type CCTXClient = crosschaintypes.QueryClient const ( FungibleAdminName = "fungibleadmin" - DefaultCctxTimeout = 8 * time.Minute + DefaultCctxTimeout = 4 * time.Minute ) // WaitCctxMinedByInboundHash waits until cctx is mined; returns the cctxIndex (the last one) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index a51c3fa927..eb7686b5c2 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -79,7 +79,6 @@ func (k Keeper) CheckMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error return errors.Wrap(types.ErrInvalidAddress, err.Error()) } if ethTssAddress.Hex() == msg.Sender { - ctx.Logger().Info("Sender is a TSS, cannot create CCTX") return types.ErrTssAddress } } else if chains.IsBitcoinChain(chain.ChainId, additionalChains) { diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index efbc109dcb..0089507844 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -129,7 +129,6 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg if !included { if !broadcasted { - fmt.Println("IsOutboundProcessed: outbound not broadcasted yet") return false, false, nil } // If the broadcasted outbound is nonce 0, just wait for inclusion and don't schedule more keysign @@ -144,10 +143,8 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // Try including this outbound broadcasted by myself txResult, inMempool := ob.checkIncludedTx(cctx, txnHash) if txResult == nil { // check failed, try again next time - fmt.Println("IsOutboundProcessed: txResult is nil, check failed, try again next time") return false, false, nil } else if inMempool { // still in mempool (should avoid unnecessary Tss keysign) - fmt.Println("IsOutboundProcessed: outbound still in mempool") ob.logger.Outbound.Info().Msgf("IsOutboundProcessed: outbound %s is still in mempool", outboundID) return true, false, nil } @@ -157,7 +154,6 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // Get tx result again in case it is just included res = ob.getIncludedTx(nonce) if res == nil { - fmt.Println("IsOutboundProcessed: setIncludedTx failed") return false, false, nil } ob.logger.Outbound.Info().Msgf("IsOutboundProcessed: setIncludedTx succeeded for outbound %s", outboundID) @@ -166,7 +162,7 @@ func (ob *Observer) IsOutboundProcessed(cctx *crosschaintypes.CrossChainTx, logg // It's safe to use cctx's amount to post confirmation because it has already been verified in observeOutbound() amountInSat := params.Amount.BigInt() if res.Confirmations < ob.ConfirmationsThreshold(amountInSat) { - fmt.Printf( + ob.logger.Outbound.Debug().Msgf( "IsOutboundProcessed: outbound not confirmed yet %d: %d", res.Confirmations, ob.ConfirmationsThreshold(amountInSat), diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 99f09ad53d..8c6cd10559 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -248,7 +248,6 @@ func (tss *TSS) Sign( } if ksRes.Status == thorcommon.Fail { - fmt.Println("signing tssPubkey", tssPubkey) log.Warn().Msgf("keysign status FAIL posting blame to core, blaming node(s): %#v", ksRes.Blame.BlameNodes) // post blame data if enabled From 614eae6d0a00d32451a557209031b319c7b92423 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 8 Jul 2024 09:44:10 -0400 Subject: [PATCH 25/40] add comments for zetasupervisor lib --- cmd/zetaclientd-supervisor/lib.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/zetaclientd-supervisor/lib.go b/cmd/zetaclientd-supervisor/lib.go index 0eedce3311..37e0c199c7 100644 --- a/cmd/zetaclientd-supervisor/lib.go +++ b/cmd/zetaclientd-supervisor/lib.go @@ -214,7 +214,7 @@ func (s *zetaclientdSupervisor) handleTssUpdate(ctx context.Context) { s.restartChan <- syscall.SIGHUP } } - return + s.logger.Warn().Msg("handleTssUpdate exiting without success") } func (s *zetaclientdSupervisor) handleNewTssKeyGeneration(ctx context.Context) { @@ -259,7 +259,7 @@ func (s *zetaclientdSupervisor) handleNewTssKeyGeneration(ctx context.Context) { s.restartChan <- syscall.SIGHUP } } - return + s.logger.Warn().Msg("handleNewTssKeyGeneration exiting without success") } func (s *zetaclientdSupervisor) handleNewKeygen(ctx context.Context) { From f48748720bac92e5b907d144a0be49d48ee65495 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 8 Jul 2024 12:39:24 -0400 Subject: [PATCH 26/40] add new user for migration tests --- cmd/zetae2e/config/localnet.yml | 8 ++++---- contrib/localnet/orchestrator/start-zetae2e.sh | 5 +++++ pkg/gas/gas_limits.go | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index 21239e5d87..83b32c10f2 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -32,14 +32,14 @@ additional_accounts: bech32_address: "zeta17w0adeg64ky0daxwd2ugyuneellmjgnx4e483s" evm_address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" private_key: "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + user_migration: + bech32_address: "zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz" + evm_address: "0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD" + private_key: "0BCC2FA28B526F90E1D54648D612DB901E860BF68248555593F91EA801C6B482" user_fungible_admin: bech32_address: "zeta1svzuz982w09vf2y08xsh8qplj36phyz466krj3" evm_address: "0x8305C114Ea73cAc4A88f39A173803F94741b9055" private_key: "d88d09a7d6849c15a36eb6931f9dd616091a63e9849a2cc86f309ba11fb8fec5" - user_migration_admin: - bech32_address: "zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz" - evm_address: "0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD" - private_key: "0BCC2FA28B526F90E1D54648D612DB901E860BF68248555593F91EA801C6B482" rpcs: zevm: "http://zetacore0:8545" evm: "http://eth:8545" diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 86dc089c2b..b51c1e6344 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -77,6 +77,11 @@ address=$(yq -r '.additional_accounts.user_admin.evm_address' config.yml) echo "funding admin tester address ${address} with 10000 Ether" geth --exec "eth.sendTransaction({from: eth.coinbase, to: '${address}', value: web3.toWei(10000,'ether')})" attach http://eth:8545 +# unlock migration tests accounts +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 if [ "$LOCALNET_MODE" == "upgrade" ]; then diff --git a/pkg/gas/gas_limits.go b/pkg/gas/gas_limits.go index 04e416477e..b585918b10 100644 --- a/pkg/gas/gas_limits.go +++ b/pkg/gas/gas_limits.go @@ -7,7 +7,7 @@ import ( const ( // EVMSend is the gas limit required to transfer tokens on an EVM based chain - EVMSend = 100_000 + EVMSend = 21_000 // TODO: Move gas limits from zeta-client to this file // https://github.com/zeta-chain/node/issues/1606 From 3b095a5167b61f4cf56c25cbc138f52043320a93 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 8 Jul 2024 13:18:24 -0400 Subject: [PATCH 27/40] add new user for migration tests --- cmd/zetae2e/local/post_migration.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/zetae2e/local/post_migration.go b/cmd/zetae2e/local/post_migration.go index d4fc7ab459..c1d34da9a4 100644 --- a/cmd/zetae2e/local/post_migration.go +++ b/cmd/zetae2e/local/post_migration.go @@ -19,7 +19,7 @@ func postMigrationTestRoutine( testNames ...string, ) func() error { return func() (err error) { - account := conf.AdditionalAccounts.UserMigration + account := conf.AdditionalAccounts.UserBitcoin // initialize runner for post migration test postMigrationRunner, err := initTestRunner( "postMigration", From 248aa74bcab5e5e40b5a10600252241b57305bc1 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 9 Jul 2024 18:41:55 -0400 Subject: [PATCH 28/40] change name to start-tss-migration-test --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e7a58fb3e3..057dd25ab9 100644 --- a/Makefile +++ b/Makefile @@ -254,7 +254,7 @@ start-stress-test: zetanode @echo "--> Starting stress test" cd contrib/localnet/ && $(DOCKER) compose --profile stress -f docker-compose.yml up -d -start-migrate-test: zetanode +start-tss-migration-test: zetanode @echo "--> Starting migration test" export E2E_ARGS="--test-migration" && \ cd contrib/localnet/ && $(DOCKER) compose up -d From aba41988595bc8c20f5e12e2197f224f7b75b3b7 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 11 Jul 2024 10:46:36 -0400 Subject: [PATCH 29/40] add changes for comments 1 --- cmd/zetaclientd-supervisor/lib.go | 14 ++++++++------ cmd/zetaclientd-supervisor/main.go | 1 + cmd/zetaclientd/keygen_tss.go | 5 +++-- cmd/zetaclientd/start.go | 2 +- cmd/zetae2e/local/local.go | 13 +++++-------- cmd/zetae2e/local/migration.go | 9 --------- e2e/e2etests/e2etests.go | 4 ++-- e2e/e2etests/test_migrate_tss.go | 12 ++++++------ e2e/runner/bitcoin.go | 3 ++- e2e/runner/setup_bitcoin.go | 2 +- e2e/txserver/zeta_tx_server.go | 1 + .../keeper/cctx_orchestrator_validate_inbound.go | 4 ++-- .../cctx_orchestrator_validate_inbound_test.go | 4 ++-- x/crosschain/types/errors.go | 2 +- 14 files changed, 35 insertions(+), 41 deletions(-) diff --git a/cmd/zetaclientd-supervisor/lib.go b/cmd/zetaclientd-supervisor/lib.go index 37e0c199c7..cf9b883ea6 100644 --- a/cmd/zetaclientd-supervisor/lib.go +++ b/cmd/zetaclientd-supervisor/lib.go @@ -100,8 +100,8 @@ func (s *zetaclientdSupervisor) Start(ctx context.Context) { go s.watchForVersionChanges(ctx) go s.handleCoreUpgradePlan(ctx) go s.handleNewKeygen(ctx) - go s.handleNewTssKeyGeneration(ctx) - go s.handleTssUpdate(ctx) + go s.handleNewTSSKeyGeneration(ctx) + go s.handleTSSUpdate(ctx) } func (s *zetaclientdSupervisor) WaitForReloadSignal(ctx context.Context) { @@ -177,10 +177,11 @@ func (s *zetaclientdSupervisor) watchForVersionChanges(ctx context.Context) { } } -func (s *zetaclientdSupervisor) handleTssUpdate(ctx context.Context) { +func (s *zetaclientdSupervisor) handleTSSUpdate(ctx context.Context) { maxRetries := 11 retryInterval := 5 * time.Second + // TODO : use retry library under pkg/retry for i := 0; i < maxRetries; i++ { client := observertypes.NewQueryClient(s.zetacoredConn) tss, err := client.TSS(ctx, &observertypes.QueryGetTSSRequest{}) @@ -214,13 +215,14 @@ func (s *zetaclientdSupervisor) handleTssUpdate(ctx context.Context) { s.restartChan <- syscall.SIGHUP } } - s.logger.Warn().Msg("handleTssUpdate exiting without success") + s.logger.Warn().Msg("handleTSSUpdate exiting without success") } -func (s *zetaclientdSupervisor) handleNewTssKeyGeneration(ctx context.Context) { +func (s *zetaclientdSupervisor) handleNewTSSKeyGeneration(ctx context.Context) { maxRetries := 11 retryInterval := 5 * time.Second + // TODO : use retry library under pkg/retry for i := 0; i < maxRetries; i++ { client := observertypes.NewQueryClient(s.zetacoredConn) alltss, err := client.TssHistory(ctx, &observertypes.QueryTssHistoryRequest{}) @@ -259,7 +261,7 @@ func (s *zetaclientdSupervisor) handleNewTssKeyGeneration(ctx context.Context) { s.restartChan <- syscall.SIGHUP } } - s.logger.Warn().Msg("handleNewTssKeyGeneration exiting without success") + s.logger.Warn().Msg("handleNewTSSKeyGeneration exiting without success") } func (s *zetaclientdSupervisor) handleNewKeygen(ctx context.Context) { diff --git a/cmd/zetaclientd-supervisor/main.go b/cmd/zetaclientd-supervisor/main.go index 203fbb5786..ee1e247be4 100644 --- a/cmd/zetaclientd-supervisor/main.go +++ b/cmd/zetaclientd-supervisor/main.go @@ -49,6 +49,7 @@ func main() { os.Exit(1) } supervisor.Start(ctx) + // listen for SIGHUP to trigger a restart of zetaclientd signal.Notify(supervisor.restartChan, syscall.SIGHUP) shouldRestart := true diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 49c1407028..e1b31b07dc 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -22,12 +22,12 @@ import ( "github.com/zeta-chain/zetacore/zetaclient/zetacore" ) -// GenerateTss generates a new TSS if keygen is set. +// GenerateTSS generates a new TSS if keygen is set. // If a TSS was generated successfully in the past,and the keygen was successful, the function will return without doing anything. // If a keygen has been set the functions will wait for the correct block to arrive and generate a new TSS. // In case of a successful keygen a TSS success vote is broadcasted to zetacore and the newly generate TSS is tested. The generated keyshares are stored in the correct directory // In case of a failed keygen a TSS failed vote is broadcasted to zetacore. -func GenerateTss( +func GenerateTSS( appContext *context.AppContext, logger zerolog.Logger, zetaCoreClient *zetacore.Client, @@ -161,6 +161,7 @@ func keygenTss( return res.PubKey, nil } +// TestTSS tests the TSS keygen by signing a sample message with the TSS key. func TestTSS(pubkey string, tssServer tss.TssServer, logger zerolog.Logger) error { keygenLogger := logger.With().Str("module", "test-keygen").Logger() keygenLogger.Info().Msgf("KeyGen success ! Doing a Key-sign test") diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index e2b3dae4e7..c6d03c3edd 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -214,7 +214,7 @@ func start(_ *cobra.Command, _ []string) error { // Generate a new TSS if keygen is set and add it into the tss server // If TSS has already been generated, and keygen was successful ; we use the existing TSS - err = GenerateTss(appContext, masterLogger, zetacoreClient, server) + err = GenerateTSS(appContext, masterLogger, zetacoreClient, server) if err != nil { return err } diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 829569cefd..c68d8cfc67 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -326,14 +326,12 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) if testMigration { - migrationCtx, cancel := context.WithCancel(context.Background()) - deployerRunner.CtxCancel = cancel migrationStartTime := time.Now() logger.Print("🏁 starting tss migration") response, err := deployerRunner.CctxClient.LastZetaHeight( - migrationCtx, + deployerRunner.Ctx, &crosschaintypes.QueryLastZetaHeightRequest{}, ) require.NoError(deployerRunner, err) @@ -341,12 +339,12 @@ func localE2ETest(cmd *cobra.Command, _ []string) { require.NoError(deployerRunner, err) // Generate new TSS - waitKeygenHeight(migrationCtx, deployerRunner.CctxClient, deployerRunner.ObserverClient, logger, 0) + 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.TestMigrateTssEthName) + fn := migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTSSEthName) if err := fn(); err != nil { logger.Print("❌ %v", err) @@ -361,10 +359,9 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestBitcoinWithdrawSegWitName, e2etests.TestEtherWithdrawName, } - eg.Go(postMigrationTestRoutine(conf, deployerRunner, verbose, tests...)) + fn = postMigrationTestRoutine(conf, deployerRunner, verbose, tests...) - if err := eg.Wait(); err != nil { - deployerRunner.CtxCancel() + if err := fn(); err != nil { logger.Print("❌ %v", err) logger.Print("❌ post migration tests failed") os.Exit(1) diff --git a/cmd/zetae2e/local/migration.go b/cmd/zetae2e/local/migration.go index f50a2cdb6b..d6fab1b709 100644 --- a/cmd/zetae2e/local/migration.go +++ b/cmd/zetae2e/local/migration.go @@ -2,7 +2,6 @@ package local import ( "fmt" - "runtime" "time" "github.com/fatih/color" @@ -20,14 +19,6 @@ func migrationTestRoutine( testNames ...string, ) func() error { return func() (err error) { - defer func() { - if r := recover(); r != nil { - // print stack trace - stack := make([]byte, 4096) - n := runtime.Stack(stack, false) - err = fmt.Errorf("admin panic: %v, stack trace %s", r, stack[:n]) - } - }() account := conf.AdditionalAccounts.UserMigration // initialize runner for migration test migrationTestRunner, err := initTestRunner( diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 7b59a79764..b8d6386ebc 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -101,7 +101,7 @@ const ( TestUpdateBytecodeConnectorName = "update_bytecode_connector" TestRateLimiterName = "rate_limiter" - TestMigrateTssEthName = "migrate_tss_eth" + TestMigrateTSSEthName = "migrate_tss_eth" /* Special tests @@ -545,7 +545,7 @@ var AllE2ETests = []runner.E2ETest{ TestDeployContract, ), runner.NewE2ETest( - TestMigrateTssEthName, + TestMigrateTSSEthName, "migrate TSS funds", []runner.ArgDefinition{}, TestMigrateTss, diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index ba48571360..548d82b315 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/pkg/chains" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" @@ -43,11 +44,10 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { btcBalance += utxo.Amount } - // Use fixed fee for migration btcTSSBalanceOld := btcBalance - fees := 0.01 - btcBalance -= fees - btcChain := int64(18444) + // Use fixed fee of 0.01 for migration + btcBalance = btcBalance - 0.01 + btcChain := chains.BitcoinRegtest.ChainId //migrate btc funds // #nosec G701 e2eTest - always in range @@ -73,7 +73,7 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { ethTSSBalanceOld := tssBalance tssBalanceUint := sdkmath.NewUintFromString(tssBalance.String()) - evmChainID, err := r.EVMClient.ChainID(context.Background()) + evmChainID, err := r.EVMClient.ChainID(r.Ctx) require.NoError(r, err) // Migrate TSS funds for the eth chain @@ -135,7 +135,7 @@ func TestMigrateTss(r *runner.E2ERunner, _ []string) { require.NoError(r, err) r.BTCTSSAddress = btcTssAddressNew - r.AddTssToNode() + r.AddTSSToNode() utxos, err = r.GetTop20UTXOsForTssAddress() require.NoError(r, err) diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index 916ce4cf30..7417bc0a07 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -55,7 +55,8 @@ func (r *E2ERunner) ListDeployerUTXOs() ([]btcjson.ListUnspentResult, error) { return utxos, nil } -// GetTop20UTXOsForTssAddress returns the top 20 UTXOs for the TSS address +// GetTop20UTXOsForTssAddress returns the top 20 UTXOs for the TSS address. +// Top 20 utxos should be used for TSS migration, as we can only migrate at max 20 utxos at a time. func (r *E2ERunner) GetTop20UTXOsForTssAddress() ([]btcjson.ListUnspentResult, error) { // query UTXOs from node utxos, err := r.BtcRPCClient.ListUnspentMinMaxAddresses( diff --git a/e2e/runner/setup_bitcoin.go b/e2e/runner/setup_bitcoin.go index 5ec7ebccae..236bb4fa11 100644 --- a/e2e/runner/setup_bitcoin.go +++ b/e2e/runner/setup_bitcoin.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/require" ) -func (r *E2ERunner) AddTssToNode() { +func (r *E2ERunner) AddTSSToNode() { r.Logger.Print("⚙️ add new tss to Bitcoin node") startTime := time.Now() defer func() { diff --git a/e2e/txserver/zeta_tx_server.go b/e2e/txserver/zeta_tx_server.go index 213ee803b7..a803cba2d6 100644 --- a/e2e/txserver/zeta_tx_server.go +++ b/e2e/txserver/zeta_tx_server.go @@ -424,6 +424,7 @@ func (zts ZetaTxServer) FundEmissionsPool(account string, amount *big.Int) error return err } +// UpdateKeygen sets a new keygen height . The new height is the current height + 30 func (zts ZetaTxServer) UpdateKeygen(height int64) error { keygenHeight := height + 30 _, err := zts.BroadcastTx(zts.GetAccountName(0), observertypes.NewMsgUpdateKeygen( diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index eb7686b5c2..2f905b3481 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -79,7 +79,7 @@ func (k Keeper) CheckMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error return errors.Wrap(types.ErrInvalidAddress, err.Error()) } if ethTssAddress.Hex() == msg.Sender { - return types.ErrTssAddress + return types.ErrMigrationFromOldTss } } else if chains.IsBitcoinChain(chain.ChainId, additionalChains) { bitcoinParams, err := chains.BitcoinNetParamsFromChainID(chain.ChainId) @@ -91,7 +91,7 @@ func (k Keeper) CheckMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error return errors.Wrap(types.ErrInvalidAddress, err.Error()) } if btcTssAddress == msg.Sender { - return types.ErrTssAddress + return types.ErrMigrationFromOldTss } } } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index 1de4fa367b..9e8f757ed3 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -177,7 +177,7 @@ func TestKeeper_CheckMigration(t *testing.T) { } err = k.CheckMigration(ctx, &msg) - require.ErrorIs(t, err, types.ErrTssAddress) + require.ErrorIs(t, err, types.ErrMigrationFromOldTss) }) t.Run("fails when sender is a TSS address for btc chain for btc chain", func(t *testing.T) { @@ -207,7 +207,7 @@ func TestKeeper_CheckMigration(t *testing.T) { } err = k.CheckMigration(ctx, &msg) - require.ErrorIs(t, err, types.ErrTssAddress) + require.ErrorIs(t, err, types.ErrMigrationFromOldTss) }) t.Run("fails if bitcoin network params not found for BTC chain", func(t *testing.T) { diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index a00b903a5f..eb3e579f6a 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -51,5 +51,5 @@ var ( ErrInitiatitingOutbound = errorsmod.Register(ModuleName, 1154, "cannot initiate outbound") ErrInvalidWithdrawalAmount = errorsmod.Register(ModuleName, 1155, "invalid withdrawal amount") - ErrTssAddress = errorsmod.Register(ModuleName, 1156, "sender cannot be a TSS address") + ErrMigrationFromOldTss = errorsmod.Register(ModuleName, 1156, "migration tx from an old tss address detected") ) From ba3540db75230d2a96bfd959b31b7df7eb8b99df Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 11 Jul 2024 12:20:19 -0400 Subject: [PATCH 30/40] add changes for comments 1 --- cmd/zetae2e/local/local.go | 2 +- e2e/e2etests/e2etests.go | 6 +- e2e/e2etests/test_migrate_tss.go | 2 +- ...cctx_orchestrator_validate_inbound_test.go | 400 ++++++++++++++++++ 4 files changed, 405 insertions(+), 5 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index c68d8cfc67..84898fe7a0 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -344,7 +344,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { // 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.TestMigrateTSSEthName) + fn := migrationTestRoutine(conf, deployerRunner, verbose, e2etests.TestMigrateTSSName) if err := fn(); err != nil { logger.Print("❌ %v", err) diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index b8d6386ebc..453a87ee68 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -101,7 +101,7 @@ const ( TestUpdateBytecodeConnectorName = "update_bytecode_connector" TestRateLimiterName = "rate_limiter" - TestMigrateTSSEthName = "migrate_tss_eth" + TestMigrateTSSName = "migrate_TSS" /* Special tests @@ -545,9 +545,9 @@ var AllE2ETests = []runner.E2ETest{ TestDeployContract, ), runner.NewE2ETest( - TestMigrateTSSEthName, + TestMigrateTSSName, "migrate TSS funds", []runner.ArgDefinition{}, - TestMigrateTss, + TestMigrateTSS, ), } diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index 548d82b315..77bd2eff6d 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -20,7 +20,7 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" ) -func TestMigrateTss(r *runner.E2ERunner, _ []string) { +func TestMigrateTSS(r *runner.E2ERunner, _ []string) { r.SetBtcAddress(r.Name, false) stop := r.MineBlocksIfLocalBitcoin() defer stop() diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index 9e8f757ed3..bbcd1b9786 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -3,8 +3,11 @@ package keeper_test import ( "testing" + sdkmath "cosmossdk.io/math" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/zeta-chain/zetacore/pkg/chains" + "github.com/zeta-chain/zetacore/pkg/coin" "github.com/zeta-chain/zetacore/pkg/crypto" keepertest "github.com/zeta-chain/zetacore/testutil/keeper" "github.com/zeta-chain/zetacore/testutil/sample" @@ -12,6 +15,403 @@ import ( observerTypes "github.com/zeta-chain/zetacore/x/observer/types" ) +func TestKeeper_ValidateInbound(t *testing.T) { + t.Run("successfully validate inbound", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + UseAuthorityMock: true, + }) + + // Setup mock data + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + receiver := sample.EthAddress() + creator := sample.AccAddress() + amount := sdkmath.NewUint(42) + message := "test" + inboundBlockHeight := uint64(420) + inboundHash := sample.Hash() + gasLimit := uint64(100) + asset := "test-asset" + eventIndex := uint64(1) + cointType := coin.CoinType_ERC20 + tss := sample.Tss() + receiverChain := chains.Goerli + senderChain := chains.Goerli + sender := sample.EthAddress() + tssList := sample.TssList(3) + + // Set up mocks for CheckMigration + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + // setup Mocks for GetTSS + observerMock.On("GetTSS", mock.Anything).Return(tss, true) + // setup Mocks for IsInboundEnabled + observerMock.On("IsInboundEnabled", ctx).Return(true) + // setup mocks for Initiate Outbound + observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observerTypes.ChainNonces{Nonce: 1}, true) + observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything).Return(observerTypes.PendingNonces{NonceHigh: 1}, true) + observerMock.On("SetChainNonces", mock.Anything, mock.Anything).Return(nil) + observerMock.On("SetPendingNonces", mock.Anything, mock.Anything).Return(nil) + // setup Mocks for SetCctxAndNonceToCctxAndInboundHashToCctx + observerMock.On("SetNonceToCctx", mock.Anything, mock.Anything).Return(nil) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: senderChain.ChainId, + MedianIndex: 0, + Prices: []uint64{100}, + }) + + // call InitiateOutbound + msg := types.MsgVoteInbound{ + Creator: creator, + Sender: sender.String(), + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + GasLimit: gasLimit, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, + } + + _, err := k.ValidateInbound(ctx, &msg, false) + require.NoError(t, err) + require.Len(t, k.GetAllCrossChainTx(ctx), 1) + }) + + t.Run("fail if tss not found", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + UseAuthorityMock: true, + }) + + // Setup mock data + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + receiver := sample.EthAddress() + creator := sample.AccAddress() + amount := sdkmath.NewUint(42) + message := "test" + inboundBlockHeight := uint64(420) + inboundHash := sample.Hash() + gasLimit := uint64(100) + asset := "test-asset" + eventIndex := uint64(1) + cointType := coin.CoinType_ERC20 + tss := sample.Tss() + receiverChain := chains.Goerli + senderChain := chains.Goerli + sender := sample.EthAddress() + tssList := sample.TssList(3) + + // Set up mocks for CheckMigration + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + // setup Mocks for GetTSS + observerMock.On("GetTSS", mock.Anything).Return(tss, false) + // setup Mocks for IsInboundEnabled + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: senderChain.ChainId, + MedianIndex: 0, + Prices: []uint64{100}, + }) + + // call InitiateOutbound + msg := types.MsgVoteInbound{ + Creator: creator, + Sender: sender.String(), + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + GasLimit: gasLimit, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, + } + + _, err := k.ValidateInbound(ctx, &msg, false) + require.ErrorIs(t, err, types.ErrCannotFindTSSKeys) + }) + + t.Run("fail if InitiateOutbound fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + UseAuthorityMock: true, + }) + + // Setup mock data + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + receiver := sample.EthAddress() + creator := sample.AccAddress() + amount := sdkmath.NewUint(42) + message := "test" + inboundBlockHeight := uint64(420) + inboundHash := sample.Hash() + gasLimit := uint64(100) + asset := "test-asset" + eventIndex := uint64(1) + cointType := coin.CoinType_ERC20 + tss := sample.Tss() + receiverChain := chains.Goerli + senderChain := chains.Goerli + sender := sample.EthAddress() + tssList := sample.TssList(3) + + // Set up mocks for CheckMigration + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + // setup Mocks for GetTSS + observerMock.On("GetTSS", mock.Anything).Return(tss, true) + // setup Mocks for IsInboundEnabled + observerMock.On("IsInboundEnabled", ctx).Return(true) + // setup mocks for Initiate Outbound + observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observerTypes.ChainNonces{Nonce: 1}, false) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: senderChain.ChainId, + MedianIndex: 0, + Prices: []uint64{100}, + }) + + // call InitiateOutbound + msg := types.MsgVoteInbound{ + Creator: creator, + Sender: sender.String(), + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + GasLimit: gasLimit, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, + } + + _, err := k.ValidateInbound(ctx, &msg, false) + require.ErrorIs(t, err, types.ErrCannotFindReceiverNonce) + }) + + t.Run("does not set cctx if SetCctxAndNonceToCctxAndInboundHashToCctx fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + UseAuthorityMock: true, + }) + + // Setup mock data + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + receiver := sample.EthAddress() + creator := sample.AccAddress() + amount := sdkmath.NewUint(42) + message := "test" + inboundBlockHeight := uint64(420) + inboundHash := sample.Hash() + gasLimit := uint64(100) + asset := "test-asset" + eventIndex := uint64(1) + cointType := coin.CoinType_ERC20 + tss := sample.Tss() + receiverChain := chains.Goerli + senderChain := chains.Goerli + sender := sample.EthAddress() + tssList := sample.TssList(3) + + // Set up mocks for CheckMigration + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + // setup Mocks for GetTSS + observerMock.On("GetTSS", mock.Anything).Return(tss, true).Twice() + // setup Mocks for IsInboundEnabled + observerMock.On("IsInboundEnabled", ctx).Return(true) + // setup mocks for Initiate Outbound + observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observerTypes.ChainNonces{Nonce: 1}, true) + observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything).Return(observerTypes.PendingNonces{NonceHigh: 1}, true) + observerMock.On("SetChainNonces", mock.Anything, mock.Anything).Return(nil) + observerMock.On("SetPendingNonces", mock.Anything, mock.Anything).Return(nil) + // setup Mocks for SetCctxAndNonceToCctxAndInboundHashToCctx + observerMock.On("GetTSS", mock.Anything).Return(tss, false).Once() + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: senderChain.ChainId, + MedianIndex: 0, + Prices: []uint64{100}, + }) + + // call InitiateOutbound + msg := types.MsgVoteInbound{ + Creator: creator, + Sender: sender.String(), + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + GasLimit: gasLimit, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, + } + + _, err := k.ValidateInbound(ctx, &msg, false) + require.NoError(t, err) + require.Len(t, k.GetAllCrossChainTx(ctx), 0) + }) + + t.Run("fail if inbound is disabled", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + UseAuthorityMock: true, + }) + + // Setup mock data + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + receiver := sample.EthAddress() + creator := sample.AccAddress() + amount := sdkmath.NewUint(42) + message := "test" + inboundBlockHeight := uint64(420) + inboundHash := sample.Hash() + gasLimit := uint64(100) + asset := "test-asset" + eventIndex := uint64(1) + cointType := coin.CoinType_ERC20 + tss := sample.Tss() + receiverChain := chains.Goerli + senderChain := chains.Goerli + sender := sample.EthAddress() + tssList := sample.TssList(3) + + // Set up mocks for CheckMigration + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + // setup Mocks for GetTSS + observerMock.On("GetTSS", mock.Anything).Return(tss, true) + // setup Mocks for IsInboundEnabled + observerMock.On("IsInboundEnabled", ctx).Return(false) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: senderChain.ChainId, + MedianIndex: 0, + Prices: []uint64{100}, + }) + + // call InitiateOutbound + msg := types.MsgVoteInbound{ + Creator: creator, + Sender: sender.String(), + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + GasLimit: gasLimit, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, + } + + _, err := k.ValidateInbound(ctx, &msg, false) + require.ErrorIs(t, err, observerTypes.ErrInboundDisabled) + }) + + t.Run("fails when CheckMigration fails", func(t *testing.T) { + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, + keepertest.CrosschainMockOptions{ + UseObserverMock: true, + UseFungibleMock: true, + UseAuthorityMock: true, + }) + + // Setup mock data + observerMock := keepertest.GetCrosschainObserverMock(t, k) + authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) + receiver := sample.EthAddress() + creator := sample.AccAddress() + amount := sdkmath.NewUint(42) + message := "test" + inboundBlockHeight := uint64(420) + inboundHash := sample.Hash() + gasLimit := uint64(100) + asset := "test-asset" + eventIndex := uint64(1) + cointType := coin.CoinType_ERC20 + receiverChain := chains.Goerli + senderChain := chains.Goerli + sender := sample.EthAddress() + tssList := sample.TssList(3) + + // Set up mocks for CheckMigration + observerMock.On("GetAllTSS", ctx).Return(tssList) + observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, false) + authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) + + k.SetGasPrice(ctx, types.GasPrice{ + ChainId: senderChain.ChainId, + MedianIndex: 0, + Prices: []uint64{100}, + }) + + // call InitiateOutbound + msg := types.MsgVoteInbound{ + Creator: creator, + Sender: sender.String(), + SenderChainId: senderChain.ChainId, + Receiver: receiver.String(), + ReceiverChain: receiverChain.ChainId, + Amount: amount, + Message: message, + InboundHash: inboundHash.String(), + InboundBlockHeight: inboundBlockHeight, + GasLimit: gasLimit, + CoinType: cointType, + TxOrigin: sender.String(), + Asset: asset, + EventIndex: eventIndex, + } + + _, err := k.ValidateInbound(ctx, &msg, false) + require.ErrorIs(t, err, observerTypes.ErrSupportedChains) + }) +} func TestKeeper_CheckMigration(t *testing.T) { t.Run("Do not return error if sender is not a TSS address for evm chain", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, From 8ca3864f6bfe321036c7c5ddc29cd99723dfb001 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 11 Jul 2024 13:39:32 -0400 Subject: [PATCH 31/40] rename to CheckIfMigrationDeposit --- .../cctx_orchestrator_validate_inbound.go | 8 ++--- ...cctx_orchestrator_validate_inbound_test.go | 32 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index 2f905b3481..d2413f7620 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -17,7 +17,7 @@ func (k Keeper) ValidateInbound( msg *types.MsgVoteInbound, shouldPayGas bool, ) (*types.CrossChainTx, error) { - err := k.CheckMigration(ctx, msg) + err := k.CheckIfMigrationDeposit(ctx, msg) if err != nil { return nil, err } @@ -57,9 +57,9 @@ func (k Keeper) ValidateInbound( return &cctx, nil } -// CheckMigration checks if the sender is a TSS address and returns an error if it is. -// If the sender is an older TSS address, this means that it is a migration transfer, and we do not need to treat this as a deposit. -func (k Keeper) CheckMigration(ctx sdk.Context, msg *types.MsgVoteInbound) error { +// CheckIfMigrationDeposit checks if the sender is a TSS address and returns an error if it is. +// If the sender is an older TSS address, this means that it is a migration transfer, and we do not need to treat this as a deposit and process the CCTX +func (k Keeper) CheckIfMigrationDeposit(ctx sdk.Context, msg *types.MsgVoteInbound) error { additionalChains := k.GetAuthorityKeeper().GetAdditionalChainList(ctx) // Ignore cctx originating from zeta chain/zevm for this check as there is no TSS in zeta chain if chains.IsZetaChain(msg.SenderChainId, additionalChains) { diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index bbcd1b9786..c93a2ebc1b 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -43,7 +43,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckMigration + // Set up mocks for CheckIfMigrationDeposit observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -115,7 +115,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckMigration + // Set up mocks for CheckIfMigrationDeposit observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -178,7 +178,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckMigration + // Set up mocks for CheckIfMigrationDeposit observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -244,7 +244,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckMigration + // Set up mocks for CheckIfMigrationDeposit observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -316,7 +316,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckMigration + // Set up mocks for CheckIfMigrationDeposit observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -353,7 +353,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { require.ErrorIs(t, err, observerTypes.ErrInboundDisabled) }) - t.Run("fails when CheckMigration fails", func(t *testing.T) { + t.Run("fails when CheckIfMigrationDeposit fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseObserverMock: true, @@ -379,7 +379,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckMigration + // Set up mocks for CheckIfMigrationDeposit observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, false) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -436,7 +436,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckMigration(ctx, &msg) + err := k.CheckIfMigrationDeposit(ctx, &msg) require.NoError(t, err) }) @@ -463,7 +463,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckMigration(ctx, &msg) + err := k.CheckIfMigrationDeposit(ctx, &msg) require.NoError(t, err) }) @@ -492,7 +492,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckMigration(ctx, &msg) + err := k.CheckIfMigrationDeposit(ctx, &msg) require.ErrorIs(t, err, observerTypes.ErrSupportedChains) }) @@ -520,7 +520,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckMigration(ctx, &msg) + err := k.CheckIfMigrationDeposit(ctx, &msg) require.ErrorIs(t, err, types.ErrInvalidAddress) }) @@ -548,7 +548,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckMigration(ctx, &msg) + err := k.CheckIfMigrationDeposit(ctx, &msg) require.ErrorIs(t, err, types.ErrInvalidAddress) }) @@ -576,7 +576,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender.String(), } - err = k.CheckMigration(ctx, &msg) + err = k.CheckIfMigrationDeposit(ctx, &msg) require.ErrorIs(t, err, types.ErrMigrationFromOldTss) }) @@ -606,7 +606,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err = k.CheckMigration(ctx, &msg) + err = k.CheckIfMigrationDeposit(ctx, &msg) require.ErrorIs(t, err, types.ErrMigrationFromOldTss) }) @@ -636,7 +636,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckMigration(ctx, &msg) + err := k.CheckIfMigrationDeposit(ctx, &msg) require.ErrorContains(t, err, "no Bitcoin net params for chain ID: 999") }) @@ -658,7 +658,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckMigration(ctx, &msg) + err := k.CheckIfMigrationDeposit(ctx, &msg) require.NoError(t, err) }) } From 69bfc25c6b4e2141f99affa4df32a5883cbaddf5 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 11 Jul 2024 13:56:15 -0400 Subject: [PATCH 32/40] rename to CheckIfMigrationDeposit --- cmd/zetae2e/local/local.go | 1 - e2e/runner/setup_bitcoin.go | 3 --- 2 files changed, 4 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 84898fe7a0..69863ef466 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -326,7 +326,6 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) if testMigration { - migrationStartTime := time.Now() logger.Print("🏁 starting tss migration") diff --git a/e2e/runner/setup_bitcoin.go b/e2e/runner/setup_bitcoin.go index 236bb4fa11..0a0e2c0e09 100644 --- a/e2e/runner/setup_bitcoin.go +++ b/e2e/runner/setup_bitcoin.go @@ -24,9 +24,6 @@ func (r *E2ERunner) AddTSSToNode() { // mine some blocks to get some BTC into the deployer address _, err = r.GenerateToAddressIfLocalBitcoin(101, r.BTCDeployerAddress) require.NoError(r, err) - - _, err = r.GenerateToAddressIfLocalBitcoin(4, r.BTCDeployerAddress) - require.NoError(r, err) } func (r *E2ERunner) SetupBitcoinAccount(initNetwork bool) { From e248ad00f22119f135ad413b0cee8b0c719ab985 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Thu, 11 Jul 2024 19:15:36 -0400 Subject: [PATCH 33/40] use cctx_Gateway to check cctx --- .../cctx_orchestrator_validate_inbound.go | 18 +++++------ ...cctx_orchestrator_validate_inbound_test.go | 19 ++++++------ x/crosschain/keeper/evm_hooks_test.go | 30 ++++++++++++------- x/crosschain/types/errors.go | 4 +-- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index d2413f7620..f3bda67590 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -17,16 +17,16 @@ func (k Keeper) ValidateInbound( msg *types.MsgVoteInbound, shouldPayGas bool, ) (*types.CrossChainTx, error) { - err := k.CheckIfMigrationDeposit(ctx, msg) - if err != nil { - return nil, err - } - tss, tssFound := k.zetaObserverKeeper.GetTSS(ctx) if !tssFound { return nil, types.ErrCannotFindTSSKeys } + err := k.CheckIfMigrationDeposit(ctx, msg) + if err != nil { + return nil, err + } + // Do not process if inbound is disabled if !k.zetaObserverKeeper.IsInboundEnabled(ctx) { return nil, observertypes.ErrInboundDisabled @@ -61,10 +61,6 @@ func (k Keeper) ValidateInbound( // If the sender is an older TSS address, this means that it is a migration transfer, and we do not need to treat this as a deposit and process the CCTX func (k Keeper) CheckIfMigrationDeposit(ctx sdk.Context, msg *types.MsgVoteInbound) error { additionalChains := k.GetAuthorityKeeper().GetAdditionalChainList(ctx) - // Ignore cctx originating from zeta chain/zevm for this check as there is no TSS in zeta chain - if chains.IsZetaChain(msg.SenderChainId, additionalChains) { - return nil - } historicalTssList := k.zetaObserverKeeper.GetAllTSS(ctx) chain, found := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId) @@ -72,6 +68,10 @@ func (k Keeper) CheckIfMigrationDeposit(ctx sdk.Context, msg *types.MsgVoteInbou return observertypes.ErrSupportedChains.Wrapf("chain not found for chainID %d", msg.SenderChainId) } + if chain.CctxGateway != chains.CCTXGateway_observers { + return nil + } + for _, tss := range historicalTssList { if chains.IsEVMChain(chain.ChainId, additionalChains) { ethTssAddress, err := crypto.GetTssAddrEVM(tss.TssPubkey) diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index c93a2ebc1b..d0c696dc20 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -98,7 +98,6 @@ func TestKeeper_ValidateInbound(t *testing.T) { // Setup mock data observerMock := keepertest.GetCrosschainObserverMock(t, k) - authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) receiver := sample.EthAddress() creator := sample.AccAddress() amount := sdkmath.NewUint(42) @@ -113,12 +112,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { receiverChain := chains.Goerli senderChain := chains.Goerli sender := sample.EthAddress() - tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationDeposit - observerMock.On("GetAllTSS", ctx).Return(tssList) - observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) - authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) // setup Mocks for GetTSS observerMock.On("GetTSS", mock.Anything).Return(tss, false) // setup Mocks for IsInboundEnabled @@ -379,6 +373,9 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) + // setup Mocks for GetTSS + observerMock.On("GetTSS", mock.Anything).Return(tssList[0], true) + // Set up mocks for CheckIfMigrationDeposit observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, false) @@ -620,8 +617,9 @@ func TestKeeper_CheckMigration(t *testing.T) { observerMock := keepertest.GetCrosschainObserverMock(t, k) authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) chain := chains.Chain{ - ChainId: 999, - Consensus: chains.Consensus_bitcoin, + ChainId: 999, + Consensus: chains.Consensus_bitcoin, + CctxGateway: chains.CCTXGateway_observers, } tssList := sample.TssList(3) sender := sample.AccAddress() @@ -640,14 +638,15 @@ func TestKeeper_CheckMigration(t *testing.T) { require.ErrorContains(t, err, "no Bitcoin net params for chain ID: 999") }) - t.Run("returns early if sender chain is zeta chain", func(t *testing.T) { + t.Run("fails if gateway is not observer ", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, }) authorityMock := keepertest.GetCrosschainAuthorityMock(t, k) - chain := chains.ZetaChainTestnet + chain := chains.GoerliLocalnet + chain.CctxGateway = chains.CCTXGateway_zevm sender := sample.AccAddress() // Set up mocks diff --git a/x/crosschain/keeper/evm_hooks_test.go b/x/crosschain/keeper/evm_hooks_test.go index 36b8938a8a..12e01fba14 100644 --- a/x/crosschain/keeper/evm_hooks_test.go +++ b/x/crosschain/keeper/evm_hooks_test.go @@ -214,7 +214,8 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { chain := chains.BitcoinMainnet chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) event, err := crosschainkeeper.ParseZRC20WithdrawalEvent(*sample.GetValidZRC20WithdrawToBTC(t).Logs[3]) @@ -239,7 +240,8 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { chain := chains.Ethereum chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) event, err := crosschainkeeper.ParseZRC20WithdrawalEvent(*sample.GetValidZrc20WithdrawToETH(t).Logs[11]) @@ -378,7 +380,8 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { chain := chains.Ethereum chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) k.RemoveGasPrice(ctx, strconv.FormatInt(chainID, 10)) @@ -400,7 +403,8 @@ func TestKeeper_ProcessZRC20WithdrawalEvent(t *testing.T) { chain := chains.Ethereum chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) zk.ObserverKeeper.SetChainNonces(ctx, observertypes.ChainNonces{ Index: chain.ChainName.String(), @@ -472,7 +476,8 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { chain := chains.Ethereum chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) admin := keepertest.SetAdminPolicies(ctx, zk.AuthorityKeeper) @@ -604,7 +609,8 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { chain := chains.Ethereum chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) amount, ok := sdkmath.NewIntFromString("20000000000000000000000") @@ -633,7 +639,8 @@ func TestKeeper_ProcessZetaSentEvent(t *testing.T) { chain := chains.Ethereum chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) admin := keepertest.SetAdminPolicies(ctx, zk.AuthorityKeeper) @@ -673,7 +680,8 @@ func TestKeeper_ProcessLogs(t *testing.T) { chain := chains.BitcoinMainnet chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) block := sample.GetValidZRC20WithdrawToBTC(t) @@ -699,7 +707,8 @@ func TestKeeper_ProcessLogs(t *testing.T) { chain := chains.Ethereum chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) admin := keepertest.SetAdminPolicies(ctx, zk.AuthorityKeeper) SetupStateForProcessLogsZetaSent(t, ctx, k, zk, sdkk, chain, admin) @@ -799,7 +808,8 @@ func TestKeeper_ProcessLogs(t *testing.T) { chain := chains.BitcoinMainnet chainID := chain.ChainId - setSupportedChain(ctx, zk, chainID) + senderChain := chains.ZetaChainMainnet + setSupportedChain(ctx, zk, []int64{chainID, senderChain.ChainId}...) SetupStateForProcessLogs(t, ctx, k, zk, sdkk, chain) block := sample.GetValidZRC20WithdrawToBTC(t) diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index eb3e579f6a..e7df34baa8 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -50,6 +50,6 @@ var ( ErrMaxTxOutTrackerHashesReached = errorsmod.Register(ModuleName, 1153, "max tx out tracker hashes reached") ErrInitiatitingOutbound = errorsmod.Register(ModuleName, 1154, "cannot initiate outbound") ErrInvalidWithdrawalAmount = errorsmod.Register(ModuleName, 1155, "invalid withdrawal amount") - - ErrMigrationFromOldTss = errorsmod.Register(ModuleName, 1156, "migration tx from an old tss address detected") + ErrMigrationFromOldTss = errorsmod.Register(ModuleName, 1156, "migration tx from an old tss address detected") + ErrValidatingInbound = errorsmod.Register(ModuleName, 1157, "unable to validate inbound") ) From 1ffe90727cffc72f20c38c8c510bc2d9d490b287 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Fri, 12 Jul 2024 11:03:13 -0400 Subject: [PATCH 34/40] add Tss migration to e2e.yml --- .github/workflows/e2e.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index e0dc06924a..abade6a3f4 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -28,6 +28,8 @@ jobs: UPGRADE_TESTS: ${{ steps.matrix-conditionals.outputs.UPGRADE_TESTS }} UPGRADE_LIGHT_TESTS: ${{ steps.matrix-conditionals.outputs.UPGRADE_LIGHT_TESTS }} ADMIN_TESTS: ${{ steps.matrix-conditionals.outputs.ADMIN_TESTS }} + TSS_MIGRATION_TESTS: ${{ steps.matrix-conditionals.outputs.TSS_MIGRATION_TESTS }} + steps: # use cli rather than event context to avoid race conditions (label added after push) - id: matrix-conditionals @@ -46,6 +48,9 @@ jobs: if [[ "$labels" == *"ADMIN_TESTS"* ]]; then echo "ADMIN_TESTS=true" >> $GITHUB_OUTPUT fi + if [[ "$labels" == *"TSS_MIGRATION_TESTS"* ]]; then + echo "TSS_MIGRATION_TESTS=true" >> $GITHUB_OUTPUT + fi elif [[ ${{ github.event_name }} == 'merge_group' ]]; then echo "DEFAULT_TESTS=true" >> $GITHUB_OUTPUT elif [[ ${{ github.event_name }} == 'push' && ${{ github.ref }} == 'refs/heads/develop' ]]; then @@ -54,6 +59,7 @@ jobs: echo "UPGRADE_TESTS=true" >> $GITHUB_OUTPUT echo "UPGRADE_LIGHT_TESTS=true" >> $GITHUB_OUTPUT echo "ADMIN_TESTS=true" >> $GITHUB_OUTPUT + echo "TSS_MIGRATION_TESTS=true" >> $GITHUB_OUTPUT fi e2e: @@ -74,6 +80,9 @@ jobs: - make-target: "start-e2e-admin-test" runs-on: ubuntu-20.04 run: ${{ needs.matrix-conditionals.outputs.ADMIN_TESTS == 'true' }} + - make-target: "start-tss-migration-test" + runs-on: ubuntu-20.04 + run: ${{ needs.matrix-conditionals.outputs.TSS_MIGRATION_TESTS == 'true' }} name: ${{ matrix.make-target }} uses: ./.github/workflows/reusable-e2e.yml with: From be5054dbfab44469ac21f1807b3ac34ae0883f74 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Sun, 14 Jul 2024 10:17:56 -0400 Subject: [PATCH 35/40] move to a sub function --- cmd/zetae2e/local/local.go | 83 ++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 69863ef466..f292dd9931 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -326,45 +326,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) if testMigration { - migrationStartTime := time.Now() - logger.Print("🏁 starting tss migration") - - response, err := deployerRunner.CctxClient.LastZetaHeight( - deployerRunner.Ctx, - &crosschaintypes.QueryLastZetaHeightRequest{}, - ) - require.NoError(deployerRunner, err) - err = zetaTxServer.UpdateKeygen(response.Height) - require.NoError(deployerRunner, err) - - // 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) - - if err := fn(); err != nil { - logger.Print("❌ %v", err) - logger.Print("❌ tss migration failed") - os.Exit(1) - } - - logger.Print("✅ migration completed in %s ", time.Since(migrationStartTime).String()) - logger.Print("🏁 starting post migration tests") - - tests := []string{ - e2etests.TestBitcoinWithdrawSegWitName, - e2etests.TestEtherWithdrawName, - } - fn = postMigrationTestRoutine(conf, deployerRunner, verbose, tests...) - - if err := fn(); err != nil { - logger.Print("❌ %v", err) - logger.Print("❌ post migration tests failed") - os.Exit(1) - } + runTSSMigrationTest(deployerRunner, logger, verbose, conf) } // print and validate report @@ -418,6 +380,49 @@ func waitKeygenHeight( } } +func runTSSMigrationTest(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) + + // 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) + + if err := fn(); err != nil { + logger.Print("❌ %v", err) + logger.Print("❌ tss migration failed") + os.Exit(1) + } + + logger.Print("✅ migration completed in %s ", time.Since(migrationStartTime).String()) + logger.Print("🏁 starting post migration tests") + + tests := []string{ + e2etests.TestBitcoinWithdrawSegWitName, + e2etests.TestEtherWithdrawName, + } + 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 { return testutil.Must(v, err) } From 43073d482bc88787e5ab29ce3de0a57f0e1833fb Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 15 Jul 2024 12:18:00 -0400 Subject: [PATCH 36/40] resolve comments 2 --- cmd/zetae2e/config/localnet.yml | 4 +-- e2e/runner/bitcoin.go | 5 ++-- .../cctx_orchestrator_validate_inbound.go | 26 +++++++++------- ...cctx_orchestrator_validate_inbound_test.go | 30 +++++++++---------- zetaclient/chains/bitcoin/signer/signer.go | 4 +-- zetaclient/chains/evm/observer/outbound.go | 4 ++- 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index 83b32c10f2..59452f723a 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -34,8 +34,8 @@ additional_accounts: private_key: "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" user_migration: bech32_address: "zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz" - evm_address: "0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD" - private_key: "0BCC2FA28B526F90E1D54648D612DB901E860BF68248555593F91EA801C6B482" + evm_address: "0x0b166ef9e7231bb80a7a3fa73cea7f3827e7d5bd" + private_key: "0bcc2fa28b526f90e1d54648d612db901e860bf68248555593f91ea801c6b482" user_fungible_admin: bech32_address: "zeta1svzuz982w09vf2y08xsh8qplj36phyz466krj3" evm_address: "0x8305C114Ea73cAc4A88f39A173803F94741b9055" diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index 7417bc0a07..deb1109901 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/rs/zerolog/log" "github.com/stretchr/testify/require" + "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/signer" "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/pkg/chains" @@ -72,8 +73,8 @@ func (r *E2ERunner) GetTop20UTXOsForTssAddress() ([]btcjson.ListUnspentResult, e return utxos[i].Amount < utxos[j].Amount }) - if len(utxos) > 20 { - utxos = utxos[:20] + if len(utxos) > signer.MaxNoOfInputsPerTx { + utxos = utxos[:signer.MaxNoOfInputsPerTx] } return utxos, nil } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index f3bda67590..24d139f76f 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -22,7 +22,7 @@ func (k Keeper) ValidateInbound( return nil, types.ErrCannotFindTSSKeys } - err := k.CheckIfMigrationDeposit(ctx, msg) + err := k.CheckIfMigrationTransfer(ctx, msg) if err != nil { return nil, err } @@ -57,9 +57,9 @@ func (k Keeper) ValidateInbound( return &cctx, nil } -// CheckIfMigrationDeposit checks if the sender is a TSS address and returns an error if it is. +// CheckIfMigrationTransfer checks if the sender is a TSS address and returns an error if it is. // If the sender is an older TSS address, this means that it is a migration transfer, and we do not need to treat this as a deposit and process the CCTX -func (k Keeper) CheckIfMigrationDeposit(ctx sdk.Context, msg *types.MsgVoteInbound) error { +func (k Keeper) CheckIfMigrationTransfer(ctx sdk.Context, msg *types.MsgVoteInbound) error { additionalChains := k.GetAuthorityKeeper().GetAdditionalChainList(ctx) historicalTssList := k.zetaObserverKeeper.GetAllTSS(ctx) @@ -68,12 +68,14 @@ func (k Keeper) CheckIfMigrationDeposit(ctx sdk.Context, msg *types.MsgVoteInbou return observertypes.ErrSupportedChains.Wrapf("chain not found for chainID %d", msg.SenderChainId) } + // the check is only necessary if the inbound is validated from observers from a connected chain if chain.CctxGateway != chains.CCTXGateway_observers { return nil } - for _, tss := range historicalTssList { - if chains.IsEVMChain(chain.ChainId, additionalChains) { + switch { + case chains.IsEVMChain(chain.ChainId, additionalChains): + for _, tss := range historicalTssList { ethTssAddress, err := crypto.GetTssAddrEVM(tss.TssPubkey) if err != nil { return errors.Wrap(types.ErrInvalidAddress, err.Error()) @@ -81,11 +83,14 @@ func (k Keeper) CheckIfMigrationDeposit(ctx sdk.Context, msg *types.MsgVoteInbou if ethTssAddress.Hex() == msg.Sender { return types.ErrMigrationFromOldTss } - } else if chains.IsBitcoinChain(chain.ChainId, additionalChains) { - bitcoinParams, err := chains.BitcoinNetParamsFromChainID(chain.ChainId) - if err != nil { - return err - } + + } + case chains.IsBitcoinChain(chain.ChainId, additionalChains): + bitcoinParams, err := chains.BitcoinNetParamsFromChainID(chain.ChainId) + if err != nil { + return err + } + for _, tss := range historicalTssList { btcTssAddress, err := crypto.GetTssAddrBTC(tss.TssPubkey, bitcoinParams) if err != nil { return errors.Wrap(types.ErrInvalidAddress, err.Error()) @@ -95,5 +100,6 @@ func (k Keeper) CheckIfMigrationDeposit(ctx sdk.Context, msg *types.MsgVoteInbou } } } + return nil } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index d0c696dc20..8be95af4c7 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -43,7 +43,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationDeposit + // Set up mocks for CheckIfMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -172,7 +172,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationDeposit + // Set up mocks for CheckIfMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -238,7 +238,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationDeposit + // Set up mocks for CheckIfMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -310,7 +310,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationDeposit + // Set up mocks for CheckIfMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -347,7 +347,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { require.ErrorIs(t, err, observerTypes.ErrInboundDisabled) }) - t.Run("fails when CheckIfMigrationDeposit fails", func(t *testing.T) { + t.Run("fails when CheckIfMigrationTransfer fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseObserverMock: true, @@ -376,7 +376,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { // setup Mocks for GetTSS observerMock.On("GetTSS", mock.Anything).Return(tssList[0], true) - // Set up mocks for CheckIfMigrationDeposit + // Set up mocks for CheckIfMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, false) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -433,7 +433,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationDeposit(ctx, &msg) + err := k.CheckIfMigrationTransfer(ctx, &msg) require.NoError(t, err) }) @@ -460,7 +460,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationDeposit(ctx, &msg) + err := k.CheckIfMigrationTransfer(ctx, &msg) require.NoError(t, err) }) @@ -489,7 +489,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationDeposit(ctx, &msg) + err := k.CheckIfMigrationTransfer(ctx, &msg) require.ErrorIs(t, err, observerTypes.ErrSupportedChains) }) @@ -517,7 +517,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationDeposit(ctx, &msg) + err := k.CheckIfMigrationTransfer(ctx, &msg) require.ErrorIs(t, err, types.ErrInvalidAddress) }) @@ -545,7 +545,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationDeposit(ctx, &msg) + err := k.CheckIfMigrationTransfer(ctx, &msg) require.ErrorIs(t, err, types.ErrInvalidAddress) }) @@ -573,7 +573,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender.String(), } - err = k.CheckIfMigrationDeposit(ctx, &msg) + err = k.CheckIfMigrationTransfer(ctx, &msg) require.ErrorIs(t, err, types.ErrMigrationFromOldTss) }) @@ -603,7 +603,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err = k.CheckIfMigrationDeposit(ctx, &msg) + err = k.CheckIfMigrationTransfer(ctx, &msg) require.ErrorIs(t, err, types.ErrMigrationFromOldTss) }) @@ -634,7 +634,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationDeposit(ctx, &msg) + err := k.CheckIfMigrationTransfer(ctx, &msg) require.ErrorContains(t, err, "no Bitcoin net params for chain ID: 999") }) @@ -657,7 +657,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationDeposit(ctx, &msg) + err := k.CheckIfMigrationTransfer(ctx, &msg) require.NoError(t, err) }) } diff --git a/zetaclient/chains/bitcoin/signer/signer.go b/zetaclient/chains/bitcoin/signer/signer.go index 259f55bc53..d8027d1668 100644 --- a/zetaclient/chains/bitcoin/signer/signer.go +++ b/zetaclient/chains/bitcoin/signer/signer.go @@ -33,7 +33,7 @@ import ( const ( // the maximum number of inputs per outbound - maxNoOfInputsPerTx = 20 + MaxNoOfInputsPerTx = 20 // the rank below (or equal to) which we consolidate UTXOs consolidationRank = 10 @@ -196,7 +196,7 @@ func (signer *Signer) SignWithdrawTx( // select N UTXOs to cover the total expense prevOuts, total, consolidatedUtxo, consolidatedValue, err := observer.SelectUTXOs( amount+estimateFee+float64(nonceMark)*1e-8, - maxNoOfInputsPerTx, + MaxNoOfInputsPerTx, nonce, consolidationRank, false, diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index 5952d1fa4e..86218df8f8 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -366,6 +366,8 @@ func (ob *Observer) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Rec } if from != ob.TSS().EVMAddress() { // must be TSS address // If from is not TSS address, check if it is one of the previous TSS addresses We can still try to confirm a tx which was broadcast by an old TSS + // This is to handle situations where the outbound has already been broad-casted by an older TSS address and the zetacore is waiting for the all the required block confirmations + // to go through before marking the cctx into a finalized state log.Info().Msgf("confirmTxByHash: sender %s for outbound %s chain %d is not current TSS address %s", from.Hex(), transaction.Hash().Hex(), ob.Chain().ChainId, ob.TSS().EVMAddress().Hex()) addressList := ob.TSS().EVMAddressList() @@ -404,7 +406,7 @@ func (ob *Observer) checkConfirmedTx(txHash string, nonce uint64) (*ethtypes.Rec log.Error().Msgf("confirmTxByHash: receipt is nil for txHash %s nonce %d", txHash, nonce) return nil, nil, false } - + ob.LastBlock() // check confirmations lastHeight, err := ob.evmClient.BlockNumber(context.Background()) if err != nil { From e4291529795b8e953b8e915541a6deb4dccbcc02 Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 15 Jul 2024 20:03:46 -0400 Subject: [PATCH 37/40] resolve comments 3 --- Makefile | 2 +- cmd/zetaclientd/keygen_tss.go | 22 +++--- cmd/zetaclientd/start.go | 4 +- cmd/zetae2e/config/localnet.yml | 2 +- cmd/zetae2e/local/local.go | 1 - cmd/zetae2e/local/post_migration.go | 6 +- e2e/config/config.go | 10 ++- e2e/e2etests/test_migrate_tss.go | 20 ++--- .../cctx_orchestrator_validate_inbound.go | 1 - .../chains/bitcoin/observer/outbound.go | 10 +-- zetaclient/chains/evm/observer/outbound.go | 75 +++++++++++++++---- zetaclient/tss/tss_signer.go | 17 +++-- zetaclient/zetacore/client_monitor.go | 14 ++-- 13 files changed, 114 insertions(+), 70 deletions(-) diff --git a/Makefile b/Makefile index ab0eac8b99..4cb7375fae 100644 --- a/Makefile +++ b/Makefile @@ -87,7 +87,7 @@ build-testnet-ubuntu: go.sum docker rm temp-container install: go.sum - @echo "--> Installing zetacored ,zetaclientd and zetaclientd-supervisor" + @echo "--> Installing zetacored, zetaclientd, and zetaclientd-supervisor" @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetacored @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetaclientd @go install -mod=readonly $(BUILD_FLAGS) ./cmd/zetaclientd-supervisor diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 7b50479903..71beeb17fe 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -17,7 +17,6 @@ import ( "github.com/zeta-chain/zetacore/pkg/chains" observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" - "github.com/zeta-chain/zetacore/zetaclient/context" zctx "github.com/zeta-chain/zetacore/zetaclient/context" "github.com/zeta-chain/zetacore/zetaclient/metrics" mc "github.com/zeta-chain/zetacore/zetaclient/tss" @@ -30,12 +29,15 @@ import ( // In case of a successful keygen a TSS success vote is broadcasted to zetacore and the newly generate TSS is tested. The generated keyshares are stored in the correct directory // In case of a failed keygen a TSS failed vote is broadcasted to zetacore. func GenerateTSS( - appContext *context.AppContext, + ctx context.Context, logger zerolog.Logger, zetaCoreClient *zetacore.Client, keygenTssServer *tss.TssServer) error { keygenLogger := logger.With().Str("module", "keygen").Logger() - + app, err := zctx.FromContext(ctx) + if err != nil { + return err + } // If Keygen block is set it will try to generate new TSS at the block // This is a blocking thread and will wait until the ceremony is complete successfully // If the TSS generation is unsuccessful , it will loop indefinitely until a new TSS is generated @@ -62,7 +64,7 @@ func GenerateTSS( // Try generating TSS at keygen block , only when status is pending keygen and generation has not been tried at the block if keyGen.Status == observertypes.KeygenStatus_PendingKeygen { // Return error if RPC is not working - currentBlock, err := zetaCoreClient.GetBlockHeight() + currentBlock, err := zetaCoreClient.GetBlockHeight(ctx) if err != nil { keygenLogger.Error().Err(err).Msg("GetBlockHeight RPC error") continue @@ -83,10 +85,11 @@ func GenerateTSS( } // Try keygen only once at a particular block, irrespective of whether it is successful or failure triedKeygenAtBlock = true - newPubkey, err := keygenTss(keyGen, *keygenTssServer, zetaCoreClient, keygenLogger) + newPubkey, err := keygenTss(ctx, keyGen, *keygenTssServer, zetaCoreClient, keygenLogger) if err != nil { keygenLogger.Error().Err(err).Msg("keygenTss error") - tssFailedVoteHash, err := zetaCoreClient.SetTSS("", keyGen.BlockNumber, chains.ReceiveStatus_failed) + tssFailedVoteHash, err := zetaCoreClient.PostVoteTSS(ctx, + "", keyGen.BlockNumber, chains.ReceiveStatus_failed) if err != nil { keygenLogger.Error().Err(err).Msg("Failed to broadcast Failed TSS Vote to zetacore") return err @@ -95,7 +98,7 @@ func GenerateTSS( continue } // If TSS is successful , broadcast the vote to zetacore and also set the Pubkey - tssSuccessVoteHash, err := zetaCoreClient.SetTSS( + tssSuccessVoteHash, err := zetaCoreClient.PostVoteTSS(ctx, newPubkey, keyGen.BlockNumber, chains.ReceiveStatus_success, @@ -123,6 +126,7 @@ func GenerateTSS( // If the keygen is successful, the function returns the new TSS pubkey. // If the keygen is unsuccessful, the function posts blame and returns an error. func keygenTss( + ctx context.Context, keyGen observertypes.Keygen, tssServer tss.TssServer, zetacoreClient interfaces.ZetacoreClient, @@ -140,10 +144,10 @@ func keygenTss( return "", err } index := fmt.Sprintf("keygen-%s-%d", digest, keyGen.BlockNumber) - zetaHash, err := tss.ZetacoreClient.PostVoteBlameData( + zetaHash, err := zetacoreClient.PostVoteBlameData( ctx, &res.Blame, - tss.ZetacoreClient.Chain().ChainId, + zetacoreClient.Chain().ChainId, index, ) if err != nil { diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index edbedb9a66..fef035aee5 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -212,7 +212,7 @@ func start(_ *cobra.Command, _ []string) error { // Generate a new TSS if keygen is set and add it into the tss server // If TSS has already been generated, and keygen was successful ; we use the existing TSS - err = GenerateTSS(appContext, masterLogger, zetacoreClient, server) + err = GenerateTSS(ctx, masterLogger, zetacoreClient, server) if err != nil { return err } @@ -223,7 +223,7 @@ func start(_ *cobra.Command, _ []string) error { bitcoinChainID = btcChain.ChainId } tss, err := mc.NewTSS( - appContext, + ctx, zetacoreClient, tssHistoricalList, bitcoinChainID, diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index 3afb6a3408..cbd703ba6a 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -34,7 +34,7 @@ additional_accounts: private_key: "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" user_migration: bech32_address: "zeta1pvtxa708yvdmszn687nne6nl8qn704daf420xz" - evm_address: "0x0b166ef9e7231bb80a7a3fa73cea7f3827e7d5bd" + evm_address: "0x0B166ef9e7231Bb80A7A3FA73CEA7F3827E7D5BD" private_key: "0bcc2fa28b526f90e1d54648d612db901e860bf68248555593f91ea801c6b482" policy_accounts: emergency_policy_account: diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 63a9bf1974..20e6c72f8e 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -424,7 +424,6 @@ 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/cmd/zetae2e/local/post_migration.go b/cmd/zetae2e/local/post_migration.go index c1d34da9a4..f339ce0bc1 100644 --- a/cmd/zetae2e/local/post_migration.go +++ b/cmd/zetae2e/local/post_migration.go @@ -1,10 +1,10 @@ package local import ( - "fmt" "time" "github.com/fatih/color" + "github.com/pkg/errors" "github.com/zeta-chain/zetacore/e2e/config" "github.com/zeta-chain/zetacore/e2e/e2etests" @@ -40,11 +40,11 @@ func postMigrationTestRoutine( testNames..., ) if err != nil { - return fmt.Errorf("postMigrationRunner tests failed: %v", err) + return errors.Wrap(err, "postMigrationRunner tests failed") } if err := postMigrationRunner.RunE2ETests(testsToRun); err != nil { - return fmt.Errorf("postMigrationRunner tests failed: %v", err) + return errors.Wrap(err, "postMigrationRunner tests failed") } if err := postMigrationRunner.CheckBtcTSSBalance(); err != nil { diff --git a/e2e/config/config.go b/e2e/config/config.go index b22b956494..6132dccbbd 100644 --- a/e2e/config/config.go +++ b/e2e/config/config.go @@ -199,6 +199,7 @@ func (a AdditionalAccounts) AsSlice() []Account { a.UserEther, a.UserMisc, a.UserAdmin, + a.UserMigration, } } @@ -283,19 +284,20 @@ func (c *Config) GenerateKeys() error { if err != nil { return err } - c.PolicyAccounts.EmergencyPolicyAccount, err = generateAccount() + c.AdditionalAccounts.UserMigration, err = generateAccount() if err != nil { return err } - c.PolicyAccounts.OperationalPolicyAccount, err = generateAccount() + + c.PolicyAccounts.EmergencyPolicyAccount, err = generateAccount() if err != nil { return err } - c.PolicyAccounts.AdminPolicyAccount, err = generateAccount() + c.PolicyAccounts.OperationalPolicyAccount, err = generateAccount() if err != nil { return err } - c.AdditionalAccounts.UserMigration, err = generateAccount() + c.PolicyAccounts.AdminPolicyAccount, err = generateAccount() if err != nil { return err } diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index 77bd2eff6d..8dc57b3e0a 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -28,10 +28,10 @@ func TestMigrateTSS(r *runner.E2ERunner, _ []string) { // Pause inbound procoessing for tss migration r.Logger.Info("Pause inbound processing") msg := observertypes.NewMsgDisableCCTX( - r.ZetaTxServer.GetAccountAddress(0), + r.ZetaTxServer.MustGetAccountAddressFromName(utils.EmergencyPolicyName), false, true) - _, err := r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msg) + _, err := r.ZetaTxServer.BroadcastTx(utils.EmergencyPolicyName, msg) require.NoError(r, err) // Migrate btc @@ -53,11 +53,11 @@ func TestMigrateTSS(r *runner.E2ERunner, _ []string) { // #nosec G701 e2eTest - always in range migrationAmountBTC := sdkmath.NewUint(uint64(btcBalance * 1e8)) msgMigrateFunds := crosschaintypes.NewMsgMigrateTssFunds( - r.ZetaTxServer.GetAccountAddress(0), + r.ZetaTxServer.MustGetAccountAddressFromName(utils.AdminPolicyName), btcChain, migrationAmountBTC, ) - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) + _, err = r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msgMigrateFunds) require.NoError(r, err) // Fetch migrator cctx for btc migration @@ -78,11 +78,11 @@ func TestMigrateTSS(r *runner.E2ERunner, _ []string) { // Migrate TSS funds for the eth chain msgMigrateFunds = crosschaintypes.NewMsgMigrateTssFunds( - r.ZetaTxServer.GetAccountAddress(0), + r.ZetaTxServer.MustGetAccountAddressFromName(utils.AdminPolicyName), evmChainID.Int64(), tssBalanceUint, ) - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgMigrateFunds) + _, err = r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msgMigrateFunds) require.NoError(r, err) // Fetch migrator cctx for eth migration @@ -110,10 +110,10 @@ func TestMigrateTSS(r *runner.E2ERunner, _ []string) { return allTss.TssList[i].FinalizedZetaHeight < allTss.TssList[j].FinalizedZetaHeight }) msgUpdateTss := crosschaintypes.NewMsgUpdateTssAddress( - r.ZetaTxServer.GetAccountAddress(0), + r.ZetaTxServer.MustGetAccountAddressFromName(utils.AdminPolicyName), allTss.TssList[1].TssPubkey, ) - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgUpdateTss) + _, err = r.ZetaTxServer.BroadcastTx(utils.AdminPolicyName, msgUpdateTss) require.NoError(r, err) // Wait for atleast one block for the TSS to be updated @@ -174,9 +174,9 @@ func TestMigrateTSS(r *runner.E2ERunner, _ []string) { require.True(r, ethTSSBalanceNew.Cmp(ethTSSBalanceOld) < 0) msgEnable := observertypes.NewMsgEnableCCTX( - r.ZetaTxServer.GetAccountAddress(0), + r.ZetaTxServer.MustGetAccountAddressFromName(utils.OperationalPolicyName), true, true) - _, err = r.ZetaTxServer.BroadcastTx(utils.FungibleAdminName, msgEnable) + _, err = r.ZetaTxServer.BroadcastTx(utils.OperationalPolicyName, msgEnable) require.NoError(r, err) } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index 24d139f76f..2d1dfb030d 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -83,7 +83,6 @@ func (k Keeper) CheckIfMigrationTransfer(ctx sdk.Context, msg *types.MsgVoteInbo if ethTssAddress.Hex() == msg.Sender { return types.ErrMigrationFromOldTss } - } case chains.IsBitcoinChain(chain.ChainId, additionalChains): bitcoinParams, err := chains.BitcoinNetParamsFromChainID(chain.ChainId) diff --git a/zetaclient/chains/bitcoin/observer/outbound.go b/zetaclient/chains/bitcoin/observer/outbound.go index 80db586c28..c7c1c649d7 100644 --- a/zetaclient/chains/bitcoin/observer/outbound.go +++ b/zetaclient/chains/bitcoin/observer/outbound.go @@ -184,11 +184,11 @@ func (ob *Observer) IsOutboundProcessed( // It's safe to use cctx's amount to post confirmation because it has already been verified in observeOutbound() amountInSat := params.Amount.BigInt() if res.Confirmations < ob.ConfirmationsThreshold(amountInSat) { - ob.logger.Outbound.Debug().Msgf( - "IsOutboundProcessed: outbound not confirmed yet %d: %d", - res.Confirmations, - ob.ConfirmationsThreshold(amountInSat), - ) + ob.logger.Outbound.Debug(). + Int64("currentConfirmations", res.Confirmations). + Int64("requiredConfirmations", ob.ConfirmationsThreshold(amountInSat)). + Msg("IsOutboundProcessed: outbound not confirmed yet") + return true, false, nil } diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index ac5dbf0152..4b847b52c5 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -9,7 +9,6 @@ import ( "time" "cosmossdk.io/math" - "github.com/ethereum/go-ethereum" ethcommon "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/pkg/errors" @@ -390,11 +389,18 @@ func (ob *Observer) checkConfirmedTx( if err != nil { log.Error(). Err(err). - Msgf("confirmTxByHash: error getting transaction for outbound %s chain %d", txHash, ob.Chain().ChainId) + Str("function", "confirmTxByHash"). + Str("outboundTxHash", txHash). + Int64("chainID", ob.Chain().ChainId). + Msg("error getting transaction for outbound") return nil, nil, false } if transaction == nil { // should not happen - log.Error().Msgf("confirmTxByHash: transaction is nil for txHash %s nonce %d", txHash, nonce) + log.Error(). + Str("function", "confirmTxByHash"). + Str("outboundTxHash", txHash). + Uint64("nonce", nonce). + Msg("transaction is nil for txHash") return nil, nil, false } @@ -404,15 +410,23 @@ func (ob *Observer) checkConfirmedTx( if err != nil { log.Error(). Err(err). - Msgf("confirmTxByHash: local recovery of sender address failed for outbound %s chain %d", transaction.Hash().Hex(), ob.Chain().ChainId) + Str("function", "confirmTxByHash"). + Str("outboundTxHash", transaction.Hash().Hex()). + Int64("chainID", ob.Chain().ChainId). + Msg("local recovery of sender address failed for outbound") return nil, nil, false } if from != ob.TSS().EVMAddress() { // must be TSS address // If from is not TSS address, check if it is one of the previous TSS addresses We can still try to confirm a tx which was broadcast by an old TSS // This is to handle situations where the outbound has already been broad-casted by an older TSS address and the zetacore is waiting for the all the required block confirmations // to go through before marking the cctx into a finalized state - log.Info().Msgf("confirmTxByHash: sender %s for outbound %s chain %d is not current TSS address %s", - from.Hex(), transaction.Hash().Hex(), ob.Chain().ChainId, ob.TSS().EVMAddress().Hex()) + log.Info(). + Str("function", "confirmTxByHash"). + Str("sender", from.Hex()). + Str("outboundTxHash", transaction.Hash().Hex()). + Int64("chainID", ob.Chain().ChainId). + Str("currentTSSAddress", ob.TSS().EVMAddress().Hex()). + Msg("sender is not current TSS address") addressList := ob.TSS().EVMAddressList() isOldTssAddress := false for _, addr := range addressList { @@ -422,14 +436,22 @@ func (ob *Observer) checkConfirmedTx( } if !isOldTssAddress { log.Error(). - Msgf("confirmTxByHash: sender %s for outbound %s chain %d is not current or old TSS address. Current TSS %s", - from.Hex(), transaction.Hash().Hex(), ob.Chain().ChainId, ob.TSS().EVMAddress().Hex()) + Str("function", "confirmTxByHash"). + Str("sender", from.Hex()). + Str("outboundTxHash", transaction.Hash().Hex()). + Int64("chainID", ob.Chain().ChainId). + Str("currentTSSAddress", ob.TSS().EVMAddress().Hex()). + Msg("sender is not current or old TSS address") return nil, nil, false } } if transaction.Nonce() != nonce { // must match cctx nonce log.Error(). - Msgf("confirmTxByHash: outbound %s nonce mismatch: wanted %d, got tx nonce %d", txHash, nonce, transaction.Nonce()) + Str("function", "confirmTxByHash"). + Str("outboundTxHash", txHash). + Uint64("wantedNonce", nonce). + Uint64("gotTxNonce", transaction.Nonce()). + Msg("outbound nonce mismatch") return nil, nil, false } @@ -442,26 +464,41 @@ func (ob *Observer) checkConfirmedTx( // query receipt receipt, err := ob.evmClient.TransactionReceipt(ctx, ethcommon.HexToHash(txHash)) if err != nil { - log.Error().Err(err).Msgf("confirmTxByHash: TransactionReceipt error, txHash %s nonce %d", txHash, nonce) + log.Error(). + Err(err). + Str("function", "confirmTxByHash"). + Str("outboundTxHash", txHash). + Uint64("nonce", nonce). + Msg("transactionReceipt error") return nil, nil, false } if receipt == nil { // should not happen - log.Error().Msgf("confirmTxByHash: receipt is nil for txHash %s nonce %d", txHash, nonce) + log.Error(). + Str("function", "confirmTxByHash"). + Str("outboundTxHash", txHash). + Uint64("nonce", nonce). + Msg("receipt is nil") return nil, nil, false } ob.LastBlock() // check confirmations - lastHeight, err := ob.evmClient.BlockNumber(context.Background()) + lastHeight, err := ob.evmClient.BlockNumber(ctx) if err != nil { log.Error(). + Str("function", "confirmTxByHash"). Err(err). - Msgf("confirmTxByHash: error getting block number for chain %d", ob.GetChainParams().ChainId) + Int64("chainID", ob.GetChainParams().ChainId). + Msg("error getting block number for chain") return nil, nil, false } if !ob.HasEnoughConfirmations(receipt, lastHeight) { log.Debug(). - Msgf("confirmTxByHash: txHash %s nonce %d included but not confirmed: receipt block %d, current block %d", - txHash, nonce, receipt.BlockNumber, lastHeight) + Str("function", "confirmTxByHash"). + Str("txHash", txHash). + Uint64("nonce", nonce). + Uint64("receiptBlock", receipt.BlockNumber.Uint64()). + Uint64("currentBlock", lastHeight). + Msg("txHash included but not confirmed") return nil, nil, false } @@ -469,7 +506,13 @@ func (ob *Observer) checkConfirmedTx( // Note: a guard for false BlockNumber in receipt. The blob-carrying tx won't come here err = ob.CheckTxInclusion(transaction, receipt) if err != nil { - log.Error().Err(err).Msgf("confirmTxByHash: checkTxInclusion error for txHash %s nonce %d", txHash, nonce) + log.Error(). + Err(err). + Str("function", "confirmTxByHash"). + Str("errorContext", "checkTxInclusion"). + Str("txHash", txHash). + Uint64("nonce", nonce). + Msg("checkTxInclusion error") return nil, nil, false } diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 65bc1a9a21..7db6f27a8e 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -33,7 +33,7 @@ import ( observertypes "github.com/zeta-chain/zetacore/x/observer/types" "github.com/zeta-chain/zetacore/zetaclient/chains/interfaces" "github.com/zeta-chain/zetacore/zetaclient/config" - appcontext "github.com/zeta-chain/zetacore/zetaclient/context" + zctx "github.com/zeta-chain/zetacore/zetaclient/context" "github.com/zeta-chain/zetacore/zetaclient/keys" "github.com/zeta-chain/zetacore/zetaclient/metrics" ) @@ -92,7 +92,6 @@ type TSS struct { // NewTSS creates a new TSS instance which can be used to sign transactions func NewTSS( ctx context.Context, - appContext *appcontext.AppContext, client interfaces.ZetacoreClient, tssHistoricalList []observertypes.TSS, bitcoinChainID int64, @@ -100,23 +99,27 @@ func NewTSS( tssServer *tss.TssServer, ) (*TSS, error) { logger := log.With().Str("module", "tss_signer").Logger() + app, err := zctx.FromContext(ctx) + if err != nil { + return nil, err + } newTss := TSS{ Server: tssServer, Keys: make(map[string]*Key), - CurrentPubkey: appContext.GetCurrentTssPubKey(), + CurrentPubkey: app.GetCurrentTssPubKey(), logger: logger, ZetacoreClient: client, KeysignsTracker: NewKeysignsTracker(logger), BitcoinChainID: bitcoinChainID, } - err := newTss.LoadTssFilesFromDirectory(appContext.Config().TssPath) + err = newTss.LoadTssFilesFromDirectory(app.Config().TssPath) if err != nil { return nil, err } - _, pubkeyInBech32, err := keys.GetKeyringKeybase(appContext.Config(), hotkeyPassword) + _, pubkeyInBech32, err := keys.GetKeyringKeybase(app.Config(), hotkeyPassword) if err != nil { return nil, err } @@ -137,7 +140,7 @@ func NewTSS( } metrics.NumActiveMsgSigns.Set(0) - newTss.Signers = appContext.GetKeygen().GranteePubkeys + newTss.Signers = app.GetKeygen().GranteePubkeys return &newTss, nil } @@ -305,8 +308,6 @@ func (tss *TSS) Sign( return [65]byte{}, fmt.Errorf("signuature verification fail") } - fmt.Print("Successfully signed the digest") - return sigbyte, nil } diff --git a/zetaclient/zetacore/client_monitor.go b/zetaclient/zetacore/client_monitor.go index 6c124ced48..b505af90a1 100644 --- a/zetaclient/zetacore/client_monitor.go +++ b/zetaclient/zetacore/client_monitor.go @@ -168,15 +168,11 @@ func retryWithBackoff(call func() error, attempts int, minInternal, maxInterval if attempts < 1 { return errors.New("attempts must be positive") } + bo := backoff.NewExponentialBackOff() + bo.InitialInterval = minInternal + bo.MaxInterval = maxInterval - bo := backoff.WithMaxRetries( - backoff.NewExponentialBackOff( - backoff.WithInitialInterval(minInternal), - backoff.WithMaxInterval(maxInterval), - ), - // #nosec G115 always positive - uint64(attempts), - ) + backoffWithRetry := backoff.WithMaxRetries(bo, uint64(attempts)) - return retry.DoWithBackoff(call, bo) + return retry.DoWithBackoff(call, backoffWithRetry) } From a50d868883f1f42fc33be4408de3b181e6f00e6a Mon Sep 17 00:00:00 2001 From: Tanmay Date: Mon, 15 Jul 2024 21:08:25 -0400 Subject: [PATCH 38/40] add todo --- e2e/e2etests/test_migrate_tss.go | 2 +- e2e/runner/bitcoin.go | 2 +- .../cctx_orchestrator_validate_inbound_test.go | 15 ++++++++++----- x/crosschain/types/errors.go | 8 ++++++-- zetaclient/chains/evm/observer/outbound.go | 3 +++ 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/e2e/e2etests/test_migrate_tss.go b/e2e/e2etests/test_migrate_tss.go index 8dc57b3e0a..c72b876f0f 100644 --- a/e2e/e2etests/test_migrate_tss.go +++ b/e2e/e2etests/test_migrate_tss.go @@ -11,10 +11,10 @@ import ( "github.com/btcsuite/btcutil" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" - "github.com/zeta-chain/zetacore/pkg/chains" "github.com/zeta-chain/zetacore/e2e/runner" "github.com/zeta-chain/zetacore/e2e/utils" + "github.com/zeta-chain/zetacore/pkg/chains" zetacrypto "github.com/zeta-chain/zetacore/pkg/crypto" crosschaintypes "github.com/zeta-chain/zetacore/x/crosschain/types" observertypes "github.com/zeta-chain/zetacore/x/observer/types" diff --git a/e2e/runner/bitcoin.go b/e2e/runner/bitcoin.go index deb1109901..868c344766 100644 --- a/e2e/runner/bitcoin.go +++ b/e2e/runner/bitcoin.go @@ -15,7 +15,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/rs/zerolog/log" "github.com/stretchr/testify/require" - "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/signer" "github.com/zeta-chain/zetacore/e2e/utils" "github.com/zeta-chain/zetacore/pkg/chains" @@ -26,6 +25,7 @@ import ( lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types" zetabitcoin "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin" btcobserver "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/observer" + "github.com/zeta-chain/zetacore/zetaclient/chains/bitcoin/signer" ) var blockHeaderBTCTimeout = 5 * time.Minute diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index 8be95af4c7..2666869b18 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -52,8 +52,10 @@ func TestKeeper_ValidateInbound(t *testing.T) { // setup Mocks for IsInboundEnabled observerMock.On("IsInboundEnabled", ctx).Return(true) // setup mocks for Initiate Outbound - observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observerTypes.ChainNonces{Nonce: 1}, true) - observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything).Return(observerTypes.PendingNonces{NonceHigh: 1}, true) + observerMock.On("GetChainNonces", mock.Anything, mock.Anything). + Return(observerTypes.ChainNonces{Nonce: 1}, true) + observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything). + Return(observerTypes.PendingNonces{NonceHigh: 1}, true) observerMock.On("SetChainNonces", mock.Anything, mock.Anything).Return(nil) observerMock.On("SetPendingNonces", mock.Anything, mock.Anything).Return(nil) // setup Mocks for SetCctxAndNonceToCctxAndInboundHashToCctx @@ -181,7 +183,8 @@ func TestKeeper_ValidateInbound(t *testing.T) { // setup Mocks for IsInboundEnabled observerMock.On("IsInboundEnabled", ctx).Return(true) // setup mocks for Initiate Outbound - observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observerTypes.ChainNonces{Nonce: 1}, false) + observerMock.On("GetChainNonces", mock.Anything, mock.Anything). + Return(observerTypes.ChainNonces{Nonce: 1}, false) k.SetGasPrice(ctx, types.GasPrice{ ChainId: senderChain.ChainId, @@ -247,8 +250,10 @@ func TestKeeper_ValidateInbound(t *testing.T) { // setup Mocks for IsInboundEnabled observerMock.On("IsInboundEnabled", ctx).Return(true) // setup mocks for Initiate Outbound - observerMock.On("GetChainNonces", mock.Anything, mock.Anything).Return(observerTypes.ChainNonces{Nonce: 1}, true) - observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything).Return(observerTypes.PendingNonces{NonceHigh: 1}, true) + observerMock.On("GetChainNonces", mock.Anything, mock.Anything). + Return(observerTypes.ChainNonces{Nonce: 1}, true) + observerMock.On("GetPendingNonces", mock.Anything, mock.Anything, mock.Anything). + Return(observerTypes.PendingNonces{NonceHigh: 1}, true) observerMock.On("SetChainNonces", mock.Anything, mock.Anything).Return(nil) observerMock.On("SetPendingNonces", mock.Anything, mock.Anything).Return(nil) // setup Mocks for SetCctxAndNonceToCctxAndInboundHashToCctx diff --git a/x/crosschain/types/errors.go b/x/crosschain/types/errors.go index e7df34baa8..b468d2c962 100644 --- a/x/crosschain/types/errors.go +++ b/x/crosschain/types/errors.go @@ -50,6 +50,10 @@ var ( ErrMaxTxOutTrackerHashesReached = errorsmod.Register(ModuleName, 1153, "max tx out tracker hashes reached") ErrInitiatitingOutbound = errorsmod.Register(ModuleName, 1154, "cannot initiate outbound") ErrInvalidWithdrawalAmount = errorsmod.Register(ModuleName, 1155, "invalid withdrawal amount") - ErrMigrationFromOldTss = errorsmod.Register(ModuleName, 1156, "migration tx from an old tss address detected") - ErrValidatingInbound = errorsmod.Register(ModuleName, 1157, "unable to validate inbound") + ErrMigrationFromOldTss = errorsmod.Register( + ModuleName, + 1156, + "migration tx from an old tss address detected", + ) + ErrValidatingInbound = errorsmod.Register(ModuleName, 1157, "unable to validate inbound") ) diff --git a/zetaclient/chains/evm/observer/outbound.go b/zetaclient/chains/evm/observer/outbound.go index 4b847b52c5..7b4f200d52 100644 --- a/zetaclient/chains/evm/observer/outbound.go +++ b/zetaclient/chains/evm/observer/outbound.go @@ -420,6 +420,9 @@ func (ob *Observer) checkConfirmedTx( // If from is not TSS address, check if it is one of the previous TSS addresses We can still try to confirm a tx which was broadcast by an old TSS // This is to handle situations where the outbound has already been broad-casted by an older TSS address and the zetacore is waiting for the all the required block confirmations // to go through before marking the cctx into a finalized state + + // TODO : improve this logic to verify that the correct TSS address is the from address. + // https://github.com/zeta-chain/node/issues/2487 log.Info(). Str("function", "confirmTxByHash"). Str("sender", from.Hex()). From c2eced50b8b655969272d649518712fe7225e67a Mon Sep 17 00:00:00 2001 From: Tanmay Date: Tue, 16 Jul 2024 12:44:10 -0400 Subject: [PATCH 39/40] resolve comments 4 --- Makefile | 2 +- changelog.md | 2 +- cmd/zetaclientd-supervisor/lib.go | 1 + cmd/zetaclientd/keygen_tss.go | 8 ++-- cmd/zetae2e/local/local.go | 8 ++-- .../cctx_orchestrator_validate_inbound.go | 17 ++++----- ...cctx_orchestrator_validate_inbound_test.go | 38 +++++++++---------- 7 files changed, 38 insertions(+), 38 deletions(-) diff --git a/Makefile b/Makefile index 4cb7375fae..75bd9e9f92 100644 --- a/Makefile +++ b/Makefile @@ -256,7 +256,7 @@ start-stress-test: zetanode start-tss-migration-test: zetanode @echo "--> Starting migration test" - export E2E_ARGS="--test-migration" && \ + export E2E_ARGS="--test-tss-migration" && \ cd contrib/localnet/ && $(DOCKER) compose up -d ############################################################################### diff --git a/changelog.md b/changelog.md index b2b61d30cc..bfe1c6b7d0 100644 --- a/changelog.md +++ b/changelog.md @@ -80,7 +80,7 @@ * [2369](https://github.com/zeta-chain/node/pull/2369) - fix random cross-chain swap failure caused by using tiny UTXO * [2549](https://github.com/zeta-chain/node/pull/2459) - add separate accounts for each policy in e2e tests * [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 +* [2440](https://github.com/zeta-chain/node/pull/2440) - Add e2e test for TSS migration ### Fixes diff --git a/cmd/zetaclientd-supervisor/lib.go b/cmd/zetaclientd-supervisor/lib.go index cf9b883ea6..71f492e88b 100644 --- a/cmd/zetaclientd-supervisor/lib.go +++ b/cmd/zetaclientd-supervisor/lib.go @@ -182,6 +182,7 @@ func (s *zetaclientdSupervisor) handleTSSUpdate(ctx context.Context) { retryInterval := 5 * time.Second // TODO : use retry library under pkg/retry + // https://github.com/zeta-chain/node/issues/2492 for i := 0; i < maxRetries; i++ { client := observertypes.NewQueryClient(s.zetacoredConn) tss, err := client.TSS(ctx, &observertypes.QueryGetTSSRequest{}) diff --git a/cmd/zetaclientd/keygen_tss.go b/cmd/zetaclientd/keygen_tss.go index 71beeb17fe..8d677a2680 100644 --- a/cmd/zetaclientd/keygen_tss.go +++ b/cmd/zetaclientd/keygen_tss.go @@ -85,9 +85,9 @@ func GenerateTSS( } // Try keygen only once at a particular block, irrespective of whether it is successful or failure triedKeygenAtBlock = true - newPubkey, err := keygenTss(ctx, keyGen, *keygenTssServer, zetaCoreClient, keygenLogger) + newPubkey, err := keygenTSS(ctx, keyGen, *keygenTssServer, zetaCoreClient, keygenLogger) if err != nil { - keygenLogger.Error().Err(err).Msg("keygenTss error") + keygenLogger.Error().Err(err).Msg("keygenTSS error") tssFailedVoteHash, err := zetaCoreClient.PostVoteTSS(ctx, "", keyGen.BlockNumber, chains.ReceiveStatus_failed) if err != nil { @@ -122,10 +122,10 @@ func GenerateTSS( return errors.New("unexpected state for TSS generation") } -// keygenTss generates a new TSS using the keygen request and the TSS server. +// keygenTSS generates a new TSS using the keygen request and the TSS server. // If the keygen is successful, the function returns the new TSS pubkey. // If the keygen is unsuccessful, the function posts blame and returns an error. -func keygenTss( +func keygenTSS( ctx context.Context, keyGen observertypes.Keygen, tssServer tss.TssServer, diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 20e6c72f8e..3b935c4791 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -36,7 +36,7 @@ const ( flagLight = "light" flagSetupOnly = "setup-only" flagSkipSetup = "skip-setup" - flagTestMigration = "test-migration" + flagTestTSSMigration = "test-tss-migration" flagSkipBitcoinSetup = "skip-bitcoin-setup" flagSkipHeaderProof = "skip-header-proof" ) @@ -69,7 +69,7 @@ func NewLocalCmd() *cobra.Command { cmd.Flags().Bool(flagSkipSetup, false, "set to true to skip setup") cmd.Flags().Bool(flagSkipBitcoinSetup, false, "set to true to skip bitcoin wallet setup") cmd.Flags().Bool(flagSkipHeaderProof, false, "set to true to skip header proof tests") - cmd.Flags().Bool(flagTestMigration, false, "set to true to include a migration test at the end") + cmd.Flags().Bool(flagTestTSSMigration, false, "set to true to include a migration test at the end") return cmd } @@ -90,7 +90,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { skipSetup = must(cmd.Flags().GetBool(flagSkipSetup)) skipBitcoinSetup = must(cmd.Flags().GetBool(flagSkipBitcoinSetup)) skipHeaderProof = must(cmd.Flags().GetBool(flagSkipHeaderProof)) - testMigration = must(cmd.Flags().GetBool(flagTestMigration)) + testTSSMigration = must(cmd.Flags().GetBool(flagTestTSSMigration)) ) logger := runner.NewLogger(verbose, color.FgWhite, "setup") @@ -329,7 +329,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("✅ e2e tests completed in %s", time.Since(testStartTime).String()) - if testMigration { + if testTSSMigration { runTSSMigrationTest(deployerRunner, logger, verbose, conf) } diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go index 2d1dfb030d..4cda69a5c3 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound.go @@ -1,7 +1,6 @@ package keeper import ( - "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/zeta-chain/zetacore/pkg/chains" @@ -22,7 +21,7 @@ func (k Keeper) ValidateInbound( return nil, types.ErrCannotFindTSSKeys } - err := k.CheckIfMigrationTransfer(ctx, msg) + err := k.CheckIfTSSMigrationTransfer(ctx, msg) if err != nil { return nil, err } @@ -57,12 +56,12 @@ func (k Keeper) ValidateInbound( return &cctx, nil } -// CheckIfMigrationTransfer checks if the sender is a TSS address and returns an error if it is. +// CheckIfTSSMigrationTransfer checks if the sender is a TSS address and returns an error if it is. // If the sender is an older TSS address, this means that it is a migration transfer, and we do not need to treat this as a deposit and process the CCTX -func (k Keeper) CheckIfMigrationTransfer(ctx sdk.Context, msg *types.MsgVoteInbound) error { +func (k Keeper) CheckIfTSSMigrationTransfer(ctx sdk.Context, msg *types.MsgVoteInbound) error { additionalChains := k.GetAuthorityKeeper().GetAdditionalChainList(ctx) - historicalTssList := k.zetaObserverKeeper.GetAllTSS(ctx) + historicalTSSList := k.zetaObserverKeeper.GetAllTSS(ctx) chain, found := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, msg.SenderChainId) if !found { return observertypes.ErrSupportedChains.Wrapf("chain not found for chainID %d", msg.SenderChainId) @@ -75,10 +74,10 @@ func (k Keeper) CheckIfMigrationTransfer(ctx sdk.Context, msg *types.MsgVoteInbo switch { case chains.IsEVMChain(chain.ChainId, additionalChains): - for _, tss := range historicalTssList { + for _, tss := range historicalTSSList { ethTssAddress, err := crypto.GetTssAddrEVM(tss.TssPubkey) if err != nil { - return errors.Wrap(types.ErrInvalidAddress, err.Error()) + continue } if ethTssAddress.Hex() == msg.Sender { return types.ErrMigrationFromOldTss @@ -89,10 +88,10 @@ func (k Keeper) CheckIfMigrationTransfer(ctx sdk.Context, msg *types.MsgVoteInbo if err != nil { return err } - for _, tss := range historicalTssList { + for _, tss := range historicalTSSList { btcTssAddress, err := crypto.GetTssAddrBTC(tss.TssPubkey, bitcoinParams) if err != nil { - return errors.Wrap(types.ErrInvalidAddress, err.Error()) + continue } if btcTssAddress == msg.Sender { return types.ErrMigrationFromOldTss diff --git a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go index 2666869b18..0f09c61025 100644 --- a/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go +++ b/x/crosschain/keeper/cctx_orchestrator_validate_inbound_test.go @@ -43,7 +43,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationTransfer + // Set up mocks for CheckIfTSSMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -174,7 +174,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationTransfer + // Set up mocks for CheckIfTSSMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -241,7 +241,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationTransfer + // Set up mocks for CheckIfTSSMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -315,7 +315,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { sender := sample.EthAddress() tssList := sample.TssList(3) - // Set up mocks for CheckIfMigrationTransfer + // Set up mocks for CheckIfTSSMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, true) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -352,7 +352,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { require.ErrorIs(t, err, observerTypes.ErrInboundDisabled) }) - t.Run("fails when CheckIfMigrationTransfer fails", func(t *testing.T) { + t.Run("fails when CheckIfTSSMigrationTransfer fails", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseObserverMock: true, @@ -381,7 +381,7 @@ func TestKeeper_ValidateInbound(t *testing.T) { // setup Mocks for GetTSS observerMock.On("GetTSS", mock.Anything).Return(tssList[0], true) - // Set up mocks for CheckIfMigrationTransfer + // Set up mocks for CheckIfTSSMigrationTransfer observerMock.On("GetAllTSS", ctx).Return(tssList) observerMock.On("GetSupportedChainFromChainID", mock.Anything, senderChain.ChainId).Return(senderChain, false) authorityMock.On("GetAdditionalChainList", ctx).Return([]chains.Chain{}) @@ -438,7 +438,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationTransfer(ctx, &msg) + err := k.CheckIfTSSMigrationTransfer(ctx, &msg) require.NoError(t, err) }) @@ -465,7 +465,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationTransfer(ctx, &msg) + err := k.CheckIfTSSMigrationTransfer(ctx, &msg) require.NoError(t, err) }) @@ -494,11 +494,11 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationTransfer(ctx, &msg) + err := k.CheckIfTSSMigrationTransfer(ctx, &msg) require.ErrorIs(t, err, observerTypes.ErrSupportedChains) }) - t.Run("fails when tss address is invalid for bitcoin chain", func(t *testing.T) { + t.Run("skips check when an older tss address is invalid for bitcoin chain", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, @@ -522,11 +522,11 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationTransfer(ctx, &msg) - require.ErrorIs(t, err, types.ErrInvalidAddress) + err := k.CheckIfTSSMigrationTransfer(ctx, &msg) + require.NoError(t, err) }) - t.Run("fails when tss address is invalid for evm chain", func(t *testing.T) { + t.Run("skips check when an older tss address is invalid for evm chain", func(t *testing.T) { k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ UseAuthorityMock: true, @@ -550,8 +550,8 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationTransfer(ctx, &msg) - require.ErrorIs(t, err, types.ErrInvalidAddress) + err := k.CheckIfTSSMigrationTransfer(ctx, &msg) + require.NoError(t, err) }) t.Run("fails when sender is a TSS address for evm chain for evm chain", func(t *testing.T) { @@ -578,7 +578,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender.String(), } - err = k.CheckIfMigrationTransfer(ctx, &msg) + err = k.CheckIfTSSMigrationTransfer(ctx, &msg) require.ErrorIs(t, err, types.ErrMigrationFromOldTss) }) @@ -608,7 +608,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err = k.CheckIfMigrationTransfer(ctx, &msg) + err = k.CheckIfTSSMigrationTransfer(ctx, &msg) require.ErrorIs(t, err, types.ErrMigrationFromOldTss) }) @@ -639,7 +639,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationTransfer(ctx, &msg) + err := k.CheckIfTSSMigrationTransfer(ctx, &msg) require.ErrorContains(t, err, "no Bitcoin net params for chain ID: 999") }) @@ -662,7 +662,7 @@ func TestKeeper_CheckMigration(t *testing.T) { Sender: sender, } - err := k.CheckIfMigrationTransfer(ctx, &msg) + err := k.CheckIfTSSMigrationTransfer(ctx, &msg) require.NoError(t, err) }) } From cb07bdb28032a13e1cb92ad54ef6141229bbca2c Mon Sep 17 00:00:00 2001 From: Tanmay Date: Wed, 17 Jul 2024 08:28:42 -0400 Subject: [PATCH 40/40] Update .github/workflows/e2e.yml Co-authored-by: Francisco de Borja Aranda Castillejo --- .github/workflows/e2e.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index cf066511cd..aab15adf8f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -73,7 +73,6 @@ jobs: uses: actions/github-script@v7 with: script: | - console.log(context); if (context.eventName === 'pull_request') { const { data: pr } = await github.rest.pulls.get({ owner: context.repo.owner,