diff --git a/cmd/root.go b/cmd/root.go index 978810e..c1bd606 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,15 +14,18 @@ package cmd import ( + "context" "errors" "fmt" "os" "strings" + "time" homedir "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" "github.com/spf13/viper" types "github.com/wealdtech/go-eth2-types" + "google.golang.org/grpc" wallet "github.com/wealdtech/go-eth2-wallet" wtypes "github.com/wealdtech/go-eth2-wallet-types" @@ -33,6 +36,10 @@ var quiet bool var verbose bool var debug bool +// For transaction commands +var wait bool +var generate bool + // Root variables, present for all commands var rootStore string var rootAccount string @@ -40,6 +47,8 @@ var rootStorePassphrase string var rootWalletPassphrase string var rootAccountPassphrase string +var eth2GRPCConn *grpc.ClientConn + // RootCmd represents the base command when called without any subcommands var RootCmd = &cobra.Command{ Use: "ethdo", @@ -69,12 +78,29 @@ func persistentPreRun(cmd *cobra.Command, args []string) { rootWalletPassphrase = viper.GetString("walletpassphrase") rootAccountPassphrase = viper.GetString("passphrase") + // ...lots of commands have transaction-related flags (e.g.) 'wait' + // as options but we want to bind them to this particular command and + // this is the first chance we get + if cmd.Flags().Lookup("wait") != nil { + err := viper.BindPFlag("wait", cmd.Flags().Lookup("wait")) + errCheck(err, "Failed to set wait option") + } + wait = viper.GetBool("wait") + if cmd.Flags().Lookup("generate") != nil { + err := viper.BindPFlag("generate", cmd.Flags().Lookup("generate")) + errCheck(err, "Failed to set generate option") + } + generate = viper.GetBool("generate") + if quiet && verbose { die("Cannot supply both quiet and verbose flags") } if quiet && debug { die("Cannot supply both quiet and debug flags") } + if generate && wait { + die("Cannot supply both generate and wait flags") + } // Set up our wallet store err := wallet.SetStore(rootStore, []byte(rootStorePassphrase)) @@ -130,6 +156,14 @@ func init() { if err := viper.BindPFlag("debug", RootCmd.PersistentFlags().Lookup("debug")); err != nil { panic(err) } + RootCmd.PersistentFlags().String("connection", "", "connection to Ethereum 2 node via GRPC") + if err := viper.BindPFlag("connection", RootCmd.PersistentFlags().Lookup("connection")); err != nil { + panic(err) + } + RootCmd.PersistentFlags().Duration("timeout", 10*time.Second, "the time after which a network request will be considered failed. Increase this if you are running on an error-prone, high-latency or low-bandwidth connection") + if err := viper.BindPFlag("timeout", RootCmd.PersistentFlags().Lookup("timeout")); err != nil { + panic(err) + } } // initConfig reads in config file and ENV variables if set. @@ -230,17 +264,38 @@ func accountFromPath(path string) (wtypes.Account, error) { return wallet.AccountByName(accountName) } -func sign(path string, data []byte, domain uint64) (types.Signature, error) { - assert(rootAccountPassphrase != "", "--passphrase is required") +// sign signs data in a domain. +func sign(account wtypes.Account, data []byte, domain uint64) (types.Signature, error) { + if !account.IsUnlocked() { + return nil, errors.New("account must be unlocked to sign") + } - account, err := accountFromPath(path) - if err != nil { - return nil, err - } - err = account.Unlock([]byte(rootAccountPassphrase)) - if err != nil { - return nil, err - } - defer account.Lock() return account.Sign(data, domain) } + +// addTransactionFlags adds flags used in all transactions. +func addTransactionFlags(cmd *cobra.Command) { + cmd.Flags().Bool("generate", false, "Do not send the transaction; generate and output as a hex string only") + cmd.Flags().Bool("wait", false, "wait for the transaction to be mined before returning") +} + +// connect connects to an Ethereum 2 endpoint. +func connect() error { + connection := "" + if viper.GetString("connection") != "" { + connection = viper.GetString("connection") + } + + if connection == "" { + return errors.New("no connection") + } + outputIf(debug, fmt.Sprintf("Connecting to %s", connection)) + + opts := []grpc.DialOption{grpc.WithInsecure()} + + ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout")) + defer cancel() + var err error + eth2GRPCConn, err = grpc.DialContext(ctx, connection, opts...) + return err +} diff --git a/cmd/validatordepositdata.go b/cmd/validatordepositdata.go index d64c258..57a1c07 100644 --- a/cmd/validatordepositdata.go +++ b/cmd/validatordepositdata.go @@ -35,8 +35,6 @@ var validatorDepositDataCmd = &cobra.Command{ ethdo validator depositdata --validatoraccount=primary/validator --withdrawalaccount=primary/current --value="32 Ether" -In quiet mode this will return 0 if the the data can be generated correctly, otherwise 1. - The information generated can be passed to ethereal to create a deposit from the Ethereum 1 chain. In quiet mode this will return 0 if the the data can be generated correctly, otherwise 1.`, @@ -74,7 +72,7 @@ In quiet mode this will return 0 if the the data can be generated correctly, oth errCheck(err, "Failed to generate deposit data signing root") outputIf(debug, fmt.Sprintf("Signing root is %x", signingRoot)) domain := types.Domain(types.DomainDeposit, []byte{0, 0, 0, 0}) - signature, err := sign(validatorDepositDataValidatorAccount, signingRoot[:], domain) + signature, err := sign(validatorAccount, signingRoot[:], domain) errCheck(err, "Failed to sign deposit data signing root") signedDepositData := struct { diff --git a/cmd/validatorexit.go b/cmd/validatorexit.go new file mode 100644 index 0000000..aa3a20e --- /dev/null +++ b/cmd/validatorexit.go @@ -0,0 +1,106 @@ +// Copyright © 2020 Weald Technology Trading +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cmd + +import ( + "context" + "fmt" + "os" + + ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" + "github.com/prysmaticlabs/go-ssz" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "github.com/wealdtech/ethdo/grpc" + types "github.com/wealdtech/go-eth2-types" +) + +var validatorExitEpoch int64 + +var validatorExitCmd = &cobra.Command{ + Use: "exit", + Short: "Send an exit request for a validator", + Long: `Send an exit request for a validator. For example: + + ethdo validator exit --account=primary/validator --passphrase=secret + +In quiet mode this will return 0 if the transaction has been sent, otherwise 1.`, + Run: func(cmd *cobra.Command, args []string) { + // Sanity checking and setup. + assert(rootAccount != "", "--account is required") + account, err := accountFromPath(rootAccount) + errCheck(err, "Failed to access account") + err = connect() + errCheck(err, "Failed to obtain connect to Ethereum 2 beacon chain node") + + // Fetch the validator's index. + index, err := grpc.FetchValidatorIndex(eth2GRPCConn, account) + errCheck(err, "Failed to obtain validator index") + outputIf(debug, fmt.Sprintf("Validator index is %d", index)) + + // Ensure the validator is active. + state, err := grpc.FetchValidatorState(eth2GRPCConn, account) + errCheck(err, "Failed to obtain validator state") + outputIf(debug, fmt.Sprintf("Validator state is %v", state)) + assert(state == ethpb.ValidatorStatus_ACTIVE, "Validator must be active to exit") + + // Ensure the validator has been active long enough to exit. + // TODO when we can fetch the current epoch + // config, err := grpc.Config(eth2GRPCConn) + // errCheck(err, "Failed to obtain beacon config") + // fmt.Printf("%+v\n", config) + validator, err := grpc.FetchValidator(eth2GRPCConn, account) + errCheck(err, "Failed to obtain validator information") + outputIf(debug, fmt.Sprintf("Activation epoch is %v", validator.ActivationEpoch)) + + outputIf(verbose, "Validator confirmed to be in a suitable state") + + // Set up the transaction. + exit := ðpb.VoluntaryExit{ + // TODO use value from config + Epoch: validator.ActivationEpoch + 2048, + ValidatorIndex: index, + } + root, err := ssz.HashTreeRoot(exit) + errCheck(err, "Failed to generate exit proposal root") + // TODO fetch current fork version from config + domain := types.Domain(types.DomainVoluntaryExit, []byte{0, 0, 0, 4}) + + err = account.Unlock([]byte(rootAccountPassphrase)) + errCheck(err, "Failed to unlock account; please confirm passphrase is correct") + signature, err := sign(account, root[:], domain) + errCheck(err, "Failed to sign exit proposal") + + proposal := ðpb.SignedVoluntaryExit{ + Exit: exit, + Signature: signature.Marshal(), + } + + validatorClient := ethpb.NewBeaconNodeValidatorClient(eth2GRPCConn) + ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout")) + defer cancel() + _, err = validatorClient.ProposeExit(ctx, proposal) + errCheck(err, "Failed to propose exit") + + outputIf(!quiet, "Validator exit transaction sent") + os.Exit(_exit_success) + }, +} + +func init() { + validatorCmd.AddCommand(validatorExitCmd) + validatorFlags(validatorExitCmd) + validatorExitCmd.Flags().Int64Var(&validatorExitEpoch, "epoch", -1, "Epoch at which to exit (defaults to now)") + addTransactionFlags(validatorExitCmd) +} diff --git a/cmd/version.go b/cmd/version.go index 2b6e511..7d2e650 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -30,7 +30,7 @@ var versionCmd = &cobra.Command{ ethdo version.`, Run: func(cmd *cobra.Command, args []string) { - fmt.Println("1.1.0") + fmt.Println("1.2.0") if viper.GetBool("verbose") { buildInfo, ok := dbg.ReadBuildInfo() if ok { diff --git a/cmd/walletaccounts.go b/cmd/walletaccounts.go index 7105370..e31e7c1 100644 --- a/cmd/walletaccounts.go +++ b/cmd/walletaccounts.go @@ -16,11 +16,8 @@ package cmd import ( "fmt" "os" - "sort" - "github.com/google/uuid" "github.com/spf13/cobra" - types "github.com/wealdtech/go-eth2-types" ) var walletAccountsCmd = &cobra.Command{ @@ -37,28 +34,21 @@ In quiet mode this will return 0 if the wallet holds any addresses, otherwise 1. wallet, err := walletFromPath(walletWallet) errCheck(err, "Failed to access wallet") - // List the accounts. They come to us in random order and we want them in name order, so store them in an array and sort - output := make([]addressListResult, 0) + hasAccounts := false for account := range wallet.Accounts() { - output = append(output, addressListResult{id: account.ID(), name: account.Name(), pubkey: account.PublicKey()}) + hasAccounts = true + if verbose { + fmt.Printf("%s\n\tUUID:\t\t%s\n\tPublic key:\t0x%048x\n", account.Name(), account.ID(), account.PublicKey().Marshal()) + } else if !quiet { + fmt.Printf("%s\n", account.Name()) + } } if quiet { - if len(output) == 0 { - os.Exit(1) - } - os.Exit(0) - } - - sort.Slice(output, func(i, j int) bool { - return output[i].name < output[j].name - }) - for _, out := range output { - if verbose { - fmt.Printf("%s\n\tUUID:\t\t%s\n\tPublic key:\t0x%048x\n", out.name, out.id, out.pubkey.Marshal()) - } else if !quiet { - fmt.Printf("%s\n", out.name) + if hasAccounts { + os.Exit(_exit_success) } + os.Exit(_exit_failure) } }, } @@ -67,9 +57,3 @@ func init() { walletCmd.AddCommand(walletAccountsCmd) walletFlags(walletAccountsCmd) } - -type addressListResult struct { - id uuid.UUID - name string - pubkey types.PublicKey -} diff --git a/cmd/walletimport.go b/cmd/walletimport.go index d7a04c9..d885113 100644 --- a/cmd/walletimport.go +++ b/cmd/walletimport.go @@ -14,7 +14,10 @@ package cmd import ( + "fmt" + "io/ioutil" "os" + "strings" "github.com/spf13/cobra" "github.com/wealdtech/go-bytesutil" @@ -36,6 +39,14 @@ In quiet mode this will return 0 if the wallet is imported successfully, otherwi assert(walletImportData != "", "--walletimportdata is required") assert(walletImportPassphrase != "", "--importpassphrase is required") + if !strings.HasPrefix(walletImportData, "0x") { + outputIf(debug, fmt.Sprintf("Reading wallet import from file %s", walletImportData)) + // Assume this is a path + fileData, err := ioutil.ReadFile(walletImportData) + errCheck(err, "Failed to read wallet import data") + walletImportData = strings.TrimSpace(string(fileData)) + } + outputIf(debug, fmt.Sprintf("Wallet import data is of length %d", len(walletImportData))) importData, err := bytesutil.FromHexString(walletImportData) errCheck(err, "Failed to decode wallet data") @@ -49,6 +60,6 @@ In quiet mode this will return 0 if the wallet is imported successfully, otherwi func init() { walletCmd.AddCommand(walletImportCmd) walletFlags(walletImportCmd) - walletImportCmd.Flags().StringVar(&walletImportData, "importdata", "", "The data to import") + walletImportCmd.Flags().StringVar(&walletImportData, "importdata", "", "The data to import, or the name of a file to read") walletImportCmd.Flags().StringVar(&walletImportPassphrase, "importpassphrase", "", "Passphrase protecting the data to import") } diff --git a/go.mod b/go.mod index 015d6ad..1a3ea48 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,19 @@ go 1.13 require ( github.com/FactomProject/go-bip39 v0.3.5 + github.com/aws/aws-sdk-go v1.28.9 // indirect github.com/dgraph-io/ristretto v0.0.1 // indirect + github.com/golang/protobuf v1.3.3 github.com/google/uuid v1.1.1 + github.com/grpc-ecosystem/grpc-gateway v1.12.2 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/minio/highwayhash v1.0.0 // indirect github.com/minio/sha256-simd v0.1.1 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/pelletier/go-toml v1.6.0 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/protolambda/zssz v0.1.4 // indirect + github.com/prysmaticlabs/ethereumapis v0.0.0-20200128075941-e1e8777cb75e github.com/prysmaticlabs/go-bitfield v0.0.0-20191017011753-53b773adde52 // indirect github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963 github.com/sirupsen/logrus v1.4.2 @@ -20,15 +25,19 @@ require ( github.com/spf13/cobra v0.0.5 github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.6.1 + github.com/spf13/viper v1.6.2 github.com/wealdtech/go-bytesutil v1.1.0 github.com/wealdtech/go-eth2-types v1.0.0 github.com/wealdtech/go-eth2-util v1.1.0 github.com/wealdtech/go-eth2-wallet v1.8.1 github.com/wealdtech/go-eth2-wallet-types v1.8.0 github.com/wealdtech/go-string2eth v1.1.0 - golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect + golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d // indirect + golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect + golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect golang.org/x/text v0.3.2 // indirect + google.golang.org/genproto v0.0.0-20200128133413-58ce757ed39b // indirect + google.golang.org/grpc v1.27.0 gopkg.in/ini.v1 v1.51.1 // indirect - gopkg.in/yaml.v2 v2.2.7 // indirect + gopkg.in/yaml.v2 v2.2.8 // indirect ) diff --git a/go.sum b/go.sum index f111ca4..f240edb 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,7 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aws/aws-sdk-go v1.25.25 h1:j3HLOqcDWjNox1DyvJRs+kVQF42Ghtv6oL6cVBfXS3U= github.com/aws/aws-sdk-go v1.25.25/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -18,9 +19,14 @@ github.com/aws/aws-sdk-go v1.26.2 h1:MzYLmCeny4bMQcAbYcucIduVZKp0sEf1eRLvHpKI5Is github.com/aws/aws-sdk-go v1.26.2/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.28.0 h1:NkmnHFVEMTRYTleRLm5xUaL1mHKKkYQl4rCd+jzD58c= github.com/aws/aws-sdk-go v1.28.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.28.1 h1:aWBD5EJrmGFuHFn9ZdaHqWWZGZYQ5Gzb3j9G0RppLpY= +github.com/aws/aws-sdk-go v1.28.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.28.9 h1:grIuBQc+p3dTRXerh5+2OxSuWFi0iXuxbFdTSg0jaW0= +github.com/aws/aws-sdk-go v1.28.9/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -41,6 +47,8 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczC github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlespiau/covertool v0.0.0-20180314162135-b0c4c6d0583a/go.mod h1:/eQMcW3eA1bzKx23ZYI2H3tXPdJB5JWYTHzoUPBvQY4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -55,7 +63,11 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/pprof v0.0.0-20190309163659-77426154d546/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -66,7 +78,10 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.12.2 h1:D0EVSTwQoQOyfY35QNSuPJA4jpZRtkoGYWQMB7XNg5o= +github.com/grpc-ecosystem/grpc-gateway v1.12.2/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -122,12 +137,15 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k= github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -135,6 +153,10 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/protolambda/zssz v0.1.4 h1:4jkt8sqwhOVR8B1JebREU/gVX0Ply4GypsV8+RWrDuw= github.com/protolambda/zssz v0.1.4/go.mod h1:a4iwOX5FE7/JkKA+J/PH0Mjo9oXftN6P8NZyL28gpag= +github.com/prysmaticlabs/ethereumapis v0.0.0-20200120174538-47cde13fd25e h1:V3GGJ1uhu+XsjylJq7onnISANLpWjRJHKfaA6IJM8Mo= +github.com/prysmaticlabs/ethereumapis v0.0.0-20200120174538-47cde13fd25e/go.mod h1:5OkRN6UmvgtP+kIewitcEKC7S5KOzLOGtya/Tz+HBns= +github.com/prysmaticlabs/ethereumapis v0.0.0-20200128075941-e1e8777cb75e h1:bnnoTY3m8FPS9pz78zPwnc0jzcLi40DBBghYuJC0DTQ= +github.com/prysmaticlabs/ethereumapis v0.0.0-20200128075941-e1e8777cb75e/go.mod h1:5OkRN6UmvgtP+kIewitcEKC7S5KOzLOGtya/Tz+HBns= github.com/prysmaticlabs/go-bitfield v0.0.0-20191017011753-53b773adde52 h1:kxZ+xSWX0qbxoiDXQBLztKeEmEQg6TgCYWAOa7gSGGU= github.com/prysmaticlabs/go-bitfield v0.0.0-20191017011753-53b773adde52/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s= github.com/prysmaticlabs/go-ssz v0.0.0-20191204195639-142dfef39d12 h1:bfPIvWvA7QSmIYARnHM9tgGx1LDeSKa2bYW5QGGArxQ= @@ -142,6 +164,7 @@ github.com/prysmaticlabs/go-ssz v0.0.0-20191204195639-142dfef39d12/go.mod h1:Vec github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963 h1:Th5ufPIaL5s/7i3gXHTgiTwfsUhWDP/PwFRiI6qV6v0= github.com/prysmaticlabs/go-ssz v0.0.0-20200101200214-e24db4d9e963/go.mod h1:VecIJZrewdAuhVckySLFt2wAAHRME934bSDurP8ftkc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0 h1:Xuk8ma/ibJ1fOy4Ee11vHhUFHQNpHhrBneOCNHVXS5w= github.com/shibukawa/configdir v0.0.0-20170330084843-e180dbdc8da0/go.mod h1:7AwjWCpdPhkSmNAgUv5C7EJ4AbmjEB3r047r3DXWu3Y= @@ -174,6 +197,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= +github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= +github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -205,6 +230,8 @@ github.com/wealdtech/go-eth2-wallet v1.5.0 h1:6QFNfXyX009C8WIxnflyEctogx1QzQ8cBb github.com/wealdtech/go-eth2-wallet v1.5.0/go.mod h1:jpYP8snFvI3/rTS+zdfyyUsyf6EXoSHl5ByWmFYq72Q= github.com/wealdtech/go-eth2-wallet v1.8.0 h1:QO8HzHDXNgc8AEBulz0IFdk+U9SDc0+UX3dNVstB8wY= github.com/wealdtech/go-eth2-wallet v1.8.0/go.mod h1:PWvCjr8NXZbEIIpFYAc7tgjc50X9PCo7K4LzXn3//bY= +github.com/wealdtech/go-eth2-wallet v1.8.1 h1:w5fD2c0Q9WSYbTF7XpdBsiTcPUHfLlU1blAhH8ROffY= +github.com/wealdtech/go-eth2-wallet v1.8.1/go.mod h1:Kvzo9EdxUvibt/KarimGTOHY3pEcQTyIV1A+XDmei48= github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.0.0 h1:IcpS4VpXhYz+TVupB5n6C6IQzaKwG+Rc8nvgCa/da4c= github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.0.0/go.mod h1:X8WRO5hEwbjx8ZOqoRmtS1ngyflKs25GkP7qGv7yOqE= github.com/wealdtech/go-eth2-wallet-hd v1.6.0 h1:01G1IzKmpO33+jUEmdAU5My/PmoKjSoxsli9LpXQl9w= @@ -215,12 +242,16 @@ github.com/wealdtech/go-eth2-wallet-hd v1.8.0 h1:3oYkM6H94vA5y5RUtiBErrZSOxZnwgq github.com/wealdtech/go-eth2-wallet-hd v1.8.0/go.mod h1:EgleYFBLF2AFAPkoNiEsVJkfRMjOj76zKtKEx38bjuk= github.com/wealdtech/go-eth2-wallet-hd v1.9.0 h1:AtBkFvE4Usrzz+jkLgThfSW5kiXKKbQLK8rHS9OXu5I= github.com/wealdtech/go-eth2-wallet-hd v1.9.0/go.mod h1:QGIkXF1AtI9cLByFlnnRXDoK01/SuunRfGLzhWDMnCU= +github.com/wealdtech/go-eth2-wallet-hd v1.9.1 h1:u53yvtm4cJM3HZS0L9Lt1i3YjbxJ9y4SJvlcsp2nX6o= +github.com/wealdtech/go-eth2-wallet-hd v1.9.1/go.mod h1:QGIkXF1AtI9cLByFlnnRXDoK01/SuunRfGLzhWDMnCU= github.com/wealdtech/go-eth2-wallet-nd v1.5.0 h1:0nOOD0TpvGTSbRF7NGxAzgFPoEdM0Awnr9Mx3mroOm4= github.com/wealdtech/go-eth2-wallet-nd v1.5.0/go.mod h1:KiORm3eoIq+XR043MPekEPebU8I12918bE7ldrqk9iw= github.com/wealdtech/go-eth2-wallet-nd v1.6.0 h1:uMX6K/LdJdo56vaR8pIDrwGDX8w+e/MxA88B19Ys/gw= github.com/wealdtech/go-eth2-wallet-nd v1.6.0/go.mod h1:oVsPJTBSHnBphYush38VQYCuLwYi/HViqvZByh9vqJ0= github.com/wealdtech/go-eth2-wallet-nd v1.7.0 h1:hdQ1XTbz/d1ySY5/kDNQokVP7nM3i6pe/tLgVJqhlxk= github.com/wealdtech/go-eth2-wallet-nd v1.7.0/go.mod h1:3vaCTMI2yPndhgjXqM6ynv3yrU0VvqksQ4MaQLCgZIo= +github.com/wealdtech/go-eth2-wallet-nd v1.7.1 h1:UtOUJaaVDYybYAZInCnKqVbiHEoqLzg6XlVs1qMoNgo= +github.com/wealdtech/go-eth2-wallet-nd v1.7.1/go.mod h1:3vaCTMI2yPndhgjXqM6ynv3yrU0VvqksQ4MaQLCgZIo= github.com/wealdtech/go-eth2-wallet-store-filesystem v1.4.0 h1:IH9ncOXxd10A4C6EAptnycuRcoenRmf60oKq5yirfpc= github.com/wealdtech/go-eth2-wallet-store-filesystem v1.4.0/go.mod h1:FCzZpqn1KqU1ezKKjjxh6l9NjmCAiTwZksgE+bnTD68= github.com/wealdtech/go-eth2-wallet-store-filesystem v1.5.0 h1:bVOahxWdk0qkZ6xseQBw8fNmCDIbmIM/4KHY+cUSWj8= @@ -270,21 +301,33 @@ golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vK golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200109152110-61a87790db17 h1:nVJ3guKA9qdkEQ3TUdXI9QSINo2CUPM/cySEvw2w8I0= golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200117160349-530e935923ad h1:Jh8cai0fqIK+f6nG0UgPW5wFk8wmiMhM3AyciDBdtQg= +golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190326090315-15845e8f865b/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -305,6 +348,8 @@ golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -313,13 +358,26 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190106171756-3ef68632349c/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190325223049-1d95b17f1b04/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20200128133413-58ce757ed39b h1:c8OBoXP3kTbDWWB/oVE3FkR851p4iZ3MPadz7zXEIPU= +google.golang.org/genproto v0.0.0-20200128133413-58ce757ed39b/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0 h1:G+97AoqBnmZIT91cLG/EkCoK9NSelj64P8bOHHNmGn0= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= +google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -334,8 +392,12 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/grpc/beaconchain.go b/grpc/beaconchain.go new file mode 100644 index 0000000..6d76a93 --- /dev/null +++ b/grpc/beaconchain.go @@ -0,0 +1,47 @@ +// Copyright © 2020 Weald Technology Trading +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + + "github.com/spf13/viper" + "google.golang.org/grpc" + + "github.com/golang/protobuf/ptypes/empty" + ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" + wtypes "github.com/wealdtech/go-eth2-wallet-types" +) + +// FetchChainConfig fetches the chain configuration from the beacon node. +func FetchChainConfig(conn *grpc.ClientConn) (*ethpb.BeaconConfig, error) { + beaconClient := ethpb.NewBeaconChainClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout")) + defer cancel() + return beaconClient.GetBeaconConfig(ctx, &empty.Empty{}) +} + +// FetchValidator fetches validator information from the beacon node. +func FetchValidator(conn *grpc.ClientConn, account wtypes.Account) (*ethpb.Validator, error) { + beaconClient := ethpb.NewBeaconChainClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout")) + defer cancel() + + req := ðpb.GetValidatorRequest{ + QueryFilter: ðpb.GetValidatorRequest_PublicKey{ + PublicKey: account.PublicKey().Marshal(), + }, + } + return beaconClient.GetValidator(ctx, req) +} diff --git a/grpc/beaconnode.go b/grpc/beaconnode.go new file mode 100644 index 0000000..85a2bc5 --- /dev/null +++ b/grpc/beaconnode.go @@ -0,0 +1,60 @@ +// Copyright © 2020 Weald Technology Trading +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package grpc + +import ( + "context" + + "github.com/spf13/viper" + "google.golang.org/grpc" + + ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1" + wtypes "github.com/wealdtech/go-eth2-wallet-types" +) + +// FetchValidatorIndex fetches the index of a validator. +func FetchValidatorIndex(conn *grpc.ClientConn, account wtypes.Account) (uint64, error) { + validatorClient := ethpb.NewBeaconNodeValidatorClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout")) + defer cancel() + + // Fetch the account. + req := ðpb.ValidatorIndexRequest{ + PublicKey: account.PublicKey().Marshal(), + } + resp, err := validatorClient.ValidatorIndex(ctx, req) + if err != nil { + return 0, err + } + + return resp.Index, nil +} + +// FetchValidatorState fetches the state of a validator. +func FetchValidatorState(conn *grpc.ClientConn, account wtypes.Account) (ethpb.ValidatorStatus, error) { + validatorClient := ethpb.NewBeaconNodeValidatorClient(conn) + ctx, cancel := context.WithTimeout(context.Background(), viper.GetDuration("timeout")) + defer cancel() + + // Fetch the account. + req := ðpb.ValidatorStatusRequest{ + PublicKey: account.PublicKey().Marshal(), + } + resp, err := validatorClient.ValidatorStatus(ctx, req) + if err != nil { + return 0, err + } + + return resp.Status, nil +}