diff --git a/cmd/zetae2e/get_zetaclient_bootstrap.go b/cmd/zetae2e/get_zetaclient_bootstrap.go new file mode 100644 index 0000000000..2919c41b06 --- /dev/null +++ b/cmd/zetae2e/get_zetaclient_bootstrap.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "net" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/spf13/cobra" + "github.com/zeta-chain/node/pkg/rpc" + "github.com/zeta-chain/node/pkg/sdkconfig" + observertypes "github.com/zeta-chain/node/x/observer/types" + "gitlab.com/thorchain/tss/go-tss/conversion" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +func NewGetZetaclientBootstrap() *cobra.Command { + var ConfigureZetaclientBootstrapCmd = &cobra.Command{ + Use: "get-zetaclient-bootstrap", + Short: "get bootstrap address book entries for zetaclient", + RunE: getZetaclientBootstrap, + } + + return ConfigureZetaclientBootstrapCmd +} + +func getZetaclientBootstrap(cmd *cobra.Command, _ []string) error { + sdkconfig.SetDefault(true) + rpcClient, err := rpc.NewGRPCClients( + "zetacore0:9090", + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + ) + if err != nil { + return fmt.Errorf("get zetacore rpc client: %w", err) + } + var res *observertypes.QueryAllNodeAccountResponse + for { + res, err = rpcClient.Observer.NodeAccountAll(cmd.Context(), &observertypes.QueryAllNodeAccountRequest{}) + if err != nil { + return fmt.Errorf("get all node accounts: %w", err) + } + if len(res.NodeAccount) > 1 { + break + } + fmt.Fprintln(cmd.OutOrStderr(), "waiting for node accounts") + } + + // note that we deliberately do not filter ourselfs/localhost + // to mirror the production configuration + for _, account := range res.NodeAccount { + accAddr, err := sdk.AccAddressFromBech32(account.Operator) + if err != nil { + return err + } + valAddr := sdk.ValAddress(accAddr).String() + validatorRes, err := rpcClient.Staking.Validator(cmd.Context(), &stakingtypes.QueryValidatorRequest{ + ValidatorAddr: valAddr, + }) + if err != nil { + return fmt.Errorf("getting validator info for %s: %w", account.Operator, err) + } + // in localnet, moniker is also the hostname + moniker := validatorRes.Validator.Description.Moniker + + peerId, err := conversion.Bech32PubkeyToPeerID(account.GranteePubkey.Secp256k1.String()) + if err != nil { + return fmt.Errorf("conferting pubkey to peerid: %w", err) + } + zetaclientHostname := strings.ReplaceAll(moniker, "zetacore", "zetaclient") + + // resolve the hostname + // something in libp2p/go-tss requires /ip4/ and doesn't tolerate /dns4/ + ipAddresses, err := net.LookupIP(zetaclientHostname) + if err != nil { + return fmt.Errorf("failed to resolve hostname %s: %w", zetaclientHostname, err) + } + if len(ipAddresses) == 0 { + return fmt.Errorf("no IP addresses found for hostname %s", zetaclientHostname) + } + ipv4Address := "" + for _, ip := range ipAddresses { + if ip.To4() != nil { + ipv4Address = ip.String() + break + } + } + if ipv4Address == "" { + return fmt.Errorf("no IPv4 address found for hostname %s", zetaclientHostname) + } + fmt.Printf("/ip4/%s/tcp/6668/p2p/%s\n", ipv4Address, peerId.String()) + } + + return nil +} diff --git a/cmd/zetae2e/root.go b/cmd/zetae2e/root.go index 28b4b0c003..d885b532e2 100644 --- a/cmd/zetae2e/root.go +++ b/cmd/zetae2e/root.go @@ -29,6 +29,7 @@ func NewRootCmd() *cobra.Command { NewStressTestCmd(), NewInitCmd(), NewSetupBitcoinCmd(), + NewGetZetaclientBootstrap(), ) return cmd diff --git a/contrib/localnet/scripts/start-zetaclientd.sh b/contrib/localnet/scripts/start-zetaclientd.sh index 93fa5c2af6..6e909631af 100755 --- a/contrib/localnet/scripts/start-zetaclientd.sh +++ b/contrib/localnet/scripts/start-zetaclientd.sh @@ -68,6 +68,9 @@ echo "operatorAddress: $operatorAddress" RELAYER_KEY_PATH="$HOME/.zetacored/relayer-keys" mkdir -p "${RELAYER_KEY_PATH}" +mkdir -p "$HOME/.tss/" +zetae2e get-zetaclient-bootstrap > "$HOME/.tss/address_book.seed" + echo "Start zetaclientd" # skip initialization if the config file already exists (zetaclientd init has already been run) if [[ $HOSTNAME == "zetaclient0" && ! -f ~/.zetacored/config/zetaclient_config.json ]] @@ -90,13 +93,7 @@ if [[ $HOSTNAME != "zetaclient0" && ! -f ~/.zetacored/config/zetaclient_config.j then num=$(echo $HOSTNAME | tr -dc '0-9') node="zetacore$num" - MYIP=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1) - SEED="" - while [ -z "$SEED" ] - do - SEED=$(curl --retry 30 --retry-delay 1 --max-time 1 --retry-connrefused -s zetaclient0:8123/p2p) - done - zetaclientd init --peer "/ip4/172.20.0.21/tcp/6668/p2p/${SEED}" --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 1 --keyring-backend "$BACKEND" --pre-params "$PREPARAMS_PATH" + zetaclientd init --zetacore-url "$node" --chain-id athens_101-1 --operator "$operatorAddress" --log-format=text --public-ip "$MYIP" --log-level 1 --keyring-backend "$BACKEND" --pre-params "$PREPARAMS_PATH" # import relayer private key for zetaclient{$num} import_relayer_key "${num}"