code.vegaprotocol.io/vega@v0.79.0/core/protocol/upon_genesis.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 protocol
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  	"sort"
    22  
    23  	"code.vegaprotocol.io/vega/core/assets"
    24  	"code.vegaprotocol.io/vega/core/types"
    25  	"code.vegaprotocol.io/vega/logging"
    26  	proto "code.vegaprotocol.io/vega/protos/vega"
    27  
    28  	"github.com/cenkalti/backoff"
    29  	"golang.org/x/exp/maps"
    30  )
    31  
    32  // UponGenesis loads all asset from genesis state.
    33  func (svcs *allServices) UponGenesis(ctx context.Context, rawstate []byte) (err error) {
    34  	svcs.log.Debug("Entering node.NodeCommand.UponGenesis")
    35  	defer func() {
    36  		if err != nil {
    37  			svcs.log.Debug("Failure in node.NodeCommand.UponGenesis", logging.Error(err))
    38  		} else {
    39  			svcs.log.Debug("Leaving node.NodeCommand.UponGenesis without error")
    40  		}
    41  	}()
    42  
    43  	state, err := assets.LoadGenesisState(rawstate)
    44  	if err != nil {
    45  		return err
    46  	}
    47  	if state == nil {
    48  		return nil
    49  	}
    50  
    51  	keys := maps.Keys(state)
    52  	sort.Strings(keys)
    53  	for _, k := range keys {
    54  		err := svcs.loadAsset(ctx, k, state[k])
    55  		if err != nil {
    56  			return err
    57  		}
    58  	}
    59  
    60  	return nil
    61  }
    62  
    63  func (svcs *allServices) loadAsset(ctx context.Context, id string, v *proto.AssetDetails) error {
    64  	rawAsset, err := types.AssetDetailsFromProto(v)
    65  	if err != nil {
    66  		return err
    67  	}
    68  	aid, err := svcs.assets.NewAsset(ctx, id, rawAsset)
    69  	if err != nil {
    70  		return fmt.Errorf("error instanciating asset %v", err)
    71  	}
    72  
    73  	if !rawAsset.Quantum.IsPositive() {
    74  		svcs.log.Panic("invalid asset found - asset quantum must be positive", logging.String("quantum", rawAsset.Quantum.String()))
    75  	}
    76  
    77  	asset, err := svcs.assets.Get(aid)
    78  	if err != nil {
    79  		return fmt.Errorf("unable to get asset %v", err)
    80  	}
    81  
    82  	// the validation is required only for validators
    83  	if svcs.conf.IsValidator() {
    84  		// just a simple backoff here
    85  		err = backoff.Retry(
    86  			func() error {
    87  				return svcs.assets.ValidateAsset(aid)
    88  			},
    89  			backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 5),
    90  		)
    91  		if err != nil {
    92  			return fmt.Errorf("unable to instantiate asset \"%s\": %w", v.Name, err)
    93  		}
    94  	} else {
    95  		svcs.assets.ValidateAssetNonValidator(aid)
    96  	}
    97  
    98  	if err := svcs.assets.Enable(ctx, aid); err != nil {
    99  		svcs.log.Error("invalid genesis asset",
   100  			logging.String("asset-details", v.String()),
   101  			logging.Error(err))
   102  		return fmt.Errorf("unable to enable asset: %v", err)
   103  	}
   104  
   105  	assetD := asset.Type()
   106  	if err := svcs.collateral.EnableAsset(ctx, *assetD); err != nil {
   107  		return fmt.Errorf("unable to enable asset in collateral: %v", err)
   108  	}
   109  
   110  	svcs.log.Info("new asset added successfully",
   111  		logging.String("asset", asset.String()))
   112  
   113  	return nil
   114  }