mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-05 09:14:28 +00:00
d6fb8c29c9
* 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 <rkapka@wp.pl> * Update config/validator/service/proposer_settings.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update validator/client/validator.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update config/validator/service/proposer_settings.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update config/proposer/loader.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update config/proposer/loader.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update config/proposer/loader.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update config/proposer/loader.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update config/proposer/loader.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update config/validator/service/proposer_settings.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * Update config/util.go Co-authored-by: Radosław Kapka <rkapka@wp.pl> * some of the review feedback * more review comments * adding more test coverage * Update config/proposer/loader.go Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com> * Update config/proposer/loader.go Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com> * Update config/proposer/loader.go Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com> * Update config/proposer/loader.go Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com> * 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 <rkapka@wp.pl> Co-authored-by: Manu NALEPA <enalepa@offchainlabs.com>
284 lines
9.3 KiB
Go
284 lines
9.3 KiB
Go
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
|
|
}
|