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 }