github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/config/network.go (about)

     1  package config
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  
    10  	"github.com/0xPolygon/supernets2-node/etherman"
    11  	"github.com/0xPolygon/supernets2-node/log"
    12  	"github.com/0xPolygon/supernets2-node/merkletree"
    13  	"github.com/0xPolygon/supernets2-node/state"
    14  	"github.com/ethereum/go-ethereum/common"
    15  	"github.com/urfave/cli/v2"
    16  )
    17  
    18  // NetworkConfig is the configuration struct for the different environments
    19  type NetworkConfig struct {
    20  	L1Config                    etherman.L1Config `json:"l1Config"`
    21  	L2GlobalExitRootManagerAddr common.Address
    22  	L2BridgeAddr                common.Address
    23  	Genesis                     state.Genesis
    24  	MaxCumulativeGasUsed        uint64
    25  }
    26  
    27  type network string
    28  
    29  const mainnet network = "mainnet"
    30  const testnet network = "testnet"
    31  const custom network = "custom"
    32  
    33  type genesisFromJSON struct {
    34  	Root            string                   `json:"root"`
    35  	GenesisBlockNum uint64                   `json:"genesisBlockNumber"`
    36  	Genesis         []genesisAccountFromJSON `json:"genesis"`
    37  	L1Config        etherman.L1Config
    38  }
    39  
    40  type genesisAccountFromJSON struct {
    41  	Balance      string            `json:"balance"`
    42  	Nonce        string            `json:"nonce"`
    43  	Address      string            `json:"address"`
    44  	Bytecode     string            `json:"bytecode"`
    45  	Storage      map[string]string `json:"storage"`
    46  	ContractName string            `json:"contractName"`
    47  }
    48  
    49  func (cfg *Config) loadNetworkConfig(ctx *cli.Context) {
    50  	var networkJSON string
    51  	switch ctx.String(FlagNetwork) {
    52  	case string(mainnet):
    53  		networkJSON = MainnetNetworkConfigJSON
    54  	case string(testnet):
    55  		networkJSON = TestnetNetworkConfigJSON
    56  	case string(custom):
    57  		var err error
    58  		networkJSON, err = loadGenesisFileAsString(ctx)
    59  		if err != nil {
    60  			panic(err.Error())
    61  		}
    62  	default:
    63  		panic(fmt.Errorf("unsupported --network value. Must be one of: [%s, %s, %s]", mainnet, testnet, custom))
    64  	}
    65  	config, err := loadGenesisFromJSONString(networkJSON)
    66  	if err != nil {
    67  		panic(fmt.Errorf("failed to load genesis configuration from file. Error: %v", err))
    68  	}
    69  	cfg.NetworkConfig = config
    70  }
    71  
    72  func loadGenesisFileAsString(ctx *cli.Context) (string, error) {
    73  	cfgPath := ctx.String(FlagCustomNetwork)
    74  	if cfgPath != "" {
    75  		f, err := os.Open(cfgPath) //nolint:gosec
    76  		if err != nil {
    77  			return "", err
    78  		}
    79  		defer func() {
    80  			err := f.Close()
    81  			if err != nil {
    82  				log.Error(err)
    83  			}
    84  		}()
    85  
    86  		b, err := io.ReadAll(f)
    87  		if err != nil {
    88  			return "", err
    89  		}
    90  		return string(b), nil
    91  	} else {
    92  		return "", errors.New("custom netwrork file not provided. Please use the custom-network-file flag")
    93  	}
    94  }
    95  
    96  func loadGenesisFromJSONString(jsonStr string) (NetworkConfig, error) {
    97  	var cfg NetworkConfig
    98  
    99  	var cfgJSON genesisFromJSON
   100  	if err := json.Unmarshal([]byte(jsonStr), &cfgJSON); err != nil {
   101  		return NetworkConfig{}, err
   102  	}
   103  
   104  	if len(cfgJSON.Genesis) == 0 {
   105  		return cfg, nil
   106  	}
   107  
   108  	cfg.L1Config = cfgJSON.L1Config
   109  	cfg.Genesis = state.Genesis{
   110  		GenesisBlockNum: cfgJSON.GenesisBlockNum,
   111  		Root:            common.HexToHash(cfgJSON.Root),
   112  		GenesisActions:  []*state.GenesisAction{},
   113  	}
   114  
   115  	const l2GlobalExitRootManagerSCName = "PolygonZkEVMGlobalExitRootL2 proxy"
   116  	const l2BridgeSCName = "PolygonZkEVMBridge proxy"
   117  
   118  	for _, account := range cfgJSON.Genesis {
   119  		if account.ContractName == l2GlobalExitRootManagerSCName {
   120  			cfg.L2GlobalExitRootManagerAddr = common.HexToAddress(account.Address)
   121  		}
   122  		if account.ContractName == l2BridgeSCName {
   123  			cfg.L2BridgeAddr = common.HexToAddress(account.Address)
   124  		}
   125  		if account.Balance != "" && account.Balance != "0" {
   126  			action := &state.GenesisAction{
   127  				Address: account.Address,
   128  				Type:    int(merkletree.LeafTypeBalance),
   129  				Value:   account.Balance,
   130  			}
   131  			cfg.Genesis.GenesisActions = append(cfg.Genesis.GenesisActions, action)
   132  		}
   133  		if account.Nonce != "" && account.Nonce != "0" {
   134  			action := &state.GenesisAction{
   135  				Address: account.Address,
   136  				Type:    int(merkletree.LeafTypeNonce),
   137  				Value:   account.Nonce,
   138  			}
   139  			cfg.Genesis.GenesisActions = append(cfg.Genesis.GenesisActions, action)
   140  		}
   141  		if account.Bytecode != "" {
   142  			action := &state.GenesisAction{
   143  				Address:  account.Address,
   144  				Type:     int(merkletree.LeafTypeCode),
   145  				Bytecode: account.Bytecode,
   146  			}
   147  			cfg.Genesis.GenesisActions = append(cfg.Genesis.GenesisActions, action)
   148  		}
   149  		if len(account.Storage) > 0 {
   150  			for storageKey, storageValue := range account.Storage {
   151  				action := &state.GenesisAction{
   152  					Address:         account.Address,
   153  					Type:            int(merkletree.LeafTypeStorage),
   154  					StoragePosition: storageKey,
   155  					Value:           storageValue,
   156  				}
   157  				cfg.Genesis.GenesisActions = append(cfg.Genesis.GenesisActions, action)
   158  			}
   159  		}
   160  	}
   161  
   162  	return cfg, nil
   163  }