code.vegaprotocol.io/vega@v0.79.0/core/netparams/snapshot.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  	"encoding/json"
    21  	"fmt"
    22  	"sort"
    23  
    24  	"code.vegaprotocol.io/vega/core/types"
    25  	vgcontext "code.vegaprotocol.io/vega/libs/context"
    26  	"code.vegaprotocol.io/vega/libs/proto"
    27  	"code.vegaprotocol.io/vega/logging"
    28  	vegapb "code.vegaprotocol.io/vega/protos/vega"
    29  )
    30  
    31  type snapState struct {
    32  	data  []byte
    33  	pl    *types.NetParams
    34  	index map[string]int
    35  	t     *types.PayloadNetParams
    36  }
    37  
    38  func newSnapState(store map[string]value) *snapState {
    39  	state := &snapState{
    40  		pl:    &types.NetParams{},
    41  		index: make(map[string]int, len(store)),
    42  		t:     &types.PayloadNetParams{},
    43  	}
    44  	// set pointer
    45  	state.t.NetParams = state.pl
    46  	// set the initial state
    47  	state.build(store)
    48  	return state
    49  }
    50  
    51  func (s *snapState) build(store map[string]value) {
    52  	params := make([]*types.NetworkParameter, 0, len(store))
    53  	for k, v := range store {
    54  		params = append(params, &types.NetworkParameter{
    55  			Key:   k,
    56  			Value: v.String(),
    57  		})
    58  	}
    59  	// sort by key
    60  	sort.SliceStable(params, func(i, j int) bool {
    61  		return params[i].Key < params[j].Key
    62  	})
    63  	// build the index
    64  	for i, p := range params {
    65  		s.index[p.Key] = i
    66  	}
    67  	s.pl.Params = params
    68  }
    69  
    70  func (s *snapState) Keys() []string {
    71  	return []string{
    72  		s.t.Key(),
    73  	}
    74  }
    75  
    76  func (s *snapState) Namespace() types.SnapshotNamespace {
    77  	return s.t.Namespace()
    78  }
    79  
    80  func (s *snapState) hashState() error {
    81  	// apparently the payload types can't me marshalled by themselves
    82  	pl := types.Payload{
    83  		Data: s.t,
    84  	}
    85  	data, err := proto.Marshal(pl.IntoProto())
    86  	if err != nil {
    87  		return err
    88  	}
    89  	s.data = data
    90  	return nil
    91  }
    92  
    93  func (s *snapState) GetState(_ string) ([]byte, error) {
    94  	if err := s.hashState(); err != nil {
    95  		return nil, err
    96  	}
    97  	return s.data, nil
    98  }
    99  
   100  func (s *snapState) update(k, v string) {
   101  	i, ok := s.index[k]
   102  	if !ok {
   103  		i = len(s.pl.Params)
   104  		s.pl.Params = append(s.pl.Params, &types.NetworkParameter{
   105  			Key: k,
   106  		})
   107  	}
   108  	s.pl.Params[i].Value = v
   109  }
   110  
   111  // make Store implement/forward the dataprovider interface
   112  
   113  func (s *Store) Namespace() types.SnapshotNamespace {
   114  	return s.state.Namespace()
   115  }
   116  
   117  func (s *Store) Keys() []string {
   118  	return s.state.Keys()
   119  }
   120  
   121  func (s *Store) Stopped() bool {
   122  	return false
   123  }
   124  
   125  func (s *Store) GetState(k string) ([]byte, []types.StateProvider, error) {
   126  	state, err := s.state.GetState(k)
   127  	return state, nil, err
   128  }
   129  
   130  func (s *Store) LoadState(ctx context.Context, pl *types.Payload) ([]types.StateProvider, error) {
   131  	if pl.Namespace() != s.state.Namespace() {
   132  		return nil, types.ErrInvalidSnapshotNamespace
   133  	}
   134  
   135  	s.isProtocolUpgradeRunning = vgcontext.InProgressUpgrade(ctx)
   136  
   137  	np, ok := pl.Data.(*types.PayloadNetParams)
   138  	if !ok {
   139  		return nil, types.ErrInconsistentNamespaceKeys // it's the only possible key/namespace combo here
   140  	}
   141  
   142  	for _, kv := range np.NetParams.Params {
   143  		if err := s.UpdateOptionalValidation(ctx, kv.Key, kv.Value, false, false); err != nil {
   144  			return nil, err
   145  		}
   146  	}
   147  
   148  	if vgcontext.InProgressUpgradeFrom(ctx, "v0.76.8") {
   149  		bridgeConfig := &vegapb.EthereumConfig{}
   150  		if err := s.GetJSONStruct(BlockchainsPrimaryEthereumConfig, bridgeConfig); err != nil {
   151  			s.log.Panic("expected ethereum block chain config", logging.Error(err))
   152  		}
   153  
   154  		// update ethereum config block-time to 12s
   155  		if bridgeConfig.BlockTime == "" {
   156  			bridgeConfig.BlockTime = "12s"
   157  			v, err := json.Marshal(bridgeConfig)
   158  			if err != nil {
   159  				s.log.Panic("unable to update ethereum chain block time", logging.Error(err))
   160  			}
   161  
   162  			if err := s.UpdateOptionalValidation(ctx, BlockchainsPrimaryEthereumConfig, string(v), false, false); err != nil {
   163  				return nil, err
   164  			}
   165  		}
   166  	}
   167  
   168  	// Now they have been loaded, dispatch the changes so that the other engines pick them up
   169  	for k := range s.store {
   170  		if err := s.dispatchUpdate(ctx, k); err != nil {
   171  			return nil, fmt.Errorf("could not propagate netparams update to listener, %v: %v", k, err)
   172  		}
   173  	}
   174  
   175  	var err error
   176  	s.state.data, err = proto.Marshal(pl.IntoProto())
   177  	s.paramUpdates = map[string]struct{}{}
   178  	return nil, err
   179  }