diff --git a/changelog.md b/changelog.md index 9af4cbca39..4b321781d0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,28 @@ # CHANGELOG +## 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 @@ -28,6 +51,7 @@ * [2979](https://github.com/zeta-chain/node/pull/2979) - add fungible keeper ability to lock/unlock ZRC20 tokens * [3012](https://github.com/zeta-chain/node/pull/3012) - integrate authenticated calls erc20 smart contract functionality into protocol * [3025](https://github.com/zeta-chain/node/pull/3025) - standard memo for Bitcoin inbound +* [3028](https://github.com/zeta-chain/node/pull/3028) - whitelist connection gater ### Refactor @@ -141,7 +165,7 @@ * [2518](https://github.com/zeta-chain/node/pull/2518) - add support for Solana address in zetacore * [2483](https://github.com/zeta-chain/node/pull/2483) - add priorityFee (gasTipCap) gas to the state * [2567](https://github.com/zeta-chain/node/pull/2567) - add sign latency metric to zetaclient (zetaclient_sign_latency) -* [2524](https://github.com/zeta-chain/node/pull/2524) - add inscription envelop parsing +* [2524](https://github.com/zeta-chain/node/pull/2524) - add inscription envelop parsing * [2560](https://github.com/zeta-chain/node/pull/2560) - add support for Solana SOL token withdraw * [2533](https://github.com/zeta-chain/node/pull/2533) - parse memo from both OP_RETURN and inscription * [2765](https://github.com/zeta-chain/node/pull/2765) - bitcoin depositor fee improvement @@ -223,7 +247,7 @@ ### CI -* [2388](https://github.com/zeta-chain/node/pull/2388) - added GitHub attestations of binaries produced in the release workflow. +* [2388](https://github.com/zeta-chain/node/pull/2388) - added GitHub attestations of binaries produced in the release workflow. * [2285](https://github.com/zeta-chain/node/pull/2285) - added nightly EVM performance testing pipeline, modified localnet testing docker image to utilize debian:bookworm, removed build-jet runners where applicable, removed deprecated/removed upgrade path testing pipeline * [2268](https://github.com/zeta-chain/node/pull/2268) - updated the publish-release pipeline to utilize the Github Actions Ubuntu 20.04 Runners * [2070](https://github.com/zeta-chain/node/pull/2070) - Added commands to build binaries from the working branch as a live full node rpc to test non-governance changes @@ -635,7 +659,7 @@ Getting the correct TSS address for Bitcoin now requires providing the Bitcoin c ### Tests -* Add unit tests for adding votes to a ballot +* Add unit tests for adding votes to a ballot ### CI @@ -675,7 +699,7 @@ Getting the correct TSS address for Bitcoin now requires providing the Bitcoin c ### Refactoring * [1226](https://github.com/zeta-chain/node/pull/1226) - call `onCrossChainCall` when depositing to a contract -* [1238](https://github.com/zeta-chain/node/pull/1238) - change default mempool version in config +* [1238](https://github.com/zeta-chain/node/pull/1238) - change default mempool version in config * [1279](https://github.com/zeta-chain/node/pull/1279) - remove duplicate funtion name IsEthereum * [1289](https://github.com/zeta-chain/node/pull/1289) - skip gas stability pool funding when gasLimit is equal gasUsed diff --git a/cmd/zetaclientd/p2p_diagnostics.go b/cmd/zetaclientd/p2p_diagnostics.go deleted file mode 100644 index 201b91504b..0000000000 --- a/cmd/zetaclientd/p2p_diagnostics.go +++ /dev/null @@ -1,229 +0,0 @@ -package main - -import ( - "context" - "fmt" - "os" - "sync" - "time" - - "github.com/cometbft/cometbft/crypto/secp256k1" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - libp2p "github.com/libp2p/go-libp2p" - dht "github.com/libp2p/go-libp2p-kad-dht" - "github.com/libp2p/go-libp2p/core/crypto" - "github.com/libp2p/go-libp2p/core/network" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p/core/protocol" - drouting "github.com/libp2p/go-libp2p/p2p/discovery/routing" - dutil "github.com/libp2p/go-libp2p/p2p/discovery/util" - maddr "github.com/multiformats/go-multiaddr" - "github.com/rs/zerolog" - - "github.com/zeta-chain/node/pkg/cosmos" - "github.com/zeta-chain/node/zetaclient/config" - "github.com/zeta-chain/node/zetaclient/metrics" -) - -func RunDiagnostics( - startLogger zerolog.Logger, - peers []maddr.Multiaddr, - hotkeyPk cryptotypes.PrivKey, - cfg config.Config, -) error { - startLogger.Warn().Msg("P2P Diagnostic mode enabled") - startLogger.Warn().Msgf("seed peer: %s", peers) - priKey := secp256k1.PrivKey(hotkeyPk.Bytes()[:32]) - pubkeyBech32, err := cosmos.Bech32ifyPubKey(cosmos.Bech32PubKeyTypeAccPub, hotkeyPk.PubKey()) - if err != nil { - startLogger.Error().Err(err).Msg("Bech32ifyPubKey error") - return err - } - startLogger.Warn().Msgf("my pubkey %s", pubkeyBech32) - - var s *metrics.TelemetryServer - if len(peers) == 0 { - startLogger.Warn().Msg("No seed peer specified; assuming I'm the host") - } - p2pPriKey, err := crypto.UnmarshalSecp256k1PrivateKey(priKey[:]) - if err != nil { - startLogger.Error().Err(err).Msg("UnmarshalSecp256k1PrivateKey error") - return err - } - listenAddress, err := maddr.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/tcp/%d", 6668)) - if err != nil { - startLogger.Error().Err(err).Msg("NewMultiaddr error") - return err - } - IP := os.Getenv("MYIP") - if len(IP) == 0 { - startLogger.Warn().Msg("empty env MYIP") - } - var externalAddr maddr.Multiaddr - if len(IP) != 0 { - externalAddr, err = maddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d", IP, 6668)) - if err != nil { - startLogger.Error().Err(err).Msg("NewMultiaddr error") - return err - } - } - - host, err := libp2p.New( - libp2p.ListenAddrs(listenAddress), - libp2p.Identity(p2pPriKey), - libp2p.AddrsFactory(func(addrs []maddr.Multiaddr) []maddr.Multiaddr { - if externalAddr != nil { - return []maddr.Multiaddr{externalAddr} - } - return addrs - }), - libp2p.DisableRelay(), - ) - if err != nil { - startLogger.Error().Err(err).Msg("fail to create host") - return err - } - startLogger.Info().Msgf("host created: ID %s", host.ID().String()) - if len(peers) == 0 { - s = metrics.NewTelemetryServer() - s.SetP2PID(host.ID().String()) - go func() { - startLogger.Info().Msg("Starting TSS HTTP Server...") - if err := s.Start(); err != nil { - fmt.Println(err) - } - }() - } - - // create stream handler - handleStream := func(s network.Stream) { - defer s.Close() - - // read the message - buf := make([]byte, 1024) - n, err := s.Read(buf) - if err != nil { - startLogger.Error().Err(err).Msg("read stream error") - return - } - // send the message back - if _, err := s.Write(buf[:n]); err != nil { - startLogger.Error().Err(err).Msg("write stream error") - return - } - } - ProtocolID := "/echo/0.3.0" - host.SetStreamHandler(protocol.ID(ProtocolID), handleStream) - - kademliaDHT, err := dht.New(context.Background(), host, dht.Mode(dht.ModeServer)) - if err != nil { - return fmt.Errorf("fail to create DHT: %w", err) - } - startLogger.Info().Msg("Bootstrapping the DHT") - if err = kademliaDHT.Bootstrap(context.Background()); err != nil { - return fmt.Errorf("fail to bootstrap DHT: %w", err) - } - - var wg sync.WaitGroup - for _, peerAddr := range peers { - peerinfo, err := peer.AddrInfoFromP2pAddr(peerAddr) - if err != nil { - startLogger.Error().Err(err).Msgf("fail to parse peer address %s", peerAddr) - continue - } - wg.Add(1) - go func() { - defer wg.Done() - if err := host.Connect(context.Background(), *peerinfo); err != nil { - startLogger.Warn().Msgf("Connection failed with bootstrap node: %s", *peerinfo) - } else { - startLogger.Info().Msgf("Connection established with bootstrap node: %s", *peerinfo) - } - }() - } - wg.Wait() - - // We use a rendezvous point "meet me here" to announce our location. - // This is like telling your friends to meet you at the Eiffel Tower. - startLogger.Info().Msgf("Announcing ourselves...") - routingDiscovery := drouting.NewRoutingDiscovery(kademliaDHT) - dutil.Advertise(context.Background(), routingDiscovery, "ZetaZetaOpenTheDoor") - startLogger.Info().Msgf("Successfully announced!") - - // every 1min, print out the p2p diagnostic - ticker := time.NewTicker(time.Duration(cfg.P2PDiagnosticTicker) * time.Second) - round := 0 - - for range ticker.C { - round++ - // Now, look for others who have announced - // This is like your friend telling you the location to meet you. - startLogger.Info().Msgf("Searching for other peers...") - peerChan, err := routingDiscovery.FindPeers(context.Background(), "ZetaZetaOpenTheDoor") - if err != nil { - return err - } - - peerCount := 0 - okPingPongCount := 0 - for peer := range peerChan { - peerCount++ - if peer.ID == host.ID() { - startLogger.Info().Msgf("Found myself #(%d): %s", peerCount, peer) - continue - } - startLogger.Info().Msgf("Found peer #(%d): %s; pinging the peer...", peerCount, peer) - stream, err := host.NewStream(context.Background(), peer.ID, protocol.ID(ProtocolID)) - if err != nil { - startLogger.Error().Err(err).Msgf("fail to create stream to peer %s", peer) - continue - } - - // write a message to the stream - message := fmt.Sprintf( - "round %d %s => %s", - round, - host.ID().String()[len(host.ID().String())-5:], - peer.ID.String()[len(peer.ID.String())-5:], - ) - _, err = stream.Write([]byte(message)) - if err != nil { - startLogger.Error().Err(err).Msgf("fail to write to stream to peer %s", peer) - err = stream.Close() - if err != nil { - startLogger.Warn().Err(err).Msgf("fail to close stream to peer %s", peer) - } - continue - } - - // read the echoed message - buf := make([]byte, 1024) - nr, err := stream.Read(buf) - if err != nil { - startLogger.Error().Err(err).Msgf("fail to read from stream to peer %s", peer) - err = stream.Close() - if err != nil { - startLogger.Warn().Err(err).Msgf("fail to close stream to peer %s", peer) - } - continue - } - startLogger.Debug().Msgf("echoed message: %s", string(buf[:nr])) - err = stream.Close() - if err != nil { - startLogger.Warn().Err(err).Msgf("fail to close stream to peer %s", peer) - } - - // check if the message is echoed correctly - if string(buf[:nr]) != message { - startLogger.Error(). - Msgf("ping-pong failed with peer #(%d): %s; want %s got %s", peerCount, peer, message, string(buf[:nr])) - continue - } - startLogger.Info().Msgf("ping-pong success with peer #(%d): %s;", peerCount, peer) - okPingPongCount++ - } - startLogger.Info(). - Msgf("Expect %d peers in total; successful pings (%d/%d)", peerCount, okPingPongCount, peerCount-1) - } - return nil -} diff --git a/cmd/zetaclientd/start.go b/cmd/zetaclientd/start.go index f00abdcde1..f86a5fa2ee 100644 --- a/cmd/zetaclientd/start.go +++ b/cmd/zetaclientd/start.go @@ -9,14 +9,18 @@ import ( "os/signal" "path/filepath" "strings" + "sync" "syscall" "time" "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/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" @@ -179,13 +183,6 @@ func start(_ *cobra.Command, _ []string) error { log.Error().Err(err).Msg("peer address error") } initPreParams(cfg.PreParamsPath) - if cfg.P2PDiagnostic { - err := RunDiagnostics(startLogger, peers, hotkeyPk, cfg) - if err != nil { - startLogger.Error().Err(err).Msg("RunDiagnostics error") - return err - } - } m, err := metrics.NewMetrics() if err != nil { @@ -204,8 +201,19 @@ func start(_ *cobra.Command, _ []string) error { } 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) + } + // Create TSS server - server, err := mc.SetupTSSServer(peers, priKey, preParams, appContext.Config(), tssKeyPass, true) + server, err := mc.SetupTSSServer(peers, priKey, preParams, appContext.Config(), tssKeyPass, true, whitelistedPeers) if err != nil { return fmt.Errorf("SetupTSSServer error: %w", err) } @@ -222,6 +230,40 @@ func start(_ *cobra.Command, _ []string) error { signalChannel <- syscall.SIGTERM }) + go func() { + for { + time.Sleep(30 * time.Second) + ps := server.GetKnownPeers() + metrics.NumConnectedPeers.Set(float64(len(ps))) + telemetryServer.SetConnectedPeers(ps) + } + }() + go func() { + host := server.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 = GenerateTSS(ctx, masterLogger, zetacoreClient, server) diff --git a/go.mod b/go.mod index c554fdd384..e4d529298e 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,6 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/libp2p/go-libp2p v0.27.8 - github.com/libp2p/go-libp2p-kad-dht v0.24.2 github.com/mattn/go-sqlite3 v1.14.19 // indirect github.com/multiformats/go-multiaddr v0.9.0 github.com/nanmu42/etherscan-api v1.10.0 @@ -190,15 +189,11 @@ require ( github.com/huin/goupnp v1.2.0 // indirect github.com/iancoleman/orderedmap v0.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/ipfs/boxo v0.10.0 // indirect github.com/ipfs/go-cid v0.4.1 // indirect - github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-log/v2 v2.5.1 // indirect - github.com/ipld/go-ipld-prime v0.20.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect - github.com/jbenet/goprocess v0.1.4 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -212,8 +207,6 @@ require ( github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect - github.com/libp2p/go-libp2p-record v0.2.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect @@ -261,7 +254,6 @@ require ( github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect @@ -293,7 +285,6 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect - github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/yudai/gojsondiff v1.0.0 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect github.com/zondax/hid v0.9.2 // indirect @@ -319,7 +310,6 @@ require ( golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - gonum.org/v1/gonum v0.13.0 // indirect google.golang.org/api v0.155.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect @@ -341,6 +331,7 @@ require ( require ( github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20220328075252-7dd334e3daae // indirect + github.com/onsi/ginkgo/v2 v2.9.5 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/snksoft/crc v1.1.0 // indirect @@ -367,5 +358,5 @@ replace ( github.com/bnb-chain/tss-lib => github.com/zeta-chain/tss-lib v0.0.0-20240916163010-2e6b438bd901 github.com/ethereum/go-ethereum => github.com/zeta-chain/go-ethereum v1.10.26-spc github.com/libp2p/go-libp2p => github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4 - gitlab.com/thorchain/tss/go-tss => github.com/zeta-chain/go-tss v0.0.0-20241028192852-b5233fc8c2b3 + gitlab.com/thorchain/tss/go-tss => github.com/zeta-chain/go-tss v0.0.0-20241031223543-18765295f992 ) diff --git a/go.sum b/go.sum index b2e97005c3..c3a69f1405 100644 --- a/go.sum +++ b/go.sum @@ -2343,7 +2343,6 @@ github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslW github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= @@ -2553,8 +2552,8 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs= -github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/rpmpack v0.0.0-20191226140753-aa36bfddb3a0/go.mod h1:RaTPr0KUf2K7fnZYLNDrr8rxAamWs3iNywJLtQ2AzBg= github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= @@ -2616,7 +2615,6 @@ github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= @@ -2836,24 +2834,16 @@ github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1: github.com/informalsystems/tm-load-test v1.0.0/go.mod h1:WVaSKaQdfZK3v0C74EMzn7//+3aeCZF8wkIKBz2/M74= github.com/informalsystems/tm-load-test v1.3.0/go.mod h1:OQ5AQ9TbT5hKWBNIwsMjn6Bf4O0U4b1kRc+0qZlQJKw= github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= -github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY= -github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= -github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= -github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= -github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= -github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= -github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= -github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/httpexpect/v2 v2.3.1/go.mod h1:ICTf89VBKSD3KB0fsyyHviKF8G8hyepP0dOXJPWz3T0= @@ -2874,12 +2864,9 @@ github.com/jaguilar/vt100 v0.0.0-20150826170717-2703a27b14ea/go.mod h1:QMdK4dGB3 github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= -github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= -github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= -github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= @@ -2942,7 +2929,6 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= -github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= @@ -3088,12 +3074,6 @@ github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFG github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= -github.com/libp2p/go-libp2p-kad-dht v0.24.2 h1:zd7myKBKCmtZBhI3I0zm8xBkb28v3gmSEtQfBdAdFwc= -github.com/libp2p/go-libp2p-kad-dht v0.24.2/go.mod h1:BShPzRbK6+fN3hk8a0WGAYKpb8m4k+DtchkqouGTrSg= -github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= -github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= -github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= -github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= @@ -3457,8 +3437,8 @@ github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkA github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc= -github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= -github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= +github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= +github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -3618,8 +3598,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/pointlander/compress v1.1.1-0.20190518213731-ff44bd196cc3/go.mod h1:q5NXNGzqj5uPnVuhGkZfmgHqNUhf15VLi6L9kW0VEc0= github.com/pointlander/jetset v1.0.1-0.20190518214125-eee7eff80bd4/go.mod h1:RdR1j20Aj5pB6+fw6Y9Ur7lMHpegTEjY1vc19hEZL40= github.com/pointlander/peg v1.0.1/go.mod h1:5hsGDQR2oZI4QoWz0/Kdg3VSVEC31iJw/b7WjqCBGRI= -github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= -github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/polyfloyd/go-errorlint v1.0.0/go.mod h1:KZy4xxPJyy88/gldCe5OdW6OQRtNO3EZE7hXzmnebgA= github.com/polyfloyd/go-errorlint v1.0.2/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= @@ -3855,12 +3833,10 @@ github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXi github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/assertions v1.13.0 h1:Dx1kYM01xsSqKPno3aqLnrwac2LetPvN23diwyr69Qs= github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= @@ -4108,9 +4084,8 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= -github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y= github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= @@ -4145,10 +4120,6 @@ github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= -github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= -github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= @@ -4204,8 +4175,8 @@ github.com/zeta-chain/go-ethereum v1.10.26-spc h1:NvY4rR9yw52wfxWt7YoFsWbaIwVMyO github.com/zeta-chain/go-ethereum v1.10.26-spc/go.mod h1:/6CsT5Ceen2WPLI/oCA3xMcZ5sWMF/D46SjM/ayY0Oo= github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4 h1:FmO3HfVdZ7LzxBUfg6sVzV7ilKElQU2DZm8PxJ7KcYI= github.com/zeta-chain/go-libp2p v0.0.0-20240710192637-567fbaacc2b4/go.mod h1:TBv5NY/CqWYIfUstXO1fDWrt4bDoqgCw79yihqBspg8= -github.com/zeta-chain/go-tss v0.0.0-20241028192852-b5233fc8c2b3 h1:IecdEwyguY3dtI7xRT+yW6ml/Z9cfIVHiB4q6huBhc4= -github.com/zeta-chain/go-tss v0.0.0-20241028192852-b5233fc8c2b3/go.mod h1:B1FDE6kHs8hozKSX1/iXgCdvlFbS6+FeAupoBHDK0Cc= +github.com/zeta-chain/go-tss v0.0.0-20241031223543-18765295f992 h1:jpfOoQGHQo29CKZaAPLCjguj35ikpV4UHFI99nL3fVA= +github.com/zeta-chain/go-tss v0.0.0-20241031223543-18765295f992/go.mod h1:nqelgf4HKkqlXaVg8X38a61WfyYB+ivCt6nnjoTIgCc= github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138 h1:vck/FcIIpFOvpBUm0NO17jbEtmSz/W/a5Y4jRuSJl6I= github.com/zeta-chain/keystone/keys v0.0.0-20240826165841-3874f358c138/go.mod h1:U494OsZTWsU75hqoriZgMdSsgSGP1mUL1jX+wN/Aez8= github.com/zeta-chain/protocol-contracts v1.0.2-athens3.0.20241028082130-577403818960 h1:uLcbGIyQzhFkbxcnRyc4RUjRHMfR/rrztFG7jvR3EUs= @@ -5172,8 +5143,6 @@ gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= -gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= -gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= diff --git a/zetaclient/chains/bitcoin/fee.go b/zetaclient/chains/bitcoin/fee.go index f56a479364..7ce483a5bf 100644 --- a/zetaclient/chains/bitcoin/fee.go +++ b/zetaclient/chains/bitcoin/fee.go @@ -56,6 +56,9 @@ var ( DefaultDepositorFee = DepositorFee(defaultDepositorFeeRate) ) +// DepositorFeeCalculator is a function type to calculate the Bitcoin depositor fee +type DepositorFeeCalculator func(interfaces.BTCRPCClient, *btcjson.TxRawResult, *chaincfg.Params) (float64, error) + // FeeRateToSatPerByte converts a fee rate in BTC/KB to sat/byte. func FeeRateToSatPerByte(rate float64) *big.Int { // #nosec G115 always in range diff --git a/zetaclient/chains/bitcoin/observer/inbound.go b/zetaclient/chains/bitcoin/observer/inbound.go index b08fbea18c..43b3792447 100644 --- a/zetaclient/chains/bitcoin/observer/inbound.go +++ b/zetaclient/chains/bitcoin/observer/inbound.go @@ -254,12 +254,6 @@ func (ob *Observer) CheckReceiptForBtcTxHash(ctx context.Context, txHash string, return "", fmt.Errorf("block %d is not confirmed yet", blockVb.Height) } - // calculate depositor fee - depositorFee, err := bitcoin.CalcDepositorFee(ob.btcClient, tx, ob.netParams) - if err != nil { - return "", errors.Wrapf(err, "error calculating depositor fee for inbound %s", tx.Txid) - } - // #nosec G115 always positive event, err := GetBtcEvent( ob.btcClient, @@ -268,7 +262,7 @@ func (ob *Observer) CheckReceiptForBtcTxHash(ctx context.Context, txHash string, uint64(blockVb.Height), ob.logger.Inbound, ob.netParams, - depositorFee, + bitcoin.CalcDepositorFee, ) if err != nil { return "", err @@ -322,13 +316,7 @@ func FilterAndParseIncomingTx( continue // the first tx is coinbase; we do not process coinbase tx } - // calculate depositor fee - depositorFee, err := bitcoin.CalcDepositorFee(rpcClient, &txs[idx], netParams) - if err != nil { - return nil, errors.Wrapf(err, "error calculating depositor fee for inbound %s", tx.Txid) - } - - event, err := GetBtcEvent(rpcClient, tx, tssAddress, blockNumber, logger, netParams, depositorFee) + event, err := GetBtcEvent(rpcClient, tx, tssAddress, blockNumber, logger, netParams, bitcoin.CalcDepositorFee) if err != nil { // unable to parse the tx, the caller should retry return nil, errors.Wrapf(err, "error getting btc event for tx %s in block %d", tx.Txid, blockNumber) @@ -390,12 +378,12 @@ func GetBtcEvent( blockNumber uint64, logger zerolog.Logger, netParams *chaincfg.Params, - depositorFee float64, + feeCalculator bitcoin.DepositorFeeCalculator, ) (*BTCInboundEvent, error) { if netParams.Name == chaincfg.MainNetParams.Name { - return GetBtcEventWithoutWitness(rpcClient, tx, tssAddress, blockNumber, logger, netParams, depositorFee) + return GetBtcEventWithoutWitness(rpcClient, tx, tssAddress, blockNumber, logger, netParams, feeCalculator) } - return GetBtcEventWithWitness(rpcClient, tx, tssAddress, blockNumber, logger, netParams, depositorFee) + return GetBtcEventWithWitness(rpcClient, tx, tssAddress, blockNumber, logger, netParams, feeCalculator) } // GetBtcEventWithoutWitness either returns a valid BTCInboundEvent or nil @@ -408,11 +396,15 @@ func GetBtcEventWithoutWitness( blockNumber uint64, logger zerolog.Logger, netParams *chaincfg.Params, - depositorFee float64, + feeCalculator bitcoin.DepositorFeeCalculator, ) (*BTCInboundEvent, error) { - found := false - var value float64 - var memo []byte + var ( + found bool + value float64 + depositorFee float64 + memo []byte + ) + if len(tx.Vout) >= 2 { // 1st vout must have tss address as receiver with p2wpkh scriptPubKey vout0 := tx.Vout[0] @@ -429,6 +421,12 @@ func GetBtcEventWithoutWitness( return nil, nil } + // calculate depositor fee + depositorFee, err = feeCalculator(rpcClient, &tx, netParams) + if err != nil { + return nil, errors.Wrapf(err, "error calculating depositor fee for inbound %s", tx.Txid) + } + // deposit amount has to be no less than the minimum depositor fee if vout0.Value < depositorFee { logger.Info(). diff --git a/zetaclient/chains/bitcoin/observer/inbound_test.go b/zetaclient/chains/bitcoin/observer/inbound_test.go index 838315b7b8..7ec938aab0 100644 --- a/zetaclient/chains/bitcoin/observer/inbound_test.go +++ b/zetaclient/chains/bitcoin/observer/inbound_test.go @@ -23,6 +23,7 @@ import ( "github.com/zeta-chain/node/testutil/sample" "github.com/zeta-chain/node/zetaclient/chains/bitcoin" "github.com/zeta-chain/node/zetaclient/chains/bitcoin/observer" + "github.com/zeta-chain/node/zetaclient/chains/interfaces" clientcommon "github.com/zeta-chain/node/zetaclient/common" "github.com/zeta-chain/node/zetaclient/keys" "github.com/zeta-chain/node/zetaclient/testutils" @@ -30,6 +31,13 @@ import ( "github.com/zeta-chain/node/zetaclient/testutils/testrpc" ) +// mockDepositFeeCalculator returns a mock depositor fee calculator that returns the given fee and error. +func mockDepositFeeCalculator(fee float64, err error) bitcoin.DepositorFeeCalculator { + return func(interfaces.BTCRPCClient, *btcjson.TxRawResult, *chaincfg.Params) (float64, error) { + return fee, err + } +} + func TestAvgFeeRateBlock828440(t *testing.T) { // load archived block 828440 var blockVb btcjson.GetBlockVerboseTxResult @@ -278,6 +286,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { // fee rate of above tx is 28 sat/vB depositorFee := bitcoin.DepositorFee(28 * clientcommon.BTCOutboundGasPriceMultiplier) + feeCalculator := mockDepositFeeCalculator(depositorFee, nil) // expected result memo, err := hex.DecodeString(tx.Vout[1].ScriptPubKey.Hex[4:]) @@ -309,7 +318,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, eventExpected, event) @@ -333,7 +342,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, eventExpected, event) @@ -357,7 +366,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, eventExpected, event) @@ -381,7 +390,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, eventExpected, event) @@ -405,7 +414,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, eventExpected, event) @@ -425,7 +434,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) @@ -445,7 +454,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) @@ -459,7 +468,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) @@ -479,12 +488,31 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) }) + t.Run("should return error if RPC failed to calculate depositor fee", func(t *testing.T) { + // load tx + tx := testutils.LoadBTCInboundRawResult(t, TestDataDir, chain.ChainId, txHash, false) + + // get BTC event + rpcClient := mocks.NewBTCRPCClient(t) + event, err := observer.GetBtcEventWithoutWitness( + rpcClient, + *tx, + tssAddress, + blockNumber, + log.Logger, + net, + mockDepositFeeCalculator(0.0, errors.New("rpc error")), + ) + require.ErrorContains(t, err, "rpc error") + require.Nil(t, event) + }) + t.Run("should skip tx if amount is less than depositor fee", func(t *testing.T) { // load tx and modify amount to less than depositor fee tx := testutils.LoadBTCInboundRawResult(t, TestDataDir, chain.ChainId, txHash, false) @@ -499,7 +527,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) @@ -519,7 +547,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) @@ -539,7 +567,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) @@ -570,7 +598,7 @@ func TestGetBtcEventWithoutWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) @@ -588,6 +616,7 @@ func TestGetBtcEventErrors(t *testing.T) { // fee rate of above tx is 28 sat/vB depositorFee := bitcoin.DepositorFee(28 * clientcommon.BTCOutboundGasPriceMultiplier) + feeCalculator := mockDepositFeeCalculator(depositorFee, nil) t.Run("should return error on invalid Vout[0] script", func(t *testing.T) { // load tx and modify Vout[0] script to invalid script @@ -603,7 +632,7 @@ func TestGetBtcEventErrors(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.Error(t, err) require.Nil(t, event) @@ -623,7 +652,7 @@ func TestGetBtcEventErrors(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.ErrorContains(t, err, "no input found") require.Nil(t, event) @@ -645,7 +674,7 @@ func TestGetBtcEventErrors(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.ErrorContains(t, err, "error getting sender address") require.Nil(t, event) @@ -662,6 +691,8 @@ func TestGetBtcEvent(t *testing.T) { net := &chaincfg.MainNetParams // 2.992e-05, see avgFeeRate https://mempool.space/api/v1/blocks/835640 depositorFee := bitcoin.DepositorFee(22 * clientcommon.BTCOutboundGasPriceMultiplier) + feeCalculator := mockDepositFeeCalculator(depositorFee, nil) + txHash2 := "37777defed8717c581b4c0509329550e344bdc14ac38f71fc050096887e535c8" tx := testutils.LoadBTCInboundRawResult(t, TestDataDir, chain.ChainId, txHash2, false) rpcClient := mocks.NewBTCRPCClient(t) @@ -673,7 +704,7 @@ func TestGetBtcEvent(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, (*observer.BTCInboundEvent)(nil), event) @@ -693,6 +724,7 @@ func TestGetBtcEvent(t *testing.T) { // fee rate of above tx is 28 sat/vB depositorFee := bitcoin.DepositorFee(28 * clientcommon.BTCOutboundGasPriceMultiplier) + feeCalculator := mockDepositFeeCalculator(depositorFee, nil) // expected result memo, err := hex.DecodeString(tx.Vout[1].ScriptPubKey.Hex[4:]) @@ -723,7 +755,7 @@ func TestGetBtcEvent(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, eventExpected, event) diff --git a/zetaclient/chains/bitcoin/observer/witness.go b/zetaclient/chains/bitcoin/observer/witness.go index 22ce75719b..7ecb6724d8 100644 --- a/zetaclient/chains/bitcoin/observer/witness.go +++ b/zetaclient/chains/bitcoin/observer/witness.go @@ -23,7 +23,7 @@ func GetBtcEventWithWitness( blockNumber uint64, logger zerolog.Logger, netParams *chaincfg.Params, - depositorFee float64, + feeCalculator bitcoin.DepositorFeeCalculator, ) (*BTCInboundEvent, error) { if len(tx.Vout) < 1 { logger.Debug().Msgf("no output %s", tx.Txid) @@ -39,6 +39,12 @@ func GetBtcEventWithWitness( return nil, nil } + // calculate depositor fee + depositorFee, err := feeCalculator(client, &tx, netParams) + if err != nil { + return nil, errors.Wrapf(err, "error calculating depositor fee for inbound %s", tx.Txid) + } + isAmountValid, amount := isValidAmount(tx.Vout[0].Value, depositorFee) if !isAmountValid { logger.Info(). diff --git a/zetaclient/chains/bitcoin/observer/witness_test.go b/zetaclient/chains/bitcoin/observer/witness_test.go index af14427c6e..745f2003a9 100644 --- a/zetaclient/chains/bitcoin/observer/witness_test.go +++ b/zetaclient/chains/bitcoin/observer/witness_test.go @@ -61,6 +61,7 @@ func TestGetBtcEventWithWitness(t *testing.T) { // fee rate of above tx is 28 sat/vB depositorFee := bitcoin.DepositorFee(28 * clientcommon.BTCOutboundGasPriceMultiplier) + feeCalculator := mockDepositFeeCalculator(depositorFee, nil) t.Run("decode OP_RETURN ok", func(t *testing.T) { tx := testutils.LoadBTCInboundRawResult(t, TestDataDir, chain.ChainId, txHash, false) @@ -93,7 +94,7 @@ func TestGetBtcEventWithWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, eventExpected, event) @@ -131,7 +132,7 @@ func TestGetBtcEventWithWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, eventExpected, event) @@ -172,7 +173,7 @@ func TestGetBtcEventWithWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Equal(t, event, eventExpected) @@ -192,12 +193,31 @@ func TestGetBtcEventWithWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) }) + t.Run("should return error if RPC failed to calculate depositor fee", func(t *testing.T) { + // load tx + tx := testutils.LoadBTCInboundRawResult(t, TestDataDir, chain.ChainId, txHash, false) + + // get BTC event + rpcClient := mocks.NewBTCRPCClient(t) + event, err := observer.GetBtcEventWithWitness( + rpcClient, + *tx, + tssAddress, + blockNumber, + log.Logger, + net, + mockDepositFeeCalculator(0.0, errors.New("rpc error")), + ) + require.ErrorContains(t, err, "rpc error") + require.Nil(t, event) + }) + t.Run("should skip tx if amount is less than depositor fee", func(t *testing.T) { // load tx and modify amount to less than depositor fee tx := testutils.LoadBTCInboundRawResult(t, TestDataDir, chain.ChainId, txHash, false) @@ -212,7 +232,7 @@ func TestGetBtcEventWithWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) @@ -234,7 +254,7 @@ func TestGetBtcEventWithWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.ErrorContains(t, err, "rpc error") require.Nil(t, event) @@ -268,7 +288,7 @@ func TestGetBtcEventWithWitness(t *testing.T) { blockNumber, log.Logger, net, - depositorFee, + feeCalculator, ) require.NoError(t, err) require.Nil(t, event) diff --git a/zetaclient/metrics/metrics.go b/zetaclient/metrics/metrics.go index a0a7341f94..a826da58f2 100644 --- a/zetaclient/metrics/metrics.go +++ b/zetaclient/metrics/metrics.go @@ -148,6 +148,12 @@ var ( }, []string{"host"}, ) + + NumConnectedPeers = promauto.NewGauge(prometheus.GaugeOpts{ + Namespace: ZetaClientNamespace, + Name: "num_connected_peers", + Help: "The number of connected peers (authenticated keygen peers)", + }) ) // NewMetrics creates a new Metrics instance diff --git a/zetaclient/metrics/telemetry.go b/zetaclient/metrics/telemetry.go index d0cd85b538..506945859c 100644 --- a/zetaclient/metrics/telemetry.go +++ b/zetaclient/metrics/telemetry.go @@ -10,6 +10,7 @@ import ( "time" "github.com/gorilla/mux" + "github.com/libp2p/go-libp2p/core/peer" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -30,6 +31,8 @@ type TelemetryServer struct { status types.Status ipAddress string HotKeyBurnRate *BurnRate + connectedPeers []peer.AddrInfo + rtt map[peer.ID]int64 } // NewTelemetryServer should only listen to the loopback @@ -39,6 +42,8 @@ func NewTelemetryServer() *TelemetryServer { lastScannedBlockNumber: make(map[int64]uint64), lastStartTimestamp: time.Now(), HotKeyBurnRate: NewBurnRate(100), + connectedPeers: make([]peer.AddrInfo, 0), + rtt: make(map[peer.ID]int64), } s := &http.Server{ Addr: ":8123", @@ -50,6 +55,30 @@ func NewTelemetryServer() *TelemetryServer { return hs } +func (t *TelemetryServer) SetPingRTT(rtt map[peer.ID]int64) { + t.mu.Lock() + defer t.mu.Unlock() + t.rtt = rtt +} + +func (t *TelemetryServer) GetPingRTT() map[peer.ID]int64 { + t.mu.Lock() + defer t.mu.Unlock() + return t.rtt +} + +func (t *TelemetryServer) SetConnectedPeers(peers []peer.AddrInfo) { + t.mu.Lock() + defer t.mu.Unlock() + t.connectedPeers = peers +} + +func (t *TelemetryServer) GetConnectedPeers() []peer.AddrInfo { + t.mu.Lock() + defer t.mu.Unlock() + return t.connectedPeers +} + // SetP2PID sets p2pid func (t *TelemetryServer) SetP2PID(p2pid string) { t.mu.Lock() @@ -145,7 +174,8 @@ func (t *TelemetryServer) Handlers() http.Handler { router.Handle("/status", http.HandlerFunc(t.statusHandler)).Methods(http.MethodGet) router.Handle("/ip", http.HandlerFunc(t.ipHandler)).Methods(http.MethodGet) router.Handle("/hotkeyburnrate", http.HandlerFunc(t.hotKeyFeeBurnRate)).Methods(http.MethodGet) - + router.Handle("/connectedpeers", http.HandlerFunc(t.connectedPeersHandler)).Methods(http.MethodGet) + router.Handle("/pingrtt", http.HandlerFunc(t.pingRTTHandler)).Methods(http.MethodGet) router.Use(logMiddleware()) return router @@ -184,17 +214,14 @@ func (t *TelemetryServer) pingHandler(w http.ResponseWriter, _ *http.Request) { // p2pHandler returns the p2p id func (t *TelemetryServer) p2pHandler(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) - t.mu.Lock() - defer t.mu.Unlock() - fmt.Fprintf(w, "%s", t.p2pid) + fmt.Fprintf(w, "%s", t.GetP2PID()) } // ipHandler returns the ip address func (t *TelemetryServer) ipHandler(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) - t.mu.Lock() - defer t.mu.Unlock() - fmt.Fprintf(w, "%s", t.ipAddress) + + fmt.Fprintf(w, "%s", t.GetIPAddress()) } func (t *TelemetryServer) lastScannedBlockHandler(w http.ResponseWriter, _ *http.Request) { @@ -251,6 +278,34 @@ func (t *TelemetryServer) hotKeyFeeBurnRate(w http.ResponseWriter, _ *http.Reque fmt.Fprintf(w, "%v", t.HotKeyBurnRate.GetBurnRate()) } +func (t *TelemetryServer) connectedPeersHandler(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + peers := t.GetConnectedPeers() + data, err := json.Marshal(peers) + if err != nil { + t.logger.Error().Err(err).Msg("Failed to marshal connected peers") + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + fmt.Fprintf(w, "%s", string(data)) +} + +func (t *TelemetryServer) pingRTTHandler(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + rtt := t.GetPingRTT() + rtt2 := make(map[string]int64) + for k, v := range rtt { + rtt2[k.String()] = v + } + data, err := json.Marshal(rtt2) + if err != nil { + t.logger.Error().Err(err).Msg("Failed to marshal ping RTT") + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + fmt.Fprintf(w, "%s", string(data)) +} + // logMiddleware logs the incoming HTTP request func logMiddleware() mux.MiddlewareFunc { return func(handler http.Handler) http.Handler { diff --git a/zetaclient/tss/tss_signer.go b/zetaclient/tss/tss_signer.go index 0c7daa98e7..e3df81d7ad 100644 --- a/zetaclient/tss/tss_signer.go +++ b/zetaclient/tss/tss_signer.go @@ -148,6 +148,7 @@ func SetupTSSServer( cfg config.Config, tssPassword string, enableMonitor bool, + whitelistedPeers []gopeer.ID, ) (*tss.TssServer, error) { bootstrapPeers := peer log.Info().Msgf("Peers AddrList %v", bootstrapPeers) @@ -173,7 +174,6 @@ func SetupTSSServer( bootstrapPeers, 6668, privkey, - "MetaMetaOpenTheDoor", tsspath, thorcommon.TssConfig{ EnableMonitor: enableMonitor, @@ -185,6 +185,7 @@ func SetupTSSServer( preParams, // use pre-generated pre-params if non-nil IP, // for docker test tssPassword, + whitelistedPeers, ) if err != nil { log.Error().Err(err).Msg("NewTSS error")