package kv import ( "context" "fmt" "github.com/pkg/errors" fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams" validatorServiceConfig "github.com/prysmaticlabs/prysm/v4/config/validator/service" validatorpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1/validator-client" bolt "go.etcd.io/bbolt" "go.opencensus.io/trace" "google.golang.org/protobuf/proto" ) // NoProposerSettingsFound is an error thrown when no settings are found in bucket var NoProposerSettingsFound = 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 NoProposerSettingsFound } 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") defer span.End() to := &validatorpb.ProposerSettingsPayload{} if err := s.db.View(func(tx *bolt.Tx) error { bkt := tx.Bucket(proposerSettingsBucket) b := bkt.Get(proposerSettingsKey) if len(b) == 0 { return NoProposerSettingsFound } if err := proto.Unmarshal(b, to); err != nil { return errors.Wrap(err, "failed to unmarshal proposer settings") } return nil }); err != nil { return nil, err } return validatorServiceConfig.ToSettings(to) } // ProposerSettingsExists returns true or false if the settings exist or not func (s *Store) ProposerSettingsExists(ctx context.Context) (bool, error) { ps, err := s.ProposerSettings(ctx) if err != nil { if errors.Is(err, NoProposerSettingsFound) { return false, nil } return false, err } if ps == nil { return false, nil } return true, nil } // SaveProposerSettings saves the entire proposer setting overriding the existing settings func (s *Store) SaveProposerSettings(ctx context.Context, settings *validatorServiceConfig.ProposerSettings) error { _, span := trace.StartSpan(ctx, "validator.db.SaveProposerSettings") defer span.End() // nothing to save if !settings.ShouldBeSaved() { log.Warn("proposer settings are empty, nothing has been saved") return nil } return s.db.Update(func(tx *bolt.Tx) error { bkt := tx.Bucket(proposerSettingsBucket) m, err := proto.Marshal(settings.ToPayload()) if err != nil { return errors.Wrap(err, "failed to marshal proposer settings") } return bkt.Put(proposerSettingsKey, m) }) }