From d6fb8c29c9e51f9778b341bdd276d2b3202128ae Mon Sep 17 00:00:00 2001 From: james-prysm <90280386+james-prysm@users.noreply.github.com> Date: Mon, 4 Mar 2024 09:12:11 -0600 Subject: [PATCH] refactoring how proposer settings load into validator client (#13645) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactoring how proposer settings load * fixing tests and moving test data * fixing linting and adding comments * accidently removed a function, adding it back in * fixing usage of dependency * gaz * fixing package visibility * gaz * iface config gaz * adding visibility for db * fix ineffectual assignment to err * adding in log for when the builder is set but ignored due to no fee recipient * Update config/validator/service/proposer_settings.go Co-authored-by: Radosław Kapka * Update config/validator/service/proposer_settings.go Co-authored-by: Radosław Kapka * Update validator/client/validator.go Co-authored-by: Radosław Kapka * Update config/validator/service/proposer_settings.go Co-authored-by: Radosław Kapka * Update config/proposer/loader.go Co-authored-by: Radosław Kapka * Update config/proposer/loader.go Co-authored-by: Radosław Kapka * Update config/proposer/loader.go Co-authored-by: Radosław Kapka * Update config/proposer/loader.go Co-authored-by: Radosław Kapka * Update config/proposer/loader.go Co-authored-by: Radosław Kapka * Update config/validator/service/proposer_settings.go Co-authored-by: Radosław Kapka * Update config/util.go Co-authored-by: Radosław Kapka * some of the review feedback * more review comments * adding more test coverage * Update config/proposer/loader.go Co-authored-by: Manu NALEPA * Update config/proposer/loader.go Co-authored-by: Manu NALEPA * Update config/proposer/loader.go Co-authored-by: Manu NALEPA * Update config/proposer/loader.go Co-authored-by: Manu NALEPA * updating based on feedback * renaming variable * fixing unhandled errors * fixing tests * gaz * adding in gaslimit log * fixing log * some more review comments * renaming and moving proposer settings file --------- Co-authored-by: Radosław Kapka Co-authored-by: Manu NALEPA --- cmd/validator/flags/BUILD.bazel | 1 + config/BUILD.bazel | 27 + .../service => proposer}/BUILD.bazel | 7 +- config/proposer/loader/BUILD.bazel | 45 + config/proposer/loader/loader.go | 283 ++++++ config/proposer/loader/loader_test.go | 921 ++++++++++++++++++ .../bad-gas-value-proposer-settings.json | 0 .../bad-prepare-beacon-proposer-config.json | 0 .../default-only-proposer-config.json | 1 - config/proposer/loader/testdata/empty.json | 3 + ...re-beacon-proposer-config-badchecksum.json | 0 ...epare-beacon-proposer-config-multiple.json | 0 .../good-prepare-beacon-proposer-config.json | 0 .../good-prepare-beacon-proposer-config.yaml | 0 .../loader/testdata/proposer-config-only.json | 7 + .../loader}/testdata/someotherfile.json | 0 .../settings.go} | 175 ++-- .../settings_test.go} | 36 +- config/util.go | 76 ++ config/util_test.go | 61 ++ validator/accounts/testing/BUILD.bazel | 2 +- validator/accounts/testing/mock.go | 8 +- validator/client/BUILD.bazel | 4 +- validator/client/iface/BUILD.bazel | 2 +- validator/client/iface/validator.go | 6 +- validator/client/runner_test.go | 20 +- validator/client/service.go | 10 +- validator/client/testutil/BUILD.bazel | 2 +- validator/client/testutil/mock_validator.go | 8 +- validator/client/validator.go | 12 +- validator/client/validator_test.go | 194 ++-- validator/db/iface/BUILD.bazel | 7 +- validator/db/iface/interface.go | 8 +- validator/db/kv/BUILD.bazel | 4 +- validator/db/kv/proposer_settings.go | 79 +- validator/db/kv/proposer_settings_test.go | 47 +- validator/db/testing/BUILD.bazel | 1 + validator/node/BUILD.bazel | 16 +- validator/node/node.go | 297 +----- validator/node/node_test.go | 729 -------------- validator/rpc/BUILD.bazel | 4 +- validator/rpc/handlers_keymanager.go | 24 +- validator/rpc/handlers_keymanager_test.go | 142 +-- 43 files changed, 1823 insertions(+), 1446 deletions(-) rename config/{validator/service => proposer}/BUILD.bazel (86%) create mode 100644 config/proposer/loader/BUILD.bazel create mode 100644 config/proposer/loader/loader.go create mode 100644 config/proposer/loader/loader_test.go rename {validator/node => config/proposer/loader}/testdata/bad-gas-value-proposer-settings.json (100%) rename {validator/node => config/proposer/loader}/testdata/bad-prepare-beacon-proposer-config.json (100%) rename {validator/node => config/proposer/loader}/testdata/default-only-proposer-config.json (83%) create mode 100644 config/proposer/loader/testdata/empty.json rename {validator/node => config/proposer/loader}/testdata/good-prepare-beacon-proposer-config-badchecksum.json (100%) rename {validator/node => config/proposer/loader}/testdata/good-prepare-beacon-proposer-config-multiple.json (100%) rename {validator/node => config/proposer/loader}/testdata/good-prepare-beacon-proposer-config.json (100%) rename {validator/node => config/proposer/loader}/testdata/good-prepare-beacon-proposer-config.yaml (100%) create mode 100644 config/proposer/loader/testdata/proposer-config-only.json rename {validator/node => config/proposer/loader}/testdata/someotherfile.json (100%) rename config/{validator/service/proposer_settings.go => proposer/settings.go} (55%) rename config/{validator/service/proposer_settings_test.go => proposer/settings_test.go} (88%) create mode 100644 config/util.go create mode 100644 config/util_test.go diff --git a/cmd/validator/flags/BUILD.bazel b/cmd/validator/flags/BUILD.bazel index 83d533f1e..3c4d2b5cf 100644 --- a/cmd/validator/flags/BUILD.bazel +++ b/cmd/validator/flags/BUILD.bazel @@ -10,6 +10,7 @@ go_library( visibility = [ "//cmd/prysmctl:__subpackages__", "//cmd/validator:__subpackages__", + "//config:__subpackages__", "//testing/endtoend:__subpackages__", "//validator:__subpackages__", ], diff --git a/config/BUILD.bazel b/config/BUILD.bazel index 24647eeb1..156091044 100644 --- a/config/BUILD.bazel +++ b/config/BUILD.bazel @@ -1,3 +1,5 @@ +load("@prysm//tools/go:def.bzl", "go_library", "go_test") + config_setting( name = "mainnet", flag_values = { @@ -11,3 +13,28 @@ config_setting( "//proto:network": "minimal", }, ) + +go_library( + name = "go_default_library", + srcs = ["util.go"], + importpath = "github.com/prysmaticlabs/prysm/v5/config", + visibility = ["//visibility:public"], + deps = [ + "@com_github_ethereum_go_ethereum//common:go_default_library", + "@com_github_pkg_errors//:go_default_library", + "@com_github_sirupsen_logrus//:go_default_library", + "@io_k8s_apimachinery//pkg/util/yaml:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["util_test.go"], + embed = [":go_default_library"], + deps = [ + "//config/params:go_default_library", + "//testing/assert:go_default_library", + "//testing/require:go_default_library", + "@com_github_sirupsen_logrus//hooks/test:go_default_library", + ], +) diff --git a/config/validator/service/BUILD.bazel b/config/proposer/BUILD.bazel similarity index 86% rename from config/validator/service/BUILD.bazel rename to config/proposer/BUILD.bazel index e77b4842c..6a7004d7a 100644 --- a/config/validator/service/BUILD.bazel +++ b/config/proposer/BUILD.bazel @@ -2,10 +2,11 @@ load("@prysm//tools/go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", - srcs = ["proposer_settings.go"], - importpath = "github.com/prysmaticlabs/prysm/v5/config/validator/service", + srcs = ["settings.go"], + importpath = "github.com/prysmaticlabs/prysm/v5/config/proposer", visibility = ["//visibility:public"], deps = [ + "//config:go_default_library", "//config/fieldparams:go_default_library", "//consensus-types/validator:go_default_library", "//encoding/bytesutil:go_default_library", @@ -18,7 +19,7 @@ go_library( go_test( name = "go_default_test", - srcs = ["proposer_settings_test.go"], + srcs = ["settings_test.go"], embed = [":go_default_library"], deps = [ "//config/fieldparams:go_default_library", diff --git a/config/proposer/loader/BUILD.bazel b/config/proposer/loader/BUILD.bazel new file mode 100644 index 000000000..650e090d0 --- /dev/null +++ b/config/proposer/loader/BUILD.bazel @@ -0,0 +1,45 @@ +load("@prysm//tools/go:def.bzl", "go_library", "go_test") + +go_test( + name = "go_default_test", + size = "small", + srcs = ["loader_test.go"], + data = glob(["testdata/**"]), + embed = [":go_default_library"], + deps = [ + "//cmd/validator/flags:go_default_library", + "//config/fieldparams:go_default_library", + "//config/params:go_default_library", + "//config/proposer:go_default_library", + "//consensus-types/validator:go_default_library", + "//encoding/bytesutil:go_default_library", + "//testing/assert:go_default_library", + "//testing/require:go_default_library", + "//validator/db/iface:go_default_library", + "//validator/db/testing:go_default_library", + "@com_github_ethereum_go_ethereum//common:go_default_library", + "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", + "@com_github_sirupsen_logrus//hooks/test:go_default_library", + "@com_github_urfave_cli_v2//:go_default_library", + ], +) + +go_library( + name = "go_default_library", + srcs = ["loader.go"], + importpath = "github.com/prysmaticlabs/prysm/v5/config/proposer/loader", + visibility = ["//visibility:public"], + deps = [ + "//cmd/validator/flags:go_default_library", + "//config:go_default_library", + "//config/params:go_default_library", + "//config/proposer:go_default_library", + "//consensus-types/validator:go_default_library", + "//proto/prysm/v1alpha1/validator-client:go_default_library", + "//validator/db/iface:go_default_library", + "@com_github_ethereum_go_ethereum//common:go_default_library", + "@com_github_pkg_errors//:go_default_library", + "@com_github_sirupsen_logrus//:go_default_library", + "@com_github_urfave_cli_v2//:go_default_library", + ], +) diff --git a/config/proposer/loader/loader.go b/config/proposer/loader/loader.go new file mode 100644 index 000000000..9831a9e06 --- /dev/null +++ b/config/proposer/loader/loader.go @@ -0,0 +1,283 @@ +package loader + +import ( + "fmt" + "strconv" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/cmd/validator/flags" + "github.com/prysmaticlabs/prysm/v5/config" + "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/config/proposer" + "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" + validatorpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/validator-client" + "github.com/prysmaticlabs/prysm/v5/validator/db/iface" + log "github.com/sirupsen/logrus" + "github.com/urfave/cli/v2" +) + +type settingsType int + +const ( + none settingsType = iota + defaultFlag + fileFlag + urlFlag + onlyDB +) + +type settingsLoader struct { + loadMethods []settingsType + existsInDB bool + db iface.ValidatorDB + options *flagOptions +} + +type flagOptions struct { + builderConfig *proposer.BuilderConfig + gasLimit *validator.Uint64 +} + +// SettingsLoaderOption sets additional options that affect the proposer settings +type SettingsLoaderOption func(cliCtx *cli.Context, psl *settingsLoader) error + +// WithBuilderConfig applies the --enable-builder flag to proposer settings +func WithBuilderConfig() SettingsLoaderOption { + return func(cliCtx *cli.Context, psl *settingsLoader) error { + if cliCtx.Bool(flags.EnableBuilderFlag.Name) { + psl.options.builderConfig = &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + } + } + return nil + } +} + +// WithGasLimit applies the --suggested-gas-limit flag to proposer settings +func WithGasLimit() SettingsLoaderOption { + return func(cliCtx *cli.Context, psl *settingsLoader) error { + sgl := cliCtx.String(flags.BuilderGasLimitFlag.Name) + if sgl != "" { + gl, err := strconv.ParseUint(sgl, 10, 64) + if err != nil { + return errors.Errorf("Value set by --%s is not a uint64", flags.BuilderGasLimitFlag.Name) + } + if gl == 0 { + log.Warnf("Gas limit was intentionally set to 0, this will be replaced with the default gas limit of %d", params.BeaconConfig().DefaultBuilderGasLimit) + } + rgl := reviewGasLimit(validator.Uint64(gl)) + psl.options.gasLimit = &rgl + } + return nil + } +} + +// NewProposerSettingsLoader returns a new proposer settings loader that can process the proposer settings based on flag options +func NewProposerSettingsLoader(cliCtx *cli.Context, db iface.ValidatorDB, opts ...SettingsLoaderOption) (*settingsLoader, error) { + if cliCtx.IsSet(flags.ProposerSettingsFlag.Name) && cliCtx.IsSet(flags.ProposerSettingsURLFlag.Name) { + return nil, fmt.Errorf("cannot specify both --%s and --%s flags; choose one method for specifying proposer settings", flags.ProposerSettingsFlag.Name, flags.ProposerSettingsURLFlag.Name) + } + psExists, err := db.ProposerSettingsExists(cliCtx.Context) + if err != nil { + return nil, err + } + psl := &settingsLoader{db: db, existsInDB: psExists, options: &flagOptions{}} + + if cliCtx.IsSet(flags.SuggestedFeeRecipientFlag.Name) { + psl.loadMethods = append(psl.loadMethods, defaultFlag) + } + if cliCtx.IsSet(flags.ProposerSettingsFlag.Name) { + psl.loadMethods = append(psl.loadMethods, fileFlag) + } + if cliCtx.IsSet(flags.ProposerSettingsURLFlag.Name) { + psl.loadMethods = append(psl.loadMethods, urlFlag) + } + if len(psl.loadMethods) == 0 { + method := none + if psExists { + // override with db + method = onlyDB + } + psl.loadMethods = append(psl.loadMethods, method) + } + + for _, o := range opts { + if err := o(cliCtx, psl); err != nil { + return nil, err + } + } + + return psl, nil +} + +// Load saves the proposer settings to the database +func (psl *settingsLoader) Load(cliCtx *cli.Context) (*proposer.Settings, error) { + loadConfig := &validatorpb.ProposerSettingsPayload{} + + // override settings based on other options + if psl.options.builderConfig != nil && psl.options.gasLimit != nil { + psl.options.builderConfig.GasLimit = *psl.options.gasLimit + } + + // check if database has settings already + if psl.existsInDB { + dbps, err := psl.db.ProposerSettings(cliCtx.Context) + if err != nil { + return nil, err + } + loadConfig = dbps.ToConsensus() + } + + // start to process based on load method + for _, method := range psl.loadMethods { + switch method { + case defaultFlag: + suggestedFeeRecipient := cliCtx.String(flags.SuggestedFeeRecipientFlag.Name) + if !common.IsHexAddress(suggestedFeeRecipient) { + return nil, errors.Errorf("--%s is not a valid Ethereum address", flags.SuggestedFeeRecipientFlag.Name) + } + if err := config.WarnNonChecksummedAddress(suggestedFeeRecipient); err != nil { + return nil, err + } + defaultConfig := &validatorpb.ProposerOptionPayload{ + FeeRecipient: suggestedFeeRecipient, + } + if psl.options.builderConfig != nil { + defaultConfig.Builder = psl.options.builderConfig.ToConsensus() + } + loadConfig.DefaultConfig = defaultConfig + case fileFlag: + var settingFromFile *validatorpb.ProposerSettingsPayload + if err := config.UnmarshalFromFile(cliCtx.String(flags.ProposerSettingsFlag.Name), &settingFromFile); err != nil { + return nil, err + } + if settingFromFile == nil { + return nil, errors.Errorf("proposer settings is empty after unmarshalling from file specified by %s flag", flags.ProposerSettingsFlag.Name) + } + loadConfig = psl.processProposerSettings(settingFromFile, loadConfig) + case urlFlag: + var settingFromURL *validatorpb.ProposerSettingsPayload + if err := config.UnmarshalFromURL(cliCtx.Context, cliCtx.String(flags.ProposerSettingsURLFlag.Name), &settingFromURL); err != nil { + return nil, err + } + if settingFromURL == nil { + return nil, errors.New("proposer settings is empty after unmarshalling from url") + } + loadConfig = psl.processProposerSettings(settingFromURL, loadConfig) + case onlyDB: + loadConfig = psl.processProposerSettings(nil, loadConfig) + case none: + if psl.options.builderConfig != nil { + // if there are no proposer settings provided, create a default where fee recipient is not populated, this will be skipped for validator registration on validators that don't have a fee recipient set. + // skip saving to DB if only builder settings are provided until a trigger like keymanager API updates with fee recipient values + option := &proposer.Option{ + BuilderConfig: psl.options.builderConfig.Clone(), + } + loadConfig.DefaultConfig = option.ToConsensus() + } + default: + return nil, errors.New("load method for proposer settings does not exist") + } + } + + // exit early if nothing is provided + if loadConfig == nil || (loadConfig.ProposerConfig == nil && loadConfig.DefaultConfig == nil) { + log.Warn("No proposer settings were provided") + return nil, nil + } + ps, err := proposer.SettingFromConsensus(loadConfig) + if err != nil { + return nil, err + } + if err := psl.db.SaveProposerSettings(cliCtx.Context, ps); err != nil { + return nil, err + } + return ps, nil +} + +func (psl *settingsLoader) processProposerSettings(loadedSettings, dbSettings *validatorpb.ProposerSettingsPayload) *validatorpb.ProposerSettingsPayload { + if loadedSettings == nil && dbSettings == nil { + return nil + } + + // loaded settings have higher priority than db settings + newSettings := &validatorpb.ProposerSettingsPayload{} + + var builderConfig *validatorpb.BuilderConfig + var gasLimitOnly *validator.Uint64 + + if psl.options != nil { + if psl.options.builderConfig != nil { + builderConfig = psl.options.builderConfig.ToConsensus() + } + if psl.options.gasLimit != nil { + gasLimitOnly = psl.options.gasLimit + } + } + + if dbSettings != nil && dbSettings.DefaultConfig != nil { + if builderConfig == nil { + dbSettings.DefaultConfig.Builder = nil + } + newSettings.DefaultConfig = dbSettings.DefaultConfig + } + if loadedSettings != nil && loadedSettings.DefaultConfig != nil { + newSettings.DefaultConfig = loadedSettings.DefaultConfig + } + + // process any builder overrides on defaults + if newSettings.DefaultConfig != nil { + newSettings.DefaultConfig.Builder = processBuilderConfig(newSettings.DefaultConfig.Builder, builderConfig, gasLimitOnly) + } + + if dbSettings != nil && len(dbSettings.ProposerConfig) != 0 { + for _, option := range dbSettings.ProposerConfig { + if builderConfig == nil { + option.Builder = nil + } + } + newSettings.ProposerConfig = dbSettings.ProposerConfig + } + if loadedSettings != nil && len(loadedSettings.ProposerConfig) != 0 { + newSettings.ProposerConfig = loadedSettings.ProposerConfig + } + + // process any overrides for proposer config + for _, option := range newSettings.ProposerConfig { + if option != nil { + option.Builder = processBuilderConfig(option.Builder, builderConfig, gasLimitOnly) + } + } + + // if default and proposer configs are both missing even after db setting + if newSettings.DefaultConfig == nil && newSettings.ProposerConfig == nil { + return nil + } + + return newSettings +} + +func processBuilderConfig(current *validatorpb.BuilderConfig, override *validatorpb.BuilderConfig, gasLimitOnly *validator.Uint64) *validatorpb.BuilderConfig { + if current != nil { + current.GasLimit = reviewGasLimit(current.GasLimit) + if override != nil { + current.Enabled = override.Enabled + } + if gasLimitOnly != nil { + current.GasLimit = *gasLimitOnly + } + return current + } + return override +} + +func reviewGasLimit(gasLimit validator.Uint64) validator.Uint64 { + // sets gas limit to default if not defined or set to 0 + if gasLimit == 0 { + return validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit) + } + // TODO(10810): add in warning for ranges + return gasLimit +} diff --git a/config/proposer/loader/loader_test.go b/config/proposer/loader/loader_test.go new file mode 100644 index 000000000..20b24e335 --- /dev/null +++ b/config/proposer/loader/loader_test.go @@ -0,0 +1,921 @@ +package loader + +import ( + "context" + "flag" + "fmt" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/prysmaticlabs/prysm/v5/cmd/validator/flags" + fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" + "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/config/proposer" + "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" + "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" + "github.com/prysmaticlabs/prysm/v5/testing/assert" + "github.com/prysmaticlabs/prysm/v5/testing/require" + "github.com/prysmaticlabs/prysm/v5/validator/db/iface" + dbTest "github.com/prysmaticlabs/prysm/v5/validator/db/testing" + logtest "github.com/sirupsen/logrus/hooks/test" + "github.com/urfave/cli/v2" +) + +func TestProposerSettingsLoader(t *testing.T) { + hook := logtest.NewGlobal() + type proposerSettingsFlag struct { + dir string + url string + defaultfee string + defaultgas string + } + + type args struct { + proposerSettingsFlagValues *proposerSettingsFlag + } + tests := []struct { + name string + args args + want func() *proposer.Settings + urlResponse string + wantInitErr string + wantErr string + wantLog string + withdb func(db iface.ValidatorDB) error + validatorRegistrationEnabled bool + skipDBSavedCheck bool + }{ + { + name: "db settings override file settings if file default config is missing", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/proposer-config-only.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), + }, + }, + } + }, + withdb: func(db iface.ValidatorDB) error { + settings := &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + return db.SaveProposerSettings(context.Background(), settings) + }, + }, + { + name: "db settings override file settings if file proposer config is missing and enable builder is true", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/default-only-proposer-config.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(40000000), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + withdb: func(db iface.ValidatorDB) error { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + settings := &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(40000000), + }, + }, + }, + } + return db.SaveProposerSettings(context.Background(), settings) + }, + validatorRegistrationEnabled: true, + }, + { + name: "Empty json file loaded throws a warning", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/empty.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + return nil + }, + wantLog: "No proposer settings were provided", + skipDBSavedCheck: true, + }, + { + name: "Happy Path default only proposer settings file with builder settings,", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/default-only-proposer-config.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + return &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + }, + { + name: "Happy Path Config file File, bad checksum", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config-badchecksum.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), + }, + }, + } + }, + wantErr: "", + wantLog: "is not a checksum Ethereum address", + }, + { + name: "Happy Path Config file File multiple fee recipients", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config-multiple.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + key2, err := hexutil.Decode("0xb057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7b") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + bytesutil.ToBytes48(key2): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x60155530FCE8a85ec7055A5F8b2bE214B3DaeFd4"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(35000000), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(40000000), + }, + }, + } + }, + wantErr: "", + }, + { + name: "Happy Path Config URL File", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "./testdata/good-prepare-beacon-proposer-config.json", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + }, + } + }, + wantErr: "", + }, + { + name: "Happy Path Config YAML file with custom Gas Limit", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config.yaml", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: 40000000, + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: false, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + wantErr: "", + }, + { + name: "Happy Path Suggested Fee ", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "", + defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", + }, + }, + want: func() *proposer.Settings { + return &proposer.Settings{ + ProposeConfig: nil, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + }, + } + }, + wantErr: "", + }, + { + name: "Happy Path Suggested Fee , validator registration enabled", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "", + defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", + }, + }, + want: func() *proposer.Settings { + return &proposer.Settings{ + ProposeConfig: nil, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + wantErr: "", + validatorRegistrationEnabled: true, + }, + { + name: "Happy Path Suggested Fee , validator registration enabled and default gas", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "", + defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", + defaultgas: "50000000", + }, + }, + want: func() *proposer.Settings { + return &proposer.Settings{ + ProposeConfig: nil, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: 50000000, + }, + }, + } + }, + wantErr: "", + validatorRegistrationEnabled: true, + }, + { + name: "File with default gas that overrides", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config.yaml", + url: "", + defaultfee: "", + defaultgas: "50000000", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: 50000000, + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: false, + GasLimit: validator.Uint64(50000000), + }, + }, + } + }, + wantErr: "", + }, + { + name: "Suggested Fee does not Override Config", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config.json", + url: "", + defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89B", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + }, + } + }, + wantErr: "", + }, + { + name: "Suggested Fee with validator registration does not Override Config", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config.json", + url: "", + defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89B", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + wantErr: "", + validatorRegistrationEnabled: true, + }, + { + name: "Enable Builder flag overrides empty config", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + validatorRegistrationEnabled: true, + }, + { + name: "Enable Builder flag does override completed builder config", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config.yaml", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(40000000), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + validatorRegistrationEnabled: true, + }, + { + name: "Only Enable Builder flag", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + return &proposer.Settings{ + DefaultConfig: &proposer.Option{ + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + validatorRegistrationEnabled: true, + skipDBSavedCheck: true, + }, + { + name: "No Flags but saved to DB with builder and override removed builder data", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + }, + } + }, + withdb: func(db iface.ValidatorDB) error { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + settings := &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(40000000), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + return db.SaveProposerSettings(context.Background(), settings) + }, + }, + { + name: "Enable builder flag but saved to DB without builder data now includes builder data", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + }, + }, + } + }, + withdb: func(db iface.ValidatorDB) error { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + settings := &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + }, + } + return db.SaveProposerSettings(context.Background(), settings) + }, + validatorRegistrationEnabled: true, + }, + { + name: "No flags, but saved to database", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + return &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + }, + } + }, + withdb: func(db iface.ValidatorDB) error { + key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") + require.NoError(t, err) + settings := &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ + bytesutil.ToBytes48(key1): { + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), + }, + }, + }, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ + FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), + }, + }, + } + return db.SaveProposerSettings(context.Background(), settings) + }, + }, + { + name: "No flags set means empty config", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + return nil + }, + wantErr: "", + skipDBSavedCheck: true, + }, + { + name: "Bad File Path", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/bad-prepare-beacon-proposer-config.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + return nil + }, + wantErr: "failed to unmarshal yaml file", + }, + { + name: "Both URL and Dir flags used resulting in error", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/good-prepare-beacon-proposer-config.json", + url: "./testdata/good-prepare-beacon-proposer-config.json", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + return &proposer.Settings{} + }, + wantInitErr: "cannot specify both", + }, + { + name: "Bad Gas value in JSON", + args: args{ + proposerSettingsFlagValues: &proposerSettingsFlag{ + dir: "./testdata/bad-gas-value-proposer-settings.json", + url: "", + defaultfee: "", + }, + }, + want: func() *proposer.Settings { + return nil + }, + wantErr: "failed to unmarshal yaml file", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + app := cli.App{} + set := flag.NewFlagSet("test", 0) + if tt.args.proposerSettingsFlagValues.dir != "" { + set.String(flags.ProposerSettingsFlag.Name, tt.args.proposerSettingsFlagValues.dir, "") + require.NoError(t, set.Set(flags.ProposerSettingsFlag.Name, tt.args.proposerSettingsFlagValues.dir)) + } + if tt.args.proposerSettingsFlagValues.url != "" { + content, err := os.ReadFile(tt.args.proposerSettingsFlagValues.url) + require.NoError(t, err) + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + w.Header().Set("Content-Type", "application/json") + _, err := fmt.Fprintf(w, "%s", content) + require.NoError(t, err) + })) + defer srv.Close() + + set.String(flags.ProposerSettingsURLFlag.Name, tt.args.proposerSettingsFlagValues.url, "") + require.NoError(t, set.Set(flags.ProposerSettingsURLFlag.Name, srv.URL)) + } + if tt.args.proposerSettingsFlagValues.defaultfee != "" { + set.String(flags.SuggestedFeeRecipientFlag.Name, tt.args.proposerSettingsFlagValues.defaultfee, "") + require.NoError(t, set.Set(flags.SuggestedFeeRecipientFlag.Name, tt.args.proposerSettingsFlagValues.defaultfee)) + } + if tt.args.proposerSettingsFlagValues.defaultgas != "" { + set.String(flags.BuilderGasLimitFlag.Name, tt.args.proposerSettingsFlagValues.defaultgas, "") + require.NoError(t, set.Set(flags.BuilderGasLimitFlag.Name, tt.args.proposerSettingsFlagValues.defaultgas)) + } + if tt.validatorRegistrationEnabled { + set.Bool(flags.EnableBuilderFlag.Name, true, "") + } + cliCtx := cli.NewContext(&app, set, nil) + validatorDB := dbTest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{}) + if tt.withdb != nil { + err := tt.withdb(validatorDB) + require.NoError(t, err) + } + loader, err := NewProposerSettingsLoader( + cliCtx, + validatorDB, + WithBuilderConfig(), + WithGasLimit(), + ) + if tt.wantInitErr != "" { + require.ErrorContains(t, tt.wantInitErr, err) + return + } else { + require.NoError(t, err) + } + got, err := loader.Load(cliCtx) + if tt.wantErr != "" { + require.ErrorContains(t, tt.wantErr, err) + return + } + if tt.wantLog != "" { + assert.LogsContain(t, hook, + tt.wantLog, + ) + } + w := tt.want() + require.DeepEqual(t, w, got) + if !tt.skipDBSavedCheck { + dbSettings, err := validatorDB.ProposerSettings(cliCtx.Context) + require.NoError(t, err) + require.DeepEqual(t, w, dbSettings) + } + }) + } +} + +func Test_ProposerSettingsLoaderWithOnlyBuilder_DoesNotSaveInDB(t *testing.T) { + app := cli.App{} + set := flag.NewFlagSet("test", 0) + set.Bool(flags.EnableBuilderFlag.Name, true, "") + cliCtx := cli.NewContext(&app, set, nil) + validatorDB := dbTest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{}) + loader, err := NewProposerSettingsLoader( + cliCtx, + validatorDB, + WithBuilderConfig(), + WithGasLimit(), + ) + require.NoError(t, err) + got, err := loader.Load(cliCtx) + require.NoError(t, err) + _, err = validatorDB.ProposerSettings(cliCtx.Context) + require.ErrorContains(t, "no proposer settings found in bucket", err) + want := &proposer.Settings{ + DefaultConfig: &proposer.Option{ + BuilderConfig: &proposer.BuilderConfig{ + Enabled: true, + GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), + Relays: nil, + }, + }, + } + require.DeepEqual(t, want, got) +} diff --git a/validator/node/testdata/bad-gas-value-proposer-settings.json b/config/proposer/loader/testdata/bad-gas-value-proposer-settings.json similarity index 100% rename from validator/node/testdata/bad-gas-value-proposer-settings.json rename to config/proposer/loader/testdata/bad-gas-value-proposer-settings.json diff --git a/validator/node/testdata/bad-prepare-beacon-proposer-config.json b/config/proposer/loader/testdata/bad-prepare-beacon-proposer-config.json similarity index 100% rename from validator/node/testdata/bad-prepare-beacon-proposer-config.json rename to config/proposer/loader/testdata/bad-prepare-beacon-proposer-config.json diff --git a/validator/node/testdata/default-only-proposer-config.json b/config/proposer/loader/testdata/default-only-proposer-config.json similarity index 83% rename from validator/node/testdata/default-only-proposer-config.json rename to config/proposer/loader/testdata/default-only-proposer-config.json index a54eb32f5..666efc2dd 100644 --- a/validator/node/testdata/default-only-proposer-config.json +++ b/config/proposer/loader/testdata/default-only-proposer-config.json @@ -1,5 +1,4 @@ { - "proposer_config": {}, "default_config": { "fee_recipient": "0xAe967917c465db8578ca9024c205720b1a3651A9", "builder": {"enabled": true} diff --git a/config/proposer/loader/testdata/empty.json b/config/proposer/loader/testdata/empty.json new file mode 100644 index 000000000..0db3279e4 --- /dev/null +++ b/config/proposer/loader/testdata/empty.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/validator/node/testdata/good-prepare-beacon-proposer-config-badchecksum.json b/config/proposer/loader/testdata/good-prepare-beacon-proposer-config-badchecksum.json similarity index 100% rename from validator/node/testdata/good-prepare-beacon-proposer-config-badchecksum.json rename to config/proposer/loader/testdata/good-prepare-beacon-proposer-config-badchecksum.json diff --git a/validator/node/testdata/good-prepare-beacon-proposer-config-multiple.json b/config/proposer/loader/testdata/good-prepare-beacon-proposer-config-multiple.json similarity index 100% rename from validator/node/testdata/good-prepare-beacon-proposer-config-multiple.json rename to config/proposer/loader/testdata/good-prepare-beacon-proposer-config-multiple.json diff --git a/validator/node/testdata/good-prepare-beacon-proposer-config.json b/config/proposer/loader/testdata/good-prepare-beacon-proposer-config.json similarity index 100% rename from validator/node/testdata/good-prepare-beacon-proposer-config.json rename to config/proposer/loader/testdata/good-prepare-beacon-proposer-config.json diff --git a/validator/node/testdata/good-prepare-beacon-proposer-config.yaml b/config/proposer/loader/testdata/good-prepare-beacon-proposer-config.yaml similarity index 100% rename from validator/node/testdata/good-prepare-beacon-proposer-config.yaml rename to config/proposer/loader/testdata/good-prepare-beacon-proposer-config.yaml diff --git a/config/proposer/loader/testdata/proposer-config-only.json b/config/proposer/loader/testdata/proposer-config-only.json new file mode 100644 index 000000000..5b85bed4a --- /dev/null +++ b/config/proposer/loader/testdata/proposer-config-only.json @@ -0,0 +1,7 @@ +{ + "proposer_config": { + "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a": { + "fee_recipient": "0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3" + } + } +} diff --git a/validator/node/testdata/someotherfile.json b/config/proposer/loader/testdata/someotherfile.json similarity index 100% rename from validator/node/testdata/someotherfile.json rename to config/proposer/loader/testdata/someotherfile.json diff --git a/config/validator/service/proposer_settings.go b/config/proposer/settings.go similarity index 55% rename from config/validator/service/proposer_settings.go rename to config/proposer/settings.go index 12b7569d1..205667255 100644 --- a/config/validator/service/proposer_settings.go +++ b/config/proposer/settings.go @@ -1,4 +1,4 @@ -package validator_service_config +package proposer import ( "fmt" @@ -6,51 +6,77 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/config" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" validatorpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/validator-client" ) -// ToSettings converts struct to ProposerSettings -func ToSettings(ps *validatorpb.ProposerSettingsPayload) (*ProposerSettings, error) { - settings := &ProposerSettings{} - if ps.ProposerConfig != nil { - settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption) +// SettingFromConsensus converts struct to Settings while verifying the fields +func SettingFromConsensus(ps *validatorpb.ProposerSettingsPayload) (*Settings, error) { + settings := &Settings{} + if ps.ProposerConfig != nil && len(ps.ProposerConfig) != 0 { + settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*Option) for key, optionPayload := range ps.ProposerConfig { if optionPayload.FeeRecipient == "" { continue } - b, err := hexutil.Decode(key) + decodedKey, err := hexutil.Decode(key) if err != nil { return nil, errors.Wrap(err, fmt.Sprintf("cannot decode public key %s", key)) } - p := &ProposerOption{ + if len(decodedKey) != fieldparams.BLSPubkeyLength { + return nil, fmt.Errorf("%v is not a bls public key", key) + } + if err := verifyOption(key, optionPayload); err != nil { + return nil, err + } + p := &Option{ FeeRecipientConfig: &FeeRecipientConfig{ FeeRecipient: common.HexToAddress(optionPayload.FeeRecipient), }, } if optionPayload.Builder != nil { - p.BuilderConfig = ToBuilderConfig(optionPayload.Builder) + p.BuilderConfig = BuilderConfigFromConsensus(optionPayload.Builder) } - settings.ProposeConfig[bytesutil.ToBytes48(b)] = p + settings.ProposeConfig[bytesutil.ToBytes48(decodedKey)] = p } } if ps.DefaultConfig != nil { - d := &ProposerOption{} + d := &Option{} if ps.DefaultConfig.FeeRecipient != "" { + if !common.IsHexAddress(ps.DefaultConfig.FeeRecipient) { + return nil, errors.New("default fee recipient is not a valid Ethereum address") + } + if err := config.WarnNonChecksummedAddress(ps.DefaultConfig.FeeRecipient); err != nil { + return nil, err + } d.FeeRecipientConfig = &FeeRecipientConfig{ FeeRecipient: common.HexToAddress(ps.DefaultConfig.FeeRecipient), } } if ps.DefaultConfig.Builder != nil { - d.BuilderConfig = ToBuilderConfig(ps.DefaultConfig.Builder) + d.BuilderConfig = BuilderConfigFromConsensus(ps.DefaultConfig.Builder) } settings.DefaultConfig = d } return settings, nil } +func verifyOption(key string, option *validatorpb.ProposerOptionPayload) error { + if option == nil { + return fmt.Errorf("fee recipient is required for proposer %s", key) + } + if !common.IsHexAddress(option.FeeRecipient) { + return errors.New("fee recipient is not a valid Ethereum address") + } + if err := config.WarnNonChecksummedAddress(option.FeeRecipient); err != nil { + return err + } + return nil +} + // BuilderConfig is the struct representation of the JSON config file set in the validator through the CLI. // GasLimit is a number set to help the network decide on the maximum gas in each block. type BuilderConfig struct { @@ -59,29 +85,28 @@ type BuilderConfig struct { Relays []string `json:"relays,omitempty" yaml:"relays,omitempty"` } -// ToBuilderConfig converts protobuf to a builder config used in inmemory storage -func ToBuilderConfig(from *validatorpb.BuilderConfig) *BuilderConfig { +// BuilderConfigFromConsensus converts protobuf to a builder config used in in-memory storage +func BuilderConfigFromConsensus(from *validatorpb.BuilderConfig) *BuilderConfig { if from == nil { return nil } - config := &BuilderConfig{ + c := &BuilderConfig{ Enabled: from.Enabled, GasLimit: from.GasLimit, } if from.Relays != nil { relays := make([]string, len(from.Relays)) copy(relays, from.Relays) - config.Relays = relays + c.Relays = relays } - - return config + return c } -// ProposerSettings is a Prysm internal representation of the fee recipient config on the validator client. -// validatorpb.ProposerSettingsPayload maps to ProposerSettings on import through the CLI. -type ProposerSettings struct { - ProposeConfig map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption - DefaultConfig *ProposerOption +// Settings is a Prysm internal representation of the fee recipient config on the validator client. +// validatorpb.ProposerSettingsPayload maps to Settings on import through the CLI. +type Settings struct { + ProposeConfig map[[fieldparams.BLSPubkeyLength]byte]*Option + DefaultConfig *Option } // ShouldBeSaved goes through checks to see if the value should be saveable @@ -89,12 +114,12 @@ type ProposerSettings struct { // 1. settings are not nil // 2. proposeconfig is not nil (this defines specific settings for each validator key), default config can be nil in this case and fall back to beacon node settings // 3. defaultconfig is not nil, meaning it has at least fee recipient settings (this defines general settings for all validator keys but keys will use settings from propose config if available), propose config can be nil in this case -func (settings *ProposerSettings) ShouldBeSaved() bool { - return settings != nil && (settings.ProposeConfig != nil || settings.DefaultConfig != nil && settings.DefaultConfig.FeeRecipientConfig != nil) +func (ps *Settings) ShouldBeSaved() bool { + return ps != nil && (ps.ProposeConfig != nil || ps.DefaultConfig != nil && ps.DefaultConfig.FeeRecipientConfig != nil) } -// ToPayload converts struct to ProposerSettingsPayload -func (ps *ProposerSettings) ToPayload() *validatorpb.ProposerSettingsPayload { +// ToConsensus converts struct to ProposerSettingsPayload +func (ps *Settings) ToConsensus() *validatorpb.ProposerSettingsPayload { if ps == nil { return nil } @@ -102,25 +127,11 @@ func (ps *ProposerSettings) ToPayload() *validatorpb.ProposerSettingsPayload { if ps.ProposeConfig != nil { payload.ProposerConfig = make(map[string]*validatorpb.ProposerOptionPayload) for key, option := range ps.ProposeConfig { - p := &validatorpb.ProposerOptionPayload{} - if option.FeeRecipientConfig != nil { - p.FeeRecipient = option.FeeRecipientConfig.FeeRecipient.Hex() - } - if option.BuilderConfig != nil { - p.Builder = option.BuilderConfig.ToPayload() - } - payload.ProposerConfig[hexutil.Encode(key[:])] = p + payload.ProposerConfig[hexutil.Encode(key[:])] = option.ToConsensus() } } if ps.DefaultConfig != nil { - p := &validatorpb.ProposerOptionPayload{} - if ps.DefaultConfig.FeeRecipientConfig != nil { - p.FeeRecipient = ps.DefaultConfig.FeeRecipientConfig.FeeRecipient.Hex() - } - if ps.DefaultConfig.BuilderConfig != nil { - p.Builder = ps.DefaultConfig.BuilderConfig.ToPayload() - } - payload.DefaultConfig = p + payload.DefaultConfig = ps.DefaultConfig.ToConsensus() } return payload } @@ -130,23 +141,52 @@ type FeeRecipientConfig struct { FeeRecipient common.Address } -// ProposerOption is a Prysm internal representation of the ProposerOptionPayload on the validator client in bytes format instead of hex. -type ProposerOption struct { +// Option is a Prysm internal representation of the ProposerOptionPayload on the validator client in bytes format instead of hex. +type Option struct { FeeRecipientConfig *FeeRecipientConfig BuilderConfig *BuilderConfig } +// Clone creates a deep copy of proposer option +func (po *Option) Clone() *Option { + if po == nil { + return nil + } + p := &Option{} + if po.FeeRecipientConfig != nil { + p.FeeRecipientConfig = po.FeeRecipientConfig.Clone() + } + if po.BuilderConfig != nil { + p.BuilderConfig = po.BuilderConfig.Clone() + } + return p +} + +func (po *Option) ToConsensus() *validatorpb.ProposerOptionPayload { + if po == nil { + return nil + } + p := &validatorpb.ProposerOptionPayload{} + if po.FeeRecipientConfig != nil { + p.FeeRecipient = po.FeeRecipientConfig.FeeRecipient.Hex() + } + if po.BuilderConfig != nil { + p.Builder = po.BuilderConfig.ToConsensus() + } + return p +} + // Clone creates a deep copy of the proposer settings -func (ps *ProposerSettings) Clone() *ProposerSettings { +func (ps *Settings) Clone() *Settings { if ps == nil { return nil } - clone := &ProposerSettings{} + clone := &Settings{} if ps.DefaultConfig != nil { clone.DefaultConfig = ps.DefaultConfig.Clone() } if ps.ProposeConfig != nil { - clone.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption) + clone.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*Option) for k, v := range ps.ProposeConfig { keyCopy := k valCopy := v.Clone() @@ -170,46 +210,31 @@ func (bc *BuilderConfig) Clone() *BuilderConfig { if bc == nil { return nil } - config := &BuilderConfig{} - config.Enabled = bc.Enabled - config.GasLimit = bc.GasLimit + c := &BuilderConfig{} + c.Enabled = bc.Enabled + c.GasLimit = bc.GasLimit var relays []string if bc.Relays != nil { relays = make([]string, len(bc.Relays)) copy(relays, bc.Relays) - config.Relays = relays + c.Relays = relays } - return config + return c } -// ToPayload converts Builder Config to the protobuf object -func (bc *BuilderConfig) ToPayload() *validatorpb.BuilderConfig { +// ToConsensus converts Builder Config to the protobuf object +func (bc *BuilderConfig) ToConsensus() *validatorpb.BuilderConfig { if bc == nil { return nil } - config := &validatorpb.BuilderConfig{} - config.Enabled = bc.Enabled + c := &validatorpb.BuilderConfig{} + c.Enabled = bc.Enabled var relays []string if bc.Relays != nil { relays = make([]string, len(bc.Relays)) copy(relays, bc.Relays) - config.Relays = relays + c.Relays = relays } - config.GasLimit = bc.GasLimit - return config -} - -// Clone creates a deep copy of proposer option -func (po *ProposerOption) Clone() *ProposerOption { - if po == nil { - return nil - } - p := &ProposerOption{} - if po.FeeRecipientConfig != nil { - p.FeeRecipientConfig = po.FeeRecipientConfig.Clone() - } - if po.BuilderConfig != nil { - p.BuilderConfig = po.BuilderConfig.Clone() - } - return p + c.GasLimit = bc.GasLimit + return c } diff --git a/config/validator/service/proposer_settings_test.go b/config/proposer/settings_test.go similarity index 88% rename from config/validator/service/proposer_settings_test.go rename to config/proposer/settings_test.go index 1b3a1d101..c550bbd2c 100644 --- a/config/validator/service/proposer_settings_test.go +++ b/config/proposer/settings_test.go @@ -1,4 +1,4 @@ -package validator_service_config +package proposer import ( "testing" @@ -16,8 +16,8 @@ func Test_Proposer_Setting_Cloning(t *testing.T) { key1hex := "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a" key1, err := hexutil.Decode(key1hex) require.NoError(t, err) - settings := &ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption{ + settings := &Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*Option{ bytesutil.ToBytes48(key1): { FeeRecipientConfig: &FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), @@ -29,7 +29,7 @@ func Test_Proposer_Setting_Cloning(t *testing.T) { }, }, }, - DefaultConfig: &ProposerOption{ + DefaultConfig: &Option{ FeeRecipientConfig: &FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), }, @@ -59,15 +59,15 @@ func Test_Proposer_Setting_Cloning(t *testing.T) { require.NotEqual(t, settings.DefaultConfig.BuilderConfig.GasLimit, clone.GasLimit) }) - t.Run("Happy Path ToBuilderConfig", func(t *testing.T) { + t.Run("Happy Path BuilderConfigFromConsensus", func(t *testing.T) { clone := settings.DefaultConfig.BuilderConfig.Clone() - config := ToBuilderConfig(clone.ToPayload()) + config := BuilderConfigFromConsensus(clone.ToConsensus()) require.DeepEqual(t, config.Relays, clone.Relays) require.Equal(t, config.Enabled, clone.Enabled) require.Equal(t, config.GasLimit, clone.GasLimit) }) - t.Run("To Payload and ToSettings", func(t *testing.T) { - payload := settings.ToPayload() + t.Run("To Payload and SettingFromConsensus", func(t *testing.T) { + payload := settings.ToConsensus() option, ok := settings.ProposeConfig[bytesutil.ToBytes48(key1)] require.Equal(t, true, ok) fee := option.FeeRecipientConfig.FeeRecipient.Hex() @@ -77,7 +77,7 @@ func Test_Proposer_Setting_Cloning(t *testing.T) { require.Equal(t, settings.DefaultConfig.FeeRecipientConfig.FeeRecipient.Hex(), payload.DefaultConfig.FeeRecipient) require.Equal(t, settings.DefaultConfig.BuilderConfig.Enabled, payload.DefaultConfig.Builder.Enabled) potion.FeeRecipient = "" - newSettings, err := ToSettings(payload) + newSettings, err := SettingFromConsensus(payload) require.NoError(t, err) // when converting to settings if a fee recipient is empty string then it will be skipped @@ -88,7 +88,7 @@ func Test_Proposer_Setting_Cloning(t *testing.T) { // if fee recipient is set it will not skip potion.FeeRecipient = fee - newSettings, err = ToSettings(payload) + newSettings, err = SettingFromConsensus(payload) require.NoError(t, err) noption, ok = newSettings.ProposeConfig[bytesutil.ToBytes48(key1)] require.Equal(t, true, ok) @@ -104,8 +104,8 @@ func TestProposerSettings_ShouldBeSaved(t *testing.T) { key1, err := hexutil.Decode(key1hex) require.NoError(t, err) type fields struct { - ProposeConfig map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption - DefaultConfig *ProposerOption + ProposeConfig map[[fieldparams.BLSPubkeyLength]byte]*Option + DefaultConfig *Option } tests := []struct { name string @@ -115,7 +115,7 @@ func TestProposerSettings_ShouldBeSaved(t *testing.T) { { name: "Should be saved, proposeconfig populated and no default config", fields: fields{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*Option{ bytesutil.ToBytes48(key1): { FeeRecipientConfig: &FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), @@ -135,7 +135,7 @@ func TestProposerSettings_ShouldBeSaved(t *testing.T) { name: "Should be saved, default populated and no proposeconfig ", fields: fields{ ProposeConfig: nil, - DefaultConfig: &ProposerOption{ + DefaultConfig: &Option{ FeeRecipientConfig: &FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), }, @@ -151,7 +151,7 @@ func TestProposerSettings_ShouldBeSaved(t *testing.T) { { name: "Should be saved, all populated", fields: fields{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*ProposerOption{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*Option{ bytesutil.ToBytes48(key1): { FeeRecipientConfig: &FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), @@ -163,7 +163,7 @@ func TestProposerSettings_ShouldBeSaved(t *testing.T) { }, }, }, - DefaultConfig: &ProposerOption{ + DefaultConfig: &Option{ FeeRecipientConfig: &FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), }, @@ -189,7 +189,7 @@ func TestProposerSettings_ShouldBeSaved(t *testing.T) { name: "Should not be saved, builder data only", fields: fields{ ProposeConfig: nil, - DefaultConfig: &ProposerOption{ + DefaultConfig: &Option{ BuilderConfig: &BuilderConfig{ Enabled: true, GasLimit: validator.Uint64(40000000), @@ -202,7 +202,7 @@ func TestProposerSettings_ShouldBeSaved(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - settings := &ProposerSettings{ + settings := &Settings{ ProposeConfig: tt.fields.ProposeConfig, DefaultConfig: tt.fields.DefaultConfig, } diff --git a/config/util.go b/config/util.go new file mode 100644 index 000000000..6c69aecfe --- /dev/null +++ b/config/util.go @@ -0,0 +1,76 @@ +package config + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path/filepath" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/yaml" +) + +func UnmarshalFromURL(ctx context.Context, from string, to interface{}) error { + u, err := url.ParseRequestURI(from) + if err != nil { + return err + } + if u.Scheme == "" || u.Host == "" { + return fmt.Errorf("invalid URL: %s", from) + } + req, err := http.NewRequestWithContext(ctx, http.MethodGet, from, nil) + if err != nil { + return errors.Wrap(err, "failed to create http request") + } + req.Header.Set("Content-Type", "application/json") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return errors.Wrap(err, "failed to send http request") + } + defer func(Body io.ReadCloser) { + err = Body.Close() + if err != nil { + log.WithError(err).Error("Failed to close response body") + } + }(resp.Body) + if resp.StatusCode != http.StatusOK { + return errors.Errorf("http request to %v failed with status code %d", from, resp.StatusCode) + } + if err := json.NewDecoder(resp.Body).Decode(&to); err != nil { + return errors.Wrap(err, "failed to decode http response") + } + return nil +} + +func UnmarshalFromFile(from string, to interface{}) error { + cleanpath := filepath.Clean(from) + b, err := os.ReadFile(cleanpath) + if err != nil { + return errors.Wrap(err, "failed to open file") + } + + if err := yaml.Unmarshal(b, to); err != nil { + return errors.Wrap(err, "failed to unmarshal yaml file") + } + return nil +} + +func WarnNonChecksummedAddress(feeRecipient string) error { + mixedcaseAddress, err := common.NewMixedcaseAddressFromString(feeRecipient) + if err != nil { + return errors.Wrapf(err, "could not decode fee recipient %s", feeRecipient) + } + if !mixedcaseAddress.ValidChecksum() { + log.Warnf("Fee recipient %s is not a checksum Ethereum address. "+ + "The checksummed address is %s and will be used as the fee recipient. "+ + "We recommend using a mixed-case address (checksum) "+ + "to prevent spelling mistakes in your fee recipient Ethereum address", feeRecipient, mixedcaseAddress.Address().Hex()) + } + return nil +} diff --git a/config/util_test.go b/config/util_test.go new file mode 100644 index 000000000..9cc567a54 --- /dev/null +++ b/config/util_test.go @@ -0,0 +1,61 @@ +package config + +import ( + "context" + "net/http" + "net/http/httptest" + "os" + "strings" + "testing" + + "github.com/prysmaticlabs/prysm/v5/config/params" + "github.com/prysmaticlabs/prysm/v5/testing/assert" + "github.com/prysmaticlabs/prysm/v5/testing/require" + "github.com/sirupsen/logrus/hooks/test" +) + +func TestUnmarshalFromURL_Success(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, err := w.Write([]byte(`{"key":"value"}`)) + require.NoError(t, err) + })) + defer server.Close() + + var result map[string]string + err := UnmarshalFromURL(context.Background(), server.URL, &result) + if err != nil { + t.Errorf("UnmarshalFromURL failed: %v", err) + } + if result["key"] != "value" { + t.Errorf("Expected value to be 'value', got '%s'", result["key"]) + } +} + +func TestUnmarshalFromFile_Success(t *testing.T) { + // Temporarily create a YAML file + tmpFile, err := os.CreateTemp(t.TempDir(), "example.*.yaml") + require.NoError(t, err) + defer require.NoError(t, os.Remove(tmpFile.Name())) // Clean up + + content := []byte("key: value") + + require.NoError(t, os.WriteFile(tmpFile.Name(), content, params.BeaconIoConfig().ReadWritePermissions)) + require.NoError(t, tmpFile.Close()) + + var result map[string]string + require.NoError(t, UnmarshalFromFile(tmpFile.Name(), &result)) + require.Equal(t, result["key"], "value") +} + +func TestWarnNonChecksummedAddress(t *testing.T) { + logHook := test.NewGlobal() + address := "0x967646dCD8d34F4E02204faeDcbAe0cC96fB9245" + err := WarnNonChecksummedAddress(address) + require.NoError(t, err) + assert.LogsDoNotContain(t, logHook, "is not a checksum Ethereum address") + address = strings.ToLower("0x967646dCD8d34F4E02204faeDcbAe0cC96fB9244") + err = WarnNonChecksummedAddress(address) + require.NoError(t, err) + assert.LogsContain(t, logHook, "is not a checksum Ethereum address") +} diff --git a/validator/accounts/testing/BUILD.bazel b/validator/accounts/testing/BUILD.bazel index eb2b15bc4..c5beb1367 100644 --- a/validator/accounts/testing/BUILD.bazel +++ b/validator/accounts/testing/BUILD.bazel @@ -10,7 +10,7 @@ go_library( "//validator:__subpackages__", ], deps = [ - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/primitives:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "//validator/accounts/iface:go_default_library", diff --git a/validator/accounts/testing/mock.go b/validator/accounts/testing/mock.go index 1a591b06a..d1e511611 100644 --- a/validator/accounts/testing/mock.go +++ b/validator/accounts/testing/mock.go @@ -7,7 +7,7 @@ import ( "sync" "time" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/validator/accounts/iface" @@ -89,7 +89,7 @@ func (_ *Wallet) InitializeKeymanager(_ context.Context, _ iface.InitKeymanagerC type Validator struct { Km keymanager.IKeymanager - proposerSettings *validatorserviceconfig.ProposerSettings + proposerSettings *proposer.Settings } func (_ *Validator) LogSubmittedSyncCommitteeMessages() {} @@ -203,12 +203,12 @@ func (_ *Validator) SignValidatorRegistrationRequest(_ context.Context, _ iface2 } // ProposerSettings for mocking -func (m *Validator) ProposerSettings() *validatorserviceconfig.ProposerSettings { +func (m *Validator) ProposerSettings() *proposer.Settings { return m.proposerSettings } // SetProposerSettings for mocking -func (m *Validator) SetProposerSettings(_ context.Context, settings *validatorserviceconfig.ProposerSettings) error { +func (m *Validator) SetProposerSettings(_ context.Context, settings *proposer.Settings) error { m.proposerSettings = settings return nil } diff --git a/validator/client/BUILD.bazel b/validator/client/BUILD.bazel index b1d281754..e1368e7b2 100644 --- a/validator/client/BUILD.bazel +++ b/validator/client/BUILD.bazel @@ -36,7 +36,7 @@ go_library( "//config/features:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/interfaces:go_default_library", "//consensus-types/primitives:go_default_library", @@ -126,7 +126,7 @@ go_test( "//config/features:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/blocks:go_default_library", "//consensus-types/blocks/testing:go_default_library", "//consensus-types/interfaces:go_default_library", diff --git a/validator/client/iface/BUILD.bazel b/validator/client/iface/BUILD.bazel index dea805517..283d7bc4f 100644 --- a/validator/client/iface/BUILD.bazel +++ b/validator/client/iface/BUILD.bazel @@ -13,7 +13,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//config/fieldparams:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/primitives:go_default_library", "//consensus-types/validator:go_default_library", "//crypto/bls:go_default_library", diff --git a/validator/client/iface/validator.go b/validator/client/iface/validator.go index 18ebfb512..b51fb76f0 100644 --- a/validator/client/iface/validator.go +++ b/validator/client/iface/validator.go @@ -6,7 +6,7 @@ import ( "time" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/crypto/bls" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" @@ -62,8 +62,8 @@ type Validator interface { CheckDoppelGanger(ctx context.Context) error PushProposerSettings(ctx context.Context, km keymanager.IKeymanager, slot primitives.Slot, deadline time.Time) error SignValidatorRegistrationRequest(ctx context.Context, signer SigningFunc, newValidatorRegistration *ethpb.ValidatorRegistrationV1) (*ethpb.SignedValidatorRegistrationV1, error) - ProposerSettings() *validatorserviceconfig.ProposerSettings - SetProposerSettings(context.Context, *validatorserviceconfig.ProposerSettings) error + ProposerSettings() *proposer.Settings + SetProposerSettings(context.Context, *proposer.Settings) error StartEventStream(ctx context.Context) error EventStreamIsRunning() bool NodeIsHealthy(ctx context.Context) bool diff --git a/validator/client/runner_test.go b/validator/client/runner_test.go index ab61d4cf7..d4faced80 100644 --- a/validator/client/runner_test.go +++ b/validator/client/runner_test.go @@ -11,7 +11,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/async/event" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/testing/assert" "github.com/prysmaticlabs/prysm/v5/testing/require" @@ -225,9 +225,9 @@ func notActive(t *testing.T) [fieldparams.BLSPubkeyLength]byte { func TestUpdateProposerSettingsAt_EpochStart(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}} - err := v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + err := v.SetProposerSettings(context.Background(), &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9"), }, }, @@ -250,9 +250,9 @@ func TestUpdateProposerSettingsAt_EpochStart(t *testing.T) { func TestUpdateProposerSettingsAt_EpochEndOk(t *testing.T) { v := &testutil.FakeValidator{Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}, ProposerSettingWait: time.Duration(params.BeaconConfig().SecondsPerSlot-1) * time.Second} - err := v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + err := v.SetProposerSettings(context.Background(), &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9"), }, }, @@ -279,9 +279,9 @@ func TestUpdateProposerSettings_ContinuesAfterValidatorRegistrationFails(t *test ProposerSettingsErr: errors.Wrap(ErrBuilderValidatorRegistration, errSomeotherError.Error()), Km: &mockKeymanager{accountsChangedFeed: &event.Feed{}}, } - err := v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + err := v.SetProposerSettings(context.Background(), &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9"), }, }, diff --git a/validator/client/service.go b/validator/client/service.go index 2da49d8ea..9c8540c70 100644 --- a/validator/client/service.go +++ b/validator/client/service.go @@ -17,7 +17,7 @@ import ( lruwrpr "github.com/prysmaticlabs/prysm/v5/cache/lru" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" "github.com/prysmaticlabs/prysm/v5/validator/accounts/wallet" @@ -75,7 +75,7 @@ type ValidatorService struct { grpcHeaders []string graffiti []byte Web3SignerConfig *remoteweb3signer.SetupConfig - proposerSettings *validatorserviceconfig.ProposerSettings + proposerSettings *proposer.Settings validatorsRegBatchSize int } @@ -100,7 +100,7 @@ type Config struct { GraffitiFlag string Endpoint string Web3SignerConfig *remoteweb3signer.SetupConfig - ProposerSettings *validatorserviceconfig.ProposerSettings + ProposerSettings *proposer.Settings BeaconApiEndpoint string BeaconApiTimeout time.Duration ValidatorsRegBatchSize int @@ -271,7 +271,7 @@ func (v *ValidatorService) Keymanager() (keymanager.IKeymanager, error) { } // ProposerSettings returns a deep copy of the underlying proposer settings in the validator -func (v *ValidatorService) ProposerSettings() *validatorserviceconfig.ProposerSettings { +func (v *ValidatorService) ProposerSettings() *proposer.Settings { settings := v.validator.ProposerSettings() if settings != nil { return settings.Clone() @@ -280,7 +280,7 @@ func (v *ValidatorService) ProposerSettings() *validatorserviceconfig.ProposerSe } // SetProposerSettings sets the proposer settings on the validator service as well as the underlying validator -func (v *ValidatorService) SetProposerSettings(ctx context.Context, settings *validatorserviceconfig.ProposerSettings) error { +func (v *ValidatorService) SetProposerSettings(ctx context.Context, settings *proposer.Settings) error { // validator service proposer settings is only used for pass through from node -> validator service -> validator. // in memory use of proposer settings happens on validator. v.proposerSettings = settings diff --git a/validator/client/testutil/BUILD.bazel b/validator/client/testutil/BUILD.bazel index 34292bc09..a565abb7a 100644 --- a/validator/client/testutil/BUILD.bazel +++ b/validator/client/testutil/BUILD.bazel @@ -11,7 +11,7 @@ go_library( visibility = ["//validator:__subpackages__"], deps = [ "//config/fieldparams:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", "//proto/prysm/v1alpha1:go_default_library", diff --git a/validator/client/testutil/mock_validator.go b/validator/client/testutil/mock_validator.go index 46c58d682..ce397db98 100644 --- a/validator/client/testutil/mock_validator.go +++ b/validator/client/testutil/mock_validator.go @@ -6,7 +6,7 @@ import ( "time" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" prysmTime "github.com/prysmaticlabs/prysm/v5/time" @@ -52,7 +52,7 @@ type FakeValidator struct { IndexToPubkeyMap map[uint64][fieldparams.BLSPubkeyLength]byte PubkeyToIndexMap map[[fieldparams.BLSPubkeyLength]byte]uint64 PubkeysToStatusesMap map[[fieldparams.BLSPubkeyLength]byte]ethpb.ValidatorStatus - proposerSettings *validatorserviceconfig.ProposerSettings + proposerSettings *proposer.Settings ProposerSettingWait time.Duration Km keymanager.IKeymanager } @@ -276,12 +276,12 @@ func (*FakeValidator) SignValidatorRegistrationRequest(_ context.Context, _ ifac } // ProposerSettings for mocking -func (fv *FakeValidator) ProposerSettings() *validatorserviceconfig.ProposerSettings { +func (fv *FakeValidator) ProposerSettings() *proposer.Settings { return fv.proposerSettings } // SetProposerSettings for mocking -func (fv *FakeValidator) SetProposerSettings(_ context.Context, settings *validatorserviceconfig.ProposerSettings) error { +func (fv *FakeValidator) SetProposerSettings(_ context.Context, settings *proposer.Settings) error { fv.proposerSettings = settings return nil } diff --git a/validator/client/validator.go b/validator/client/validator.go index d298eaf5d..5f60c8a74 100644 --- a/validator/client/validator.go +++ b/validator/client/validator.go @@ -26,7 +26,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/config/features" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/crypto/hash" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" @@ -106,7 +106,7 @@ type validator struct { voteStats voteStats syncCommitteeStats syncCommitteeStats Web3SignerConfig *remoteweb3signer.SetupConfig - proposerSettings *validatorserviceconfig.ProposerSettings + proposerSettings *proposer.Settings walletInitializedChannel chan *wallet.Wallet validatorsRegBatchSize int } @@ -1028,12 +1028,12 @@ func (v *validator) logDuties(slot primitives.Slot, currentEpochDuties []*ethpb. } // ProposerSettings gets the current proposer settings saved in memory validator -func (v *validator) ProposerSettings() *validatorserviceconfig.ProposerSettings { +func (v *validator) ProposerSettings() *proposer.Settings { return v.proposerSettings } // SetProposerSettings sets and saves the passed in proposer settings overriding the in memory one -func (v *validator) SetProposerSettings(ctx context.Context, settings *validatorserviceconfig.ProposerSettings) error { +func (v *validator) SetProposerSettings(ctx context.Context, settings *proposer.Settings) error { if v.db == nil { return errors.New("db is not set") } @@ -1196,6 +1196,10 @@ func (v *validator) buildSignedRegReqs(ctx context.Context, pubkeys [][fieldpara gasLimit := params.BeaconConfig().DefaultBuilderGasLimit enabled := false + if v.ProposerSettings().DefaultConfig != nil && v.ProposerSettings().DefaultConfig.FeeRecipientConfig == nil && v.ProposerSettings().DefaultConfig.BuilderConfig != nil { + log.Warn("Builder is `enabled` in default config but will be ignored because no fee recipient was provided!") + } + if v.ProposerSettings().DefaultConfig != nil && v.ProposerSettings().DefaultConfig.FeeRecipientConfig != nil { defaultConfig := v.ProposerSettings().DefaultConfig feeRecipient = defaultConfig.FeeRecipientConfig.FeeRecipient // Use cli defaultBuilderConfig for fee recipient. diff --git a/validator/client/validator_test.go b/validator/client/validator_test.go index e2692d8a8..906446bdd 100644 --- a/validator/client/validator_test.go +++ b/validator/client/validator_test.go @@ -18,7 +18,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/config/features" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" validatorType "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" "github.com/prysmaticlabs/prysm/v5/crypto/bls" @@ -1415,7 +1415,7 @@ func TestValidator_WaitForKeymanagerInitialization_Interop(t *testing.T) { require.NotNil(t, km) } -func TestValidator_PushProposerSettings(t *testing.T) { +func TestValidator_PushSettings(t *testing.T) { ctrl := gomock.NewController(t) ctx := context.Background() db := dbTest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{}) @@ -1459,7 +1459,7 @@ func TestValidator_PushProposerSettings(t *testing.T) { } err := v.WaitForKeymanagerInitialization(ctx) require.NoError(t, err) - config := make(map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption) + config := make(map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option) km, err := v.Keymanager() require.NoError(t, err) keys, err := km.FetchValidatingPublicKeys(ctx) @@ -1479,22 +1479,22 @@ func TestValidator_PushProposerSettings(t *testing.T) { {FeeRecipient: common.HexToAddress(defaultFeeHex).Bytes(), ValidatorIndex: 2}, }, }).Return(nil, nil) - config[keys[0]] = &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + config[keys[0]] = &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x055Fb65722E7b2455043BFEBf6177F1D2e9738D9"), }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 40000000, }, } - err = v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ + err = v.SetProposerSettings(context.Background(), &proposer.Settings{ ProposeConfig: config, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress(defaultFeeHex), }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 35000000, }, @@ -1541,7 +1541,7 @@ func TestValidator_PushProposerSettings(t *testing.T) { } err := v.WaitForKeymanagerInitialization(ctx) require.NoError(t, err) - config := make(map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption) + config := make(map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option) km, err := v.Keymanager() require.NoError(t, err) keys, err := km.FetchValidatingPublicKeys(ctx) @@ -1561,22 +1561,22 @@ func TestValidator_PushProposerSettings(t *testing.T) { {FeeRecipient: common.HexToAddress(defaultFeeHex).Bytes(), ValidatorIndex: 2}, }, }).Return(nil, nil) - config[keys[0]] = &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + config[keys[0]] = &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x055Fb65722E7b2455043BFEBf6177F1D2e9738D9"), }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 40000000, }, } - err = v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ + err = v.SetProposerSettings(context.Background(), &proposer.Settings{ ProposeConfig: config, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress(defaultFeeHex), }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: false, GasLimit: 35000000, }, @@ -1619,7 +1619,7 @@ func TestValidator_PushProposerSettings(t *testing.T) { } err := v.WaitForKeymanagerInitialization(ctx) require.NoError(t, err) - config := make(map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption) + config := make(map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option) km, err := v.Keymanager() require.NoError(t, err) keys, err := km.FetchValidatingPublicKeys(ctx) @@ -1639,15 +1639,15 @@ func TestValidator_PushProposerSettings(t *testing.T) { {FeeRecipient: common.HexToAddress(defaultFeeHex).Bytes(), ValidatorIndex: 2}, }, }).Return(nil, nil) - config[keys[0]] = &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + config[keys[0]] = &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x055Fb65722E7b2455043BFEBf6177F1D2e9738D9"), }, } - err = v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ + err = v.SetProposerSettings(context.Background(), &proposer.Settings{ ProposeConfig: config, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress(defaultFeeHex), }, }, @@ -1687,13 +1687,13 @@ func TestValidator_PushProposerSettings(t *testing.T) { require.NoError(t, err) keys, err := km.FetchValidatingPublicKeys(ctx) require.NoError(t, err) - err = v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ + err = v.SetProposerSettings(context.Background(), &proposer.Settings{ ProposeConfig: nil, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress(defaultFeeHex), }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: validatorType.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), }, @@ -1748,13 +1748,13 @@ func TestValidator_PushProposerSettings(t *testing.T) { } err := v.WaitForKeymanagerInitialization(ctx) require.NoError(t, err) - err = v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ + err = v.SetProposerSettings(context.Background(), &proposer.Settings{ ProposeConfig: nil, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress(defaultFeeHex), }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 40000000, }, @@ -1812,7 +1812,7 @@ func TestValidator_PushProposerSettings(t *testing.T) { } err := v.WaitForKeymanagerInitialization(ctx) require.NoError(t, err) - config := make(map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption) + config := make(map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option) km, err := v.Keymanager() require.NoError(t, err) keys, err := km.FetchValidatingPublicKeys(ctx) @@ -1830,15 +1830,15 @@ func TestValidator_PushProposerSettings(t *testing.T) { {FeeRecipient: common.HexToAddress("0x0").Bytes(), ValidatorIndex: 1}, }, }).Return(nil, nil) - config[keys[0]] = &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + config[keys[0]] = &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.Address{}, }, } - err = v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ + err = v.SetProposerSettings(context.Background(), &proposer.Settings{ ProposeConfig: config, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress(defaultFeeHex), }, }, @@ -1864,7 +1864,7 @@ func TestValidator_PushProposerSettings(t *testing.T) { } err := v.WaitForKeymanagerInitialization(ctx) require.NoError(t, err) - config := make(map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption) + config := make(map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option) km, err := v.Keymanager() require.NoError(t, err) keys, err := km.FetchValidatingPublicKeys(ctx) @@ -1873,15 +1873,15 @@ func TestValidator_PushProposerSettings(t *testing.T) { gomock.Any(), // ctx ðpb.ValidatorIndexRequest{PublicKey: keys[0][:]}, ).Return(nil, errors.New("could not find validator index for public key")) - config[keys[0]] = &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + config[keys[0]] = &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455043BFEBf6177F1D2e9738D9"), }, } - err = v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ + err = v.SetProposerSettings(context.Background(), &proposer.Settings{ ProposeConfig: config, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress(defaultFeeHex), }, }, @@ -1907,7 +1907,7 @@ func TestValidator_PushProposerSettings(t *testing.T) { } err := v.WaitForKeymanagerInitialization(ctx) require.NoError(t, err) - config := make(map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption) + config := make(map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option) km, err := v.Keymanager() require.NoError(t, err) keys, err := km.FetchValidatingPublicKeys(ctx) @@ -1921,22 +1921,22 @@ func TestValidator_PushProposerSettings(t *testing.T) { PublicKeys: [][]byte{keys[0][:]}, }, nil) - config[keys[0]] = &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + config[keys[0]] = &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.Address{}, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 40000000, }, } - err = v.SetProposerSettings(context.Background(), &validatorserviceconfig.ProposerSettings{ + err = v.SetProposerSettings(context.Background(), &proposer.Settings{ ProposeConfig: config, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress(defaultFeeHex), }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 40000000, }, @@ -2072,26 +2072,26 @@ func TestValidator_buildPrepProposerReqs_WithoutDefaultConfig(t *testing.T) { }, nil) v := validator{ validatorClient: client, - proposerSettings: &validatorserviceconfig.ProposerSettings{ + proposerSettings: &proposer.Settings{ DefaultConfig: nil, - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + ProposeConfig: map[[48]byte]*proposer.Option{ pubkey1: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient1, }, }, pubkey2: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient2, }, }, pubkey3: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient3, }, }, pubkey4: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient4, }, }, @@ -2215,30 +2215,30 @@ func TestValidator_buildPrepProposerReqs_WithDefaultConfig(t *testing.T) { v := validator{ validatorClient: client, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + proposerSettings: &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: defaultFeeRecipient, }, }, - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ pubkey1: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient1, }, }, pubkey2: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient2, }, }, pubkey3: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient3, }, }, pubkey8: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient8, }, }, @@ -2322,38 +2322,38 @@ func TestValidator_buildSignedRegReqs_DefaultConfigDisabled(t *testing.T) { v := validator{ signedValidatorRegistrations: map[[48]byte]*ethpb.SignedValidatorRegistrationV1{}, validatorClient: client, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + proposerSettings: &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: defaultFeeRecipient, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: false, GasLimit: 9999, }, }, - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + ProposeConfig: map[[48]byte]*proposer.Option{ pubkey1: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient1, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 1111, }, }, pubkey2: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient2, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: false, GasLimit: 2222, }, }, pubkey3: { FeeRecipientConfig: nil, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 3333, }, @@ -2407,38 +2407,38 @@ func TestValidator_buildSignedRegReqs_DefaultConfigEnabled(t *testing.T) { v := validator{ signedValidatorRegistrations: map[[48]byte]*ethpb.SignedValidatorRegistrationV1{}, validatorClient: client, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + proposerSettings: &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: defaultFeeRecipient, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 9999, }, }, - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + ProposeConfig: map[[48]byte]*proposer.Option{ pubkey1: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient1, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 1111, }, }, pubkey2: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient2, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: false, GasLimit: 2222, }, }, pubkey3: { FeeRecipientConfig: nil, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 3333, }, @@ -2485,12 +2485,12 @@ func TestValidator_buildSignedRegReqs_SignerOnError(t *testing.T) { v := validator{ signedValidatorRegistrations: map[[48]byte]*ethpb.SignedValidatorRegistrationV1{}, validatorClient: client, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + proposerSettings: &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: defaultFeeRecipient, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 9999, }, @@ -2529,22 +2529,22 @@ func TestValidator_buildSignedRegReqs_TimestampBeforeGenesis(t *testing.T) { signedValidatorRegistrations: map[[48]byte]*ethpb.SignedValidatorRegistrationV1{}, validatorClient: client, genesisTime: uint64(time.Now().UTC().Unix() + 1000), - proposerSettings: &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + proposerSettings: &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: defaultFeeRecipient, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 9999, }, }, - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + ProposeConfig: map[[48]byte]*proposer.Option{ pubkey1: { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient1, }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 1111, }, diff --git a/validator/db/iface/BUILD.bazel b/validator/db/iface/BUILD.bazel index 82f3ba56b..de1b6c09e 100644 --- a/validator/db/iface/BUILD.bazel +++ b/validator/db/iface/BUILD.bazel @@ -5,10 +5,13 @@ go_library( srcs = ["interface.go"], importpath = "github.com/prysmaticlabs/prysm/v5/validator/db/iface", # Other packages must use github.com/prysmaticlabs/prysm/v5/validator/db.Database alias. - visibility = ["//validator:__subpackages__"], + visibility = [ + "//config:__subpackages__", + "//validator:__subpackages__", + ], deps = [ "//config/fieldparams:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/primitives:go_default_library", "//monitoring/backup:go_default_library", "//proto/prysm/v1alpha1:go_default_library", diff --git a/validator/db/iface/interface.go b/validator/db/iface/interface.go index 13840377c..c8e23ba89 100644 --- a/validator/db/iface/interface.go +++ b/validator/db/iface/interface.go @@ -6,7 +6,7 @@ import ( "io" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - validatorServiceConfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/monitoring/backup" ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" @@ -65,9 +65,7 @@ type ValidatorDB interface { GraffitiOrderedIndex(ctx context.Context, fileHash [32]byte) (uint64, error) // ProposerSettings related methods - ProposerSettings(context.Context) (*validatorServiceConfig.ProposerSettings, error) + ProposerSettings(context.Context) (*proposer.Settings, error) ProposerSettingsExists(ctx context.Context) (bool, error) - UpdateProposerSettingsDefault(context.Context, *validatorServiceConfig.ProposerOption) error - UpdateProposerSettingsForPubkey(context.Context, [fieldparams.BLSPubkeyLength]byte, *validatorServiceConfig.ProposerOption) error - SaveProposerSettings(ctx context.Context, settings *validatorServiceConfig.ProposerSettings) error + SaveProposerSettings(ctx context.Context, settings *proposer.Settings) error } diff --git a/validator/db/kv/BUILD.bazel b/validator/db/kv/BUILD.bazel index 9a340bad8..c893136e3 100644 --- a/validator/db/kv/BUILD.bazel +++ b/validator/db/kv/BUILD.bazel @@ -30,7 +30,7 @@ go_library( "//config/features:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/primitives:go_default_library", "//encoding/bytesutil:go_default_library", "//io/file:go_default_library", @@ -70,7 +70,7 @@ go_test( deps = [ "//config/fieldparams:go_default_library", "//config/params:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/primitives:go_default_library", "//consensus-types/validator:go_default_library", "//crypto/hash:go_default_library", diff --git a/validator/db/kv/proposer_settings.go b/validator/db/kv/proposer_settings.go index b84fc2ed8..6b573dbc2 100644 --- a/validator/db/kv/proposer_settings.go +++ b/validator/db/kv/proposer_settings.go @@ -2,11 +2,9 @@ package kv import ( "context" - "fmt" "github.com/pkg/errors" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - validatorServiceConfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" validatorpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/validator-client" bolt "go.etcd.io/bbolt" "go.opencensus.io/trace" @@ -16,74 +14,9 @@ import ( // ErrNoProposerSettingsFound is an error thrown when no settings are found in bucket var ErrNoProposerSettingsFound = errors.New("no proposer settings found in bucket") -// UpdateProposerSettingsForPubkey updates the existing settings for an internal representation of the proposers settings file at a particular public key -func (s *Store) UpdateProposerSettingsForPubkey(ctx context.Context, pubkey [fieldparams.BLSPubkeyLength]byte, options *validatorServiceConfig.ProposerOption) error { - _, span := trace.StartSpan(ctx, "validator.db.UpdateProposerSettingsForPubkey") - defer span.End() - err := s.db.Update(func(tx *bolt.Tx) error { - bkt := tx.Bucket(proposerSettingsBucket) - b := bkt.Get(proposerSettingsKey) - if len(b) == 0 { - return fmt.Errorf("no proposer settings found in bucket") - } - to := &validatorpb.ProposerSettingsPayload{} - if err := proto.Unmarshal(b, to); err != nil { - return errors.Wrap(err, "failed to unmarshal proposer settings") - } - settings, err := validatorServiceConfig.ToSettings(to) - if err != nil { - return errors.Wrap(err, "failed to convert payload to proposer settings") - } - if settings.ProposeConfig == nil { - settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption) - } - settings.ProposeConfig[pubkey] = options - m, err := proto.Marshal(settings.ToPayload()) - if err != nil { - return errors.Wrap(err, "failed to marshal proposer settings") - } - return bkt.Put(proposerSettingsKey, m) - }) - return err -} - -// UpdateProposerSettingsDefault updates the existing default settings for proposer settings -func (s *Store) UpdateProposerSettingsDefault(ctx context.Context, options *validatorServiceConfig.ProposerOption) error { - _, span := trace.StartSpan(ctx, "validator.db.UpdateProposerSettingsDefault") - defer span.End() - if options == nil { - return errors.New("proposer settings option was empty") - } - if options.FeeRecipientConfig == nil { - return errors.New("fee recipient cannot be empty") - } - err := s.db.Update(func(tx *bolt.Tx) error { - bkt := tx.Bucket(proposerSettingsBucket) - b := bkt.Get(proposerSettingsKey) - if len(b) == 0 { - return ErrNoProposerSettingsFound - } - to := &validatorpb.ProposerSettingsPayload{} - if err := proto.Unmarshal(b, to); err != nil { - return errors.Wrap(err, "failed to unmarshal proposer settings") - } - settings, err := validatorServiceConfig.ToSettings(to) - if err != nil { - return errors.Wrap(err, "failed to convert payload to proposer settings") - } - settings.DefaultConfig = options - m, err := proto.Marshal(settings.ToPayload()) - if err != nil { - return errors.Wrap(err, "failed to marshal proposer settings") - } - return bkt.Put(proposerSettingsKey, m) - }) - return err -} - // ProposerSettings gets the current proposer settings -func (s *Store) ProposerSettings(ctx context.Context) (*validatorServiceConfig.ProposerSettings, error) { - _, span := trace.StartSpan(ctx, "validator.db.ProposerSettings") +func (s *Store) ProposerSettings(ctx context.Context) (*proposer.Settings, error) { + _, span := trace.StartSpan(ctx, "validator.db.Settings") defer span.End() to := &validatorpb.ProposerSettingsPayload{} if err := s.db.View(func(tx *bolt.Tx) error { @@ -99,7 +32,7 @@ func (s *Store) ProposerSettings(ctx context.Context) (*validatorServiceConfig.P }); err != nil { return nil, err } - return validatorServiceConfig.ToSettings(to) + return proposer.SettingFromConsensus(to) } // ProposerSettingsExists returns true or false if the settings exist or not @@ -118,7 +51,7 @@ func (s *Store) ProposerSettingsExists(ctx context.Context) (bool, error) { } // SaveProposerSettings saves the entire proposer setting overriding the existing settings -func (s *Store) SaveProposerSettings(ctx context.Context, settings *validatorServiceConfig.ProposerSettings) error { +func (s *Store) SaveProposerSettings(ctx context.Context, settings *proposer.Settings) error { _, span := trace.StartSpan(ctx, "validator.db.SaveProposerSettings") defer span.End() // nothing to save @@ -128,7 +61,7 @@ func (s *Store) SaveProposerSettings(ctx context.Context, settings *validatorSer } return s.db.Update(func(tx *bolt.Tx) error { bkt := tx.Bucket(proposerSettingsBucket) - m, err := proto.Marshal(settings.ToPayload()) + m, err := proto.Marshal(settings.ToConsensus()) if err != nil { return errors.Wrap(err, "failed to marshal proposer settings") } diff --git a/validator/db/kv/proposer_settings_test.go b/validator/db/kv/proposer_settings_test.go index 846576631..d33a389c7 100644 --- a/validator/db/kv/proposer_settings_test.go +++ b/validator/db/kv/proposer_settings_test.go @@ -8,7 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - validatorServiceConfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/testing/require" @@ -20,23 +20,23 @@ func TestStore_ProposerSettings_ReadAndWrite(t *testing.T) { db := setupDB(t, [][fieldparams.BLSPubkeyLength]byte{}) key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") require.NoError(t, err) - settings := &validatorServiceConfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption{ + settings := &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), }, - BuilderConfig: &validatorServiceConfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: validator.Uint64(40000000), }, }, }, - DefaultConfig: &validatorServiceConfig.ProposerOption{ - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), }, - BuilderConfig: &validatorServiceConfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: false, GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), }, @@ -54,12 +54,12 @@ func TestStore_ProposerSettings_ReadAndWrite(t *testing.T) { db := setupDB(t, [][fieldparams.BLSPubkeyLength]byte{}) key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") require.NoError(t, err) - settings := &validatorServiceConfig.ProposerSettings{ - DefaultConfig: &validatorServiceConfig.ProposerOption{ - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ + settings := &proposer.Settings{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), }, - BuilderConfig: &validatorServiceConfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: false, GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), }, @@ -67,38 +67,41 @@ func TestStore_ProposerSettings_ReadAndWrite(t *testing.T) { } err = db.SaveProposerSettings(ctx, settings) require.NoError(t, err) - upatedDefault := &validatorServiceConfig.ProposerOption{ - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ + updatedDefault := &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x9995733c5af9B61374A128e6F85f553aF09ff89B"), }, - BuilderConfig: &validatorServiceConfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), }, } - err = db.UpdateProposerSettingsDefault(ctx, upatedDefault) + settings.DefaultConfig = updatedDefault + err = db.SaveProposerSettings(ctx, settings) require.NoError(t, err) dbSettings, err := db.ProposerSettings(ctx) require.NoError(t, err) require.NotNil(t, dbSettings) - require.DeepEqual(t, dbSettings.DefaultConfig, upatedDefault) - option := &validatorServiceConfig.ProposerOption{ - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ + require.DeepEqual(t, dbSettings.DefaultConfig, updatedDefault) + option := &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), }, - BuilderConfig: &validatorServiceConfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: validator.Uint64(40000000), }, } - err = db.UpdateProposerSettingsForPubkey(ctx, bytesutil.ToBytes48(key1), option) + + dbSettings.ProposeConfig = map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{bytesutil.ToBytes48(key1): option} + err = db.SaveProposerSettings(ctx, dbSettings) require.NoError(t, err) newSettings, err := db.ProposerSettings(ctx) require.NoError(t, err) require.NotNil(t, newSettings) - require.DeepEqual(t, newSettings.DefaultConfig, upatedDefault) + require.DeepEqual(t, newSettings.DefaultConfig, updatedDefault) op, ok := newSettings.ProposeConfig[bytesutil.ToBytes48(key1)] require.Equal(t, ok, true) require.DeepEqual(t, op, option) diff --git a/validator/db/testing/BUILD.bazel b/validator/db/testing/BUILD.bazel index 8c4332cce..8130c134c 100644 --- a/validator/db/testing/BUILD.bazel +++ b/validator/db/testing/BUILD.bazel @@ -6,6 +6,7 @@ go_library( importpath = "github.com/prysmaticlabs/prysm/v5/validator/db/testing", visibility = [ "//cmd:__subpackages__", + "//config:__subpackages__", "//validator:__subpackages__", ], deps = [ diff --git a/validator/node/BUILD.bazel b/validator/node/BUILD.bazel index 3332d48cd..176b2d5eb 100644 --- a/validator/node/BUILD.bazel +++ b/validator/node/BUILD.bazel @@ -4,27 +4,19 @@ go_test( name = "go_default_test", size = "small", srcs = ["node_test.go"], - data = glob(["testdata/**"]), embed = [":go_default_library"], deps = [ "//cmd:go_default_library", "//cmd/validator/flags:go_default_library", - "//config/fieldparams:go_default_library", - "//config/params:go_default_library", - "//config/validator/service:go_default_library", - "//consensus-types/validator:go_default_library", "//encoding/bytesutil:go_default_library", "//io/file:go_default_library", "//testing/assert:go_default_library", "//testing/require:go_default_library", "//validator/accounts:go_default_library", "//validator/accounts/wallet:go_default_library", - "//validator/db/iface:go_default_library", "//validator/db/kv:go_default_library", - "//validator/db/testing:go_default_library", "//validator/keymanager:go_default_library", "//validator/keymanager/remote-web3signer:go_default_library", - "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_sirupsen_logrus//hooks/test:go_default_library", "@com_github_urfave_cli_v2//:go_default_library", @@ -50,10 +42,9 @@ go_library( "//cmd:go_default_library", "//cmd/validator/flags:go_default_library", "//config/features:go_default_library", - "//config/fieldparams:go_default_library", "//config/params:go_default_library", - "//config/validator/service:go_default_library", - "//consensus-types/validator:go_default_library", + "//config/proposer:go_default_library", + "//config/proposer/loader:go_default_library", "//container/slice:go_default_library", "//encoding/bytesutil:go_default_library", "//io/file:go_default_library", @@ -61,7 +52,6 @@ go_library( "//monitoring/prometheus:go_default_library", "//monitoring/tracing:go_default_library", "//proto/prysm/v1alpha1:go_default_library", - "//proto/prysm/v1alpha1/validator-client:go_default_library", "//runtime:go_default_library", "//runtime/debug:go_default_library", "//runtime/prereqs:go_default_library", @@ -75,7 +65,6 @@ go_library( "//validator/keymanager/remote-web3signer:go_default_library", "//validator/rpc:go_default_library", "//validator/web:go_default_library", - "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", "@com_github_gorilla_mux//:go_default_library", "@com_github_grpc_ecosystem_grpc_gateway_v2//runtime:go_default_library", @@ -83,7 +72,6 @@ go_library( "@com_github_prysmaticlabs_fastssz//:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", "@com_github_urfave_cli_v2//:go_default_library", - "@io_k8s_apimachinery//pkg/util/yaml:go_default_library", "@org_golang_google_protobuf//encoding/protojson:go_default_library", ], ) diff --git a/validator/node/node.go b/validator/node/node.go index 1d15f1f91..2f07dc2fa 100644 --- a/validator/node/node.go +++ b/validator/node/node.go @@ -5,22 +5,18 @@ package node import ( "context" - "encoding/json" "fmt" - "io" "net" "net/http" "net/url" "os" "os/signal" "path/filepath" - "strconv" "strings" "sync" "syscall" "time" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/gorilla/mux" gwruntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" @@ -33,10 +29,9 @@ import ( "github.com/prysmaticlabs/prysm/v5/cmd" "github.com/prysmaticlabs/prysm/v5/cmd/validator/flags" "github.com/prysmaticlabs/prysm/v5/config/features" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - validatorServiceConfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" - "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" + "github.com/prysmaticlabs/prysm/v5/config/proposer" + "github.com/prysmaticlabs/prysm/v5/config/proposer/loader" "github.com/prysmaticlabs/prysm/v5/container/slice" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/io/file" @@ -44,7 +39,6 @@ import ( "github.com/prysmaticlabs/prysm/v5/monitoring/prometheus" tracing2 "github.com/prysmaticlabs/prysm/v5/monitoring/tracing" pb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1" - validatorpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1/validator-client" "github.com/prysmaticlabs/prysm/v5/runtime" "github.com/prysmaticlabs/prysm/v5/runtime/debug" "github.com/prysmaticlabs/prysm/v5/runtime/prereqs" @@ -61,7 +55,6 @@ import ( "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" "google.golang.org/protobuf/encoding/protojson" - "k8s.io/apimachinery/pkg/util/yaml" ) // ValidatorClient defines an instance of an Ethereum validator that manages @@ -469,7 +462,7 @@ func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error { return err } - proposerSettings, err := proposerSettings(c.cliCtx, c.db) + ps, err := proposerSettings(c.cliCtx, c.db) if err != nil { return err } @@ -492,7 +485,7 @@ func (c *ValidatorClient) registerValidatorService(cliCtx *cli.Context) error { WalletInitializedFeed: c.walletInitialized, GraffitiStruct: graffitiStruct, Web3SignerConfig: web3signerConfig, - ProposerSettings: proposerSettings, + ProposerSettings: ps, BeaconApiTimeout: time.Second * 30, BeaconApiEndpoint: c.cliCtx.String(flags.BeaconRESTApiProviderFlag.Name), ValidatorsRegBatchSize: c.cliCtx.Int(flags.ValidatorsRegistrationBatchSizeFlag.Name), @@ -553,234 +546,17 @@ func Web3SignerConfig(cliCtx *cli.Context) (*remoteweb3signer.SetupConfig, error return web3signerConfig, nil } -func proposerSettings(cliCtx *cli.Context, db iface.ValidatorDB) (*validatorServiceConfig.ProposerSettings, error) { - var fileConfig *validatorpb.ProposerSettingsPayload - - if cliCtx.IsSet(flags.ProposerSettingsFlag.Name) && cliCtx.IsSet(flags.ProposerSettingsURLFlag.Name) { - return nil, errors.New("cannot specify both " + flags.ProposerSettingsFlag.Name + " and " + flags.ProposerSettingsURLFlag.Name) - } - builderConfigFromFlag, err := BuilderSettingsFromFlags(cliCtx) +func proposerSettings(cliCtx *cli.Context, db iface.ValidatorDB) (*proposer.Settings, error) { + l, err := loader.NewProposerSettingsLoader( + cliCtx, + db, + loader.WithBuilderConfig(), + loader.WithGasLimit(), + ) if err != nil { return nil, err } - // is overridden by file and URL flags - if cliCtx.IsSet(flags.SuggestedFeeRecipientFlag.Name) && - !cliCtx.IsSet(flags.ProposerSettingsFlag.Name) && - !cliCtx.IsSet(flags.ProposerSettingsURLFlag.Name) { - suggestedFee := cliCtx.String(flags.SuggestedFeeRecipientFlag.Name) - fileConfig = &validatorpb.ProposerSettingsPayload{ - ProposerConfig: nil, - DefaultConfig: &validatorpb.ProposerOptionPayload{ - FeeRecipient: suggestedFee, - Builder: builderConfigFromFlag.ToPayload(), - }, - } - } - - if cliCtx.IsSet(flags.ProposerSettingsFlag.Name) { - if err := unmarshalFromFile(cliCtx.Context, cliCtx.String(flags.ProposerSettingsFlag.Name), &fileConfig); err != nil { - return nil, err - } - } - if cliCtx.IsSet(flags.ProposerSettingsURLFlag.Name) { - if err := unmarshalFromURL(cliCtx.Context, cliCtx.String(flags.ProposerSettingsURLFlag.Name), &fileConfig); err != nil { - return nil, err - } - } - - // this condition triggers if SuggestedFeeRecipientFlag,ProposerSettingsFlag or ProposerSettingsURLFlag did not create any settings - if fileConfig == nil { - // Checks the db or enable builder settings before starting the node without proposer settings - // starting the node without proposer settings, will skip API calls for push proposer settings and register validator - return handleNoProposerSettingsFlagsProvided(cliCtx, db, builderConfigFromFlag) - } - - // convert file config to proposer config for internal use - vpSettings := &validatorServiceConfig.ProposerSettings{} - - // default fileConfig is mandatory - if fileConfig.DefaultConfig == nil { - return nil, errors.New("default fileConfig is required, proposer settings file is either empty or an incorrect format") - } - if !common.IsHexAddress(fileConfig.DefaultConfig.FeeRecipient) { - return nil, errors.New("default fileConfig fee recipient is not a valid eth1 address") - } - psExists, err := db.ProposerSettingsExists(cliCtx.Context) - if err != nil { - return nil, err - } - if err := warnNonChecksummedAddress(fileConfig.DefaultConfig.FeeRecipient); err != nil { - return nil, err - } - vpSettings.DefaultConfig = &validatorServiceConfig.ProposerOption{ - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress(fileConfig.DefaultConfig.FeeRecipient), - }, - BuilderConfig: validatorServiceConfig.ToBuilderConfig(fileConfig.DefaultConfig.Builder), - } - - if builderConfigFromFlag != nil { - config := builderConfigFromFlag.Clone() - if config.GasLimit == validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit) && vpSettings.DefaultConfig.BuilderConfig != nil { - config.GasLimit = vpSettings.DefaultConfig.BuilderConfig.GasLimit - } - vpSettings.DefaultConfig.BuilderConfig = config - } else if vpSettings.DefaultConfig.BuilderConfig != nil { - vpSettings.DefaultConfig.BuilderConfig.GasLimit = reviewGasLimit(vpSettings.DefaultConfig.BuilderConfig.GasLimit) - } - - if psExists { - // if settings exist update the default - if err := db.UpdateProposerSettingsDefault(cliCtx.Context, vpSettings.DefaultConfig); err != nil { - return nil, err - } - } - - if fileConfig.ProposerConfig != nil && len(fileConfig.ProposerConfig) != 0 { - vpSettings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption) - for key, option := range fileConfig.ProposerConfig { - decodedKey, err := hexutil.Decode(key) - if err != nil { - return nil, errors.Wrapf(err, "could not decode public key %s", key) - } - if len(decodedKey) != fieldparams.BLSPubkeyLength { - return nil, fmt.Errorf("%v is not a bls public key", key) - } - if err := verifyOption(key, option); err != nil { - return nil, err - } - currentBuilderConfig := validatorServiceConfig.ToBuilderConfig(option.Builder) - if builderConfigFromFlag != nil { - config := builderConfigFromFlag.Clone() - if config.GasLimit == validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit) && currentBuilderConfig != nil { - config.GasLimit = currentBuilderConfig.GasLimit - } - currentBuilderConfig = config - } else if currentBuilderConfig != nil { - currentBuilderConfig.GasLimit = reviewGasLimit(currentBuilderConfig.GasLimit) - } - o := &validatorServiceConfig.ProposerOption{ - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress(option.FeeRecipient), - }, - BuilderConfig: currentBuilderConfig, - } - pubkeyB := bytesutil.ToBytes48(decodedKey) - vpSettings.ProposeConfig[pubkeyB] = o - } - if psExists { - // override the existing saved settings if providing values via fileConfig.ProposerConfig - if err := db.SaveProposerSettings(cliCtx.Context, vpSettings); err != nil { - return nil, err - } - } - } - if !psExists { - // if no proposer settings ever existed in the db just save the settings - if err := db.SaveProposerSettings(cliCtx.Context, vpSettings); err != nil { - return nil, err - } - } - return vpSettings, nil -} - -func verifyOption(key string, option *validatorpb.ProposerOptionPayload) error { - if option == nil { - return fmt.Errorf("fee recipient is required for proposer %s", key) - } - if !common.IsHexAddress(option.FeeRecipient) { - return errors.New("fee recipient is not a valid eth1 address") - } - if err := warnNonChecksummedAddress(option.FeeRecipient); err != nil { - return err - } - return nil -} - -func handleNoProposerSettingsFlagsProvided(cliCtx *cli.Context, - db iface.ValidatorDB, - builderConfigFromFlag *validatorServiceConfig.BuilderConfig) (*validatorServiceConfig.ProposerSettings, error) { - log.Info("no proposer settings files have been provided, attempting to load from db.") - // checks db if proposer settings exist if none is provided. - settings, err := db.ProposerSettings(cliCtx.Context) - if err == nil { - // process any overrides to builder settings - overrideBuilderSettings(settings, builderConfigFromFlag) - // if settings are empty - log.Info("successfully loaded proposer settings from db.") - return settings, nil - } else { - log.WithError(err).Warn("no proposer settings will be loaded from the db") - } - - if cliCtx.Bool(flags.EnableBuilderFlag.Name) { - // if there are no proposer settings provided, create a default where fee recipient is not populated, this will be skipped for validator registration on validators that don't have a fee recipient set. - // skip saving to DB if only builder settings are provided until a trigger like keymanager API updates with fee recipient values - return &validatorServiceConfig.ProposerSettings{ - DefaultConfig: &validatorServiceConfig.ProposerOption{ - BuilderConfig: builderConfigFromFlag, - }, - }, nil - } - return nil, nil -} - -func overrideBuilderSettings(settings *validatorServiceConfig.ProposerSettings, builderConfigFromFlag *validatorServiceConfig.BuilderConfig) { - // override the db settings with the results based on whether the --enable-builder flag is provided. - if builderConfigFromFlag == nil { - log.Infof("proposer settings loaded from db. validator registration to builder is not enabled, please use the --%s flag if you wish to use a builder.", flags.EnableBuilderFlag.Name) - } - if settings.ProposeConfig != nil { - for key := range settings.ProposeConfig { - settings.ProposeConfig[key].BuilderConfig = builderConfigFromFlag - } - } - if settings.DefaultConfig != nil { - settings.DefaultConfig.BuilderConfig = builderConfigFromFlag - } -} - -func BuilderSettingsFromFlags(cliCtx *cli.Context) (*validatorServiceConfig.BuilderConfig, error) { - if cliCtx.Bool(flags.EnableBuilderFlag.Name) { - gasLimit := validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit) - sgl := cliCtx.String(flags.BuilderGasLimitFlag.Name) - - if sgl != "" { - gl, err := strconv.ParseUint(sgl, 10, 64) - if err != nil { - return nil, errors.New("Gas Limit is not a uint64") - } - gasLimit = reviewGasLimit(validator.Uint64(gl)) - } - return &validatorServiceConfig.BuilderConfig{ - Enabled: true, - GasLimit: gasLimit, - }, nil - } - return nil, nil -} - -func warnNonChecksummedAddress(feeRecipient string) error { - mixedcaseAddress, err := common.NewMixedcaseAddressFromString(feeRecipient) - if err != nil { - return errors.Wrapf(err, "could not decode fee recipient %s", feeRecipient) - } - if !mixedcaseAddress.ValidChecksum() { - log.Warnf("Fee recipient %s is not a checksum Ethereum address. "+ - "The checksummed address is %s and will be used as the fee recipient. "+ - "We recommend using a mixed-case address (checksum) "+ - "to prevent spelling mistakes in your fee recipient Ethereum address", feeRecipient, mixedcaseAddress.Address().Hex()) - } - return nil -} - -func reviewGasLimit(gasLimit validator.Uint64) validator.Uint64 { - // sets gas limit to default if not defined or set to 0 - if gasLimit == 0 { - return validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit) - } - // TODO(10810): add in warning for ranges - return gasLimit + return l.Load(cliCtx) } func (c *ValidatorClient) registerRPCService(router *mux.Router) error { @@ -960,55 +736,6 @@ func clearDB(ctx context.Context, dataDir string, force bool) error { return nil } -func unmarshalFromURL(ctx context.Context, from string, to interface{}) error { - u, err := url.ParseRequestURI(from) - if err != nil { - return err - } - if u.Scheme == "" || u.Host == "" { - return fmt.Errorf("invalid URL: %s", from) - } - req, reqerr := http.NewRequestWithContext(ctx, http.MethodGet, from, nil) - if reqerr != nil { - return errors.Wrap(reqerr, "failed to create http request") - } - req.Header.Set("Content-Type", "application/json") - resp, resperr := http.DefaultClient.Do(req) - if resperr != nil { - return errors.Wrap(resperr, "failed to send http request") - } - defer func(Body io.ReadCloser) { - err = Body.Close() - if err != nil { - log.WithError(err).Error("failed to close response body") - } - }(resp.Body) - if resp.StatusCode != http.StatusOK { - return errors.Errorf("http request to %v failed with status code %d", from, resp.StatusCode) - } - if decodeerr := json.NewDecoder(resp.Body).Decode(&to); decodeerr != nil { - return errors.Wrap(decodeerr, "failed to decode http response") - } - return nil -} - -func unmarshalFromFile(ctx context.Context, from string, to interface{}) error { - if ctx == nil { - return errors.New("node: nil context passed to unmarshalFromFile") - } - cleanpath := filepath.Clean(from) - b, err := os.ReadFile(cleanpath) - if err != nil { - return errors.Wrap(err, "failed to open file") - } - - if err := yaml.Unmarshal(b, to); err != nil { - return errors.Wrap(err, "failed to unmarshal yaml file") - } - - return nil -} - func configureFastSSZHashingAlgorithm() { fastssz.EnableVectorizedHTR = true } diff --git a/validator/node/node_test.go b/validator/node/node_test.go index 98ac738e2..ac7a9c0b0 100644 --- a/validator/node/node_test.go +++ b/validator/node/node_test.go @@ -3,31 +3,21 @@ package node import ( "context" "flag" - "fmt" - "net/http" - "net/http/httptest" "os" "path" "path/filepath" "testing" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/prysmaticlabs/prysm/v5/cmd" "github.com/prysmaticlabs/prysm/v5/cmd/validator/flags" - fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" - "github.com/prysmaticlabs/prysm/v5/config/params" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" - "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" "github.com/prysmaticlabs/prysm/v5/io/file" "github.com/prysmaticlabs/prysm/v5/testing/assert" "github.com/prysmaticlabs/prysm/v5/testing/require" "github.com/prysmaticlabs/prysm/v5/validator/accounts" "github.com/prysmaticlabs/prysm/v5/validator/accounts/wallet" - "github.com/prysmaticlabs/prysm/v5/validator/db/iface" "github.com/prysmaticlabs/prysm/v5/validator/db/kv" - dbTest "github.com/prysmaticlabs/prysm/v5/validator/db/testing" "github.com/prysmaticlabs/prysm/v5/validator/keymanager" remoteweb3signer "github.com/prysmaticlabs/prysm/v5/validator/keymanager/remote-web3signer" logtest "github.com/sirupsen/logrus/hooks/test" @@ -344,722 +334,3 @@ func TestWeb3SignerConfig(t *testing.T) { }) } } - -func TestProposerSettings(t *testing.T) { - hook := logtest.NewGlobal() - - type proposerSettingsFlag struct { - dir string - url string - defaultfee string - defaultgas string - } - - type args struct { - proposerSettingsFlagValues *proposerSettingsFlag - } - tests := []struct { - name string - args args - want func() *validatorserviceconfig.ProposerSettings - urlResponse string - wantErr string - wantLog string - withdb func(db iface.ValidatorDB) error - validatorRegistrationEnabled bool - }{ - { - name: "Happy Path default only proposer settings file with builder settings,", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/default-only-proposer-config.json", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - }, - }, - { - name: "Happy Path Config file File, bad checksum", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/good-prepare-beacon-proposer-config-badchecksum.json", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0xae967917c465db8578ca9024c205720b1a3651A9"), - }, - }, - } - }, - wantErr: "", - wantLog: "is not a checksum Ethereum address", - }, - { - name: "Happy Path Config file File multiple fee recipients", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/good-prepare-beacon-proposer-config-multiple.json", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - key2, err := hexutil.Decode("0xb057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7b") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - bytesutil.ToBytes48(key2): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x60155530FCE8a85ec7055A5F8b2bE214B3DaeFd4"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(35000000), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(40000000), - }, - }, - } - }, - wantErr: "", - }, - { - name: "Happy Path Config URL File", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "./testdata/good-prepare-beacon-proposer-config.json", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - }, - } - }, - wantErr: "", - }, - { - name: "Happy Path Config YAML file with custom Gas Limit", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/good-prepare-beacon-proposer-config.yaml", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: 40000000, - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: false, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - }, - wantErr: "", - }, - { - name: "Happy Path Suggested Fee ", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "", - defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: nil, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - }, - } - }, - wantErr: "", - }, - { - name: "Happy Path Suggested Fee , validator registration enabled", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "", - defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: nil, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - }, - wantErr: "", - validatorRegistrationEnabled: true, - }, - { - name: "Happy Path Suggested Fee , validator registration enabled and default gas", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "", - defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89A", - defaultgas: "50000000", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: nil, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: 50000000, - }, - }, - } - }, - wantErr: "", - validatorRegistrationEnabled: true, - }, - { - name: "Suggested Fee does not Override Config", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/good-prepare-beacon-proposer-config.json", - url: "", - defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89B", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - }, - } - }, - wantErr: "", - }, - { - name: "Suggested Fee with validator registration does not Override Config", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/good-prepare-beacon-proposer-config.json", - url: "", - defaultfee: "0x6e35733c5af9B61374A128e6F85f553aF09ff89B", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - }, - wantErr: "", - validatorRegistrationEnabled: true, - }, - { - name: "Enable Builder flag overrides empty config", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/good-prepare-beacon-proposer-config.json", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - }, - validatorRegistrationEnabled: true, - }, - { - name: "Enable Builder flag does override completed builder config", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/good-prepare-beacon-proposer-config.yaml", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(40000000), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - }, - validatorRegistrationEnabled: true, - }, - { - name: "Only Enable Builder flag", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - }, - validatorRegistrationEnabled: true, - }, - { - name: "No Flags but saved to DB with builder and override removed builder data", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - }, - } - }, - withdb: func(db iface.ValidatorDB) error { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - settings := &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(40000000), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - return db.SaveProposerSettings(context.Background(), settings) - }, - }, - { - name: "Enable builder flag but saved to DB without builder data now includes builder data", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - }, - }, - } - }, - withdb: func(db iface.ValidatorDB) error { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - settings := &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - }, - } - return db.SaveProposerSettings(context.Background(), settings) - }, - validatorRegistrationEnabled: true, - }, - { - name: "No flags, but saved to database", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - return &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - }, - } - }, - withdb: func(db iface.ValidatorDB) error { - key1, err := hexutil.Decode("0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a") - require.NoError(t, err) - settings := &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorserviceconfig.ProposerOption{ - bytesutil.ToBytes48(key1): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3"), - }, - }, - }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ - FeeRecipient: common.HexToAddress("0x6e35733c5af9B61374A128e6F85f553aF09ff89A"), - }, - }, - } - return db.SaveProposerSettings(context.Background(), settings) - }, - }, - { - name: "No flags set means empty config", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return nil - }, - wantErr: "", - }, - { - name: "Bad File Path", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/bad-prepare-beacon-proposer-config.json", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return nil - }, - wantErr: "failed to unmarshal yaml file", - }, - { - name: "Both URL and Dir flags used resulting in error", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/good-prepare-beacon-proposer-config.json", - url: "./testdata/good-prepare-beacon-proposer-config.json", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return &validatorserviceconfig.ProposerSettings{} - }, - wantErr: "cannot specify both", - }, - { - name: "Bad Gas value in JSON", - args: args{ - proposerSettingsFlagValues: &proposerSettingsFlag{ - dir: "./testdata/bad-gas-value-proposer-settings.json", - url: "", - defaultfee: "", - }, - }, - want: func() *validatorserviceconfig.ProposerSettings { - return nil - }, - wantErr: "failed to unmarshal yaml file", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - app := cli.App{} - set := flag.NewFlagSet("test", 0) - if tt.args.proposerSettingsFlagValues.dir != "" { - set.String(flags.ProposerSettingsFlag.Name, tt.args.proposerSettingsFlagValues.dir, "") - require.NoError(t, set.Set(flags.ProposerSettingsFlag.Name, tt.args.proposerSettingsFlagValues.dir)) - } - if tt.args.proposerSettingsFlagValues.url != "" { - content, err := os.ReadFile(tt.args.proposerSettingsFlagValues.url) - require.NoError(t, err) - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(200) - w.Header().Set("Content-Type", "application/json") - _, err := fmt.Fprintf(w, "%s", content) - require.NoError(t, err) - })) - defer srv.Close() - - set.String(flags.ProposerSettingsURLFlag.Name, tt.args.proposerSettingsFlagValues.url, "") - require.NoError(t, set.Set(flags.ProposerSettingsURLFlag.Name, srv.URL)) - } - if tt.args.proposerSettingsFlagValues.defaultfee != "" { - set.String(flags.SuggestedFeeRecipientFlag.Name, tt.args.proposerSettingsFlagValues.defaultfee, "") - require.NoError(t, set.Set(flags.SuggestedFeeRecipientFlag.Name, tt.args.proposerSettingsFlagValues.defaultfee)) - } - if tt.args.proposerSettingsFlagValues.defaultgas != "" { - set.String(flags.BuilderGasLimitFlag.Name, tt.args.proposerSettingsFlagValues.defaultgas, "") - require.NoError(t, set.Set(flags.BuilderGasLimitFlag.Name, tt.args.proposerSettingsFlagValues.defaultgas)) - } - if tt.validatorRegistrationEnabled { - set.Bool(flags.EnableBuilderFlag.Name, true, "") - } - cliCtx := cli.NewContext(&app, set, nil) - validatorDB := dbTest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{}) - if tt.withdb != nil { - err := tt.withdb(validatorDB) - require.NoError(t, err) - } - got, err := proposerSettings(cliCtx, validatorDB) - if tt.wantErr != "" { - require.ErrorContains(t, tt.wantErr, err) - return - } - if tt.wantLog != "" { - assert.LogsContain(t, hook, - tt.wantLog, - ) - } - w := tt.want() - require.DeepEqual(t, w, got) - - }) - } -} - -func Test_ProposerSettingsWithOnlyBuilder_DoesNotSaveInDB(t *testing.T) { - app := cli.App{} - set := flag.NewFlagSet("test", 0) - set.Bool(flags.EnableBuilderFlag.Name, true, "") - cliCtx := cli.NewContext(&app, set, nil) - validatorDB := dbTest.SetupDB(t, [][fieldparams.BLSPubkeyLength]byte{}) - got, err := proposerSettings(cliCtx, validatorDB) - require.NoError(t, err) - _, err = validatorDB.ProposerSettings(cliCtx.Context) - require.ErrorContains(t, "no proposer settings found in bucket", err) - want := &validatorserviceconfig.ProposerSettings{ - DefaultConfig: &validatorserviceconfig.ProposerOption{ - BuilderConfig: &validatorserviceconfig.BuilderConfig{ - Enabled: true, - GasLimit: validator.Uint64(params.BeaconConfig().DefaultBuilderGasLimit), - Relays: nil, - }, - }, - } - require.DeepEqual(t, want, got) -} diff --git a/validator/rpc/BUILD.bazel b/validator/rpc/BUILD.bazel index cd69bec0c..111bef412 100644 --- a/validator/rpc/BUILD.bazel +++ b/validator/rpc/BUILD.bazel @@ -33,7 +33,7 @@ go_library( "//config/features:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/primitives:go_default_library", "//consensus-types/validator:go_default_library", "//crypto/bls:go_default_library", @@ -112,7 +112,7 @@ go_test( "//config/features:go_default_library", "//config/fieldparams:go_default_library", "//config/params:go_default_library", - "//config/validator/service:go_default_library", + "//config/proposer:go_default_library", "//consensus-types/primitives:go_default_library", "//consensus-types/validator:go_default_library", "//crypto/bls:go_default_library", diff --git a/validator/rpc/handlers_keymanager.go b/validator/rpc/handlers_keymanager.go index 998068d77..477409ba8 100644 --- a/validator/rpc/handlers_keymanager.go +++ b/validator/rpc/handlers_keymanager.go @@ -15,7 +15,7 @@ import ( "github.com/prysmaticlabs/prysm/v5/beacon-chain/rpc/eth/shared" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - validatorServiceConfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" @@ -611,10 +611,10 @@ func (s *Server) SetFeeRecipientByPubkey(w http.ResponseWriter, r *http.Request) settings := s.validatorService.ProposerSettings() switch { case settings == nil: - settings = &validatorServiceConfig.ProposerSettings{ - ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption{ + settings = &proposer.Settings{ + ProposeConfig: map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey): { - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient, }, BuilderConfig: nil, @@ -623,13 +623,13 @@ func (s *Server) SetFeeRecipientByPubkey(w http.ResponseWriter, r *http.Request) DefaultConfig: nil, } case settings.ProposeConfig == nil: - var builderConfig *validatorServiceConfig.BuilderConfig + var builderConfig *proposer.BuilderConfig if settings.DefaultConfig != nil && settings.DefaultConfig.BuilderConfig != nil { builderConfig = settings.DefaultConfig.BuilderConfig.Clone() } - settings.ProposeConfig = map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption{ + settings.ProposeConfig = map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey): { - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient, }, BuilderConfig: builderConfig, @@ -638,16 +638,16 @@ func (s *Server) SetFeeRecipientByPubkey(w http.ResponseWriter, r *http.Request) default: proposerOption, found := settings.ProposeConfig[bytesutil.ToBytes48(pubkey)] if found && proposerOption != nil { - proposerOption.FeeRecipientConfig = &validatorServiceConfig.FeeRecipientConfig{ + proposerOption.FeeRecipientConfig = &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient, } } else { - var builderConfig = &validatorServiceConfig.BuilderConfig{} + var builderConfig = &proposer.BuilderConfig{} if settings.DefaultConfig != nil && settings.DefaultConfig.BuilderConfig != nil { builderConfig = settings.DefaultConfig.BuilderConfig.Clone() } - settings.ProposeConfig[bytesutil.ToBytes48(pubkey)] = &validatorServiceConfig.ProposerOption{ - FeeRecipientConfig: &validatorServiceConfig.FeeRecipientConfig{ + settings.ProposeConfig[bytesutil.ToBytes48(pubkey)] = &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: feeRecipient, }, BuilderConfig: builderConfig, @@ -769,7 +769,7 @@ func (s *Server) SetGasLimit(w http.ResponseWriter, r *http.Request) { httputil.HandleError(w, "Gas limit changes only apply when builder is enabled", http.StatusInternalServerError) return } - settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*validatorServiceConfig.ProposerOption) + settings.ProposeConfig = make(map[[fieldparams.BLSPubkeyLength]byte]*proposer.Option) option := settings.DefaultConfig.Clone() option.BuilderConfig.GasLimit = validator.Uint64(gasLimit) settings.ProposeConfig[bytesutil.ToBytes48(pubkey)] = option diff --git a/validator/rpc/handlers_keymanager_test.go b/validator/rpc/handlers_keymanager_test.go index 7aa0d97bd..67ef6fcea 100644 --- a/validator/rpc/handlers_keymanager_test.go +++ b/validator/rpc/handlers_keymanager_test.go @@ -16,7 +16,7 @@ import ( "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams" "github.com/prysmaticlabs/prysm/v5/config/params" - validatorserviceconfig "github.com/prysmaticlabs/prysm/v5/config/validator/service" + "github.com/prysmaticlabs/prysm/v5/config/proposer" "github.com/prysmaticlabs/prysm/v5/consensus-types/primitives" "github.com/prysmaticlabs/prysm/v5/consensus-types/validator" "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" @@ -849,20 +849,20 @@ func TestServer_GetGasLimit(t *testing.T) { tests := []struct { name string - args *validatorserviceconfig.ProposerSettings + args *proposer.Settings pubkey [48]byte want uint64 }{ { name: "ProposerSetting for specific pubkey exists", - args: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + args: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(byteval): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: 123456789}, + BuilderConfig: &proposer.BuilderConfig{GasLimit: 123456789}, }, }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: 987654321}, + DefaultConfig: &proposer.Option{ + BuilderConfig: &proposer.BuilderConfig{GasLimit: 987654321}, }, }, pubkey: bytesutil.ToBytes48(byteval), @@ -870,14 +870,14 @@ func TestServer_GetGasLimit(t *testing.T) { }, { name: "ProposerSetting for specific pubkey does not exist", - args: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + args: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(byteval): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: 123456789}, + BuilderConfig: &proposer.BuilderConfig{GasLimit: 123456789}, }, }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: 987654321}, + DefaultConfig: &proposer.Option{ + BuilderConfig: &proposer.BuilderConfig{GasLimit: 987654321}, }, }, // no settings for the following validator, so the gaslimit returned is the default value. @@ -941,7 +941,7 @@ func TestServer_SetGasLimit(t *testing.T) { name string pubkey []byte newGasLimit uint64 - proposerSettings *validatorserviceconfig.ProposerSettings + proposerSettings *proposer.Settings w []*want beaconReturn *beaconResp wantErr string @@ -957,7 +957,7 @@ func TestServer_SetGasLimit(t *testing.T) { name: "ProposerSettings.ProposeConfig is nil AND ProposerSettings.DefaultConfig is nil", pubkey: pubkey1, newGasLimit: 9999, - proposerSettings: &validatorserviceconfig.ProposerSettings{ + proposerSettings: &proposer.Settings{ ProposeConfig: nil, DefaultConfig: nil, }, @@ -967,9 +967,9 @@ func TestServer_SetGasLimit(t *testing.T) { name: "ProposerSettings.ProposeConfig is nil AND ProposerSettings.DefaultConfig.BuilderConfig is nil", pubkey: pubkey1, newGasLimit: 9999, - proposerSettings: &validatorserviceconfig.ProposerSettings{ + proposerSettings: &proposer.Settings{ ProposeConfig: nil, - DefaultConfig: &validatorserviceconfig.ProposerOption{ + DefaultConfig: &proposer.Option{ BuilderConfig: nil, }, }, @@ -979,8 +979,8 @@ func TestServer_SetGasLimit(t *testing.T) { name: "ProposerSettings.ProposeConfig is defined for pubkey, BuilderConfig is nil AND ProposerSettings.DefaultConfig is nil", pubkey: pubkey1, newGasLimit: 9999, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey1): { BuilderConfig: nil, }, @@ -993,10 +993,10 @@ func TestServer_SetGasLimit(t *testing.T) { name: "ProposerSettings.ProposeConfig is defined for pubkey, BuilderConfig is defined AND ProposerSettings.DefaultConfig is nil", pubkey: pubkey1, newGasLimit: 9999, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey1): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{}, + BuilderConfig: &proposer.BuilderConfig{}, }, }, DefaultConfig: nil, @@ -1007,10 +1007,10 @@ func TestServer_SetGasLimit(t *testing.T) { name: "ProposerSettings.ProposeConfig is NOT defined for pubkey, BuilderConfig is defined AND ProposerSettings.DefaultConfig is nil", pubkey: pubkey2, newGasLimit: 9999, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey2): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, GasLimit: 12345, }, @@ -1028,14 +1028,14 @@ func TestServer_SetGasLimit(t *testing.T) { name: "ProposerSettings.ProposeConfig is defined for pubkey, BuilderConfig is nil AND ProposerSettings.DefaultConfig.BuilderConfig is defined", pubkey: pubkey1, newGasLimit: 9999, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey2): { BuilderConfig: nil, }, }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - BuilderConfig: &validatorserviceconfig.BuilderConfig{ + DefaultConfig: &proposer.Option{ + BuilderConfig: &proposer.BuilderConfig{ Enabled: true, }, }, @@ -1149,24 +1149,24 @@ func TestServer_DeleteGasLimit(t *testing.T) { tests := []struct { name string pubkey []byte - proposerSettings *validatorserviceconfig.ProposerSettings + proposerSettings *proposer.Settings wantError error w []want }{ { name: "delete existing gas limit with default config", pubkey: pubkey1, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey1): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(987654321)}, + BuilderConfig: &proposer.BuilderConfig{GasLimit: validator.Uint64(987654321)}, }, bytesutil.ToBytes48(pubkey2): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(123456789)}, + BuilderConfig: &proposer.BuilderConfig{GasLimit: validator.Uint64(123456789)}, }, }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(5555)}, + DefaultConfig: &proposer.Option{ + BuilderConfig: &proposer.BuilderConfig{GasLimit: validator.Uint64(5555)}, }, }, wantError: nil, @@ -1185,13 +1185,13 @@ func TestServer_DeleteGasLimit(t *testing.T) { { name: "delete existing gas limit with no default config", pubkey: pubkey1, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey1): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(987654321)}, + BuilderConfig: &proposer.BuilderConfig{GasLimit: validator.Uint64(987654321)}, }, bytesutil.ToBytes48(pubkey2): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(123456789)}, + BuilderConfig: &proposer.BuilderConfig{GasLimit: validator.Uint64(123456789)}, }, }, }, @@ -1211,10 +1211,10 @@ func TestServer_DeleteGasLimit(t *testing.T) { { name: "delete nonexist gas limit", pubkey: pubkey2, - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(pubkey1): { - BuilderConfig: &validatorserviceconfig.BuilderConfig{GasLimit: validator.Uint64(987654321)}, + BuilderConfig: &proposer.BuilderConfig{GasLimit: validator.Uint64(987654321)}, }, }, }, @@ -1444,22 +1444,22 @@ func TestServer_ListFeeRecipientByPubkey(t *testing.T) { tests := []struct { name string - args *validatorserviceconfig.ProposerSettings + args *proposer.Settings want *want cached *eth.FeeRecipientByPubKeyResponse }{ { name: "ProposerSettings.ProposeConfig.FeeRecipientConfig defined for pubkey (and ProposerSettings.DefaultConfig.FeeRecipientConfig defined)", - args: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + args: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(byteval): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9"), }, }, }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"), }, }, @@ -1470,10 +1470,10 @@ func TestServer_ListFeeRecipientByPubkey(t *testing.T) { }, { name: "ProposerSettings.ProposeConfig.FeeRecipientConfig NOT defined for pubkey and ProposerSettings.DefaultConfig.FeeRecipientConfig defined", - args: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{}, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + args: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{}, + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9"), }, }, @@ -1576,7 +1576,7 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) { tests := []struct { name string args string - proposerSettings *validatorserviceconfig.ProposerSettings + proposerSettings *proposer.Settings want *want wantErr bool beaconReturn *beaconResp @@ -1597,7 +1597,7 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) { { name: "ProposerSetting.ProposeConfig is nil", args: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", - proposerSettings: &validatorserviceconfig.ProposerSettings{ + proposerSettings: &proposer.Settings{ ProposeConfig: nil, }, want: &want{ @@ -1612,9 +1612,9 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) { { name: "ProposerSetting.ProposeConfig is nil AND ProposerSetting.Defaultconfig is defined", args: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", - proposerSettings: &validatorserviceconfig.ProposerSettings{ + proposerSettings: &proposer.Settings{ ProposeConfig: nil, - DefaultConfig: &validatorserviceconfig.ProposerOption{}, + DefaultConfig: &proposer.Option{}, }, want: &want{ valEthAddress: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", @@ -1628,8 +1628,8 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) { { name: "ProposerSetting.ProposeConfig is defined for pubkey", args: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(byteval): {}, }, }, @@ -1645,8 +1645,8 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) { { name: "ProposerSetting.ProposeConfig not defined for pubkey", args: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{}, + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{}, }, want: &want{ valEthAddress: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", @@ -1660,8 +1660,8 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) { { name: "ProposerSetting.ProposeConfig is nil for pubkey", args: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(byteval): nil, }, }, @@ -1677,11 +1677,11 @@ func TestServer_FeeRecipientByPubkey(t *testing.T) { { name: "ProposerSetting.ProposeConfig is nil for pubkey AND DefaultConfig is not nil", args: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(byteval): nil, }, - DefaultConfig: &validatorserviceconfig.ProposerOption{}, + DefaultConfig: &proposer.Option{}, }, want: &want{ valEthAddress: "0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9", @@ -1777,22 +1777,22 @@ func TestServer_DeleteFeeRecipientByPubkey(t *testing.T) { } tests := []struct { name string - proposerSettings *validatorserviceconfig.ProposerSettings + proposerSettings *proposer.Settings want *want wantErr bool }{ { name: "Happy Path Test", - proposerSettings: &validatorserviceconfig.ProposerSettings{ - ProposeConfig: map[[48]byte]*validatorserviceconfig.ProposerOption{ + proposerSettings: &proposer.Settings{ + ProposeConfig: map[[48]byte]*proposer.Option{ bytesutil.ToBytes48(byteval): { - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x055Fb65722E7b2455012BFEBf6177F1D2e9738D5"), }, }, }, - DefaultConfig: &validatorserviceconfig.ProposerOption{ - FeeRecipientConfig: &validatorserviceconfig.FeeRecipientConfig{ + DefaultConfig: &proposer.Option{ + FeeRecipientConfig: &proposer.FeeRecipientConfig{ FeeRecipient: common.HexToAddress("0x046Fb65722E7b2455012BFEBf6177F1D2e9738D9"), }, },