diff --git a/cmd/validator/accounts/backup.go b/cmd/validator/accounts/backup.go index 82fa2222b3..f228222e46 100644 --- a/cmd/validator/accounts/backup.go +++ b/cmd/validator/accounts/backup.go @@ -33,6 +33,7 @@ func accountsBackup(c *cli.Context) error { accounts.WithKeymanager(km), accounts.WithGRPCDialOpts(dialOpts), accounts.WithBeaconRPCProvider(c.String(flags.BeaconRPCProviderFlag.Name)), + accounts.WithBeaconRESTApiProvider(c.String(flags.BeaconRESTApiProviderFlag.Name)), accounts.WithGRPCHeaders(grpcHeaders), } diff --git a/cmd/validator/accounts/delete.go b/cmd/validator/accounts/delete.go index 487aa146e7..922c1f3797 100644 --- a/cmd/validator/accounts/delete.go +++ b/cmd/validator/accounts/delete.go @@ -30,6 +30,7 @@ func accountsDelete(c *cli.Context) error { accounts.WithKeymanager(km), accounts.WithGRPCDialOpts(dialOpts), accounts.WithBeaconRPCProvider(c.String(flags.BeaconRPCProviderFlag.Name)), + accounts.WithBeaconRESTApiProvider(c.String(flags.BeaconRESTApiProviderFlag.Name)), accounts.WithGRPCHeaders(grpcHeaders), } diff --git a/cmd/validator/accounts/exit.go b/cmd/validator/accounts/exit.go index 45c83ae6c6..c1884d3c0b 100644 --- a/cmd/validator/accounts/exit.go +++ b/cmd/validator/accounts/exit.go @@ -81,6 +81,7 @@ func AccountsExit(c *cli.Context, r io.Reader) error { accounts.WithKeymanager(km), accounts.WithGRPCDialOpts(dialOpts), accounts.WithBeaconRPCProvider(beaconRPCProvider), + accounts.WithBeaconRESTApiProvider(c.String(flags.BeaconRESTApiProviderFlag.Name)), accounts.WithGRPCHeaders(grpcHeaders), } // Get full set of public keys from the keymanager. diff --git a/cmd/validator/accounts/import.go b/cmd/validator/accounts/import.go index bbc0310a71..3b0db03061 100644 --- a/cmd/validator/accounts/import.go +++ b/cmd/validator/accounts/import.go @@ -39,6 +39,7 @@ func accountsImport(c *cli.Context) error { accounts.WithKeymanager(km), accounts.WithGRPCDialOpts(dialOpts), accounts.WithBeaconRPCProvider(c.String(flags.BeaconRPCProviderFlag.Name)), + accounts.WithBeaconRESTApiProvider(c.String(flags.BeaconRESTApiProviderFlag.Name)), accounts.WithGRPCHeaders(grpcHeaders), } diff --git a/cmd/validator/accounts/list.go b/cmd/validator/accounts/list.go index 65f5609ad6..93a21ab1cb 100644 --- a/cmd/validator/accounts/list.go +++ b/cmd/validator/accounts/list.go @@ -28,6 +28,7 @@ func accountsList(c *cli.Context) error { accounts.WithKeymanager(km), accounts.WithGRPCDialOpts(dialOpts), accounts.WithBeaconRPCProvider(c.String(flags.BeaconRPCProviderFlag.Name)), + accounts.WithBeaconRESTApiProvider(c.String(flags.BeaconRESTApiProviderFlag.Name)), accounts.WithGRPCHeaders(grpcHeaders), } if c.IsSet(flags.ShowDepositDataFlag.Name) { diff --git a/cmd/validator/flags/BUILD.bazel b/cmd/validator/flags/BUILD.bazel index 40d4076709..b482762d0a 100644 --- a/cmd/validator/flags/BUILD.bazel +++ b/cmd/validator/flags/BUILD.bazel @@ -5,7 +5,10 @@ go_library( srcs = [ "flags.go", "interop.go", - ], + ] + select({ + "//validator/client/validator-client-factory:beacon_api_usage": ["beacon_api_flags.go"], + "//conditions:default": ["grpc_flags.go"], + }), importpath = "github.com/prysmaticlabs/prysm/v3/cmd/validator/flags", visibility = [ "//cmd/prysmctl:__subpackages__", diff --git a/cmd/validator/flags/beacon_api_flags.go b/cmd/validator/flags/beacon_api_flags.go new file mode 100644 index 0000000000..0bf77307e4 --- /dev/null +++ b/cmd/validator/flags/beacon_api_flags.go @@ -0,0 +1,8 @@ +//go:build use_beacon_api +// +build use_beacon_api + +package flags + +const ( + BuiltWithBeaconApi = true +) diff --git a/cmd/validator/flags/flags.go b/cmd/validator/flags/flags.go index 95885c3809..308e523235 100644 --- a/cmd/validator/flags/flags.go +++ b/cmd/validator/flags/flags.go @@ -40,6 +40,12 @@ var ( Usage: "Beacon node RPC gateway provider endpoint", Value: "127.0.0.1:3500", } + // BeaconRESTApiProviderFlag defines a beacon node REST API endpoint. + BeaconRESTApiProviderFlag = &cli.StringFlag{ + Name: "beacon-rest-api-provider", + Usage: "Beacon node REST API provider endpoint", + Value: "http://127.0.0.1:3500", + } // CertFlag defines a flag for the node's TLS certificate. CertFlag = &cli.StringFlag{ Name: "tls-cert", diff --git a/cmd/validator/flags/grpc_flags.go b/cmd/validator/flags/grpc_flags.go new file mode 100644 index 0000000000..642facd34d --- /dev/null +++ b/cmd/validator/flags/grpc_flags.go @@ -0,0 +1,8 @@ +//go:build !use_beacon_api +// +build !use_beacon_api + +package flags + +const ( + BuiltWithBeaconApi = false +) diff --git a/cmd/validator/main.go b/cmd/validator/main.go index 44c18bef09..767f045577 100644 --- a/cmd/validator/main.go +++ b/cmd/validator/main.go @@ -112,6 +112,11 @@ var appFlags = []cli.Flag{ } func init() { + // Append the Beacon REST API flags + if flags.BuiltWithBeaconApi { + appFlags = append(appFlags, flags.BeaconRESTApiProviderFlag) + } + appFlags = cmd.WrapFlags(append(appFlags, features.ValidatorFlags...)) } diff --git a/cmd/validator/usage.go b/cmd/validator/usage.go index 84b1c63b2f..628ffde583 100644 --- a/cmd/validator/usage.go +++ b/cmd/validator/usage.go @@ -128,6 +128,16 @@ var appHelpFlagGroups = []flagGroup{ } func init() { + // Append the Beacon REST API flags + if flags.BuiltWithBeaconApi { + for groupIndex := range appHelpFlagGroups { + group := &appHelpFlagGroups[groupIndex] + if group.Name == "validator" { + group.Flags = append(group.Flags, flags.BeaconRESTApiProviderFlag) + } + } + } + cli.AppHelpTemplate = appHelpTemplate type helpData struct { diff --git a/testing/endtoend/evaluators/BUILD.bazel b/testing/endtoend/evaluators/BUILD.bazel index a50222806e..a9b8b87664 100644 --- a/testing/endtoend/evaluators/BUILD.bazel +++ b/testing/endtoend/evaluators/BUILD.bazel @@ -47,7 +47,6 @@ go_library( "//testing/endtoend/types:go_default_library", "//testing/util:go_default_library", "//time/slots:go_default_library", - "//validator/client/validator-client-factory:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_ethereum_go_ethereum//ethclient:go_default_library", diff --git a/testing/endtoend/evaluators/fork.go b/testing/endtoend/evaluators/fork.go index 5744a26980..8f1dfa6d18 100644 --- a/testing/endtoend/evaluators/fork.go +++ b/testing/endtoend/evaluators/fork.go @@ -11,7 +11,6 @@ import ( "github.com/prysmaticlabs/prysm/v3/testing/endtoend/policies" "github.com/prysmaticlabs/prysm/v3/testing/endtoend/types" "github.com/prysmaticlabs/prysm/v3/time/slots" - validatorClientFactory "github.com/prysmaticlabs/prysm/v3/validator/client/validator-client-factory" "google.golang.org/grpc" ) @@ -33,7 +32,7 @@ var BellatrixForkTransition = types.Evaluator{ func altairForkOccurs(conns ...*grpc.ClientConn) error { conn := conns[0] - client := validatorClientFactory.NewValidatorClient(conn) + client := ethpb.NewBeaconNodeValidatorClient(conn) ctx, cancel := context.WithTimeout(context.Background(), streamDeadline) defer cancel() stream, err := client.StreamBlocksAltair(ctx, ðpb.StreamBlocksRequest{VerifiedOnly: true}) @@ -75,7 +74,7 @@ func altairForkOccurs(conns ...*grpc.ClientConn) error { func bellatrixForkOccurs(conns ...*grpc.ClientConn) error { conn := conns[0] - client := validatorClientFactory.NewValidatorClient(conn) + client := ethpb.NewBeaconNodeValidatorClient(conn) ctx, cancel := context.WithTimeout(context.Background(), streamDeadline) defer cancel() stream, err := client.StreamBlocksAltair(ctx, ðpb.StreamBlocksRequest{VerifiedOnly: true}) diff --git a/testing/endtoend/evaluators/operations.go b/testing/endtoend/evaluators/operations.go index eb7b267079..f8b2cc1993 100644 --- a/testing/endtoend/evaluators/operations.go +++ b/testing/endtoend/evaluators/operations.go @@ -20,7 +20,6 @@ import ( "github.com/prysmaticlabs/prysm/v3/testing/endtoend/policies" e2etypes "github.com/prysmaticlabs/prysm/v3/testing/endtoend/types" "github.com/prysmaticlabs/prysm/v3/testing/util" - validatorClientFactory "github.com/prysmaticlabs/prysm/v3/validator/client/validator-client-factory" "golang.org/x/exp/rand" "google.golang.org/grpc" "google.golang.org/protobuf/types/known/emptypb" @@ -284,7 +283,7 @@ func depositedValidatorsAreActive(conns ...*grpc.ClientConn) error { func proposeVoluntaryExit(conns ...*grpc.ClientConn) error { conn := conns[0] - valClient := validatorClientFactory.NewValidatorClient(conn) + valClient := ethpb.NewBeaconNodeValidatorClient(conn) beaconClient := ethpb.NewBeaconChainClient(conn) ctx := context.Background() diff --git a/testing/endtoend/evaluators/slashing.go b/testing/endtoend/evaluators/slashing.go index 073ac1f8e7..a1c0d09172 100644 --- a/testing/endtoend/evaluators/slashing.go +++ b/testing/endtoend/evaluators/slashing.go @@ -18,7 +18,6 @@ import ( "github.com/prysmaticlabs/prysm/v3/testing/endtoend/policies" e2eTypes "github.com/prysmaticlabs/prysm/v3/testing/endtoend/types" "github.com/prysmaticlabs/prysm/v3/testing/util" - validatorClientFactory "github.com/prysmaticlabs/prysm/v3/validator/client/validator-client-factory" "google.golang.org/grpc" "google.golang.org/protobuf/types/known/emptypb" ) @@ -109,7 +108,7 @@ func validatorsLoseBalance(conns ...*grpc.ClientConn) error { func insertDoubleAttestationIntoPool(conns ...*grpc.ClientConn) error { conn := conns[0] - valClient := validatorClientFactory.NewValidatorClient(conn) + valClient := eth.NewBeaconNodeValidatorClient(conn) beaconClient := eth.NewBeaconChainClient(conn) ctx := context.Background() @@ -186,7 +185,7 @@ func insertDoubleAttestationIntoPool(conns ...*grpc.ClientConn) error { } // We only broadcast to conns[0] here since we can trust that at least 1 node will be online. // Only broadcasting the attestation to one node also helps test slashing propagation. - client := validatorClientFactory.NewValidatorClient(conns[0]) + client := eth.NewBeaconNodeValidatorClient(conns[0]) if _, err = client.ProposeAttestation(ctx, att); err != nil { return errors.Wrap(err, "could not propose attestation") } @@ -197,7 +196,7 @@ func insertDoubleAttestationIntoPool(conns ...*grpc.ClientConn) error { func proposeDoubleBlock(conns ...*grpc.ClientConn) error { conn := conns[0] - valClient := validatorClientFactory.NewValidatorClient(conn) + valClient := eth.NewBeaconNodeValidatorClient(conn) beaconClient := eth.NewBeaconChainClient(conn) ctx := context.Background() @@ -239,7 +238,7 @@ func proposeDoubleBlock(conns ...*grpc.ClientConn) error { // If the proposer index is in the second validator client, we connect to // the corresponding beacon node instead. if proposerIndex >= types.ValidatorIndex(uint64(validatorsPerNode)) { - valClient = validatorClientFactory.NewValidatorClient(conns[1]) + valClient = eth.NewBeaconNodeValidatorClient(conns[1]) } hashLen := 32 diff --git a/validator/accounts/BUILD.bazel b/validator/accounts/BUILD.bazel index 19bcc1c96f..fe47345a90 100644 --- a/validator/accounts/BUILD.bazel +++ b/validator/accounts/BUILD.bazel @@ -43,6 +43,7 @@ go_library( "//validator/client:go_default_library", "//validator/client/iface:go_default_library", "//validator/client/validator-client-factory:go_default_library", + "//validator/helpers:go_default_library", "//validator/keymanager:go_default_library", "//validator/keymanager/derived:go_default_library", "//validator/keymanager/local:go_default_library", diff --git a/validator/accounts/cli_manager.go b/validator/accounts/cli_manager.go index 394984ff27..4d12d5c79f 100644 --- a/validator/accounts/cli_manager.go +++ b/validator/accounts/cli_manager.go @@ -2,6 +2,7 @@ package accounts import ( "context" + "time" "github.com/pkg/errors" grpcutil "github.com/prysmaticlabs/prysm/v3/api/grpc" @@ -10,6 +11,7 @@ import ( "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" iface "github.com/prysmaticlabs/prysm/v3/validator/client/iface" validatorClientFactory "github.com/prysmaticlabs/prysm/v3/validator/client/validator-client-factory" + validatorHelpers "github.com/prysmaticlabs/prysm/v3/validator/helpers" "github.com/prysmaticlabs/prysm/v3/validator/keymanager" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote" "google.golang.org/grpc" @@ -58,6 +60,8 @@ type AccountsCLIManager struct { mnemonic string numAccounts int mnemonic25thWord string + beaconApiEndpoint string + beaconApiTimeout time.Duration } func (acm *AccountsCLIManager) prepareBeaconClients(ctx context.Context) (*iface.ValidatorClient, *ethpb.NodeClient, error) { @@ -66,11 +70,18 @@ func (acm *AccountsCLIManager) prepareBeaconClients(ctx context.Context) (*iface } ctx = grpcutil.AppendHeaders(ctx, acm.grpcHeaders) - conn, err := grpc.DialContext(ctx, acm.beaconRPCProvider, acm.dialOpts...) + grpcConn, err := grpc.DialContext(ctx, acm.beaconRPCProvider, acm.dialOpts...) if err != nil { return nil, nil, errors.Wrapf(err, "could not dial endpoint %s", acm.beaconRPCProvider) } + + conn := validatorHelpers.NewNodeConnection( + grpcConn, + acm.beaconApiEndpoint, + acm.beaconApiTimeout, + ) + validatorClient := validatorClientFactory.NewValidatorClient(conn) - nodeClient := ethpb.NewNodeClient(conn) + nodeClient := ethpb.NewNodeClient(grpcConn) return &validatorClient, &nodeClient, nil } diff --git a/validator/accounts/cli_options.go b/validator/accounts/cli_options.go index 850f980d8d..d314d15d64 100644 --- a/validator/accounts/cli_options.go +++ b/validator/accounts/cli_options.go @@ -1,6 +1,8 @@ package accounts import ( + "time" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" "github.com/prysmaticlabs/prysm/v3/validator/keymanager" @@ -91,6 +93,15 @@ func WithBeaconRPCProvider(provider string) Option { } } +// WithBeaconRESTApiProvider provides a beacon node REST API endpoint to the accounts cli manager. +func WithBeaconRESTApiProvider(beaconApiEndpoint string) Option { + return func(acc *AccountsCLIManager) error { + acc.beaconApiEndpoint = beaconApiEndpoint + acc.beaconApiTimeout = time.Second * 30 + return nil + } +} + // WithWalletKeyCount tracks the number of keys in a wallet. func WithWalletKeyCount(walletKeyCount int) Option { return func(acc *AccountsCLIManager) error { diff --git a/validator/client/BUILD.bazel b/validator/client/BUILD.bazel index 783fd72f9c..3c1817c83c 100644 --- a/validator/client/BUILD.bazel +++ b/validator/client/BUILD.bazel @@ -59,6 +59,7 @@ go_library( "//validator/db:go_default_library", "//validator/db/kv:go_default_library", "//validator/graffiti:go_default_library", + "//validator/helpers:go_default_library", "//validator/keymanager:go_default_library", "//validator/keymanager/local:go_default_library", "//validator/keymanager/remote:go_default_library", diff --git a/validator/client/beacon-api/beacon_api_validator_client.go b/validator/client/beacon-api/beacon_api_validator_client.go index 11db53fe10..42ad042926 100644 --- a/validator/client/beacon-api/beacon_api_validator_client.go +++ b/validator/client/beacon-api/beacon_api_validator_client.go @@ -5,6 +5,8 @@ package beacon_api import ( "context" + "net/http" + "time" "github.com/golang/protobuf/ptypes/empty" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" @@ -12,6 +14,8 @@ import ( ) type beaconApiValidatorClient struct { + url string + httpClient http.Client } func (*beaconApiValidatorClient) GetDuties(_ context.Context, _ *ethpb.DutiesRequest) (*ethpb.DutiesResponse, error) { @@ -141,10 +145,9 @@ func (*beaconApiValidatorClient) WaitForActivation(_ context.Context, _ *ethpb.V // Deprecated: Do not use. func (*beaconApiValidatorClient) WaitForChainStart(_ context.Context, _ *empty.Empty) (ethpb.BeaconNodeValidator_WaitForChainStartClient, error) { - // TODO: Implement me panic("beaconApiValidatorClient.WaitForChainStart is not implemented") } -func NewBeaconApiValidatorClient() iface.ValidatorClient { - return &beaconApiValidatorClient{} +func NewBeaconApiValidatorClient(url string, timeout time.Duration) iface.ValidatorClient { + return &beaconApiValidatorClient{url, http.Client{Timeout: timeout}} } diff --git a/validator/client/service.go b/validator/client/service.go index 0e6b3db175..482ab0d68c 100644 --- a/validator/client/service.go +++ b/validator/client/service.go @@ -25,6 +25,7 @@ import ( validatorClientFactory "github.com/prysmaticlabs/prysm/v3/validator/client/validator-client-factory" "github.com/prysmaticlabs/prysm/v3/validator/db" "github.com/prysmaticlabs/prysm/v3/validator/graffiti" + validatorHelpers "github.com/prysmaticlabs/prysm/v3/validator/helpers" "github.com/prysmaticlabs/prysm/v3/validator/keymanager" "github.com/prysmaticlabs/prysm/v3/validator/keymanager/local" remoteweb3signer "github.com/prysmaticlabs/prysm/v3/validator/keymanager/remote-web3signer" @@ -53,7 +54,7 @@ type ValidatorService struct { emitAccountMetrics bool logValidatorBalances bool interopKeysConfig *local.InteropKeymanagerConfig - conn *grpc.ClientConn + conn validatorHelpers.NodeConnection grpcRetryDelay time.Duration grpcRetries uint maxCallRecvMsgSize int @@ -94,6 +95,8 @@ type Config struct { Endpoint string Web3SignerConfig *remoteweb3signer.SetupConfig ProposerSettings *validatorserviceconfig.ProposerSettings + BeaconApiEndpoint string + BeaconApiTimeout time.Duration } // NewValidatorService creates a new validator service for the service @@ -136,14 +139,18 @@ func NewValidatorService(ctx context.Context, cfg *Config) (*ValidatorService, e s.ctx = grpcutil.AppendHeaders(ctx, s.grpcHeaders) - conn, err := grpc.DialContext(ctx, s.endpoint, dialOpts...) + grpcConn, err := grpc.DialContext(ctx, s.endpoint, dialOpts...) if err != nil { return s, err } if s.withCert != "" { log.Info("Established secure gRPC connection") } - s.conn = conn + s.conn = validatorHelpers.NewNodeConnection( + grpcConn, + cfg.BeaconApiEndpoint, + cfg.BeaconApiTimeout, + ) return s, nil } @@ -181,9 +188,9 @@ func (v *ValidatorService) Start() { valStruct := &validator{ db: v.db, validatorClient: validatorClientFactory.NewValidatorClient(v.conn), - beaconClient: ethpb.NewBeaconChainClient(v.conn), - slashingProtectionClient: ethpb.NewSlasherClient(v.conn), - node: ethpb.NewNodeClient(v.conn), + beaconClient: ethpb.NewBeaconChainClient(v.conn.GetGrpcClientConn()), + slashingProtectionClient: ethpb.NewSlasherClient(v.conn.GetGrpcClientConn()), + node: ethpb.NewNodeClient(v.conn.GetGrpcClientConn()), graffiti: v.graffiti, logValidatorBalances: v.logValidatorBalances, emitAccountMetrics: v.emitAccountMetrics, @@ -227,7 +234,7 @@ func (v *ValidatorService) Stop() error { v.cancel() log.Info("Stopping service") if v.conn != nil { - return v.conn.Close() + return v.conn.GetGrpcClientConn().Close() } return nil } @@ -314,7 +321,7 @@ func ConstructDialOptions( // Syncing returns whether or not the beacon node is currently synchronizing the chain. func (v *ValidatorService) Syncing(ctx context.Context) (bool, error) { - nc := ethpb.NewNodeClient(v.conn) + nc := ethpb.NewNodeClient(v.conn.GetGrpcClientConn()) resp, err := nc.GetSyncStatus(ctx, &emptypb.Empty{}) if err != nil { return false, err @@ -325,6 +332,6 @@ func (v *ValidatorService) Syncing(ctx context.Context) (bool, error) { // GenesisInfo queries the beacon node for the chain genesis info containing // the genesis time along with the validator deposit contract address. func (v *ValidatorService) GenesisInfo(ctx context.Context) (*ethpb.Genesis, error) { - nc := ethpb.NewNodeClient(v.conn) + nc := ethpb.NewNodeClient(v.conn.GetGrpcClientConn()) return nc.GetGenesis(ctx, &emptypb.Empty{}) } diff --git a/validator/client/validator-client-factory/BUILD.bazel b/validator/client/validator-client-factory/BUILD.bazel index 439050c0fd..8cbd2b9e61 100644 --- a/validator/client/validator-client-factory/BUILD.bazel +++ b/validator/client/validator-client-factory/BUILD.bazel @@ -23,7 +23,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//validator/client/iface:go_default_library", - "@org_golang_google_grpc//:go_default_library", + "//validator/helpers:go_default_library", ] + select({ ":beacon_api_usage": ["//validator/client/beacon-api:go_default_library"], "//conditions:default": ["//validator/client/grpc-api:go_default_library"], diff --git a/validator/client/validator-client-factory/beacon_api_validator_client_factory.go b/validator/client/validator-client-factory/beacon_api_validator_client_factory.go index 31689c4984..a295c7b992 100644 --- a/validator/client/validator-client-factory/beacon_api_validator_client_factory.go +++ b/validator/client/validator-client-factory/beacon_api_validator_client_factory.go @@ -6,9 +6,9 @@ package validator_client_factory import ( beaconApi "github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api" "github.com/prysmaticlabs/prysm/v3/validator/client/iface" - "google.golang.org/grpc" + validatorHelpers "github.com/prysmaticlabs/prysm/v3/validator/helpers" ) -func NewValidatorClient(cc grpc.ClientConnInterface) iface.ValidatorClient { - return beaconApi.NewBeaconApiValidatorClient() +func NewValidatorClient(validatorConn validatorHelpers.NodeConnection) iface.ValidatorClient { + return beaconApi.NewBeaconApiValidatorClient(validatorConn.GetBeaconApiUrl(), validatorConn.GetBeaconApiTimeout()) } diff --git a/validator/client/validator-client-factory/grpc_validator_client_factory.go b/validator/client/validator-client-factory/grpc_validator_client_factory.go index 20105339b1..339dd500c4 100644 --- a/validator/client/validator-client-factory/grpc_validator_client_factory.go +++ b/validator/client/validator-client-factory/grpc_validator_client_factory.go @@ -6,9 +6,9 @@ package validator_client_factory import ( grpcApi "github.com/prysmaticlabs/prysm/v3/validator/client/grpc-api" "github.com/prysmaticlabs/prysm/v3/validator/client/iface" - "google.golang.org/grpc" + validatorHelpers "github.com/prysmaticlabs/prysm/v3/validator/helpers" ) -func NewValidatorClient(cc grpc.ClientConnInterface) iface.ValidatorClient { - return grpcApi.NewGrpcValidatorClient(cc) +func NewValidatorClient(validatorConn validatorHelpers.NodeConnection) iface.ValidatorClient { + return grpcApi.NewGrpcValidatorClient(validatorConn.GetGrpcClientConn()) } diff --git a/validator/helpers/BUILD.bazel b/validator/helpers/BUILD.bazel new file mode 100644 index 0000000000..37386030a1 --- /dev/null +++ b/validator/helpers/BUILD.bazel @@ -0,0 +1,11 @@ +load("@prysm//tools/go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["node_connection.go"], + importpath = "github.com/prysmaticlabs/prysm/v3/validator/helpers", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_google_grpc//:go_default_library", + ], +) diff --git a/validator/helpers/node_connection.go b/validator/helpers/node_connection.go new file mode 100644 index 0000000000..f287727cc2 --- /dev/null +++ b/validator/helpers/node_connection.go @@ -0,0 +1,43 @@ +package validator_helpers + +import ( + "time" + + "google.golang.org/grpc" +) + +// Use an interface with a private dummy function to force all other packages to call NewNodeConnection +type NodeConnection interface { + GetGrpcClientConn() *grpc.ClientConn + GetBeaconApiUrl() string + GetBeaconApiTimeout() time.Duration + dummy() +} + +type nodeConnection struct { + grpcClientConn *grpc.ClientConn + beaconApiUrl string + beaconApiTimeout time.Duration +} + +func (c *nodeConnection) GetGrpcClientConn() *grpc.ClientConn { + return c.grpcClientConn +} + +func (c *nodeConnection) GetBeaconApiUrl() string { + return c.beaconApiUrl +} + +func (c *nodeConnection) GetBeaconApiTimeout() time.Duration { + return c.beaconApiTimeout +} + +func (*nodeConnection) dummy() {} + +func NewNodeConnection(grpcConn *grpc.ClientConn, beaconApiUrl string, beaconApiTimeout time.Duration) NodeConnection { + conn := &nodeConnection{} + conn.grpcClientConn = grpcConn + conn.beaconApiUrl = beaconApiUrl + conn.beaconApiTimeout = beaconApiTimeout + return conn +} diff --git a/validator/node/node.go b/validator/node/node.go index a3d1c0fc2c..effb4a8741 100644 --- a/validator/node/node.go +++ b/validator/node/node.go @@ -18,6 +18,7 @@ import ( "strings" "sync" "syscall" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -430,6 +431,8 @@ func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error { GraffitiStruct: gStruct, Web3SignerConfig: wsc, ProposerSettings: bpc, + BeaconApiTimeout: time.Second * 30, + BeaconApiEndpoint: c.cliCtx.String(flags.BeaconRESTApiProviderFlag.Name), }) if err != nil { return errors.Wrap(err, "could not initialize validator service") diff --git a/validator/rpc/BUILD.bazel b/validator/rpc/BUILD.bazel index 63d951d497..0ba92a8013 100644 --- a/validator/rpc/BUILD.bazel +++ b/validator/rpc/BUILD.bazel @@ -46,6 +46,7 @@ go_library( "//validator/client/iface:go_default_library", "//validator/client/validator-client-factory:go_default_library", "//validator/db:go_default_library", + "//validator/helpers:go_default_library", "//validator/keymanager:go_default_library", "//validator/keymanager/derived:go_default_library", "//validator/keymanager/local:go_default_library", diff --git a/validator/rpc/beacon.go b/validator/rpc/beacon.go index a6f30e45be..c189c77dbd 100644 --- a/validator/rpc/beacon.go +++ b/validator/rpc/beacon.go @@ -15,6 +15,7 @@ import ( validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client" "github.com/prysmaticlabs/prysm/v3/validator/client" validatorClientFactory "github.com/prysmaticlabs/prysm/v3/validator/client/validator-client-factory" + validatorHelpers "github.com/prysmaticlabs/prysm/v3/validator/helpers" "google.golang.org/grpc" "google.golang.org/protobuf/types/known/emptypb" ) @@ -39,16 +40,23 @@ func (s *Server) registerBeaconClient() error { s.ctx = grpcutil.AppendHeaders(s.ctx, s.clientGrpcHeaders) - conn, err := grpc.DialContext(s.ctx, s.beaconClientEndpoint, dialOpts...) + grpcConn, err := grpc.DialContext(s.ctx, s.beaconClientEndpoint, dialOpts...) if err != nil { return errors.Wrapf(err, "could not dial endpoint: %s", s.beaconClientEndpoint) } if s.clientWithCert != "" { log.Info("Established secure gRPC connection") } - s.beaconChainClient = ethpb.NewBeaconChainClient(conn) - s.beaconNodeClient = ethpb.NewNodeClient(conn) - s.beaconNodeHealthClient = ethpb.NewHealthClient(conn) + s.beaconChainClient = ethpb.NewBeaconChainClient(grpcConn) + s.beaconNodeClient = ethpb.NewNodeClient(grpcConn) + s.beaconNodeHealthClient = ethpb.NewHealthClient(grpcConn) + + conn := validatorHelpers.NewNodeConnection( + grpcConn, + s.beaconApiEndpoint, + s.beaconApiTimeout, + ) + s.beaconNodeValidatorClient = validatorClientFactory.NewValidatorClient(conn) return nil } diff --git a/validator/rpc/server.go b/validator/rpc/server.go index 9c0a0fd3bc..bea1f0c09c 100644 --- a/validator/rpc/server.go +++ b/validator/rpc/server.go @@ -91,6 +91,8 @@ type Server struct { validatorMonitoringPort int validatorGatewayHost string validatorGatewayPort int + beaconApiEndpoint string + beaconApiTimeout time.Duration } // NewServer instantiates a new gRPC server.