prysm-pulse/config/params/configset.go
terencechain d17996f8b0
Update to V4 🚀 (#12134)
* Update V3 from V4

* Fix build v3 -> v4

* Update ssz

* Update beacon_chain.pb.go

* Fix formatter import

* Update update-mockgen.sh comment to v4

* Fix conflicts. Pass build and tests

* Fix test
2023-03-17 18:52:56 +00:00

172 lines
4.8 KiB
Go

package params
import (
"github.com/pkg/errors"
fieldparams "github.com/prysmaticlabs/prysm/v4/config/fieldparams"
)
var configs *configset
// All returns a slice of every BeaconChainConfig contained in the configset.
func All() []*BeaconChainConfig {
return configs.all()
}
// ByName returns the BeaconChainConfig with the matching `ConfigName` field.
// The runtime ensures that each config name uniquely refers to a single BeaconChainConfig.
func ByName(name string) (*BeaconChainConfig, error) {
return configs.byName(name)
}
// ByVersion returns the BeaconChainConfig that has the given version in its ForkVersionSchedule.
// The configset ensures that each fork version schedule entry uniquely points to a single BeaconChainConfig.
func ByVersion(version [fieldparams.VersionLength]byte) (*BeaconChainConfig, error) {
return configs.byVersion(version)
}
// SetActive sets the given config as active (the config that will be returned by GetActive).
// SetActive will always overwrite any config with the same ConfigName before setting the updated value to active.
func SetActive(c *BeaconChainConfig) error {
return configs.setActive(c)
}
// SetActiveWithUndo attempts to set the active config, and if successful,
// returns a callback function that can be used to revert the configset back to its previous state.
func SetActiveWithUndo(c *BeaconChainConfig) (func() error, error) {
return configs.setActiveWithUndo(c)
}
type configset struct {
active *BeaconChainConfig
versionToName map[[fieldparams.VersionLength]byte]string
nameToConfig map[string]*BeaconChainConfig
}
func newConfigset(configs ...*BeaconChainConfig) *configset {
r := &configset{
versionToName: make(map[[fieldparams.VersionLength]byte]string),
nameToConfig: make(map[string]*BeaconChainConfig),
}
for _, c := range configs {
if err := r.add(c); err != nil {
panic(err)
}
}
return r
}
var errCannotNullifyActive = errors.New("cannot set a config marked as active to nil")
var errCollisionFork = errors.New("configset cannot add config with conflicting fork version schedule")
var errCollisionName = errors.New("config with conflicting name already exists")
var errConfigNotFound = errors.New("unable to find requested BeaconChainConfig")
var errReplaceNilConfig = errors.New("replace called with a nil value")
func (r *configset) add(c *BeaconChainConfig) error {
name := c.ConfigName
if _, exists := r.nameToConfig[name]; exists {
return errors.Wrapf(errCollisionName, "ConfigName=%s", name)
}
c.InitializeForkSchedule()
for v := range c.ForkVersionSchedule {
if n, exists := r.versionToName[v]; exists {
return errors.Wrapf(errCollisionFork, "config name=%s conflicts with existing config named=%s", name, n)
}
r.versionToName[v] = name
}
r.nameToConfig[name] = c
return nil
}
func (r *configset) delete(name string) {
c, exists := r.nameToConfig[name]
if !exists {
return
}
for v := range c.ForkVersionSchedule {
delete(r.versionToName, v)
}
delete(r.nameToConfig, name)
}
func (r *configset) replace(cfg *BeaconChainConfig) error {
if cfg == nil {
return errReplaceNilConfig
}
name := cfg.ConfigName
r.delete(name)
if err := r.add(cfg); err != nil {
return err
}
if r.active != nil && r.active.ConfigName == name {
r.active = cfg
}
return nil
}
func (r *configset) replaceWithUndo(cfg *BeaconChainConfig) (func() error, error) {
name := cfg.ConfigName
prev := r.nameToConfig[name]
if err := r.replace(cfg); err != nil {
return nil, err
}
return func() error {
if prev == nil {
if r.active.ConfigName == name {
return errors.Wrapf(errCannotNullifyActive, "active config name=%s", name)
}
r.delete(name)
return nil
}
return r.replace(prev)
}, nil
}
func (r *configset) getActive() *BeaconChainConfig {
return r.active
}
func (r *configset) setActive(c *BeaconChainConfig) error {
if err := r.replace(c); err != nil {
return err
}
r.active = c
return nil
}
func (r *configset) setActiveWithUndo(c *BeaconChainConfig) (func() error, error) {
active := r.active
r.active = c
undo, err := r.replaceWithUndo(c)
if err != nil {
return nil, err
}
return func() error {
r.active = active
return undo()
}, nil
}
func (r *configset) byName(name string) (*BeaconChainConfig, error) {
c, ok := r.nameToConfig[name]
if !ok {
return nil, errors.Wrapf(errConfigNotFound, "name=%s is not a known BeaconChainConfig name", name)
}
return c, nil
}
func (r *configset) byVersion(version [fieldparams.VersionLength]byte) (*BeaconChainConfig, error) {
name, ok := r.versionToName[version]
if !ok {
return nil, errors.Wrapf(errConfigNotFound, "version=%#x not found in any known fork choice schedule", version)
}
return r.byName(name)
}
func (r *configset) all() []*BeaconChainConfig {
all := make([]*BeaconChainConfig, 0)
for _, c := range r.nameToConfig {
all = append(all, c)
}
return all
}