diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 924706af29..02977127ff 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -44,11 +44,11 @@ jobs: echo "${{ github.ref }}" check-goreleaser: - if: inputs.skip_checks != true runs-on: ${{ vars.RELEASE_RUNNER }} steps: - uses: actions/checkout@v4 - name: Build release snapshot + if: inputs.skip_checks != true run: | make release-snapshot diff --git a/Makefile b/Makefile index ebeacdb26e..7efc19b988 100644 --- a/Makefile +++ b/Makefile @@ -327,7 +327,7 @@ ifdef UPGRADE_TEST_FROM_SOURCE zetanode-upgrade: e2e-images @echo "Building zetanode-upgrade from source" $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime-source \ - --build-arg OLD_VERSION='release/v21' \ + --build-arg OLD_VERSION='release/v22' \ --build-arg NODE_VERSION=$(NODE_VERSION) \ --build-arg NODE_COMMIT=$(NODE_COMMIT) . @@ -336,7 +336,7 @@ else zetanode-upgrade: e2e-images @echo "Building zetanode-upgrade from binaries" $(DOCKER) build -t zetanode:old -f Dockerfile-localnet --target old-runtime \ - --build-arg OLD_VERSION='https://github.com/zeta-chain/node/releases/download/v21.0.0' \ + --build-arg OLD_VERSION='https://github.com/zeta-chain/node/releases/download/v22.1.1' \ --build-arg NODE_VERSION=$(NODE_VERSION) \ --build-arg NODE_COMMIT=$(NODE_COMMIT) \ . diff --git a/changelog.md b/changelog.md index af4dbbfc25..caee407d2e 100644 --- a/changelog.md +++ b/changelog.md @@ -2,20 +2,30 @@ ## Unreleased +## Refactor +* [3170](https://github.com/zeta-chain/node/pull/3170) - revamp TSS package in zetaclient + +## v23.0.0 + ### Features + * [2984](https://github.com/zeta-chain/node/pull/2984) - add Whitelist message ability to whitelist SPL tokens on Solana * [3091](https://github.com/zeta-chain/node/pull/3091) - improve build reproducability. `make release{,-build-only}` checksums should now be stable. * [3124](https://github.com/zeta-chain/node/pull/3124) - integrate SPL deposits * [3134](https://github.com/zeta-chain/node/pull/3134) - integrate SPL tokens withdraw to Solana * [3088](https://github.com/zeta-chain/node/pull/3088) - add functions to check and withdraw zrc20 as delegation rewards +* [3182](https://github.com/zeta-chain/node/pull/3182) - enable zetaclient pprof server on port 6061 ### Tests * [3075](https://github.com/zeta-chain/node/pull/3075) - ton: withdraw concurrent, deposit & revert. * [3105](https://github.com/zeta-chain/node/pull/3105) - split Bitcoin E2E tests into two runners for deposit and withdraw * [3154](https://github.com/zeta-chain/node/pull/3154) - configure Solana gateway program id for E2E tests +* [3188](https://github.com/zeta-chain/node/pull/3188) - add e2e test for v2 deposit and call with swap +* [3151](https://github.com/zeta-chain/node/pull/3151) - add withdraw emissions to e2e tests ### Refactor + * [3118](https://github.com/zeta-chain/node/pull/3118) - zetaclient: remove hsm signer * [3122](https://github.com/zeta-chain/node/pull/3122) - improve & refactor zetaclientd cli * [3125](https://github.com/zeta-chain/node/pull/3125) - drop support for header proofs @@ -23,6 +33,7 @@ * [3137](https://github.com/zeta-chain/node/pull/3137) - remove chain.Chain from zetaclientd config ### Fixes + * [3117](https://github.com/zeta-chain/node/pull/3117) - register messages for emissions module to legacy amino codec. * [3041](https://github.com/zeta-chain/node/pull/3041) - replace libp2p public DHT with private gossip peer discovery and connection gater for inbound connections * [3106](https://github.com/zeta-chain/node/pull/3106) - prevent blocked CCTX on out of gas during omnichain calls @@ -30,6 +41,49 @@ * [3149](https://github.com/zeta-chain/node/pull/3149) - abort the cctx if dust amount is detected in the revert outbound * [3155](https://github.com/zeta-chain/node/pull/3155) - fix potential panic in the Bitcoin inscription parsing * [3162](https://github.com/zeta-chain/node/pull/3162) - skip depositor fee calculation if transaction does not involve TSS address +* [3179](https://github.com/zeta-chain/node/pull/3179) - support inbound trackers for v2 cctx +* [3192](https://github.com/zeta-chain/node/pull/3192) - fix incorrect zContext origin caused by the replacement of 'sender' with 'revertAddress' + +## v22.1.2 + +## Fixes + +- [3181](https://github.com/zeta-chain/node/pull/3181) - add lock around pingRTT to prevent crash + +## v22.1.1 + +## Fixes + +- [3171](https://github.com/zeta-chain/node/pull/3171) - infinite discovery address leak + +## v22.1.0 + +## Features + +- [3028](https://github.com/zeta-chain/node/pull/3028) - whitelist connection gater + +## Fixes + +- [3041](https://github.com/zeta-chain/node/pull/3041) - replace DHT with private peer discovery +- [3162](https://github.com/zeta-chain/node/pull/3162) - skip depositor fee calculation on irrelevant transactions + +## v22.0.2 + +## Fixes + +- [3144](https://github.com/zeta-chain/node/pull/3145) - out of gas on ZetaClient during `onRevert` + +## v22.0.1 + +## Fixes + +- [3140](https://github.com/zeta-chain/node/pull/3140) - allow BTC revert with dust amount + +## v22.0.0 + +## Refactor + +* [3073](https://github.com/zeta-chain/node/pull/3073) - improve ZETA deposit check with max supply check ## v21.0.0 diff --git a/cmd/zetaclientd/initconfig.go b/cmd/zetaclientd/initconfig.go index 6619ce279a..c8a989bacf 100644 --- a/cmd/zetaclientd/initconfig.go +++ b/cmd/zetaclientd/initconfig.go @@ -7,6 +7,7 @@ import ( "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/zetaclient/config" + zetatss "github.com/zeta-chain/node/zetaclient/tss" ) // initializeConfigOptions is a set of CLI options for `init` command. @@ -73,7 +74,7 @@ func InitializeConfig(_ *cobra.Command, _ []string) error { // Validate Peer // e.g. /ip4/172.0.2.1/tcp/6668/p2p/16Uiu2HAmACG5DtqmQsHtXg4G2sLS65ttv84e7MrL4kapkjfmhxAp if opts.peer != "" { - if err := validatePeer(opts.peer); err != nil { + if _, err := zetatss.MultiAddressFromString(opts.peer); err != nil { return errors.Wrap(err, "invalid peer address") } } diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index 46d204fa34..76a3c0808c 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -2,48 +2,42 @@ package main import ( "context" - "encoding/json" - "fmt" - "io" + "net/http" + _ "net/http/pprof" // #nosec G108 -- pprof enablement is intentional "os" "os/signal" "path/filepath" "strings" - "sync" "syscall" - "time" - ecdsakeygen "github.com/bnb-chain/tss-lib/ecdsa/keygen" - "github.com/cometbft/cometbft/crypto/secp256k1" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p/p2p/protocol/ping" - maddr "github.com/multiformats/go-multiaddr" "github.com/pkg/errors" + "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/spf13/cobra" - "gitlab.com/thorchain/tss/go-tss/conversion" "github.com/zeta-chain/node/pkg/authz" "github.com/zeta-chain/node/pkg/chains" "github.com/zeta-chain/node/pkg/constant" zetaos "github.com/zeta-chain/node/pkg/os" - "github.com/zeta-chain/node/pkg/ticker" - observerTypes "github.com/zeta-chain/node/x/observer/types" "github.com/zeta-chain/node/zetaclient/chains/base" "github.com/zeta-chain/node/zetaclient/config" zctx "github.com/zeta-chain/node/zetaclient/context" + "github.com/zeta-chain/node/zetaclient/keys" "github.com/zeta-chain/node/zetaclient/maintenance" "github.com/zeta-chain/node/zetaclient/metrics" "github.com/zeta-chain/node/zetaclient/orchestrator" - mc "github.com/zeta-chain/node/zetaclient/tss" + zetatss "github.com/zeta-chain/node/zetaclient/tss" "github.com/zeta-chain/node/zetaclient/zetacore" ) -// todo revamp -// https://github.com/zeta-chain/node/issues/3119 -// https://github.com/zeta-chain/node/issues/3112 -var preParams *ecdsakeygen.LocalPreParams +const ( + // enables posting blame data to core for failed TSS signatures + envFlagPostBlame = "POST_BLAME" + envPprofAddr = "PPROF_ADDR" +) +// Start starts zetaclientd process todo revamp +// https://github.com/zeta-chain/node/issues/3112 func Start(_ *cobra.Command, _ []string) error { // Prompt for Hotkey, TSS key-share and relayer key passwords titles := []string{"HotKey", "TSS", "Solana Relayer Key"} @@ -67,13 +61,6 @@ func Start(_ *cobra.Command, _ []string) error { return errors.Wrap(err, "initLogger failed") } - // Wait until zetacore has started - if cfg.Peer != "" { - if err := validatePeer(cfg.Peer); err != nil { - return errors.Wrap(err, "unable to validate peer") - } - } - masterLogger := logger.Std startLogger := logger.Std.With().Str("module", "startup").Logger() @@ -93,6 +80,8 @@ func Start(_ *cobra.Command, _ []string) error { } }() + go runPprof(startLogger) + // CreateZetacoreClient: zetacore client is used for all communication to zetacore , which this client connects to. // Zetacore accumulates votes , and provides a centralized source of truth for all clients zetacoreClient, err := createZetacoreClient(cfg, hotkeyPass, masterLogger) @@ -148,177 +137,42 @@ func Start(_ *cobra.Command, _ []string) error { startLogger.Info().Msgf("Config is updated from zetacore\n %s", cfg.StringMasked()) - // Generate TSS address . The Tss address is generated through Keygen ceremony. The TSS key is used to sign all outbound transactions . - // The hotkeyPk is private key for the Hotkey. The Hotkey is used to sign all inbound transactions - // Each node processes a portion of the key stored in ~/.tss by default . Custom location can be specified in config file during init. - // After generating the key , the address is set on the zetacore - hotkeyPk, err := zetacoreClient.GetKeys().GetPrivateKey(hotkeyPass) - if err != nil { - startLogger.Error().Err(err).Msg("zetacore client GetPrivateKey error") - } - startLogger.Debug().Msgf("hotkeyPk %s", hotkeyPk.String()) - if len(hotkeyPk.Bytes()) != 32 { - errMsg := fmt.Sprintf("key bytes len %d != 32", len(hotkeyPk.Bytes())) - log.Error().Msg(errMsg) - return errors.New(errMsg) - } - priKey := secp256k1.PrivKey(hotkeyPk.Bytes()[:32]) - - // Generate pre Params if not present already - peers, err := initPeers(cfg.Peer) - if err != nil { - log.Error().Err(err).Msg("peer address error") - } - initPreParams(cfg.PreParamsPath) - m, err := metrics.NewMetrics() if err != nil { - log.Error().Err(err).Msg("NewMetrics") - return err + return errors.Wrap(err, "unable to create metrics") } m.Start() metrics.Info.WithLabelValues(constant.Version).Set(1) metrics.LastStartTime.SetToCurrentTime() - var tssHistoricalList []observerTypes.TSS - tssHistoricalList, err = zetacoreClient.GetTSSHistory(ctx) + telemetryServer.SetIPAddress(cfg.PublicIP) + + granteePubKeyBech32, err := resolveObserverPubKeyBech32(cfg, hotkeyPass) if err != nil { - startLogger.Error().Err(err).Msg("GetTssHistory error") + return errors.Wrap(err, "unable to resolve observer pub key bech32") } - telemetryServer.SetIPAddress(cfg.PublicIP) - - keygen := appContext.GetKeygen() - whitelistedPeers := []peer.ID{} - for _, pk := range keygen.GranteePubkeys { - pid, err := conversion.Bech32PubkeyToPeerID(pk) - if err != nil { - return err - } - whitelistedPeers = append(whitelistedPeers, pid) + tssSetupProps := zetatss.SetupProps{ + Config: cfg, + Zetacore: zetacoreClient, + GranteePubKeyBech32: granteePubKeyBech32, + HotKeyPassword: hotkeyPass, + TSSKeyPassword: tssKeyPass, + BitcoinChainIDs: btcChainIDsFromContext(appContext), + PostBlame: isEnvFlagEnabled(envFlagPostBlame), + Telemetry: telemetryServer, } - // Create TSS server - tssServer, err := mc.SetupTSSServer( - peers, - priKey, - preParams, - appContext.Config(), - tssKeyPass, - true, - whitelistedPeers, - ) + tss, err := zetatss.Setup(ctx, tssSetupProps, startLogger) if err != nil { - return fmt.Errorf("SetupTSSServer error: %w", err) + return errors.Wrap(err, "unable to setup TSS service") } - // Set P2P ID for telemetry - telemetryServer.SetP2PID(tssServer.GetLocalPeerID()) - // Creating a channel to listen for os signals (or other signals) signalChannel := make(chan os.Signal, 1) signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM) - go func() { - for { - time.Sleep(30 * time.Second) - ps := tssServer.GetKnownPeers() - metrics.NumConnectedPeers.Set(float64(len(ps))) - telemetryServer.SetConnectedPeers(ps) - } - }() - go func() { - host := tssServer.GetP2PHost() - pingRTT := make(map[peer.ID]int64) - for { - var wg sync.WaitGroup - for _, p := range whitelistedPeers { - wg.Add(1) - go func(p peer.ID) { - defer wg.Done() - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - result := <-ping.Ping(ctx, host, p) - if result.Error != nil { - masterLogger.Error().Err(result.Error).Msg("ping error") - pingRTT[p] = -1 // RTT -1 indicate ping error - return - } - pingRTT[p] = result.RTT.Nanoseconds() - }(p) - } - wg.Wait() - telemetryServer.SetPingRTT(pingRTT) - time.Sleep(30 * time.Second) - } - }() - - // 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 = mc.Generate(ctx, zetacoreClient, tssServer, masterLogger) - if err != nil { - return err - } - - tss, err := mc.New( - ctx, - zetacoreClient, - tssHistoricalList, - hotkeyPass, - tssServer, - ) - if err != nil { - startLogger.Error().Err(err).Msg("NewTSS error") - return err - } - if cfg.TestTssKeysign { - err = mc.TestTSS(tss.CurrentPubkey, *tss.Server, 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 - _ = ticker.Run(ctx, time.Second, func(ctx context.Context, t *ticker.Ticker) error { - keygen, err = zetacoreClient.GetKeyGen(ctx) - switch { - case err != nil: - startLogger.Warn().Err(err).Msg("Waiting for TSS Keygen to be a success, got error") - case keygen.Status != observerTypes.KeygenStatus_KeyGenSuccess: - startLogger.Warn().Msgf("Waiting for TSS Keygen to be a success, current status %s", keygen.Status) - default: - t.Stop() - } - - return nil - }) - - // 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 - currentTss, err := zetacoreClient.GetTSS(ctx) - if err != nil { - return errors.Wrap(err, "unable to get current TSS") - } - - // Filter supported BTC chain IDs - btcChains := appContext.FilterChains(zctx.Chain.IsBitcoin) - btcChainIDs := make([]int64, len(btcChains)) - for i, chain := range btcChains { - btcChainIDs[i] = chain.ID() - } - - // Make sure the TSS EVM/BTC addresses are well formed. - // Zetaclient should not start if TSS addresses cannot be properly derived. - tss.CurrentPubkey = currentTss.TssPubkey - err = tss.ValidateAddresses(btcChainIDs) - if err != nil { - startLogger.Error().Err(err).Msg("TSS address validation failed") - return err - } - // Starts various background TSS listeners. // Shuts down zetaclientd if any is triggered. maintenance.NewTSSListener(zetacoreClient, masterLogger).Listen(ctx, func() { @@ -409,42 +263,6 @@ func Start(_ *cobra.Command, _ []string) error { return nil } -func initPeers(peer string) ([]maddr.Multiaddr, error) { - var peers []maddr.Multiaddr - - if peer != "" { - address, err := maddr.NewMultiaddr(peer) - if err != nil { - log.Error().Err(err).Msg("NewMultiaddr error") - return []maddr.Multiaddr{}, err - } - peers = append(peers, address) - } - return peers, nil -} - -func initPreParams(path string) { - if path != "" { - path = filepath.Clean(path) - log.Info().Msgf("pre-params file path %s", path) - preParamsFile, err := os.Open(path) - if err != nil { - log.Error().Err(err).Msg("open pre-params file failed; skip") - } else { - bz, err := io.ReadAll(preParamsFile) - if err != nil { - log.Error().Err(err).Msg("read pre-params file failed; skip") - } else { - err = json.Unmarshal(bz, &preParams) - if err != nil { - log.Error().Err(err).Msg("unmarshal pre-params file failed; skip and generate new one") - preParams = nil // skip reading pre-params; generate new one instead - } - } - } - } -} - // isObserverNode checks whether THIS node is an observer node. func isObserverNode(ctx context.Context, client *zetacore.Client) (bool, error) { observers, err := client.GetObserverList(ctx) @@ -462,3 +280,30 @@ func isObserverNode(ctx context.Context, client *zetacore.Client) (bool, error) return false, nil } + +func resolveObserverPubKeyBech32(cfg config.Config, hotKeyPassword string) (string, error) { + // Get observer's public key ("grantee pub key") + _, granteePubKeyBech32, err := keys.GetKeyringKeybase(cfg, hotKeyPassword) + if err != nil { + return "", errors.Wrap(err, "unable to get keyring key base") + } + + return granteePubKeyBech32, nil +} + +// runPprof run pprof http server +// zetacored/cometbft is already listening for runPprof on 6060 (by default) +func runPprof(logger zerolog.Logger) { + addr := os.Getenv(envPprofAddr) + if addr == "" { + addr = "localhost:6061" + } + + logger.Info().Str("addr", addr).Msg("starting pprof http server") + + // #nosec G114 -- timeouts unneeded + err := http.ListenAndServe(addr, nil) + if err != nil { + logger.Error().Err(err).Msg("pprof http server error") + } +} diff --git a/cmd/zetaclientd/utils.go b/cmd/zetaclientd/utils.go index 53f2f208bc..f7ef2f91bc 100644 --- a/cmd/zetaclientd/utils.go +++ b/cmd/zetaclientd/utils.go @@ -3,8 +3,8 @@ package main import ( "context" "fmt" - "net" - "strings" + "os" + "strconv" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -16,6 +16,7 @@ import ( "github.com/zeta-chain/node/zetaclient/authz" "github.com/zeta-chain/node/zetaclient/chains/interfaces" "github.com/zeta-chain/node/zetaclient/config" + zctx "github.com/zeta-chain/node/zetaclient/context" "github.com/zeta-chain/node/zetaclient/keys" "github.com/zeta-chain/node/zetaclient/zetacore" ) @@ -101,23 +102,20 @@ func waitForZetacoreToCreateBlocks(ctx context.Context, zc interfaces.ZetacoreCl } } -func validatePeer(seedPeer string) error { - parsedPeer := strings.Split(seedPeer, "/") - - if len(parsedPeer) < 7 { - return errors.New("seed peer missing IP or ID or both, seed: " + seedPeer) - } - - seedIP := parsedPeer[2] - seedID := parsedPeer[6] +func isEnvFlagEnabled(flag string) bool { + v, _ := strconv.ParseBool(os.Getenv(flag)) + return v +} - if net.ParseIP(seedIP) == nil { - return errors.New("invalid seed IP address format, seed: " + seedPeer) - } +func btcChainIDsFromContext(app *zctx.AppContext) []int64 { + var ( + btcChains = app.FilterChains(zctx.Chain.IsBitcoin) + btcChainIDs = make([]int64, len(btcChains)) + ) - if len(seedID) == 0 { - return errors.New("seed id is empty, seed: " + seedPeer) + for i, chain := range btcChains { + btcChainIDs[i] = chain.ID() } - return nil + return btcChainIDs } diff --git a/cmd/zetae2e/config/local.yml b/cmd/zetae2e/config/local.yml index e4ec147e49..15de10ceda 100644 --- a/cmd/zetae2e/config/local.yml +++ b/cmd/zetae2e/config/local.yml @@ -65,6 +65,10 @@ additional_accounts: bech32_address: "zeta1nry9yeg6njhjrp2ctppa8558vqxal9fxk69zxg" evm_address: "0x98c852651A9CAF2185585843d3D287600Ddf9526" private_key: "bf9456c679bb5a952a9a137fcfc920e0413efdb97c36de1e57455763084230cb" + user_emissions_withdraw: + bech32_address: "zeta1n9zhyn4unvaee3ey40k7x7f5nmj7zet6qr5kl7" + evm_address: "0x9945724EBc9B3B9cc724abedE379349EE5E1657a" + private_key: "9d524fe318c0eb5f80d8b246993a9f15f924db24d4b8b873839b13bc30040d03" policy_accounts: emergency_policy_account: bech32_address: "zeta16m2cnrdwtgweq4njc6t470vl325gw4kp6s7tap" @@ -110,13 +114,15 @@ contracts: wzeta: "0x5F0b1a82749cb4E2278EC87F8BF6B618dC71a8bf" test_dapp: "0xA8D5060feb6B456e886F023709A2795373691E63" gateway: "0xa825eAa55b497AF892faca73a3797046C10B7c23" + test_dapp_v2: "0xBFF76e77D56B3C1202107f059425D56f0AEF87Ed" evm: zeta_eth: "0x733aB8b06DDDEf27Eaa72294B0d7c9cEF7f12db9" connector_eth: "0xD28D6A0b8189305551a0A8bd247a6ECa9CE781Ca" - custody: "0xff3135df4F2775f4091b81f4c7B6359CfA07862a" + custody: "0x784aE8B474aebabB74526701146a708734f6931c" erc20: "0xbD1e64A22B9F92D9Ce81aA9B4b0fFacd80215564" test_dapp: "0xBFF76e77D56B3C1202107f059425D56f0AEF87Ed" gateway: "0xF0deebCB0E9C829519C4baa794c5445171973826" + test_dapp_v2: "0xa825eAa55b497AF892faca73a3797046C10B7c23" solana: gateway_program_id: "94U5AHQMKkV5txNJ17QPXWoh474PheGou6cNP2FEuL1d" spl: "" \ No newline at end of file diff --git a/cmd/zetae2e/config/localnet.yml b/cmd/zetae2e/config/localnet.yml index 15f1e332f6..6e1c2b392c 100644 --- a/cmd/zetae2e/config/localnet.yml +++ b/cmd/zetae2e/config/localnet.yml @@ -65,6 +65,10 @@ additional_accounts: bech32_address: "zeta1nry9yeg6njhjrp2ctppa8558vqxal9fxk69zxg" evm_address: "0x98c852651A9CAF2185585843d3D287600Ddf9526" private_key: "bf9456c679bb5a952a9a137fcfc920e0413efdb97c36de1e57455763084230cb" + user_emissions_withdraw: + bech32_address: "zeta1n9zhyn4unvaee3ey40k7x7f5nmj7zet6qr5kl7" + evm_address: "0x9945724EBc9B3B9cc724abedE379349EE5E1657a" + private_key: "9d524fe318c0eb5f80d8b246993a9f15f924db24d4b8b873839b13bc30040d03" policy_accounts: emergency_policy_account: bech32_address: "zeta16m2cnrdwtgweq4njc6t470vl325gw4kp6s7tap" diff --git a/cmd/zetae2e/local/erc20.go b/cmd/zetae2e/local/erc20.go index 3b2830a066..8c9ef06869 100644 --- a/cmd/zetae2e/local/erc20.go +++ b/cmd/zetae2e/local/erc20.go @@ -37,7 +37,7 @@ func erc20TestRoutine( startTime := time.Now() // funding the account - txERC20Send := deployerRunner.SendERC20OnEvm(account.EVMAddress(), 10) + txERC20Send := deployerRunner.SendERC20OnEvm(account.EVMAddress(), 10000) erc20Runner.WaitForTxReceiptOnEvm(txERC20Send) // depositing the necessary tokens on ZetaChain diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 6199f7e33a..526a4c4d30 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -121,6 +121,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger := runner.NewLogger(verbose, color.FgWhite, "setup") testStartTime := time.Now() + logger.Print("starting E2E tests") if testAdmin { @@ -164,11 +165,13 @@ func localE2ETest(cmd *cobra.Command, _ []string) { utils.EmergencyPolicyName, utils.OperationalPolicyName, utils.AdminPolicyName, + utils.UserEmissionsWithdrawName, }, []string{ conf.PolicyAccounts.EmergencyPolicyAccount.RawPrivateKey.String(), conf.PolicyAccounts.OperationalPolicyAccount.RawPrivateKey.String(), conf.PolicyAccounts.AdminPolicyAccount.RawPrivateKey.String(), + conf.AdditionalAccounts.UserEmissionsWithdraw.RawPrivateKey.String(), }, conf.ZetaChainID, ) @@ -327,7 +330,6 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestBitcoinDepositName, e2etests.TestBitcoinDepositAndCallName, e2etests.TestBitcoinDepositAndCallRevertName, - e2etests.TestBitcoinDepositAndCallRevertWithDustName, e2etests.TestBitcoinStdMemoDepositName, e2etests.TestBitcoinStdMemoDepositAndCallName, e2etests.TestBitcoinStdMemoDepositAndCallRevertName, @@ -335,6 +337,9 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestBitcoinStdMemoInscribedDepositAndCallName, e2etests.TestCrosschainSwapName, } + bitcoinDepositTestsAdvanced := []string{ + e2etests.TestBitcoinDepositAndCallRevertWithDustName, + } bitcoinWithdrawTests := []string{ e2etests.TestBitcoinWithdrawSegWitName, e2etests.TestBitcoinWithdrawInvalidAddressName, @@ -379,6 +384,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { erc20Tests = append(erc20Tests, erc20AdvancedTests...) zetaTests = append(zetaTests, zetaAdvancedTests...) zevmMPTests = append(zevmMPTests, zevmMPAdvancedTests...) + bitcoinDepositTests = append(bitcoinDepositTests, bitcoinDepositTestsAdvanced...) bitcoinWithdrawTests = append(bitcoinWithdrawTests, bitcoinWithdrawTestsAdvanced...) ethereumTests = append(ethereumTests, ethereumAdvancedTests...) } @@ -492,6 +498,7 @@ func localE2ETest(cmd *cobra.Command, _ []string) { logger.Print("❌ e2e tests failed after %s", time.Since(testStartTime).String()) os.Exit(1) } + noError(deployerRunner.WithdrawEmissions()) // 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") diff --git a/cmd/zetae2e/local/v2.go b/cmd/zetae2e/local/v2.go index 770d7201ef..88423b9742 100644 --- a/cmd/zetae2e/local/v2.go +++ b/cmd/zetae2e/local/v2.go @@ -40,6 +40,7 @@ func startV2Tests(eg *errgroup.Group, conf config.Config, deployerRunner *runner e2etests.TestV2ERC20WithdrawAndCallName, e2etests.TestV2ERC20DepositAndCallNoMessageName, e2etests.TestV2ERC20WithdrawAndCallNoMessageName, + e2etests.TestV2DepositAndCallSwapName, )) // Test revert cases for gas token workflow diff --git a/cmd/zetae2e/run.go b/cmd/zetae2e/run.go index fe52f056d5..91116f234c 100644 --- a/cmd/zetae2e/run.go +++ b/cmd/zetae2e/run.go @@ -16,6 +16,8 @@ import ( "github.com/zeta-chain/node/e2e/config" "github.com/zeta-chain/node/e2e/e2etests" "github.com/zeta-chain/node/e2e/runner" + "github.com/zeta-chain/node/e2e/txserver" + "github.com/zeta-chain/node/e2e/utils" fungibletypes "github.com/zeta-chain/node/x/fungible/types" observertypes "github.com/zeta-chain/node/x/observer/types" ) @@ -104,6 +106,29 @@ func runE2ETest(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var runnerOpts []runner.E2ERunnerOption + + // if keys are defined for all policy accounts, we initialize a ZETA tx server allowing to send admin actions + emergencyKey := conf.PolicyAccounts.EmergencyPolicyAccount.RawPrivateKey.String() + operationalKey := conf.PolicyAccounts.OperationalPolicyAccount.RawPrivateKey.String() + adminKey := conf.PolicyAccounts.AdminPolicyAccount.RawPrivateKey.String() + if emergencyKey != "" && operationalKey != "" && adminKey != "" { + zetaTxServer, err := txserver.NewZetaTxServer( + conf.RPCs.ZetaCoreRPC, + []string{utils.EmergencyPolicyName, utils.OperationalPolicyName, utils.AdminPolicyName}, + []string{ + emergencyKey, + operationalKey, + adminKey, + }, + conf.ZetaChainID, + ) + if err != nil { + return err + } + runnerOpts = append(runnerOpts, runner.WithZetaTxServer(zetaTxServer)) + } + // initialize deployer runner with config testRunner, err := zetae2econfig.RunnerFromConfig( ctx, @@ -112,6 +137,7 @@ func runE2ETest(cmd *cobra.Command, args []string) error { conf, conf.DefaultAccount, logger, + runnerOpts..., ) if err != nil { return err diff --git a/contrib/localnet/docker-compose.yml b/contrib/localnet/docker-compose.yml index e0078230e7..2494cc0247 100644 --- a/contrib/localnet/docker-compose.yml +++ b/contrib/localnet/docker-compose.yml @@ -110,7 +110,10 @@ services: - ETHDEV_ENDPOINT=http://eth:8545 - HOTKEY_BACKEND=file - HOTKEY_PASSWORD=password # test purposes only + - PPROF_ADDR=0.0.0.0:6061 restart: always + ports: + - "6061:6061" # pprof volumes: - ssh:/root/.ssh - preparams:/root/preparams @@ -195,7 +198,7 @@ services: ipv4_address: 172.20.0.102 bitcoin: - image: ghcr.io/zeta-chain/ruimarinho-bitcoin-core:22 # version 23 is not working with btcd 0.22.0 due to change in createwallet rpc + image: ghcr.io/zeta-chain/bitcoin-core-docker:28.0 container_name: bitcoin hostname: bitcoin networks: @@ -210,6 +213,8 @@ services: -rpcbind=0.0.0.0 -rpcauth=smoketest:63acf9b8dccecce914d85ff8c044b78b$$5892f9bbc84f4364e79f0970039f88bdd823f168d4acc76099ab97b14a766a99 -txindex=1 + -deprecatedrpc=create_bdb + -deprecatedrpc=warnings solana: image: solana-local:latest diff --git a/contrib/localnet/orchestrator/start-zetae2e.sh b/contrib/localnet/orchestrator/start-zetae2e.sh index 5d8c9c5586..63064cdd1a 100644 --- a/contrib/localnet/orchestrator/start-zetae2e.sh +++ b/contrib/localnet/orchestrator/start-zetae2e.sh @@ -134,6 +134,9 @@ fund_eth_from_config '.additional_accounts.user_v2_ether_revert.evm_address' 100 # unlock v2 erc20 revert tests accounts fund_eth_from_config '.additional_accounts.user_v2_erc20_revert.evm_address' 10000 "V2 ERC20 revert tester" +# unlock emissions withdraw tests accounts +fund_eth_from_config '.additional_accounts.user_emissions_withdraw.evm_address' 10000 "emissions withdraw tester" + # unlock local solana relayer accounts if host solana > /dev/null; then solana_url=$(config_str '.rpcs.solana') @@ -183,7 +186,8 @@ if [ "$LOCALNET_MODE" == "tss-migrate" ]; then echo "waiting 10 seconds for node to restart" sleep 10 - zetae2e local --skip-setup --config "$deployed_config_path" --skip-bitcoin-setup --light --skip-header-proof + zetae2e local --skip-setup --config "$deployed_config_path" \ + --skip-bitcoin-setup --light --skip-header-proof --skip-precompiles ZETAE2E_EXIT_CODE=$? if [ $ZETAE2E_EXIT_CODE -eq 0 ]; then echo "E2E passed after migration" @@ -222,7 +226,8 @@ if [ "$LOCALNET_MODE" == "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 local $E2E_ARGS --skip-setup --config "$deployed_config_path" --light --skip-precompiles ${COMMON_ARGS} + # skip-bitcoin-dust-withdraw flag can be removed after v23 is released + zetae2e local $E2E_ARGS --skip-setup --config "$deployed_config_path" --light --skip-precompiles ${COMMON_ARGS} if [ $? -ne 0 ]; then echo "first e2e failed" exit 1 diff --git a/contrib/localnet/scripts/start-zetacored.sh b/contrib/localnet/scripts/start-zetacored.sh index 38047a6b46..56e30358c1 100755 --- a/contrib/localnet/scripts/start-zetacored.sh +++ b/contrib/localnet/scripts/start-zetacored.sh @@ -67,6 +67,55 @@ add_v17_message_authorizations() { ' $json_file > temp.json && mv temp.json $json_file } + +add_emissions_withdraw_authorizations() { + + config_file="/root/config.yml" + json_file="/root/.zetacored/config/genesis.json" + + # Check if config file exists + if [[ ! -f "$config_file" ]]; then + echo "Error: Config file not found at $config_file" + return 1 + fi + # Address to add emissions withdraw authorizations + address=$(yq -r '.additional_accounts.user_emissions_withdraw.bech32_address' "$config_file") + + # Check if genesis file exists + if [[ ! -f "$json_file" ]]; then + echo "Error: Genesis file not found at $json_file" + return 1 + fi + + echo "Adding emissions withdraw authorizations for address: $address" + + + # Using jq to parse JSON, create new entries, and append them to the authorization array + if ! jq --arg address "$address" ' + # Store the nodeAccountList array + .app_state.observer.nodeAccountList as $list | + # Iterate over the stored list to construct new objects and append to the authorization array + .app_state.authz.authorization += [ + $list[] | + { + "granter": .operator, + "grantee": $address, + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/zetachain.zetacore.emissions.MsgWithdrawEmission" + }, + "expiration": null + } + ] + ' "$json_file" > temp.json; then + echo "Error: Failed to update genesis file" + return 1 + fi + mv temp.json "$json_file" +} + + + # create keys CHAINID="athens_101-1" KEYRING="test" @@ -191,6 +240,12 @@ then zetacored collect-observer-info zetacored add-observer-list --keygen-block 25 + # Add emissions withdraw authorizations + if ! add_emissions_withdraw_authorizations; then + echo "Error: Failed to add emissions withdraw authorizations" + exit 1 + fi + # Check for the existence of "AddToOutTxTracker" string in the genesis file # If this message is found in the genesis, it means add-observer-list has been run with the v16 binary for upgrade tests # In this case, we need to add authorizations for the new v17 messages to the genesis file @@ -272,6 +327,9 @@ then # v2 erc20 revert tester address=$(yq -r '.additional_accounts.user_v2_erc20_revert.bech32_address' /root/config.yml) zetacored add-genesis-account "$address" 100000000000000000000000000azeta +# emissions withdraw tester + address=$(yq -r '.additional_accounts.user_emissions_withdraw.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/docs/openapi/openapi.html b/docs/openapi/openapi.html index 37fbfb2a16..20f878256f 100644 --- a/docs/openapi/openapi.html +++ b/docs/openapi/openapi.html @@ -5,18 +5,18 @@
- +