code.vegaprotocol.io/vega@v0.79.0/core/netparams/netparams.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package netparams
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"fmt"
    22  	"sort"
    23  	"sync"
    24  	"time"
    25  
    26  	"code.vegaprotocol.io/vega/core/events"
    27  	"code.vegaprotocol.io/vega/libs/num"
    28  	"code.vegaprotocol.io/vega/logging"
    29  
    30  	"golang.org/x/exp/maps"
    31  )
    32  
    33  var (
    34  	ErrUnknownKey                        = errors.New("unknown key")
    35  	ErrNetworkParameterUpdateDisabledFor = func(key string) error {
    36  		return fmt.Errorf("network parameter update disabled for %v", key)
    37  	}
    38  	ErrNetworkParameterDeprecated = func(key string) error {
    39  		return fmt.Errorf("network parameter has been deprecated: %v", key)
    40  	}
    41  	// a list of network parameter which cannot be updated.
    42  	updateDisallowed = []string{
    43  		BlockchainsPrimaryEthereumConfig,
    44  		BlockchainsEVMBridgeConfigs,
    45  	}
    46  )
    47  
    48  // Broker - event bus.
    49  type Broker interface {
    50  	Send(e events.Event)
    51  	SendBatch(evts []events.Event)
    52  }
    53  
    54  type Reset interface {
    55  	Reset()
    56  }
    57  
    58  //nolint:interfacebloat
    59  type value interface {
    60  	Validate(value string) error
    61  	Update(value string) error
    62  	UpdateOptionalValidation(value string, validate bool) error
    63  	String() string
    64  	ToDecimal() (num.Decimal, error)
    65  	ToInt() (int64, error)
    66  	ToUint() (*num.Uint, error)
    67  	ToBool() (bool, error)
    68  	ToString() (string, error)
    69  	ToDuration() (time.Duration, error)
    70  	ToJSONStruct(Reset) error
    71  	AddRules(...interface{}) error
    72  	GetDispatch() func(context.Context, interface{}) error
    73  	CheckDispatch(interface{}) error
    74  }
    75  
    76  type WatchParam struct {
    77  	Param string
    78  	// this is to be cast to a function accepting the
    79  	// inner type of the parameters
    80  	// e.g: for a String value, the expected function
    81  	// is to be of the type: func(string) error
    82  	Watcher interface{}
    83  }
    84  
    85  type Store struct {
    86  	log    *logging.Logger
    87  	cfg    Config
    88  	store  map[string]value
    89  	mu     sync.RWMutex
    90  	broker Broker
    91  
    92  	watchers     map[string][]WatchParam
    93  	paramUpdates map[string]struct{}
    94  
    95  	checkpointOverwrites map[string]struct{}
    96  
    97  	state *snapState
    98  
    99  	isProtocolUpgradeRunning bool
   100  }
   101  
   102  func New(log *logging.Logger, cfg Config, broker Broker) *Store {
   103  	log = log.Named(namedLogger)
   104  	log.SetLevel(cfg.Level.Get())
   105  	store := defaultNetParams()
   106  	return &Store{
   107  		log:                  log,
   108  		cfg:                  cfg,
   109  		store:                store,
   110  		broker:               broker,
   111  		watchers:             map[string][]WatchParam{},
   112  		paramUpdates:         map[string]struct{}{},
   113  		checkpointOverwrites: map[string]struct{}{},
   114  		state:                newSnapState(store),
   115  	}
   116  }
   117  
   118  // UponGenesis load the initial network parameters
   119  // from the genesis state.
   120  func (s *Store) UponGenesis(ctx context.Context, rawState []byte) (err error) {
   121  	s.log.Debug("Entering netparams.Store.UponGenesis")
   122  	defer func() {
   123  		if err != nil {
   124  			s.log.Debug("Failure in netparams.Store.UponGenesis", logging.Error(err))
   125  		} else {
   126  			s.log.Debug("Leaving netparams.Store.UponGenesis without error")
   127  		}
   128  	}()
   129  
   130  	state, err := LoadGenesisState(rawState)
   131  	if err != nil {
   132  		s.log.Error("unable to load genesis state",
   133  			logging.Error(err))
   134  		return err
   135  	}
   136  
   137  	evts := make([]events.Event, 0, len(s.store))
   138  	keys := maps.Keys(s.store)
   139  	sort.Strings(keys)
   140  	// first we going to send the initial state through the broker
   141  	for _, k := range keys {
   142  		evts = append(evts, events.NewNetworkParameterEvent(ctx, k, s.store[k].String()))
   143  	}
   144  	s.broker.SendBatch(evts)
   145  
   146  	// now iterate over all parameters and update the existing ones
   147  	keys = maps.Keys(state)
   148  	sort.Strings(keys)
   149  	for _, k := range keys {
   150  		if err := s.UpdateOptionalValidation(ctx, k, state[k], false, true); err != nil {
   151  			return fmt.Errorf("%v: %v", k, err)
   152  		}
   153  	}
   154  
   155  	// now we are going to iterate over ALL the netparams,
   156  	// and run validation, so we will know if any was forgotten,
   157  	// and left to a default which required explicit UponGenesis
   158  	// through the genesis block
   159  	for k := range AllKeys {
   160  		v, err := s.Get(k)
   161  		if err != nil {
   162  			return fmt.Errorf("%v: %v", k, err)
   163  		}
   164  		if err := s.Validate(k, v); err != nil {
   165  			return fmt.Errorf("%v: %v", k, err)
   166  		}
   167  	}
   168  
   169  	// now we can iterate again over ALL the net params,
   170  	// and dispatch the value of them all so any watchers can get updated
   171  	// with genesis values
   172  	keys = maps.Keys(s.store)
   173  	sort.Strings(keys)
   174  	for _, k := range keys {
   175  		if err := s.dispatchUpdate(ctx, k); err != nil {
   176  			return fmt.Errorf("could not propagate netparams update to listener, %v: %v", k, err)
   177  		}
   178  	}
   179  
   180  	overwrites, err := LoadGenesisStateOverwrite(rawState)
   181  	if err != nil {
   182  		s.log.Error("unable to load genesis state overwrites",
   183  			logging.Error(err))
   184  		return err
   185  	}
   186  
   187  	for _, v := range overwrites {
   188  		if _, ok := AllKeys[v]; !ok {
   189  			s.log.Error("unknown network parameter", logging.String("netp", v))
   190  		}
   191  		s.checkpointOverwrites[v] = struct{}{}
   192  	}
   193  
   194  	return nil
   195  }
   196  
   197  // Watch a list of parameters updates.
   198  func (s *Store) Watch(wp ...WatchParam) error {
   199  	for _, v := range wp {
   200  		// type check the function to dispatch updates to
   201  		if err := s.store[v.Param].CheckDispatch(v.Watcher); err != nil {
   202  			return fmt.Errorf("%v: %v", v.Param, err)
   203  		}
   204  		if watchers, ok := s.watchers[v.Param]; ok {
   205  			s.watchers[v.Param] = append(watchers, v)
   206  		} else {
   207  			s.watchers[v.Param] = []WatchParam{v}
   208  		}
   209  	}
   210  	return nil
   211  }
   212  
   213  // dispatch the update of a network parameters to all the listeners.
   214  func (s *Store) dispatchUpdate(ctx context.Context, p string) error {
   215  	val := s.store[p]
   216  	fn := val.GetDispatch()
   217  
   218  	var err error
   219  	for _, v := range s.watchers[p] {
   220  		if newerr := fn(ctx, v.Watcher); newerr != nil {
   221  			if err != nil {
   222  				err = fmt.Errorf("%v, %w", err, newerr)
   223  			} else {
   224  				err = newerr
   225  			}
   226  		}
   227  	}
   228  	return err
   229  }
   230  
   231  func (s *Store) AnyWatchers(p string) bool {
   232  	return len(s.watchers[p]) > 0
   233  }
   234  
   235  // OnTick is trigger once per blocks
   236  // we will send parameters update to watchers.
   237  func (s *Store) OnTick(ctx context.Context, _ time.Time) {
   238  	// This is useful only when a protocol upgrade
   239  	// is running. we will dispatch all new parameter
   240  	// on the first time update here.
   241  	// we propagate all parameters update to compensate
   242  	// for previous release where parameters didn't
   243  	// get propagated.
   244  	if s.isProtocolUpgradeRunning {
   245  		keys := maps.Keys(s.store)
   246  		sort.Strings(keys)
   247  
   248  		for _, k := range keys {
   249  			s.broker.Send(events.NewNetworkParameterEvent(ctx, k, s.store[k].String()))
   250  		}
   251  
   252  		s.isProtocolUpgradeRunning = false
   253  	}
   254  
   255  	if len(s.paramUpdates) <= 0 {
   256  		return
   257  	}
   258  
   259  	// sort for deterministic order of processing.
   260  	params := make([]string, 0, len(s.paramUpdates))
   261  	for k := range s.paramUpdates {
   262  		params = append(params, k)
   263  	}
   264  	sort.Strings(params)
   265  
   266  	for _, k := range params {
   267  		if err := s.dispatchUpdate(ctx, k); err != nil {
   268  			s.log.Debug("unable to dispatch netparams update", logging.Error(err))
   269  		}
   270  	}
   271  	s.paramUpdates = map[string]struct{}{}
   272  }
   273  
   274  func (s *Store) DispatchChanges(ctx context.Context) {
   275  	if len(s.paramUpdates) <= 0 {
   276  		return
   277  	}
   278  	for k := range s.paramUpdates {
   279  		if err := s.dispatchUpdate(ctx, k); err != nil {
   280  			s.log.Debug("unable to dispatch netparams update", logging.Error(err))
   281  		}
   282  	}
   283  	s.paramUpdates = map[string]struct{}{}
   284  }
   285  
   286  // Validate will call validation on the Value stored
   287  // for the given key.
   288  func (s *Store) Validate(key, value string) error {
   289  	s.mu.RLock()
   290  	defer s.mu.RUnlock()
   291  	svalue, ok := s.store[key]
   292  	if !ok {
   293  		return ErrUnknownKey
   294  	}
   295  	if err := svalue.Validate(value); err != nil {
   296  		return fmt.Errorf("unable to validate %s: %w", key, err)
   297  	}
   298  	return nil
   299  }
   300  
   301  // Update will update the stored value for a given key
   302  // will return an error if the value do not pass validation.
   303  func (s *Store) Update(ctx context.Context, key, value string) error {
   304  	return s.UpdateOptionalValidation(ctx, key, value, true, true)
   305  }
   306  
   307  func (s *Store) UpdateOptionalValidation(ctx context.Context, key, value string, validate, failIfUnknown bool) error {
   308  	s.mu.Lock()
   309  	defer s.mu.Unlock()
   310  	svalue, ok := s.store[key]
   311  	if !ok {
   312  		if failIfUnknown {
   313  			return ErrUnknownKey
   314  		}
   315  
   316  		s.log.Warn("unknown network parameter", logging.String("key", key))
   317  		return nil
   318  	}
   319  
   320  	if err := svalue.UpdateOptionalValidation(value, validate); err != nil {
   321  		return fmt.Errorf("unable to update %s: %w", key, err)
   322  	}
   323  
   324  	// update was successful we want to notify watchers
   325  	s.paramUpdates[key] = struct{}{}
   326  	// and also send it to the broker
   327  	s.broker.Send(events.NewNetworkParameterEvent(ctx, key, value))
   328  	s.state.update(key, value)
   329  
   330  	return nil
   331  }
   332  
   333  func (s *Store) updateBatch(ctx context.Context, params map[string]string) error {
   334  	evts := make([]events.Event, 0, len(params))
   335  	s.mu.Lock()
   336  	defer s.mu.Unlock()
   337  	keys := maps.Keys(params)
   338  	sort.Strings(keys)
   339  	for _, k := range keys {
   340  		v := params[k]
   341  		svalue, ok := s.store[k]
   342  		if !ok {
   343  			s.log.Warn("unknown network parameter read from checkpoint", logging.String("param", k))
   344  			continue
   345  		}
   346  		if err := svalue.UpdateOptionalValidation(v, false); err != nil {
   347  			return fmt.Errorf("unable to update %s: %w", k, err)
   348  		}
   349  		s.paramUpdates[k] = struct{}{}
   350  		s.state.update(k, v)
   351  		evts = append(evts, events.NewNetworkParameterEvent(ctx, k, v))
   352  	}
   353  	s.broker.SendBatch(evts)
   354  	return nil
   355  }
   356  
   357  // Exists check if a value exist for the given key.
   358  func (s *Store) Exists(key string) bool {
   359  	s.mu.RLock()
   360  	defer s.mu.RUnlock()
   361  	_, ok := s.store[key]
   362  	return ok
   363  }
   364  
   365  // Get a value associated to the given key.
   366  func (s *Store) Get(key string) (string, error) {
   367  	s.mu.RLock()
   368  	defer s.mu.RUnlock()
   369  	svalue, ok := s.store[key]
   370  	if !ok {
   371  		return "", ErrUnknownKey
   372  	}
   373  	return svalue.String(), nil
   374  }
   375  
   376  // GetDecimal a value associated to the given key.
   377  func (s *Store) GetDecimal(key string) (num.Decimal, error) {
   378  	s.mu.RLock()
   379  	defer s.mu.RUnlock()
   380  	svalue, ok := s.store[key]
   381  	if !ok {
   382  		return num.DecimalZero(), ErrUnknownKey
   383  	}
   384  	return svalue.ToDecimal()
   385  }
   386  
   387  // GetInt a value associated to the given key.
   388  func (s *Store) GetInt(key string) (int64, error) {
   389  	s.mu.RLock()
   390  	defer s.mu.RUnlock()
   391  	svalue, ok := s.store[key]
   392  	if !ok {
   393  		return 0, ErrUnknownKey
   394  	}
   395  	return svalue.ToInt()
   396  }
   397  
   398  // GetUint a value associated to the given key.
   399  func (s *Store) GetUint(key string) (*num.Uint, error) {
   400  	s.mu.RLock()
   401  	defer s.mu.RUnlock()
   402  	svalue, ok := s.store[key]
   403  	if !ok {
   404  		return num.UintZero(), ErrUnknownKey
   405  	}
   406  	v, err := svalue.ToUint()
   407  	if err != nil {
   408  		return num.UintZero(), err
   409  	}
   410  	return v.Clone(), nil
   411  }
   412  
   413  // GetBool a value associated to the given key.
   414  func (s *Store) GetBool(key string) (bool, error) {
   415  	s.mu.RLock()
   416  	defer s.mu.RUnlock()
   417  	svalue, ok := s.store[key]
   418  	if !ok {
   419  		return false, ErrUnknownKey
   420  	}
   421  	return svalue.ToBool()
   422  }
   423  
   424  // GetDuration a value associated to the given key.
   425  func (s *Store) GetDuration(key string) (time.Duration, error) {
   426  	s.mu.RLock()
   427  	defer s.mu.RUnlock()
   428  	svalue, ok := s.store[key]
   429  	if !ok {
   430  		return 0, ErrUnknownKey
   431  	}
   432  	return svalue.ToDuration()
   433  }
   434  
   435  // GetString a value associated to the given key.
   436  func (s *Store) GetString(key string) (string, error) {
   437  	s.mu.RLock()
   438  	defer s.mu.RUnlock()
   439  	svalue, ok := s.store[key]
   440  	if !ok {
   441  		return "", ErrUnknownKey
   442  	}
   443  	return svalue.ToString()
   444  }
   445  
   446  // GetJSONStruct a value associated to the given key.
   447  func (s *Store) GetJSONStruct(key string, v Reset) error {
   448  	s.mu.RLock()
   449  	defer s.mu.RUnlock()
   450  	svalue, ok := s.store[key]
   451  	if !ok {
   452  		return ErrUnknownKey
   453  	}
   454  	return svalue.ToJSONStruct(v)
   455  }
   456  
   457  func (s *Store) AddRules(params ...AddParamRules) error {
   458  	s.mu.RLock()
   459  	defer s.mu.RUnlock()
   460  	for _, v := range params {
   461  		value, ok := s.store[v.Param]
   462  		if !ok {
   463  			return ErrUnknownKey
   464  		}
   465  		if err := value.AddRules(v.Rules...); err != nil {
   466  			return err
   467  		}
   468  	}
   469  	return nil
   470  }
   471  
   472  func (s *Store) IsUpdateAllowed(key string) error {
   473  	s.mu.RLock()
   474  	defer s.mu.RUnlock()
   475  	_, ok := s.store[key]
   476  	if !ok {
   477  		return ErrUnknownKey
   478  	}
   479  
   480  	if _, ok := Deprecated[key]; ok {
   481  		return ErrNetworkParameterDeprecated(key)
   482  	}
   483  
   484  	for _, v := range updateDisallowed {
   485  		if v == key {
   486  			return ErrNetworkParameterUpdateDisabledFor(key)
   487  		}
   488  	}
   489  
   490  	return nil
   491  }
   492  
   493  type AddParamRules struct {
   494  	Param string
   495  	Rules []interface{}
   496  }
   497  
   498  func ParamStringRules(key string, rules ...StringRule) AddParamRules {
   499  	irules := []interface{}{}
   500  	for _, v := range rules {
   501  		irules = append(irules, v)
   502  	}
   503  	return AddParamRules{
   504  		Param: key,
   505  		Rules: irules,
   506  	}
   507  }
   508  
   509  func ParamIntRules(key string, rules ...IntRule) AddParamRules {
   510  	irules := []interface{}{}
   511  	for _, v := range rules {
   512  		irules = append(irules, v)
   513  	}
   514  	return AddParamRules{
   515  		Param: key,
   516  		Rules: irules,
   517  	}
   518  }
   519  
   520  func ParamDurationRules(key string, rules ...DurationRule) AddParamRules {
   521  	irules := []interface{}{}
   522  	for _, v := range rules {
   523  		irules = append(irules, v)
   524  	}
   525  	return AddParamRules{
   526  		Param: key,
   527  		Rules: irules,
   528  	}
   529  }
   530  
   531  func ParamJSONRules(key string, rules ...JSONRule) AddParamRules {
   532  	irules := []interface{}{}
   533  	for _, v := range rules {
   534  		irules = append(irules, v)
   535  	}
   536  	return AddParamRules{
   537  		Param: key,
   538  		Rules: irules,
   539  	}
   540  }