Onboard validator's Beacon REST API usage to e2e tests (#11704)

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* WIP

* Onboard validator's Beacon REST API usage to e2e tests

* Remove unused variables

* Remove use_beacon_api tags

* Fix DeepSource errors

* Revert unneeded changes

* Revert evaluator changes

* Revert import reordering

* Address PR comments

* Remove all REST API e2e tests except minimal one

* Fix validator pointing to inexisting beacon node port

Co-authored-by: Radosław Kapka <rkapka@wp.pl>
This commit is contained in:
Patrice Vignola 2022-12-08 06:38:56 -08:00 committed by GitHub
parent ca2618110f
commit dbeb3ee886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 54 additions and 146 deletions

View File

@ -230,9 +230,3 @@ build --modify_execution_info='GoStdlib.*=+no-remote-cache'
# Set bazel gotag # Set bazel gotag
build --define gotags=bazel build --define gotags=bazel
# Build the binary with Beacon API calls for the validator
build --flag_alias=use_beacon_api=//validator/client/validator-client-factory:use_beacon_api
build:beacon_api --use_beacon_api
build:beacon_api --define=gotags=use_beacon_api

View File

@ -5,10 +5,7 @@ go_library(
srcs = [ srcs = [
"flags.go", "flags.go",
"interop.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", importpath = "github.com/prysmaticlabs/prysm/v3/cmd/validator/flags",
visibility = [ visibility = [
"//cmd/prysmctl:__subpackages__", "//cmd/prysmctl:__subpackages__",

View File

@ -1,8 +0,0 @@
//go:build use_beacon_api
// +build use_beacon_api
package flags
const (
BuiltWithBeaconApi = true
)

View File

@ -1,8 +0,0 @@
//go:build !use_beacon_api
// +build !use_beacon_api
package flags
const (
BuiltWithBeaconApi = false
)

View File

@ -49,6 +49,7 @@ func startNode(ctx *cli.Context) error {
var appFlags = []cli.Flag{ var appFlags = []cli.Flag{
flags.BeaconRPCProviderFlag, flags.BeaconRPCProviderFlag,
flags.BeaconRPCGatewayProviderFlag, flags.BeaconRPCGatewayProviderFlag,
flags.BeaconRESTApiProviderFlag,
flags.CertFlag, flags.CertFlag,
flags.GraffitiFlag, flags.GraffitiFlag,
flags.DisablePenaltyRewardLogFlag, flags.DisablePenaltyRewardLogFlag,
@ -112,11 +113,6 @@ var appFlags = []cli.Flag{
} }
func init() { func init() {
// Append the Beacon REST API flags
if flags.BuiltWithBeaconApi {
appFlags = append(appFlags, flags.BeaconRESTApiProviderFlag)
}
appFlags = cmd.WrapFlags(append(appFlags, features.ValidatorFlags...)) appFlags = cmd.WrapFlags(append(appFlags, features.ValidatorFlags...))
} }

View File

@ -86,6 +86,7 @@ var appHelpFlagGroups = []flagGroup{
Flags: []cli.Flag{ Flags: []cli.Flag{
flags.BeaconRPCProviderFlag, flags.BeaconRPCProviderFlag,
flags.BeaconRPCGatewayProviderFlag, flags.BeaconRPCGatewayProviderFlag,
flags.BeaconRESTApiProviderFlag,
flags.CertFlag, flags.CertFlag,
flags.EnableWebFlag, flags.EnableWebFlag,
flags.DisablePenaltyRewardLogFlag, flags.DisablePenaltyRewardLogFlag,
@ -128,16 +129,6 @@ var appHelpFlagGroups = []flagGroup{
} }
func init() { 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 cli.AppHelpTemplate = appHelpTemplate
type helpData struct { type helpData struct {

View File

@ -47,6 +47,7 @@ type Flags struct {
WriteWalletPasswordOnWebOnboarding bool // WriteWalletPasswordOnWebOnboarding writes the password to disk after Prysm web signup. WriteWalletPasswordOnWebOnboarding bool // WriteWalletPasswordOnWebOnboarding writes the password to disk after Prysm web signup.
EnableDoppelGanger bool // EnableDoppelGanger enables doppelganger protection on startup for the validator. EnableDoppelGanger bool // EnableDoppelGanger enables doppelganger protection on startup for the validator.
EnableHistoricalSpaceRepresentation bool // EnableHistoricalSpaceRepresentation enables the saving of registry validators in separate buckets to save space EnableHistoricalSpaceRepresentation bool // EnableHistoricalSpaceRepresentation enables the saving of registry validators in separate buckets to save space
EnableBeaconRESTApi bool // EnableBeaconRESTApi enables experimental usage of the beacon REST API by the validator when querying a beacon node
// Logging related toggles. // Logging related toggles.
DisableGRPCConnectionLogs bool // Disables logging when a new grpc client has connected. DisableGRPCConnectionLogs bool // Disables logging when a new grpc client has connected.
EnableFullSSZDataLogging bool // Enables logging for full ssz data on rejected gossip messages EnableFullSSZDataLogging bool // Enables logging for full ssz data on rejected gossip messages
@ -290,6 +291,10 @@ func ConfigureValidator(ctx *cli.Context) error {
logEnabled(enableDoppelGangerProtection) logEnabled(enableDoppelGangerProtection)
cfg.EnableDoppelGanger = true cfg.EnableDoppelGanger = true
} }
if ctx.Bool(EnableBeaconRESTApi.Name) {
logEnabled(EnableBeaconRESTApi)
cfg.EnableBeaconRESTApi = true
}
cfg.KeystoreImportDebounceInterval = ctx.Duration(dynamicKeyReloadDebounceInterval.Name) cfg.KeystoreImportDebounceInterval = ctx.Duration(dynamicKeyReloadDebounceInterval.Name)
Init(cfg) Init(cfg)
return nil return nil

View File

@ -128,6 +128,10 @@ var (
Name: "enable-full-ssz-data-logging", Name: "enable-full-ssz-data-logging",
Usage: "Enables displaying logs for full ssz data on rejected gossip messages", Usage: "Enables displaying logs for full ssz data on rejected gossip messages",
} }
EnableBeaconRESTApi = &cli.BoolFlag{
Name: "enable-beacon-rest-api",
Usage: "Experimental enable of the beacon REST API when querying a beacon node",
}
) )
// devModeFlags holds list of flags that are set when development mode is on. // devModeFlags holds list of flags that are set when development mode is on.
@ -145,6 +149,7 @@ var ValidatorFlags = append(deprecatedFlags, []cli.Flag{
attestTimely, attestTimely,
enableSlashingProtectionPruning, enableSlashingProtectionPruning,
enableDoppelGangerProtection, enableDoppelGangerProtection,
EnableBeaconRESTApi,
}...) }...)
// E2EValidatorFlags contains a list of the validator feature flags to be tested in E2E. // E2EValidatorFlags contains a list of the validator feature flags to be tested in E2E.

View File

@ -80,7 +80,7 @@ for ((i = 0; i < ${#beacon_api_mocks[@]}; i++)); do
file=${beacon_api_mocks[i]% *}; file=${beacon_api_mocks[i]% *};
source=${beacon_api_mocks[i]#* }; source=${beacon_api_mocks[i]#* };
echo "generating $file for file: $source"; echo "generating $file for file: $source";
GO11MODULE=on mockgen -package=mock --build_flags="--tags=use_beacon_api" -source="validator/client/beacon-api/$source" -destination="$file" GO11MODULE=on mockgen -package=mock -source="validator/client/beacon-api/$source" -destination="$file"
done done
goimports -w "$beacon_api_mock_path/." goimports -w "$beacon_api_mock_path/."

View File

@ -69,6 +69,7 @@ common_deps = [
"//testing/require:go_default_library", "//testing/require:go_default_library",
"//testing/slasher/simulator:go_default_library", "//testing/slasher/simulator:go_default_library",
"//testing/util:go_default_library", "//testing/util:go_default_library",
"//validator/helpers:go_default_library",
"@com_github_pkg_errors//:go_default_library", "@com_github_pkg_errors//:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library", "@com_github_sirupsen_logrus//hooks/test:go_default_library",

View File

@ -213,6 +213,7 @@ func (v *ValidatorNode) Start(ctx context.Context) error {
fmt.Sprintf("--%s=%d", flags.MonitoringPortFlag.Name, e2e.TestParams.Ports.ValidatorMetricsPort+index), fmt.Sprintf("--%s=%d", flags.MonitoringPortFlag.Name, e2e.TestParams.Ports.ValidatorMetricsPort+index),
fmt.Sprintf("--%s=%d", flags.GRPCGatewayPort.Name, e2e.TestParams.Ports.ValidatorGatewayPort+index), fmt.Sprintf("--%s=%d", flags.GRPCGatewayPort.Name, e2e.TestParams.Ports.ValidatorGatewayPort+index),
fmt.Sprintf("--%s=localhost:%d", flags.BeaconRPCProviderFlag.Name, beaconRPCPort), fmt.Sprintf("--%s=localhost:%d", flags.BeaconRPCProviderFlag.Name, beaconRPCPort),
fmt.Sprintf("--%s=%s", flags.GrpcHeadersFlag.Name, "dummy=value,foo=bar"), // Sending random headers shouldn't break anything. fmt.Sprintf("--%s=%s", flags.GrpcHeadersFlag.Name, "dummy=value,foo=bar"), // Sending random headers shouldn't break anything.
fmt.Sprintf("--%s=%s", cmdshared.VerbosityFlag.Name, "debug"), fmt.Sprintf("--%s=%s", cmdshared.VerbosityFlag.Name, "debug"),
fmt.Sprintf("--%s=%s", flags.ProposerSettingsFlag.Name, proposerSettingsPathPath), fmt.Sprintf("--%s=%s", flags.ProposerSettingsFlag.Name, proposerSettingsPathPath),
@ -220,6 +221,18 @@ func (v *ValidatorNode) Start(ctx context.Context) error {
"--" + cmdshared.E2EConfigFlag.Name, "--" + cmdshared.E2EConfigFlag.Name,
"--" + cmdshared.AcceptTosFlag.Name, "--" + cmdshared.AcceptTosFlag.Name,
} }
if v.config.UseBeaconRestApi {
beaconRestApiPort := e2e.TestParams.Ports.PrysmBeaconNodeGatewayPort + index
if beaconRestApiPort >= e2e.TestParams.Ports.PrysmBeaconNodeGatewayPort+e2e.TestParams.BeaconNodeCount {
// Point any extra validator clients to a node we know is running.
beaconRestApiPort = e2e.TestParams.Ports.PrysmBeaconNodeGatewayPort
}
args = append(args, fmt.Sprintf("--%s=http://localhost:%d", flags.BeaconRESTApiProviderFlag.Name, beaconRestApiPort))
args = append(args, fmt.Sprintf("--%s", features.EnableBeaconRESTApi.Name))
}
// Only apply e2e flags to the current branch. New flags may not exist in previous release. // Only apply e2e flags to the current branch. New flags may not exist in previous release.
if !v.config.UsePrysmShValidator { if !v.config.UsePrysmShValidator {
args = append(args, features.E2EValidatorFlags...) args = append(args, features.E2EValidatorFlags...)

View File

@ -18,6 +18,10 @@ func TestEndToEnd_MinimalConfig_Web3Signer(t *testing.T) {
e2eMinimal(t, types.WithRemoteSigner()).run() e2eMinimal(t, types.WithRemoteSigner()).run()
} }
func TestEndToEnd_MinimalConfig_ValidatorRESTApi(t *testing.T) {
e2eMinimal(t, types.WithCheckpointSync(), types.WithValidatorRESTApi()).run()
}
func TestEndToEnd_ScenarioRun_EEOffline(t *testing.T) { func TestEndToEnd_ScenarioRun_EEOffline(t *testing.T) {
t.Skip("TODO(#10242) Prysm is current unable to handle an offline e2e") t.Skip("TODO(#10242) Prysm is current unable to handle an offline e2e")
runner := e2eMinimal(t) runner := e2eMinimal(t)

View File

@ -36,6 +36,12 @@ func WithValidatorCrossClient() E2EConfigOpt {
} }
} }
func WithValidatorRESTApi() E2EConfigOpt {
return func(cfg *E2EConfig) {
cfg.UseBeaconRestApi = true
}
}
// E2EConfig defines the struct for all configurations needed for E2E testing. // E2EConfig defines the struct for all configurations needed for E2E testing.
type E2EConfig struct { type E2EConfig struct {
TestCheckpointSync bool TestCheckpointSync bool
@ -47,6 +53,7 @@ type E2EConfig struct {
TestDeposits bool TestDeposits bool
UseFixedPeerIDs bool UseFixedPeerIDs bool
UseValidatorCrossClient bool UseValidatorCrossClient bool
UseBeaconRestApi bool
EpochsToRun uint64 EpochsToRun uint64
Seed int64 Seed int64
TracingSinkEndpoint string TracingSinkEndpoint string

View File

@ -1,6 +1,5 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test") load("@prysm//tools/go:def.bzl", "go_library", "go_test")
# gazelle:build_tags use_beacon_api
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
@ -33,7 +32,6 @@ go_library(
], ],
) )
# gazelle:build_tags use_beacon_api
go_test( go_test(
name = "go_default_test", name = "go_default_test",
size = "small", size = "small",
@ -50,7 +48,6 @@ go_test(
"wait_for_chain_start_test.go", "wait_for_chain_start_test.go",
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
gotags = ["use_beacon_api"],
deps = [ deps = [
"//api/gateway/apimiddleware:go_default_library", "//api/gateway/apimiddleware:go_default_library",
"//beacon-chain/rpc/apimiddleware:go_default_library", "//beacon-chain/rpc/apimiddleware:go_default_library",

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (
@ -66,11 +63,12 @@ func TestGetDomainData_GenesisError(t *testing.T) {
// Make sure that GetGenesis() is called exactly once // Make sure that GetGenesis() is called exactly once
genesisProvider := mock.NewMockgenesisProvider(ctrl) genesisProvider := mock.NewMockgenesisProvider(ctrl)
genesisProvider.EXPECT().GetGenesis().Return(nil, nil, errors.New("")).Times(1) genesisProvider.EXPECT().GetGenesis().Return(nil, nil, errors.New("foo error")).Times(1)
validatorClient := &beaconApiValidatorClient{genesisProvider: genesisProvider} validatorClient := &beaconApiValidatorClient{genesisProvider: genesisProvider}
_, err := validatorClient.getDomainData(epoch, domainType) _, err := validatorClient.getDomainData(epoch, domainType)
assert.ErrorContains(t, "failed to get genesis info", err) assert.ErrorContains(t, "failed to get genesis info", err)
assert.ErrorContains(t, "foo error", err)
} }
func TestGetDomainData_InvalidGenesisRoot(t *testing.T) { func TestGetDomainData_InvalidGenesisRoot(t *testing.T) {

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build use_beacon_api
// +build use_beacon_api
package beacon_api package beacon_api
import ( import (

View File

@ -1,6 +1,3 @@
//go:build !use_beacon_api
// +build !use_beacon_api
package grpc_api package grpc_api
import ( import (

View File

@ -1,32 +1,15 @@
load("@prysm//tools/go:def.bzl", "go_library") load("@prysm//tools/go:def.bzl", "go_library")
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
bool_flag(
name = "use_beacon_api",
build_setting_default = False,
)
config_setting(
name = "beacon_api_usage",
flag_values = {
":use_beacon_api": "true",
},
)
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = select({ srcs = ["validator_client_factory.go"],
":beacon_api_usage": ["beacon_api_validator_client_factory.go"],
"//conditions:default": ["grpc_validator_client_factory.go"],
}),
importpath = "github.com/prysmaticlabs/prysm/v3/validator/client/validator-client-factory", importpath = "github.com/prysmaticlabs/prysm/v3/validator/client/validator-client-factory",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//config/features:go_default_library",
"//validator/client/beacon-api:go_default_library",
"//validator/client/grpc-api:go_default_library", "//validator/client/grpc-api:go_default_library",
"//validator/client/iface:go_default_library", "//validator/client/iface:go_default_library",
"//validator/helpers:go_default_library", "//validator/helpers:go_default_library",
] + select({ ],
":beacon_api_usage": ["//validator/client/beacon-api:go_default_library"],
"//conditions:default": [],
}),
) )

View File

@ -1,14 +0,0 @@
//go:build !use_beacon_api
// +build !use_beacon_api
package validator_client_factory
import (
grpcApi "github.com/prysmaticlabs/prysm/v3/validator/client/grpc-api"
"github.com/prysmaticlabs/prysm/v3/validator/client/iface"
validatorHelpers "github.com/prysmaticlabs/prysm/v3/validator/helpers"
)
func NewValidatorClient(validatorConn validatorHelpers.NodeConnection) iface.ValidatorClient {
return grpcApi.NewGrpcValidatorClient(validatorConn.GetGrpcClientConn())
}

View File

@ -1,9 +1,7 @@
//go:build use_beacon_api
// +build use_beacon_api
package validator_client_factory package validator_client_factory
import ( import (
"github.com/prysmaticlabs/prysm/v3/config/features"
beaconApi "github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api" beaconApi "github.com/prysmaticlabs/prysm/v3/validator/client/beacon-api"
grpcApi "github.com/prysmaticlabs/prysm/v3/validator/client/grpc-api" grpcApi "github.com/prysmaticlabs/prysm/v3/validator/client/grpc-api"
"github.com/prysmaticlabs/prysm/v3/validator/client/iface" "github.com/prysmaticlabs/prysm/v3/validator/client/iface"
@ -11,6 +9,12 @@ import (
) )
func NewValidatorClient(validatorConn validatorHelpers.NodeConnection) iface.ValidatorClient { func NewValidatorClient(validatorConn validatorHelpers.NodeConnection) iface.ValidatorClient {
fallbackClient := grpcApi.NewGrpcValidatorClient(validatorConn.GetGrpcClientConn()) grpcClient := grpcApi.NewGrpcValidatorClient(validatorConn.GetGrpcClientConn())
return beaconApi.NewBeaconApiValidatorClientWithFallback(validatorConn.GetBeaconApiUrl(), validatorConn.GetBeaconApiTimeout(), fallbackClient) featureFlags := features.Get()
if featureFlags.EnableBeaconRESTApi {
return beaconApi.NewBeaconApiValidatorClientWithFallback(validatorConn.GetBeaconApiUrl(), validatorConn.GetBeaconApiTimeout(), grpcClient)
} else {
return grpcClient
}
} }