github.com/ontio/ontology@v1.14.4/vm/evm/params/config.go (about) 1 // Copyright (C) 2021 The Ontology Authors 2 // Copyright 2016 The go-ethereum Authors 3 // This file is part of the go-ethereum library. 4 // 5 // The go-ethereum library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-ethereum library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 17 18 package params 19 20 import ( 21 "fmt" 22 "math/big" 23 24 "github.com/ontio/ontology/common/constants" 25 ) 26 27 func GetChainConfig(chainId uint32) *ChainConfig { 28 return &ChainConfig{ 29 ChainID: big.NewInt(int64(chainId)), 30 HomesteadBlock: big.NewInt(0), 31 DAOForkBlock: nil, 32 DAOForkSupport: true, 33 EIP150Block: big.NewInt(0), 34 EIP155Block: big.NewInt(0), 35 EIP158Block: big.NewInt(0), 36 ByzantiumBlock: big.NewInt(0), 37 ConstantinopleBlock: big.NewInt(0), 38 PetersburgBlock: big.NewInt(0), 39 IstanbulBlock: big.NewInt(0), 40 MuirGlacierBlock: big.NewInt(0), 41 } 42 43 } 44 45 var ( 46 // MainnetChainConfig is the chain parameters to run a node on the main network. 47 MainnetChainConfig = &ChainConfig{ 48 ChainID: big.NewInt(constants.EIP155_CHAINID_MAINNET), 49 HomesteadBlock: big.NewInt(0), 50 DAOForkBlock: nil, 51 DAOForkSupport: true, 52 EIP150Block: big.NewInt(0), 53 EIP155Block: big.NewInt(0), 54 EIP158Block: big.NewInt(0), 55 ByzantiumBlock: big.NewInt(0), 56 ConstantinopleBlock: big.NewInt(0), 57 PetersburgBlock: big.NewInt(0), 58 IstanbulBlock: big.NewInt(0), 59 MuirGlacierBlock: big.NewInt(0), 60 } 61 62 // AllEthashProtocolChanges contains every protocol change (EIPs) introduced 63 // and accepted by the Ethereum core developers into the Ethash consensus. 64 // 65 // This configuration is intentionally not using keyed fields to force anyone 66 // adding flags to the config to also have to set these fields. 67 AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil} 68 69 TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil} 70 TestRules = TestChainConfig.Rules(new(big.Int)) 71 ) 72 73 // ChainConfig is the core config which determines the blockchain settings. 74 // 75 // ChainConfig is stored in the database on a per block basis. This means 76 // that any network, identified by its genesis block, can have its own 77 // set of configuration options. 78 type ChainConfig struct { 79 ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection 80 81 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 82 83 DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) 84 DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork 85 86 // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) 87 EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 88 89 EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block 90 EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block 91 92 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 93 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 94 PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) 95 IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) 96 MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) 97 98 YoloV2Block *big.Int `json:"yoloV2Block,omitempty"` // YOLO v2: Gas repricings TODO @holiman add EIP references 99 } 100 101 // String implements the fmt.Stringer interface. 102 func (c *ChainConfig) String() string { 103 return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, YOLO v2: %v}", 104 c.ChainID, 105 c.HomesteadBlock, 106 c.DAOForkBlock, 107 c.DAOForkSupport, 108 c.EIP150Block, 109 c.EIP155Block, 110 c.EIP158Block, 111 c.ByzantiumBlock, 112 c.ConstantinopleBlock, 113 c.PetersburgBlock, 114 c.IstanbulBlock, 115 c.MuirGlacierBlock, 116 c.YoloV2Block, 117 ) 118 } 119 120 // IsHomestead returns whether num is either equal to the homestead block or greater. 121 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 122 return isForked(c.HomesteadBlock, num) 123 } 124 125 // IsDAOFork returns whether num is either equal to the DAO fork block or greater. 126 func (c *ChainConfig) IsDAOFork(num *big.Int) bool { 127 return isForked(c.DAOForkBlock, num) 128 } 129 130 // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater. 131 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 132 return isForked(c.EIP150Block, num) 133 } 134 135 // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater. 136 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 137 return isForked(c.EIP155Block, num) 138 } 139 140 // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater. 141 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 142 return isForked(c.EIP158Block, num) 143 } 144 145 // IsByzantium returns whether num is either equal to the Byzantium fork block or greater. 146 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 147 return isForked(c.ByzantiumBlock, num) 148 } 149 150 // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. 151 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 152 return isForked(c.ConstantinopleBlock, num) 153 } 154 155 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. 156 func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { 157 return isForked(c.MuirGlacierBlock, num) 158 } 159 160 // IsPetersburg returns whether num is either 161 // - equal to or greater than the PetersburgBlock fork block, 162 // - OR is nil, and Constantinople is active 163 func (c *ChainConfig) IsPetersburg(num *big.Int) bool { 164 return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num) 165 } 166 167 // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater. 168 func (c *ChainConfig) IsIstanbul(num *big.Int) bool { 169 return isForked(c.IstanbulBlock, num) 170 } 171 172 // IsYoloV2 returns whether num is either equal to the YoloV1 fork block or greater. 173 func (c *ChainConfig) IsYoloV2(num *big.Int) bool { 174 return isForked(c.YoloV2Block, num) 175 } 176 177 // CheckCompatible checks whether scheduled fork transitions have been imported 178 // with a mismatching chain configuration. 179 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { 180 bhead := new(big.Int).SetUint64(height) 181 182 // Iterate checkCompatible to find the lowest conflict. 183 var lasterr *ConfigCompatError 184 for { 185 err := c.checkCompatible(newcfg, bhead) 186 if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { 187 break 188 } 189 lasterr = err 190 bhead.SetUint64(err.RewindTo) 191 } 192 return lasterr 193 } 194 195 // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough 196 // to guarantee that forks can be implemented in a different order than on official networks 197 func (c *ChainConfig) CheckConfigForkOrder() error { 198 type fork struct { 199 name string 200 block *big.Int 201 optional bool // if true, the fork may be nil and next fork is still allowed 202 } 203 var lastFork fork 204 for _, cur := range []fork{ 205 {name: "homesteadBlock", block: c.HomesteadBlock}, 206 {name: "daoForkBlock", block: c.DAOForkBlock, optional: true}, 207 {name: "eip150Block", block: c.EIP150Block}, 208 {name: "eip155Block", block: c.EIP155Block}, 209 {name: "eip158Block", block: c.EIP158Block}, 210 {name: "byzantiumBlock", block: c.ByzantiumBlock}, 211 {name: "constantinopleBlock", block: c.ConstantinopleBlock}, 212 {name: "petersburgBlock", block: c.PetersburgBlock}, 213 {name: "istanbulBlock", block: c.IstanbulBlock}, 214 {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, 215 {name: "yoloV2Block", block: c.YoloV2Block}, 216 } { 217 if lastFork.name != "" { 218 // Next one must be higher number 219 if lastFork.block == nil && cur.block != nil { 220 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v", 221 lastFork.name, cur.name, cur.block) 222 } 223 if lastFork.block != nil && cur.block != nil { 224 if lastFork.block.Cmp(cur.block) > 0 { 225 return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v", 226 lastFork.name, lastFork.block, cur.name, cur.block) 227 } 228 } 229 } 230 // If it was optional and not set, then ignore it 231 if !cur.optional || cur.block != nil { 232 lastFork = cur 233 } 234 } 235 return nil 236 } 237 238 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { 239 if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { 240 return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 241 } 242 if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) { 243 return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) 244 } 245 if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport { 246 return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) 247 } 248 if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) { 249 return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 250 } 251 if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) { 252 return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 253 } 254 if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) { 255 return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 256 } 257 if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) { 258 return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 259 } 260 if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { 261 return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 262 } 263 if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { 264 return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 265 } 266 if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) { 267 // the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople 268 // mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set 269 if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, head) { 270 return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock) 271 } 272 } 273 if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) { 274 return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock) 275 } 276 if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) { 277 return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock) 278 } 279 if isForkIncompatible(c.YoloV2Block, newcfg.YoloV2Block, head) { 280 return newCompatError("YOLOv2 fork block", c.YoloV2Block, newcfg.YoloV2Block) 281 } 282 return nil 283 } 284 285 // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to 286 // block s2 because head is already past the fork. 287 func isForkIncompatible(s1, s2, head *big.Int) bool { 288 return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) 289 } 290 291 // isForked returns whether a fork scheduled at block s is active at the given head block. 292 func isForked(s, head *big.Int) bool { 293 if s == nil || head == nil { 294 return false 295 } 296 return s.Cmp(head) <= 0 297 } 298 299 func configNumEqual(x, y *big.Int) bool { 300 if x == nil { 301 return y == nil 302 } 303 if y == nil { 304 return false 305 } 306 return x.Cmp(y) == 0 307 } 308 309 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 310 // ChainConfig that would alter the past. 311 type ConfigCompatError struct { 312 What string 313 // block numbers of the stored and new configurations 314 StoredConfig, NewConfig *big.Int 315 // the block number to which the local chain must be rewound to correct the error 316 RewindTo uint64 317 } 318 319 func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 320 var rew *big.Int 321 switch { 322 case storedblock == nil: 323 rew = newblock 324 case newblock == nil || storedblock.Cmp(newblock) < 0: 325 rew = storedblock 326 default: 327 rew = newblock 328 } 329 err := &ConfigCompatError{what, storedblock, newblock, 0} 330 if rew != nil && rew.Sign() > 0 { 331 err.RewindTo = rew.Uint64() - 1 332 } 333 return err 334 } 335 336 func (err *ConfigCompatError) Error() string { 337 return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) 338 } 339 340 // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions 341 // that do not have or require information about the block. 342 // 343 // Rules is a one time interface meaning that it shouldn't be used in between transition 344 // phases. 345 type Rules struct { 346 ChainID *big.Int 347 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 348 IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool 349 IsYoloV2 bool 350 } 351 352 // Rules ensures c's ChainID is not nil. 353 func (c *ChainConfig) Rules(num *big.Int) Rules { 354 chainID := c.ChainID 355 if chainID == nil { 356 chainID = new(big.Int) 357 } 358 return Rules{ 359 ChainID: new(big.Int).Set(chainID), 360 IsHomestead: c.IsHomestead(num), 361 IsEIP150: c.IsEIP150(num), 362 IsEIP155: c.IsEIP155(num), 363 IsEIP158: c.IsEIP158(num), 364 IsByzantium: c.IsByzantium(num), 365 IsConstantinople: c.IsConstantinople(num), 366 IsPetersburg: c.IsPetersburg(num), 367 IsIstanbul: c.IsIstanbul(num), 368 IsYoloV2: c.IsYoloV2(num), 369 } 370 }