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