github.com/calmw/ethereum@v0.1.1/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/calmw/ethereum/common" 24 ) 25 26 // Genesis hashes to enforce below configs on. 27 var ( 28 MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") 29 SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") 30 RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") 31 GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") 32 ) 33 34 func newUint64(val uint64) *uint64 { return &val } 35 36 var ( 37 MainnetTerminalTotalDifficulty, _ = new(big.Int).SetString("58_750_000_000_000_000_000_000", 0) 38 39 // MainnetChainConfig is the chain parameters to run a node on the main network. 40 MainnetChainConfig = &ChainConfig{ 41 ChainID: big.NewInt(1), 42 HomesteadBlock: big.NewInt(1_150_000), 43 DAOForkBlock: big.NewInt(1_920_000), 44 DAOForkSupport: true, 45 EIP150Block: big.NewInt(2_463_000), 46 EIP155Block: big.NewInt(2_675_000), 47 EIP158Block: big.NewInt(2_675_000), 48 ByzantiumBlock: big.NewInt(4_370_000), 49 ConstantinopleBlock: big.NewInt(7_280_000), 50 PetersburgBlock: big.NewInt(7_280_000), 51 IstanbulBlock: big.NewInt(9_069_000), 52 MuirGlacierBlock: big.NewInt(9_200_000), 53 BerlinBlock: big.NewInt(12_244_000), 54 LondonBlock: big.NewInt(12_965_000), 55 ArrowGlacierBlock: big.NewInt(13_773_000), 56 GrayGlacierBlock: big.NewInt(15_050_000), 57 TerminalTotalDifficulty: MainnetTerminalTotalDifficulty, // 58_750_000_000_000_000_000_000 58 TerminalTotalDifficultyPassed: true, 59 ShanghaiTime: newUint64(1681338455), 60 Ethash: new(EthashConfig), 61 } 62 // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. 63 SepoliaChainConfig = &ChainConfig{ 64 ChainID: big.NewInt(11155111), 65 HomesteadBlock: big.NewInt(0), 66 DAOForkBlock: nil, 67 DAOForkSupport: true, 68 EIP150Block: big.NewInt(0), 69 EIP155Block: big.NewInt(0), 70 EIP158Block: big.NewInt(0), 71 ByzantiumBlock: big.NewInt(0), 72 ConstantinopleBlock: big.NewInt(0), 73 PetersburgBlock: big.NewInt(0), 74 IstanbulBlock: big.NewInt(0), 75 MuirGlacierBlock: big.NewInt(0), 76 BerlinBlock: big.NewInt(0), 77 LondonBlock: big.NewInt(0), 78 TerminalTotalDifficulty: big.NewInt(17_000_000_000_000_000), 79 TerminalTotalDifficultyPassed: true, 80 MergeNetsplitBlock: big.NewInt(1735371), 81 ShanghaiTime: newUint64(1677557088), 82 Ethash: new(EthashConfig), 83 } 84 // RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network. 85 RinkebyChainConfig = &ChainConfig{ 86 ChainID: big.NewInt(4), 87 HomesteadBlock: big.NewInt(1), 88 DAOForkBlock: nil, 89 DAOForkSupport: true, 90 EIP150Block: big.NewInt(2), 91 EIP155Block: big.NewInt(3), 92 EIP158Block: big.NewInt(3), 93 ByzantiumBlock: big.NewInt(1_035_301), 94 ConstantinopleBlock: big.NewInt(3_660_663), 95 PetersburgBlock: big.NewInt(4_321_234), 96 IstanbulBlock: big.NewInt(5_435_345), 97 MuirGlacierBlock: nil, 98 BerlinBlock: big.NewInt(8_290_928), 99 LondonBlock: big.NewInt(8_897_988), 100 ArrowGlacierBlock: nil, 101 Clique: &CliqueConfig{ 102 Period: 15, 103 Epoch: 30000, 104 }, 105 } 106 // GoerliChainConfig contains the chain parameters to run a node on the Görli test network. 107 GoerliChainConfig = &ChainConfig{ 108 ChainID: big.NewInt(5), 109 HomesteadBlock: big.NewInt(0), 110 DAOForkBlock: nil, 111 DAOForkSupport: true, 112 EIP150Block: big.NewInt(0), 113 EIP155Block: big.NewInt(0), 114 EIP158Block: big.NewInt(0), 115 ByzantiumBlock: big.NewInt(0), 116 ConstantinopleBlock: big.NewInt(0), 117 PetersburgBlock: big.NewInt(0), 118 IstanbulBlock: big.NewInt(1_561_651), 119 MuirGlacierBlock: nil, 120 BerlinBlock: big.NewInt(4_460_644), 121 LondonBlock: big.NewInt(5_062_605), 122 ArrowGlacierBlock: nil, 123 TerminalTotalDifficulty: big.NewInt(10_790_000), 124 TerminalTotalDifficultyPassed: true, 125 ShanghaiTime: newUint64(1678832736), 126 Clique: &CliqueConfig{ 127 Period: 15, 128 Epoch: 30000, 129 }, 130 } 131 // AllEthashProtocolChanges contains every protocol change (EIPs) introduced 132 // and accepted by the Ethereum core developers into the Ethash consensus. 133 AllEthashProtocolChanges = &ChainConfig{ 134 ChainID: big.NewInt(1337), 135 HomesteadBlock: big.NewInt(0), 136 DAOForkBlock: nil, 137 DAOForkSupport: false, 138 EIP150Block: big.NewInt(0), 139 EIP155Block: big.NewInt(0), 140 EIP158Block: big.NewInt(0), 141 ByzantiumBlock: big.NewInt(0), 142 ConstantinopleBlock: big.NewInt(0), 143 PetersburgBlock: big.NewInt(0), 144 IstanbulBlock: big.NewInt(0), 145 MuirGlacierBlock: big.NewInt(0), 146 BerlinBlock: big.NewInt(0), 147 LondonBlock: big.NewInt(0), 148 ArrowGlacierBlock: big.NewInt(0), 149 GrayGlacierBlock: big.NewInt(0), 150 MergeNetsplitBlock: nil, 151 ShanghaiTime: nil, 152 CancunTime: nil, 153 PragueTime: nil, 154 TerminalTotalDifficulty: nil, 155 TerminalTotalDifficultyPassed: true, 156 Ethash: new(EthashConfig), 157 Clique: nil, 158 } 159 160 // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced 161 // and accepted by the Ethereum core developers into the Clique consensus. 162 AllCliqueProtocolChanges = &ChainConfig{ 163 ChainID: big.NewInt(1337), 164 HomesteadBlock: big.NewInt(0), 165 DAOForkBlock: nil, 166 DAOForkSupport: false, 167 EIP150Block: big.NewInt(0), 168 EIP155Block: big.NewInt(0), 169 EIP158Block: big.NewInt(0), 170 ByzantiumBlock: big.NewInt(0), 171 ConstantinopleBlock: big.NewInt(0), 172 PetersburgBlock: big.NewInt(0), 173 IstanbulBlock: big.NewInt(0), 174 MuirGlacierBlock: big.NewInt(0), 175 BerlinBlock: big.NewInt(0), 176 LondonBlock: big.NewInt(0), 177 ArrowGlacierBlock: nil, 178 GrayGlacierBlock: nil, 179 MergeNetsplitBlock: nil, 180 ShanghaiTime: nil, 181 CancunTime: nil, 182 PragueTime: nil, 183 TerminalTotalDifficulty: nil, 184 TerminalTotalDifficultyPassed: false, 185 Ethash: nil, 186 Clique: &CliqueConfig{Period: 0, Epoch: 30000}, 187 } 188 189 // TestChainConfig contains every protocol change (EIPs) introduced 190 // and accepted by the Ethereum core developers for testing proposes. 191 TestChainConfig = &ChainConfig{ 192 ChainID: big.NewInt(1), 193 HomesteadBlock: big.NewInt(0), 194 DAOForkBlock: nil, 195 DAOForkSupport: false, 196 EIP150Block: big.NewInt(0), 197 EIP155Block: big.NewInt(0), 198 EIP158Block: big.NewInt(0), 199 ByzantiumBlock: big.NewInt(0), 200 ConstantinopleBlock: big.NewInt(0), 201 PetersburgBlock: big.NewInt(0), 202 IstanbulBlock: big.NewInt(0), 203 MuirGlacierBlock: big.NewInt(0), 204 BerlinBlock: big.NewInt(0), 205 LondonBlock: big.NewInt(0), 206 ArrowGlacierBlock: big.NewInt(0), 207 GrayGlacierBlock: big.NewInt(0), 208 MergeNetsplitBlock: nil, 209 ShanghaiTime: nil, 210 CancunTime: nil, 211 PragueTime: nil, 212 TerminalTotalDifficulty: nil, 213 TerminalTotalDifficultyPassed: false, 214 Ethash: new(EthashConfig), 215 Clique: nil, 216 } 217 218 // NonActivatedConfig defines the chain configuration without activating 219 // any protocol change (EIPs). 220 NonActivatedConfig = &ChainConfig{ 221 ChainID: big.NewInt(1), 222 HomesteadBlock: nil, 223 DAOForkBlock: nil, 224 DAOForkSupport: false, 225 EIP150Block: nil, 226 EIP155Block: nil, 227 EIP158Block: nil, 228 ByzantiumBlock: nil, 229 ConstantinopleBlock: nil, 230 PetersburgBlock: nil, 231 IstanbulBlock: nil, 232 MuirGlacierBlock: nil, 233 BerlinBlock: nil, 234 LondonBlock: nil, 235 ArrowGlacierBlock: nil, 236 GrayGlacierBlock: nil, 237 MergeNetsplitBlock: nil, 238 ShanghaiTime: nil, 239 CancunTime: nil, 240 PragueTime: nil, 241 TerminalTotalDifficulty: nil, 242 TerminalTotalDifficultyPassed: false, 243 Ethash: new(EthashConfig), 244 Clique: nil, 245 } 246 TestRules = TestChainConfig.Rules(new(big.Int), false, 0) 247 ) 248 249 // NetworkNames are user friendly names to use in the chain spec banner. 250 var NetworkNames = map[string]string{ 251 MainnetChainConfig.ChainID.String(): "mainnet", 252 RinkebyChainConfig.ChainID.String(): "rinkeby", 253 GoerliChainConfig.ChainID.String(): "goerli", 254 SepoliaChainConfig.ChainID.String(): "sepolia", 255 } 256 257 // ChainConfig is the core config which determines the blockchain settings. 258 // 259 // ChainConfig is stored in the database on a per block basis. This means 260 // that any network, identified by its genesis block, can have its own 261 // set of configuration options. 262 type ChainConfig struct { 263 ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection 264 265 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 266 267 DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) 268 DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork 269 270 // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) 271 EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 272 EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block 273 EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block 274 275 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 276 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 277 PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) 278 IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) 279 MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) 280 BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin) 281 LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london) 282 ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated) 283 GrayGlacierBlock *big.Int `json:"grayGlacierBlock,omitempty"` // Eip-5133 (bomb delay) switch block (nil = no fork, 0 = already activated) 284 MergeNetsplitBlock *big.Int `json:"mergeNetsplitBlock,omitempty"` // Virtual fork after The Merge to use as a network splitter 285 286 // Fork scheduling was switched from blocks to timestamps here 287 288 ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) 289 CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) 290 PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) 291 292 // TerminalTotalDifficulty is the amount of total difficulty reached by 293 // the network that triggers the consensus upgrade. 294 TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"` 295 296 // TerminalTotalDifficultyPassed is a flag specifying that the network already 297 // passed the terminal total difficulty. Its purpose is to disable legacy sync 298 // even without having seen the TTD locally (safer long term). 299 TerminalTotalDifficultyPassed bool `json:"terminalTotalDifficultyPassed,omitempty"` 300 301 // Various consensus engines 302 Ethash *EthashConfig `json:"ethash,omitempty"` 303 Clique *CliqueConfig `json:"clique,omitempty"` 304 } 305 306 // EthashConfig is the consensus engine configs for proof-of-work based sealing. 307 type EthashConfig struct{} 308 309 // String implements the stringer interface, returning the consensus engine details. 310 func (c *EthashConfig) String() string { 311 return "ethash" 312 } 313 314 // CliqueConfig is the consensus engine configs for proof-of-authority based sealing. 315 type CliqueConfig struct { 316 Period uint64 `json:"period"` // Number of seconds between blocks to enforce 317 Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint 318 } 319 320 // String implements the stringer interface, returning the consensus engine details. 321 func (c *CliqueConfig) String() string { 322 return "clique" 323 } 324 325 // Description returns a human-readable description of ChainConfig. 326 func (c *ChainConfig) Description() string { 327 var banner string 328 329 // Create some basinc network config output 330 network := NetworkNames[c.ChainID.String()] 331 if network == "" { 332 network = "unknown" 333 } 334 banner += fmt.Sprintf("Chain ID: %v (%s)\n", c.ChainID, network) 335 switch { 336 case c.Ethash != nil: 337 if c.TerminalTotalDifficulty == nil { 338 banner += "Consensus: Ethash (proof-of-work)\n" 339 } else if !c.TerminalTotalDifficultyPassed { 340 banner += "Consensus: Beacon (proof-of-stake), merging from Ethash (proof-of-work)\n" 341 } else { 342 banner += "Consensus: Beacon (proof-of-stake), merged from Ethash (proof-of-work)\n" 343 } 344 case c.Clique != nil: 345 if c.TerminalTotalDifficulty == nil { 346 banner += "Consensus: Clique (proof-of-authority)\n" 347 } else if !c.TerminalTotalDifficultyPassed { 348 banner += "Consensus: Beacon (proof-of-stake), merging from Clique (proof-of-authority)\n" 349 } else { 350 banner += "Consensus: Beacon (proof-of-stake), merged from Clique (proof-of-authority)\n" 351 } 352 default: 353 banner += "Consensus: unknown\n" 354 } 355 banner += "\n" 356 357 // Create a list of forks with a short description of them. Forks that only 358 // makes sense for mainnet should be optional at printing to avoid bloating 359 // the output for testnets and private networks. 360 banner += "Pre-Merge hard forks (block based):\n" 361 banner += fmt.Sprintf(" - Homestead: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock) 362 if c.DAOForkBlock != nil { 363 banner += fmt.Sprintf(" - DAO Fork: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)\n", c.DAOForkBlock) 364 } 365 banner += fmt.Sprintf(" - Tangerine Whistle (EIP 150): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/tangerine-whistle.md)\n", c.EIP150Block) 366 banner += fmt.Sprintf(" - Spurious Dragon/1 (EIP 155): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.EIP155Block) 367 banner += fmt.Sprintf(" - Spurious Dragon/2 (EIP 158): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.EIP155Block) 368 banner += fmt.Sprintf(" - Byzantium: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock) 369 banner += fmt.Sprintf(" - Constantinople: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock) 370 banner += fmt.Sprintf(" - Petersburg: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock) 371 banner += fmt.Sprintf(" - Istanbul: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock) 372 if c.MuirGlacierBlock != nil { 373 banner += fmt.Sprintf(" - Muir Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock) 374 } 375 banner += fmt.Sprintf(" - Berlin: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)\n", c.BerlinBlock) 376 banner += fmt.Sprintf(" - London: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)\n", c.LondonBlock) 377 if c.ArrowGlacierBlock != nil { 378 banner += fmt.Sprintf(" - Arrow Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)\n", c.ArrowGlacierBlock) 379 } 380 if c.GrayGlacierBlock != nil { 381 banner += fmt.Sprintf(" - Gray Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)\n", c.GrayGlacierBlock) 382 } 383 banner += "\n" 384 385 // Add a special section for the merge as it's non-obvious 386 if c.TerminalTotalDifficulty == nil { 387 banner += "The Merge is not yet available for this network!\n" 388 banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n" 389 } else { 390 banner += "Merge configured:\n" 391 banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n" 392 banner += fmt.Sprintf(" - Network known to be merged: %v\n", c.TerminalTotalDifficultyPassed) 393 banner += fmt.Sprintf(" - Total terminal difficulty: %v\n", c.TerminalTotalDifficulty) 394 if c.MergeNetsplitBlock != nil { 395 banner += fmt.Sprintf(" - Merge netsplit block: #%-8v\n", c.MergeNetsplitBlock) 396 } 397 } 398 banner += "\n" 399 400 // Create a list of forks post-merge 401 banner += "Post-Merge hard forks (timestamp based):\n" 402 if c.ShanghaiTime != nil { 403 banner += fmt.Sprintf(" - Shanghai: @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md)\n", *c.ShanghaiTime) 404 } 405 if c.CancunTime != nil { 406 banner += fmt.Sprintf(" - Cancun: @%-10v\n", *c.CancunTime) 407 } 408 if c.PragueTime != nil { 409 banner += fmt.Sprintf(" - Prague: @%-10v\n", *c.PragueTime) 410 } 411 return banner 412 } 413 414 // IsHomestead returns whether num is either equal to the homestead block or greater. 415 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 416 return isBlockForked(c.HomesteadBlock, num) 417 } 418 419 // IsDAOFork returns whether num is either equal to the DAO fork block or greater. 420 func (c *ChainConfig) IsDAOFork(num *big.Int) bool { 421 return isBlockForked(c.DAOForkBlock, num) 422 } 423 424 // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater. 425 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 426 return isBlockForked(c.EIP150Block, num) 427 } 428 429 // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater. 430 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 431 return isBlockForked(c.EIP155Block, num) 432 } 433 434 // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater. 435 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 436 return isBlockForked(c.EIP158Block, num) 437 } 438 439 // IsByzantium returns whether num is either equal to the Byzantium fork block or greater. 440 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 441 return isBlockForked(c.ByzantiumBlock, num) 442 } 443 444 // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. 445 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 446 return isBlockForked(c.ConstantinopleBlock, num) 447 } 448 449 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. 450 func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { 451 return isBlockForked(c.MuirGlacierBlock, num) 452 } 453 454 // IsPetersburg returns whether num is either 455 // - equal to or greater than the PetersburgBlock fork block, 456 // - OR is nil, and Constantinople is active 457 func (c *ChainConfig) IsPetersburg(num *big.Int) bool { 458 return isBlockForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isBlockForked(c.ConstantinopleBlock, num) 459 } 460 461 // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater. 462 func (c *ChainConfig) IsIstanbul(num *big.Int) bool { 463 return isBlockForked(c.IstanbulBlock, num) 464 } 465 466 // IsBerlin returns whether num is either equal to the Berlin fork block or greater. 467 func (c *ChainConfig) IsBerlin(num *big.Int) bool { 468 return isBlockForked(c.BerlinBlock, num) 469 } 470 471 // IsLondon returns whether num is either equal to the London fork block or greater. 472 func (c *ChainConfig) IsLondon(num *big.Int) bool { 473 return isBlockForked(c.LondonBlock, num) 474 } 475 476 // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. 477 func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool { 478 return isBlockForked(c.ArrowGlacierBlock, num) 479 } 480 481 // IsGrayGlacier returns whether num is either equal to the Gray Glacier (EIP-5133) fork block or greater. 482 func (c *ChainConfig) IsGrayGlacier(num *big.Int) bool { 483 return isBlockForked(c.GrayGlacierBlock, num) 484 } 485 486 // IsTerminalPoWBlock returns whether the given block is the last block of PoW stage. 487 func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool { 488 if c.TerminalTotalDifficulty == nil { 489 return false 490 } 491 return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0 492 } 493 494 // IsShanghai returns whether time is either equal to the Shanghai fork time or greater. 495 func (c *ChainConfig) IsShanghai(time uint64) bool { 496 return isTimestampForked(c.ShanghaiTime, time) 497 } 498 499 // IsCancun returns whether num is either equal to the Cancun fork time or greater. 500 func (c *ChainConfig) IsCancun(time uint64) bool { 501 return isTimestampForked(c.CancunTime, time) 502 } 503 504 // IsPrague returns whether num is either equal to the Prague fork time or greater. 505 func (c *ChainConfig) IsPrague(time uint64) bool { 506 return isTimestampForked(c.PragueTime, time) 507 } 508 509 // CheckCompatible checks whether scheduled fork transitions have been imported 510 // with a mismatching chain configuration. 511 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { 512 var ( 513 bhead = new(big.Int).SetUint64(height) 514 btime = time 515 ) 516 // Iterate checkCompatible to find the lowest conflict. 517 var lasterr *ConfigCompatError 518 for { 519 err := c.checkCompatible(newcfg, bhead, btime) 520 if err == nil || (lasterr != nil && err.RewindToBlock == lasterr.RewindToBlock && err.RewindToTime == lasterr.RewindToTime) { 521 break 522 } 523 lasterr = err 524 525 if err.RewindToTime > 0 { 526 btime = err.RewindToTime 527 } else { 528 bhead.SetUint64(err.RewindToBlock) 529 } 530 } 531 return lasterr 532 } 533 534 // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough 535 // to guarantee that forks can be implemented in a different order than on official networks 536 func (c *ChainConfig) CheckConfigForkOrder() error { 537 type fork struct { 538 name string 539 block *big.Int // forks up to - and including the merge - were defined with block numbers 540 timestamp *uint64 // forks after the merge are scheduled using timestamps 541 optional bool // if true, the fork may be nil and next fork is still allowed 542 } 543 var lastFork fork 544 for _, cur := range []fork{ 545 {name: "homesteadBlock", block: c.HomesteadBlock}, 546 {name: "daoForkBlock", block: c.DAOForkBlock, optional: true}, 547 {name: "eip150Block", block: c.EIP150Block}, 548 {name: "eip155Block", block: c.EIP155Block}, 549 {name: "eip158Block", block: c.EIP158Block}, 550 {name: "byzantiumBlock", block: c.ByzantiumBlock}, 551 {name: "constantinopleBlock", block: c.ConstantinopleBlock}, 552 {name: "petersburgBlock", block: c.PetersburgBlock}, 553 {name: "istanbulBlock", block: c.IstanbulBlock}, 554 {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, 555 {name: "berlinBlock", block: c.BerlinBlock}, 556 {name: "londonBlock", block: c.LondonBlock}, 557 {name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true}, 558 {name: "grayGlacierBlock", block: c.GrayGlacierBlock, optional: true}, 559 {name: "mergeNetsplitBlock", block: c.MergeNetsplitBlock, optional: true}, 560 {name: "shanghaiTime", timestamp: c.ShanghaiTime}, 561 {name: "cancunTime", timestamp: c.CancunTime, optional: true}, 562 {name: "pragueTime", timestamp: c.PragueTime, optional: true}, 563 } { 564 if lastFork.name != "" { 565 switch { 566 // Non-optional forks must all be present in the chain config up to the last defined fork 567 case lastFork.block == nil && lastFork.timestamp == nil && (cur.block != nil || cur.timestamp != nil): 568 if cur.block != nil { 569 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at block %v", 570 lastFork.name, cur.name, cur.block) 571 } else { 572 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at timestamp %v", 573 lastFork.name, cur.name, cur.timestamp) 574 } 575 576 // Fork (whether defined by block or timestamp) must follow the fork definition sequence 577 case (lastFork.block != nil && cur.block != nil) || (lastFork.timestamp != nil && cur.timestamp != nil): 578 if lastFork.block != nil && lastFork.block.Cmp(cur.block) > 0 { 579 return fmt.Errorf("unsupported fork ordering: %v enabled at block %v, but %v enabled at block %v", 580 lastFork.name, lastFork.block, cur.name, cur.block) 581 } else if lastFork.timestamp != nil && *lastFork.timestamp > *cur.timestamp { 582 return fmt.Errorf("unsupported fork ordering: %v enabled at timestamp %v, but %v enabled at timestamp %v", 583 lastFork.name, lastFork.timestamp, cur.name, cur.timestamp) 584 } 585 586 // Timestamp based forks can follow block based ones, but not the other way around 587 if lastFork.timestamp != nil && cur.block != nil { 588 return fmt.Errorf("unsupported fork ordering: %v used timestamp ordering, but %v reverted to block ordering", 589 lastFork.name, cur.name) 590 } 591 } 592 } 593 // If it was optional and not set, then ignore it 594 if !cur.optional || (cur.block != nil || cur.timestamp != nil) { 595 lastFork = cur 596 } 597 } 598 return nil 599 } 600 601 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64) *ConfigCompatError { 602 if isForkBlockIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, headNumber) { 603 return newBlockCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 604 } 605 if isForkBlockIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, headNumber) { 606 return newBlockCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) 607 } 608 if c.IsDAOFork(headNumber) && c.DAOForkSupport != newcfg.DAOForkSupport { 609 return newBlockCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) 610 } 611 if isForkBlockIncompatible(c.EIP150Block, newcfg.EIP150Block, headNumber) { 612 return newBlockCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 613 } 614 if isForkBlockIncompatible(c.EIP155Block, newcfg.EIP155Block, headNumber) { 615 return newBlockCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 616 } 617 if isForkBlockIncompatible(c.EIP158Block, newcfg.EIP158Block, headNumber) { 618 return newBlockCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 619 } 620 if c.IsEIP158(headNumber) && !configBlockEqual(c.ChainID, newcfg.ChainID) { 621 return newBlockCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 622 } 623 if isForkBlockIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, headNumber) { 624 return newBlockCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 625 } 626 if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, headNumber) { 627 return newBlockCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 628 } 629 if isForkBlockIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, headNumber) { 630 // the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople 631 // mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set 632 if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, headNumber) { 633 return newBlockCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock) 634 } 635 } 636 if isForkBlockIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, headNumber) { 637 return newBlockCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock) 638 } 639 if isForkBlockIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, headNumber) { 640 return newBlockCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock) 641 } 642 if isForkBlockIncompatible(c.BerlinBlock, newcfg.BerlinBlock, headNumber) { 643 return newBlockCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock) 644 } 645 if isForkBlockIncompatible(c.LondonBlock, newcfg.LondonBlock, headNumber) { 646 return newBlockCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock) 647 } 648 if isForkBlockIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, headNumber) { 649 return newBlockCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock) 650 } 651 if isForkBlockIncompatible(c.GrayGlacierBlock, newcfg.GrayGlacierBlock, headNumber) { 652 return newBlockCompatError("Gray Glacier fork block", c.GrayGlacierBlock, newcfg.GrayGlacierBlock) 653 } 654 if isForkBlockIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, headNumber) { 655 return newBlockCompatError("Merge netsplit fork block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock) 656 } 657 if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) { 658 return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime) 659 } 660 if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) { 661 return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime) 662 } 663 if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp) { 664 return newTimestampCompatError("Prague fork timestamp", c.PragueTime, newcfg.PragueTime) 665 } 666 return nil 667 } 668 669 // BaseFeeChangeDenominator bounds the amount the base fee can change between blocks. 670 func (c *ChainConfig) BaseFeeChangeDenominator() uint64 { 671 return DefaultBaseFeeChangeDenominator 672 } 673 674 // ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have. 675 func (c *ChainConfig) ElasticityMultiplier() uint64 { 676 return DefaultElasticityMultiplier 677 } 678 679 // isForkBlockIncompatible returns true if a fork scheduled at block s1 cannot be 680 // rescheduled to block s2 because head is already past the fork. 681 func isForkBlockIncompatible(s1, s2, head *big.Int) bool { 682 return (isBlockForked(s1, head) || isBlockForked(s2, head)) && !configBlockEqual(s1, s2) 683 } 684 685 // isBlockForked returns whether a fork scheduled at block s is active at the 686 // given head block. Whilst this method is the same as isTimestampForked, they 687 // are explicitly separate for clearer reading. 688 func isBlockForked(s, head *big.Int) bool { 689 if s == nil || head == nil { 690 return false 691 } 692 return s.Cmp(head) <= 0 693 } 694 695 func configBlockEqual(x, y *big.Int) bool { 696 if x == nil { 697 return y == nil 698 } 699 if y == nil { 700 return x == nil 701 } 702 return x.Cmp(y) == 0 703 } 704 705 // isForkTimestampIncompatible returns true if a fork scheduled at timestamp s1 706 // cannot be rescheduled to timestamp s2 because head is already past the fork. 707 func isForkTimestampIncompatible(s1, s2 *uint64, head uint64) bool { 708 return (isTimestampForked(s1, head) || isTimestampForked(s2, head)) && !configTimestampEqual(s1, s2) 709 } 710 711 // isTimestampForked returns whether a fork scheduled at timestamp s is active 712 // at the given head timestamp. Whilst this method is the same as isBlockForked, 713 // they are explicitly separate for clearer reading. 714 func isTimestampForked(s *uint64, head uint64) bool { 715 if s == nil { 716 return false 717 } 718 return *s <= head 719 } 720 721 func configTimestampEqual(x, y *uint64) bool { 722 if x == nil { 723 return y == nil 724 } 725 if y == nil { 726 return x == nil 727 } 728 return *x == *y 729 } 730 731 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 732 // ChainConfig that would alter the past. 733 type ConfigCompatError struct { 734 What string 735 736 // block numbers of the stored and new configurations if block based forking 737 StoredBlock, NewBlock *big.Int 738 739 // timestamps of the stored and new configurations if time based forking 740 StoredTime, NewTime *uint64 741 742 // the block number to which the local chain must be rewound to correct the error 743 RewindToBlock uint64 744 745 // the timestamp to which the local chain must be rewound to correct the error 746 RewindToTime uint64 747 } 748 749 func newBlockCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 750 var rew *big.Int 751 switch { 752 case storedblock == nil: 753 rew = newblock 754 case newblock == nil || storedblock.Cmp(newblock) < 0: 755 rew = storedblock 756 default: 757 rew = newblock 758 } 759 err := &ConfigCompatError{ 760 What: what, 761 StoredBlock: storedblock, 762 NewBlock: newblock, 763 RewindToBlock: 0, 764 } 765 if rew != nil && rew.Sign() > 0 { 766 err.RewindToBlock = rew.Uint64() - 1 767 } 768 return err 769 } 770 771 func newTimestampCompatError(what string, storedtime, newtime *uint64) *ConfigCompatError { 772 var rew *uint64 773 switch { 774 case storedtime == nil: 775 rew = newtime 776 case newtime == nil || *storedtime < *newtime: 777 rew = storedtime 778 default: 779 rew = newtime 780 } 781 err := &ConfigCompatError{ 782 What: what, 783 StoredTime: storedtime, 784 NewTime: newtime, 785 RewindToTime: 0, 786 } 787 if rew != nil { 788 err.RewindToTime = *rew - 1 789 } 790 return err 791 } 792 793 func (err *ConfigCompatError) Error() string { 794 if err.StoredBlock != nil { 795 return fmt.Sprintf("mismatching %s in database (have block %d, want block %d, rewindto block %d)", err.What, err.StoredBlock, err.NewBlock, err.RewindToBlock) 796 } 797 return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp %d, rewindto timestamp %d)", err.What, err.StoredTime, err.NewTime, err.RewindToTime) 798 } 799 800 // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions 801 // that do not have or require information about the block. 802 // 803 // Rules is a one time interface meaning that it shouldn't be used in between transition 804 // phases. 805 type Rules struct { 806 ChainID *big.Int 807 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 808 IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool 809 IsBerlin, IsLondon bool 810 IsMerge, IsShanghai, IsCancun, IsPrague bool 811 } 812 813 // Rules ensures c's ChainID is not nil. 814 func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules { 815 chainID := c.ChainID 816 if chainID == nil { 817 chainID = new(big.Int) 818 } 819 return Rules{ 820 ChainID: new(big.Int).Set(chainID), 821 IsHomestead: c.IsHomestead(num), 822 IsEIP150: c.IsEIP150(num), 823 IsEIP155: c.IsEIP155(num), 824 IsEIP158: c.IsEIP158(num), 825 IsByzantium: c.IsByzantium(num), 826 IsConstantinople: c.IsConstantinople(num), 827 IsPetersburg: c.IsPetersburg(num), 828 IsIstanbul: c.IsIstanbul(num), 829 IsBerlin: c.IsBerlin(num), 830 IsLondon: c.IsLondon(num), 831 IsMerge: isMerge, 832 IsShanghai: c.IsShanghai(timestamp), 833 IsCancun: c.IsCancun(timestamp), 834 IsPrague: c.IsPrague(timestamp), 835 } 836 }