github.com/ethereum/go-ethereum@v1.16.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 "errors" 21 "fmt" 22 "math" 23 "math/big" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/params/forks" 27 ) 28 29 // Genesis hashes to enforce below configs on. 30 var ( 31 MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") 32 HoleskyGenesisHash = common.HexToHash("0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4") 33 SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") 34 HoodiGenesisHash = common.HexToHash("0xbbe312868b376a3001692a646dd2d7d1e4406380dfd86b98aa8a34d1557c971b") 35 ) 36 37 func newUint64(val uint64) *uint64 { return &val } 38 39 var ( 40 MainnetTerminalTotalDifficulty, _ = new(big.Int).SetString("58_750_000_000_000_000_000_000", 0) 41 42 // MainnetChainConfig is the chain parameters to run a node on the main network. 43 MainnetChainConfig = &ChainConfig{ 44 ChainID: big.NewInt(1), 45 HomesteadBlock: big.NewInt(1_150_000), 46 DAOForkBlock: big.NewInt(1_920_000), 47 DAOForkSupport: true, 48 EIP150Block: big.NewInt(2_463_000), 49 EIP155Block: big.NewInt(2_675_000), 50 EIP158Block: big.NewInt(2_675_000), 51 ByzantiumBlock: big.NewInt(4_370_000), 52 ConstantinopleBlock: big.NewInt(7_280_000), 53 PetersburgBlock: big.NewInt(7_280_000), 54 IstanbulBlock: big.NewInt(9_069_000), 55 MuirGlacierBlock: big.NewInt(9_200_000), 56 BerlinBlock: big.NewInt(12_244_000), 57 LondonBlock: big.NewInt(12_965_000), 58 ArrowGlacierBlock: big.NewInt(13_773_000), 59 GrayGlacierBlock: big.NewInt(15_050_000), 60 TerminalTotalDifficulty: MainnetTerminalTotalDifficulty, // 58_750_000_000_000_000_000_000 61 ShanghaiTime: newUint64(1681338455), 62 CancunTime: newUint64(1710338135), 63 PragueTime: newUint64(1746612311), 64 DepositContractAddress: common.HexToAddress("0x00000000219ab540356cbb839cbe05303d7705fa"), 65 Ethash: new(EthashConfig), 66 BlobScheduleConfig: &BlobScheduleConfig{ 67 Cancun: DefaultCancunBlobConfig, 68 Prague: DefaultPragueBlobConfig, 69 }, 70 } 71 // HoleskyChainConfig contains the chain parameters to run a node on the Holesky test network. 72 HoleskyChainConfig = &ChainConfig{ 73 ChainID: big.NewInt(17000), 74 HomesteadBlock: big.NewInt(0), 75 DAOForkBlock: nil, 76 DAOForkSupport: true, 77 EIP150Block: big.NewInt(0), 78 EIP155Block: big.NewInt(0), 79 EIP158Block: big.NewInt(0), 80 ByzantiumBlock: big.NewInt(0), 81 ConstantinopleBlock: big.NewInt(0), 82 PetersburgBlock: big.NewInt(0), 83 IstanbulBlock: big.NewInt(0), 84 MuirGlacierBlock: nil, 85 BerlinBlock: big.NewInt(0), 86 LondonBlock: big.NewInt(0), 87 ArrowGlacierBlock: nil, 88 GrayGlacierBlock: nil, 89 TerminalTotalDifficulty: big.NewInt(0), 90 MergeNetsplitBlock: nil, 91 ShanghaiTime: newUint64(1696000704), 92 CancunTime: newUint64(1707305664), 93 PragueTime: newUint64(1740434112), 94 DepositContractAddress: common.HexToAddress("0x4242424242424242424242424242424242424242"), 95 Ethash: new(EthashConfig), 96 BlobScheduleConfig: &BlobScheduleConfig{ 97 Cancun: DefaultCancunBlobConfig, 98 Prague: DefaultPragueBlobConfig, 99 }, 100 } 101 // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. 102 SepoliaChainConfig = &ChainConfig{ 103 ChainID: big.NewInt(11155111), 104 HomesteadBlock: big.NewInt(0), 105 DAOForkBlock: nil, 106 DAOForkSupport: true, 107 EIP150Block: big.NewInt(0), 108 EIP155Block: big.NewInt(0), 109 EIP158Block: big.NewInt(0), 110 ByzantiumBlock: big.NewInt(0), 111 ConstantinopleBlock: big.NewInt(0), 112 PetersburgBlock: big.NewInt(0), 113 IstanbulBlock: big.NewInt(0), 114 MuirGlacierBlock: big.NewInt(0), 115 BerlinBlock: big.NewInt(0), 116 LondonBlock: big.NewInt(0), 117 ArrowGlacierBlock: nil, 118 GrayGlacierBlock: nil, 119 TerminalTotalDifficulty: big.NewInt(17_000_000_000_000_000), 120 MergeNetsplitBlock: big.NewInt(1735371), 121 ShanghaiTime: newUint64(1677557088), 122 CancunTime: newUint64(1706655072), 123 PragueTime: newUint64(1741159776), 124 DepositContractAddress: common.HexToAddress("0x7f02c3e3c98b133055b8b348b2ac625669ed295d"), 125 Ethash: new(EthashConfig), 126 BlobScheduleConfig: &BlobScheduleConfig{ 127 Cancun: DefaultCancunBlobConfig, 128 Prague: DefaultPragueBlobConfig, 129 }, 130 } 131 // HoodiChainConfig contains the chain parameters to run a node on the Hoodi test network. 132 HoodiChainConfig = &ChainConfig{ 133 ChainID: big.NewInt(560048), 134 HomesteadBlock: big.NewInt(0), 135 DAOForkBlock: nil, 136 DAOForkSupport: true, 137 EIP150Block: big.NewInt(0), 138 EIP155Block: big.NewInt(0), 139 EIP158Block: big.NewInt(0), 140 ByzantiumBlock: big.NewInt(0), 141 ConstantinopleBlock: big.NewInt(0), 142 PetersburgBlock: big.NewInt(0), 143 IstanbulBlock: big.NewInt(0), 144 MuirGlacierBlock: big.NewInt(0), 145 BerlinBlock: big.NewInt(0), 146 LondonBlock: big.NewInt(0), 147 ArrowGlacierBlock: nil, 148 GrayGlacierBlock: nil, 149 TerminalTotalDifficulty: big.NewInt(0), 150 MergeNetsplitBlock: big.NewInt(0), 151 ShanghaiTime: newUint64(0), 152 CancunTime: newUint64(0), 153 PragueTime: newUint64(1742999832), 154 DepositContractAddress: common.HexToAddress("0x00000000219ab540356cBB839Cbe05303d7705Fa"), 155 Ethash: new(EthashConfig), 156 BlobScheduleConfig: &BlobScheduleConfig{ 157 Cancun: DefaultCancunBlobConfig, 158 Prague: DefaultPragueBlobConfig, 159 }, 160 } 161 // AllEthashProtocolChanges contains every protocol change (EIPs) introduced 162 // and accepted by the Ethereum core developers into the Ethash consensus. 163 AllEthashProtocolChanges = &ChainConfig{ 164 ChainID: big.NewInt(1337), 165 HomesteadBlock: big.NewInt(0), 166 DAOForkBlock: nil, 167 DAOForkSupport: false, 168 EIP150Block: big.NewInt(0), 169 EIP155Block: big.NewInt(0), 170 EIP158Block: big.NewInt(0), 171 ByzantiumBlock: big.NewInt(0), 172 ConstantinopleBlock: big.NewInt(0), 173 PetersburgBlock: big.NewInt(0), 174 IstanbulBlock: big.NewInt(0), 175 MuirGlacierBlock: big.NewInt(0), 176 BerlinBlock: big.NewInt(0), 177 LondonBlock: big.NewInt(0), 178 ArrowGlacierBlock: big.NewInt(0), 179 GrayGlacierBlock: big.NewInt(0), 180 TerminalTotalDifficulty: big.NewInt(math.MaxInt64), 181 MergeNetsplitBlock: nil, 182 ShanghaiTime: nil, 183 CancunTime: nil, 184 PragueTime: nil, 185 OsakaTime: nil, 186 VerkleTime: nil, 187 Ethash: new(EthashConfig), 188 Clique: nil, 189 } 190 191 AllDevChainProtocolChanges = &ChainConfig{ 192 ChainID: big.NewInt(1337), 193 HomesteadBlock: big.NewInt(0), 194 EIP150Block: big.NewInt(0), 195 EIP155Block: big.NewInt(0), 196 EIP158Block: big.NewInt(0), 197 ByzantiumBlock: big.NewInt(0), 198 ConstantinopleBlock: big.NewInt(0), 199 PetersburgBlock: big.NewInt(0), 200 IstanbulBlock: big.NewInt(0), 201 MuirGlacierBlock: big.NewInt(0), 202 BerlinBlock: big.NewInt(0), 203 LondonBlock: big.NewInt(0), 204 ArrowGlacierBlock: big.NewInt(0), 205 GrayGlacierBlock: big.NewInt(0), 206 ShanghaiTime: newUint64(0), 207 CancunTime: newUint64(0), 208 TerminalTotalDifficulty: big.NewInt(0), 209 PragueTime: newUint64(0), 210 BlobScheduleConfig: &BlobScheduleConfig{ 211 Cancun: DefaultCancunBlobConfig, 212 Prague: DefaultPragueBlobConfig, 213 }, 214 } 215 216 // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced 217 // and accepted by the Ethereum core developers into the Clique consensus. 218 AllCliqueProtocolChanges = &ChainConfig{ 219 ChainID: big.NewInt(1337), 220 HomesteadBlock: big.NewInt(0), 221 DAOForkBlock: nil, 222 DAOForkSupport: false, 223 EIP150Block: big.NewInt(0), 224 EIP155Block: big.NewInt(0), 225 EIP158Block: big.NewInt(0), 226 ByzantiumBlock: big.NewInt(0), 227 ConstantinopleBlock: big.NewInt(0), 228 PetersburgBlock: big.NewInt(0), 229 IstanbulBlock: big.NewInt(0), 230 MuirGlacierBlock: big.NewInt(0), 231 BerlinBlock: big.NewInt(0), 232 LondonBlock: big.NewInt(0), 233 ArrowGlacierBlock: nil, 234 GrayGlacierBlock: nil, 235 MergeNetsplitBlock: nil, 236 ShanghaiTime: nil, 237 CancunTime: nil, 238 PragueTime: nil, 239 OsakaTime: nil, 240 VerkleTime: nil, 241 TerminalTotalDifficulty: big.NewInt(math.MaxInt64), 242 Ethash: nil, 243 Clique: &CliqueConfig{Period: 0, Epoch: 30000}, 244 } 245 246 // TestChainConfig contains every protocol change (EIPs) introduced 247 // and accepted by the Ethereum core developers for testing purposes. 248 TestChainConfig = &ChainConfig{ 249 ChainID: big.NewInt(1), 250 HomesteadBlock: big.NewInt(0), 251 DAOForkBlock: nil, 252 DAOForkSupport: false, 253 EIP150Block: big.NewInt(0), 254 EIP155Block: big.NewInt(0), 255 EIP158Block: big.NewInt(0), 256 ByzantiumBlock: big.NewInt(0), 257 ConstantinopleBlock: big.NewInt(0), 258 PetersburgBlock: big.NewInt(0), 259 IstanbulBlock: big.NewInt(0), 260 MuirGlacierBlock: big.NewInt(0), 261 BerlinBlock: big.NewInt(0), 262 LondonBlock: big.NewInt(0), 263 ArrowGlacierBlock: big.NewInt(0), 264 GrayGlacierBlock: big.NewInt(0), 265 MergeNetsplitBlock: nil, 266 ShanghaiTime: nil, 267 CancunTime: nil, 268 PragueTime: nil, 269 OsakaTime: nil, 270 VerkleTime: nil, 271 TerminalTotalDifficulty: big.NewInt(math.MaxInt64), 272 Ethash: new(EthashConfig), 273 Clique: nil, 274 } 275 276 // MergedTestChainConfig contains every protocol change (EIPs) introduced 277 // and accepted by the Ethereum core developers for testing purposes. 278 MergedTestChainConfig = &ChainConfig{ 279 ChainID: big.NewInt(1), 280 HomesteadBlock: big.NewInt(0), 281 DAOForkBlock: nil, 282 DAOForkSupport: false, 283 EIP150Block: big.NewInt(0), 284 EIP155Block: big.NewInt(0), 285 EIP158Block: big.NewInt(0), 286 ByzantiumBlock: big.NewInt(0), 287 ConstantinopleBlock: big.NewInt(0), 288 PetersburgBlock: big.NewInt(0), 289 IstanbulBlock: big.NewInt(0), 290 MuirGlacierBlock: big.NewInt(0), 291 BerlinBlock: big.NewInt(0), 292 LondonBlock: big.NewInt(0), 293 ArrowGlacierBlock: big.NewInt(0), 294 GrayGlacierBlock: big.NewInt(0), 295 MergeNetsplitBlock: big.NewInt(0), 296 ShanghaiTime: newUint64(0), 297 CancunTime: newUint64(0), 298 PragueTime: newUint64(0), 299 OsakaTime: newUint64(0), 300 VerkleTime: nil, 301 TerminalTotalDifficulty: big.NewInt(0), 302 Ethash: new(EthashConfig), 303 Clique: nil, 304 BlobScheduleConfig: &BlobScheduleConfig{ 305 Cancun: DefaultCancunBlobConfig, 306 Prague: DefaultPragueBlobConfig, 307 Osaka: DefaultOsakaBlobConfig, 308 }, 309 } 310 311 // NonActivatedConfig defines the chain configuration without activating 312 // any protocol change (EIPs). 313 NonActivatedConfig = &ChainConfig{ 314 ChainID: big.NewInt(1), 315 HomesteadBlock: nil, 316 DAOForkBlock: nil, 317 DAOForkSupport: false, 318 EIP150Block: nil, 319 EIP155Block: nil, 320 EIP158Block: nil, 321 ByzantiumBlock: nil, 322 ConstantinopleBlock: nil, 323 PetersburgBlock: nil, 324 IstanbulBlock: nil, 325 MuirGlacierBlock: nil, 326 BerlinBlock: nil, 327 LondonBlock: nil, 328 ArrowGlacierBlock: nil, 329 GrayGlacierBlock: nil, 330 MergeNetsplitBlock: nil, 331 ShanghaiTime: nil, 332 CancunTime: nil, 333 PragueTime: nil, 334 OsakaTime: nil, 335 VerkleTime: nil, 336 TerminalTotalDifficulty: big.NewInt(math.MaxInt64), 337 Ethash: new(EthashConfig), 338 Clique: nil, 339 } 340 TestRules = TestChainConfig.Rules(new(big.Int), false, 0) 341 ) 342 343 var ( 344 // DefaultCancunBlobConfig is the default blob configuration for the Cancun fork. 345 DefaultCancunBlobConfig = &BlobConfig{ 346 Target: 3, 347 Max: 6, 348 UpdateFraction: 3338477, 349 } 350 // DefaultPragueBlobConfig is the default blob configuration for the Prague fork. 351 DefaultPragueBlobConfig = &BlobConfig{ 352 Target: 6, 353 Max: 9, 354 UpdateFraction: 5007716, 355 } 356 // DefaultOsakaBlobConfig is the default blob configuration for the Osaka fork. 357 DefaultOsakaBlobConfig = &BlobConfig{ 358 Target: 6, 359 Max: 9, 360 UpdateFraction: 5007716, 361 } 362 // DefaultBlobSchedule is the latest configured blob schedule for Ethereum mainnet. 363 DefaultBlobSchedule = &BlobScheduleConfig{ 364 Cancun: DefaultCancunBlobConfig, 365 Prague: DefaultPragueBlobConfig, 366 Osaka: DefaultOsakaBlobConfig, 367 } 368 ) 369 370 // NetworkNames are user friendly names to use in the chain spec banner. 371 var NetworkNames = map[string]string{ 372 MainnetChainConfig.ChainID.String(): "mainnet", 373 SepoliaChainConfig.ChainID.String(): "sepolia", 374 HoleskyChainConfig.ChainID.String(): "holesky", 375 HoodiChainConfig.ChainID.String(): "hoodi", 376 } 377 378 // ChainConfig is the core config which determines the blockchain settings. 379 // 380 // ChainConfig is stored in the database on a per block basis. This means 381 // that any network, identified by its genesis block, can have its own 382 // set of configuration options. 383 type ChainConfig struct { 384 ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection 385 386 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 387 388 DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) 389 DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork 390 391 // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) 392 EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 393 EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block 394 EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block 395 396 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 397 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 398 PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) 399 IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) 400 MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) 401 BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin) 402 LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london) 403 ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated) 404 GrayGlacierBlock *big.Int `json:"grayGlacierBlock,omitempty"` // Eip-5133 (bomb delay) switch block (nil = no fork, 0 = already activated) 405 MergeNetsplitBlock *big.Int `json:"mergeNetsplitBlock,omitempty"` // Virtual fork after The Merge to use as a network splitter 406 407 // Fork scheduling was switched from blocks to timestamps here 408 409 ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) 410 CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) 411 PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) 412 OsakaTime *uint64 `json:"osakaTime,omitempty"` // Osaka switch time (nil = no fork, 0 = already on osaka) 413 VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle) 414 415 // TerminalTotalDifficulty is the amount of total difficulty reached by 416 // the network that triggers the consensus upgrade. 417 TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"` 418 419 DepositContractAddress common.Address `json:"depositContractAddress,omitempty"` 420 421 // EnableVerkleAtGenesis is a flag that specifies whether the network uses 422 // the Verkle tree starting from the genesis block. If set to true, the 423 // genesis state will be committed using the Verkle tree, eliminating the 424 // need for any Verkle transition later. 425 // 426 // This is a temporary flag only for verkle devnet testing, where verkle is 427 // activated at genesis, and the configured activation date has already passed. 428 // 429 // In production networks (mainnet and public testnets), verkle activation 430 // always occurs after the genesis block, making this flag irrelevant in 431 // those cases. 432 EnableVerkleAtGenesis bool `json:"enableVerkleAtGenesis,omitempty"` 433 434 // Various consensus engines 435 Ethash *EthashConfig `json:"ethash,omitempty"` 436 Clique *CliqueConfig `json:"clique,omitempty"` 437 BlobScheduleConfig *BlobScheduleConfig `json:"blobSchedule,omitempty"` 438 } 439 440 // EthashConfig is the consensus engine configs for proof-of-work based sealing. 441 type EthashConfig struct{} 442 443 // String implements the stringer interface, returning the consensus engine details. 444 func (c EthashConfig) String() string { 445 return "ethash" 446 } 447 448 // CliqueConfig is the consensus engine configs for proof-of-authority based sealing. 449 type CliqueConfig struct { 450 Period uint64 `json:"period"` // Number of seconds between blocks to enforce 451 Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint 452 } 453 454 // String implements the stringer interface, returning the consensus engine details. 455 func (c CliqueConfig) String() string { 456 return fmt.Sprintf("clique(period: %d, epoch: %d)", c.Period, c.Epoch) 457 } 458 459 // Description returns a human-readable description of ChainConfig. 460 func (c *ChainConfig) Description() string { 461 var banner string 462 463 // Create some basic network config output 464 network := NetworkNames[c.ChainID.String()] 465 if network == "" { 466 network = "unknown" 467 } 468 banner += fmt.Sprintf("Chain ID: %v (%s)\n", c.ChainID, network) 469 switch { 470 case c.Ethash != nil: 471 banner += "Consensus: Beacon (proof-of-stake), merged from Ethash (proof-of-work)\n" 472 case c.Clique != nil: 473 banner += "Consensus: Beacon (proof-of-stake), merged from Clique (proof-of-authority)\n" 474 default: 475 banner += "Consensus: unknown\n" 476 } 477 banner += "\n" 478 479 // Create a list of forks with a short description of them. Forks that only 480 // makes sense for mainnet should be optional at printing to avoid bloating 481 // the output for testnets and private networks. 482 banner += "Pre-Merge hard forks (block based):\n" 483 banner += fmt.Sprintf(" - Homestead: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock) 484 if c.DAOForkBlock != nil { 485 banner += fmt.Sprintf(" - DAO Fork: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)\n", c.DAOForkBlock) 486 } 487 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) 488 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) 489 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) 490 banner += fmt.Sprintf(" - Byzantium: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock) 491 banner += fmt.Sprintf(" - Constantinople: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock) 492 banner += fmt.Sprintf(" - Petersburg: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock) 493 banner += fmt.Sprintf(" - Istanbul: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock) 494 if c.MuirGlacierBlock != nil { 495 banner += fmt.Sprintf(" - Muir Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock) 496 } 497 banner += fmt.Sprintf(" - Berlin: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)\n", c.BerlinBlock) 498 banner += fmt.Sprintf(" - London: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)\n", c.LondonBlock) 499 if c.ArrowGlacierBlock != nil { 500 banner += fmt.Sprintf(" - Arrow Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)\n", c.ArrowGlacierBlock) 501 } 502 if c.GrayGlacierBlock != nil { 503 banner += fmt.Sprintf(" - Gray Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)\n", c.GrayGlacierBlock) 504 } 505 banner += "\n" 506 507 // Add a special section for the merge as it's non-obvious 508 banner += "Merge configured:\n" 509 banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n" 510 banner += " - Network known to be merged\n" 511 banner += fmt.Sprintf(" - Total terminal difficulty: %v\n", c.TerminalTotalDifficulty) 512 if c.MergeNetsplitBlock != nil { 513 banner += fmt.Sprintf(" - Merge netsplit block: #%-8v\n", c.MergeNetsplitBlock) 514 } 515 banner += "\n" 516 517 // Create a list of forks post-merge 518 banner += "Post-Merge hard forks (timestamp based):\n" 519 if c.ShanghaiTime != nil { 520 banner += fmt.Sprintf(" - Shanghai: @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md)\n", *c.ShanghaiTime) 521 } 522 if c.CancunTime != nil { 523 banner += fmt.Sprintf(" - Cancun: @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md)\n", *c.CancunTime) 524 } 525 if c.PragueTime != nil { 526 banner += fmt.Sprintf(" - Prague: @%-10v\n", *c.PragueTime) 527 } 528 if c.OsakaTime != nil { 529 banner += fmt.Sprintf(" - Osaka: @%-10v\n", *c.OsakaTime) 530 } 531 if c.VerkleTime != nil { 532 banner += fmt.Sprintf(" - Verkle: @%-10v\n", *c.VerkleTime) 533 } 534 return banner 535 } 536 537 // BlobConfig specifies the target and max blobs per block for the associated fork. 538 type BlobConfig struct { 539 Target int `json:"target"` 540 Max int `json:"max"` 541 UpdateFraction uint64 `json:"baseFeeUpdateFraction"` 542 } 543 544 // BlobScheduleConfig determines target and max number of blobs allow per fork. 545 type BlobScheduleConfig struct { 546 Cancun *BlobConfig `json:"cancun,omitempty"` 547 Prague *BlobConfig `json:"prague,omitempty"` 548 Osaka *BlobConfig `json:"osaka,omitempty"` 549 Verkle *BlobConfig `json:"verkle,omitempty"` 550 } 551 552 // IsHomestead returns whether num is either equal to the homestead block or greater. 553 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 554 return isBlockForked(c.HomesteadBlock, num) 555 } 556 557 // IsDAOFork returns whether num is either equal to the DAO fork block or greater. 558 func (c *ChainConfig) IsDAOFork(num *big.Int) bool { 559 return isBlockForked(c.DAOForkBlock, num) 560 } 561 562 // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater. 563 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 564 return isBlockForked(c.EIP150Block, num) 565 } 566 567 // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater. 568 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 569 return isBlockForked(c.EIP155Block, num) 570 } 571 572 // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater. 573 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 574 return isBlockForked(c.EIP158Block, num) 575 } 576 577 // IsByzantium returns whether num is either equal to the Byzantium fork block or greater. 578 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 579 return isBlockForked(c.ByzantiumBlock, num) 580 } 581 582 // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. 583 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 584 return isBlockForked(c.ConstantinopleBlock, num) 585 } 586 587 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. 588 func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { 589 return isBlockForked(c.MuirGlacierBlock, num) 590 } 591 592 // IsPetersburg returns whether num is either 593 // - equal to or greater than the PetersburgBlock fork block, 594 // - OR is nil, and Constantinople is active 595 func (c *ChainConfig) IsPetersburg(num *big.Int) bool { 596 return isBlockForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isBlockForked(c.ConstantinopleBlock, num) 597 } 598 599 // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater. 600 func (c *ChainConfig) IsIstanbul(num *big.Int) bool { 601 return isBlockForked(c.IstanbulBlock, num) 602 } 603 604 // IsBerlin returns whether num is either equal to the Berlin fork block or greater. 605 func (c *ChainConfig) IsBerlin(num *big.Int) bool { 606 return isBlockForked(c.BerlinBlock, num) 607 } 608 609 // IsLondon returns whether num is either equal to the London fork block or greater. 610 func (c *ChainConfig) IsLondon(num *big.Int) bool { 611 return isBlockForked(c.LondonBlock, num) 612 } 613 614 // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. 615 func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool { 616 return isBlockForked(c.ArrowGlacierBlock, num) 617 } 618 619 // IsGrayGlacier returns whether num is either equal to the Gray Glacier (EIP-5133) fork block or greater. 620 func (c *ChainConfig) IsGrayGlacier(num *big.Int) bool { 621 return isBlockForked(c.GrayGlacierBlock, num) 622 } 623 624 // IsTerminalPoWBlock returns whether the given block is the last block of PoW stage. 625 func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool { 626 if c.TerminalTotalDifficulty == nil { 627 return false 628 } 629 return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0 630 } 631 632 // IsShanghai returns whether time is either equal to the Shanghai fork time or greater. 633 func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool { 634 return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time) 635 } 636 637 // IsCancun returns whether time is either equal to the Cancun fork time or greater. 638 func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool { 639 return c.IsLondon(num) && isTimestampForked(c.CancunTime, time) 640 } 641 642 // IsPrague returns whether time is either equal to the Prague fork time or greater. 643 func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool { 644 return c.IsLondon(num) && isTimestampForked(c.PragueTime, time) 645 } 646 647 // IsOsaka returns whether time is either equal to the Osaka fork time or greater. 648 func (c *ChainConfig) IsOsaka(num *big.Int, time uint64) bool { 649 return c.IsLondon(num) && isTimestampForked(c.OsakaTime, time) 650 } 651 652 // IsVerkle returns whether time is either equal to the Verkle fork time or greater. 653 func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { 654 return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time) 655 } 656 657 // IsVerkleGenesis checks whether the verkle fork is activated at the genesis block. 658 // 659 // Verkle mode is considered enabled if the verkle fork time is configured, 660 // regardless of whether the local time has surpassed the fork activation time. 661 // This is a temporary workaround for verkle devnet testing, where verkle is 662 // activated at genesis, and the configured activation date has already passed. 663 // 664 // In production networks (mainnet and public testnets), verkle activation 665 // always occurs after the genesis block, making this function irrelevant in 666 // those cases. 667 func (c *ChainConfig) IsVerkleGenesis() bool { 668 return c.EnableVerkleAtGenesis 669 } 670 671 // IsEIP4762 returns whether eip 4762 has been activated at given block. 672 func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool { 673 return c.IsVerkle(num, time) 674 } 675 676 // CheckCompatible checks whether scheduled fork transitions have been imported 677 // with a mismatching chain configuration. 678 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { 679 var ( 680 bhead = new(big.Int).SetUint64(height) 681 btime = time 682 ) 683 // Iterate checkCompatible to find the lowest conflict. 684 var lasterr *ConfigCompatError 685 for { 686 err := c.checkCompatible(newcfg, bhead, btime) 687 if err == nil || (lasterr != nil && err.RewindToBlock == lasterr.RewindToBlock && err.RewindToTime == lasterr.RewindToTime) { 688 break 689 } 690 lasterr = err 691 692 if err.RewindToTime > 0 { 693 btime = err.RewindToTime 694 } else { 695 bhead.SetUint64(err.RewindToBlock) 696 } 697 } 698 return lasterr 699 } 700 701 // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough 702 // to guarantee that forks can be implemented in a different order than on official networks 703 func (c *ChainConfig) CheckConfigForkOrder() error { 704 type fork struct { 705 name string 706 block *big.Int // forks up to - and including the merge - were defined with block numbers 707 timestamp *uint64 // forks after the merge are scheduled using timestamps 708 optional bool // if true, the fork may be nil and next fork is still allowed 709 } 710 var lastFork fork 711 for _, cur := range []fork{ 712 {name: "homesteadBlock", block: c.HomesteadBlock}, 713 {name: "daoForkBlock", block: c.DAOForkBlock, optional: true}, 714 {name: "eip150Block", block: c.EIP150Block}, 715 {name: "eip155Block", block: c.EIP155Block}, 716 {name: "eip158Block", block: c.EIP158Block}, 717 {name: "byzantiumBlock", block: c.ByzantiumBlock}, 718 {name: "constantinopleBlock", block: c.ConstantinopleBlock}, 719 {name: "petersburgBlock", block: c.PetersburgBlock}, 720 {name: "istanbulBlock", block: c.IstanbulBlock}, 721 {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, 722 {name: "berlinBlock", block: c.BerlinBlock}, 723 {name: "londonBlock", block: c.LondonBlock}, 724 {name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true}, 725 {name: "grayGlacierBlock", block: c.GrayGlacierBlock, optional: true}, 726 {name: "mergeNetsplitBlock", block: c.MergeNetsplitBlock, optional: true}, 727 {name: "shanghaiTime", timestamp: c.ShanghaiTime}, 728 {name: "cancunTime", timestamp: c.CancunTime, optional: true}, 729 {name: "pragueTime", timestamp: c.PragueTime, optional: true}, 730 {name: "osakaTime", timestamp: c.OsakaTime, optional: true}, 731 {name: "verkleTime", timestamp: c.VerkleTime, optional: true}, 732 } { 733 if lastFork.name != "" { 734 switch { 735 // Non-optional forks must all be present in the chain config up to the last defined fork 736 case lastFork.block == nil && lastFork.timestamp == nil && (cur.block != nil || cur.timestamp != nil): 737 if cur.block != nil { 738 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at block %v", 739 lastFork.name, cur.name, cur.block) 740 } else { 741 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at timestamp %v", 742 lastFork.name, cur.name, *cur.timestamp) 743 } 744 745 // Fork (whether defined by block or timestamp) must follow the fork definition sequence 746 case (lastFork.block != nil && cur.block != nil) || (lastFork.timestamp != nil && cur.timestamp != nil): 747 if lastFork.block != nil && lastFork.block.Cmp(cur.block) > 0 { 748 return fmt.Errorf("unsupported fork ordering: %v enabled at block %v, but %v enabled at block %v", 749 lastFork.name, lastFork.block, cur.name, cur.block) 750 } else if lastFork.timestamp != nil && *lastFork.timestamp > *cur.timestamp { 751 return fmt.Errorf("unsupported fork ordering: %v enabled at timestamp %v, but %v enabled at timestamp %v", 752 lastFork.name, *lastFork.timestamp, cur.name, *cur.timestamp) 753 } 754 755 // Timestamp based forks can follow block based ones, but not the other way around 756 if lastFork.timestamp != nil && cur.block != nil { 757 return fmt.Errorf("unsupported fork ordering: %v used timestamp ordering, but %v reverted to block ordering", 758 lastFork.name, cur.name) 759 } 760 } 761 } 762 // If it was optional and not set, then ignore it 763 if !cur.optional || (cur.block != nil || cur.timestamp != nil) { 764 lastFork = cur 765 } 766 } 767 768 // Check that all forks with blobs explicitly define the blob schedule configuration. 769 bsc := c.BlobScheduleConfig 770 if bsc == nil { 771 bsc = new(BlobScheduleConfig) 772 } 773 for _, cur := range []struct { 774 name string 775 timestamp *uint64 776 config *BlobConfig 777 }{ 778 {name: "cancun", timestamp: c.CancunTime, config: bsc.Cancun}, 779 {name: "prague", timestamp: c.PragueTime, config: bsc.Prague}, 780 {name: "osaka", timestamp: c.OsakaTime, config: bsc.Osaka}, 781 } { 782 if cur.config != nil { 783 if err := cur.config.validate(); err != nil { 784 return fmt.Errorf("invalid chain configuration in blobSchedule for fork %q: %v", cur.name, err) 785 } 786 } 787 if cur.timestamp != nil { 788 // If the fork is configured, a blob schedule must be defined for it. 789 if cur.config == nil { 790 return fmt.Errorf("invalid chain configuration: missing entry for fork %q in blobSchedule", cur.name) 791 } 792 } 793 } 794 return nil 795 } 796 797 func (bc *BlobConfig) validate() error { 798 if bc.Max < 0 { 799 return errors.New("max < 0") 800 } 801 if bc.Target < 0 { 802 return errors.New("target < 0") 803 } 804 if bc.UpdateFraction == 0 { 805 return errors.New("update fraction must be defined and non-zero") 806 } 807 return nil 808 } 809 810 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64) *ConfigCompatError { 811 if isForkBlockIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, headNumber) { 812 return newBlockCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 813 } 814 if isForkBlockIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, headNumber) { 815 return newBlockCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) 816 } 817 if c.IsDAOFork(headNumber) && c.DAOForkSupport != newcfg.DAOForkSupport { 818 return newBlockCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) 819 } 820 if isForkBlockIncompatible(c.EIP150Block, newcfg.EIP150Block, headNumber) { 821 return newBlockCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 822 } 823 if isForkBlockIncompatible(c.EIP155Block, newcfg.EIP155Block, headNumber) { 824 return newBlockCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 825 } 826 if isForkBlockIncompatible(c.EIP158Block, newcfg.EIP158Block, headNumber) { 827 return newBlockCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 828 } 829 if c.IsEIP158(headNumber) && !configBlockEqual(c.ChainID, newcfg.ChainID) { 830 return newBlockCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 831 } 832 if isForkBlockIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, headNumber) { 833 return newBlockCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 834 } 835 if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, headNumber) { 836 return newBlockCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 837 } 838 if isForkBlockIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, headNumber) { 839 // the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople 840 // mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set 841 if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, headNumber) { 842 return newBlockCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock) 843 } 844 } 845 if isForkBlockIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, headNumber) { 846 return newBlockCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock) 847 } 848 if isForkBlockIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, headNumber) { 849 return newBlockCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock) 850 } 851 if isForkBlockIncompatible(c.BerlinBlock, newcfg.BerlinBlock, headNumber) { 852 return newBlockCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock) 853 } 854 if isForkBlockIncompatible(c.LondonBlock, newcfg.LondonBlock, headNumber) { 855 return newBlockCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock) 856 } 857 if isForkBlockIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, headNumber) { 858 return newBlockCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock) 859 } 860 if isForkBlockIncompatible(c.GrayGlacierBlock, newcfg.GrayGlacierBlock, headNumber) { 861 return newBlockCompatError("Gray Glacier fork block", c.GrayGlacierBlock, newcfg.GrayGlacierBlock) 862 } 863 if isForkBlockIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, headNumber) { 864 return newBlockCompatError("Merge netsplit fork block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock) 865 } 866 if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) { 867 return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime) 868 } 869 if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) { 870 return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime) 871 } 872 if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp) { 873 return newTimestampCompatError("Prague fork timestamp", c.PragueTime, newcfg.PragueTime) 874 } 875 if isForkTimestampIncompatible(c.OsakaTime, newcfg.OsakaTime, headTimestamp) { 876 return newTimestampCompatError("Osaka fork timestamp", c.OsakaTime, newcfg.OsakaTime) 877 } 878 if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) { 879 return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime) 880 } 881 return nil 882 } 883 884 // BaseFeeChangeDenominator bounds the amount the base fee can change between blocks. 885 func (c *ChainConfig) BaseFeeChangeDenominator() uint64 { 886 return DefaultBaseFeeChangeDenominator 887 } 888 889 // ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have. 890 func (c *ChainConfig) ElasticityMultiplier() uint64 { 891 return DefaultElasticityMultiplier 892 } 893 894 // LatestFork returns the latest time-based fork that would be active for the given time. 895 func (c *ChainConfig) LatestFork(time uint64) forks.Fork { 896 // Assume last non-time-based fork has passed. 897 london := c.LondonBlock 898 899 switch { 900 case c.IsOsaka(london, time): 901 return forks.Osaka 902 case c.IsPrague(london, time): 903 return forks.Prague 904 case c.IsCancun(london, time): 905 return forks.Cancun 906 case c.IsShanghai(london, time): 907 return forks.Shanghai 908 default: 909 return forks.Paris 910 } 911 } 912 913 // Timestamp returns the timestamp associated with the fork or returns nil if 914 // the fork isn't defined or isn't a time-based fork. 915 func (c *ChainConfig) Timestamp(fork forks.Fork) *uint64 { 916 switch { 917 case fork == forks.Osaka: 918 return c.OsakaTime 919 case fork == forks.Prague: 920 return c.PragueTime 921 case fork == forks.Cancun: 922 return c.CancunTime 923 case fork == forks.Shanghai: 924 return c.ShanghaiTime 925 default: 926 return nil 927 } 928 } 929 930 // isForkBlockIncompatible returns true if a fork scheduled at block s1 cannot be 931 // rescheduled to block s2 because head is already past the fork. 932 func isForkBlockIncompatible(s1, s2, head *big.Int) bool { 933 return (isBlockForked(s1, head) || isBlockForked(s2, head)) && !configBlockEqual(s1, s2) 934 } 935 936 // isBlockForked returns whether a fork scheduled at block s is active at the 937 // given head block. Whilst this method is the same as isTimestampForked, they 938 // are explicitly separate for clearer reading. 939 func isBlockForked(s, head *big.Int) bool { 940 if s == nil || head == nil { 941 return false 942 } 943 return s.Cmp(head) <= 0 944 } 945 946 func configBlockEqual(x, y *big.Int) bool { 947 if x == nil { 948 return y == nil 949 } 950 if y == nil { 951 return x == nil 952 } 953 return x.Cmp(y) == 0 954 } 955 956 // isForkTimestampIncompatible returns true if a fork scheduled at timestamp s1 957 // cannot be rescheduled to timestamp s2 because head is already past the fork. 958 func isForkTimestampIncompatible(s1, s2 *uint64, head uint64) bool { 959 return (isTimestampForked(s1, head) || isTimestampForked(s2, head)) && !configTimestampEqual(s1, s2) 960 } 961 962 // isTimestampForked returns whether a fork scheduled at timestamp s is active 963 // at the given head timestamp. Whilst this method is the same as isBlockForked, 964 // they are explicitly separate for clearer reading. 965 func isTimestampForked(s *uint64, head uint64) bool { 966 if s == nil { 967 return false 968 } 969 return *s <= head 970 } 971 972 func configTimestampEqual(x, y *uint64) bool { 973 if x == nil { 974 return y == nil 975 } 976 if y == nil { 977 return x == nil 978 } 979 return *x == *y 980 } 981 982 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 983 // ChainConfig that would alter the past. 984 type ConfigCompatError struct { 985 What string 986 987 // block numbers of the stored and new configurations if block based forking 988 StoredBlock, NewBlock *big.Int 989 990 // timestamps of the stored and new configurations if time based forking 991 StoredTime, NewTime *uint64 992 993 // the block number to which the local chain must be rewound to correct the error 994 RewindToBlock uint64 995 996 // the timestamp to which the local chain must be rewound to correct the error 997 RewindToTime uint64 998 } 999 1000 func newBlockCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 1001 var rew *big.Int 1002 switch { 1003 case storedblock == nil: 1004 rew = newblock 1005 case newblock == nil || storedblock.Cmp(newblock) < 0: 1006 rew = storedblock 1007 default: 1008 rew = newblock 1009 } 1010 err := &ConfigCompatError{ 1011 What: what, 1012 StoredBlock: storedblock, 1013 NewBlock: newblock, 1014 RewindToBlock: 0, 1015 } 1016 if rew != nil && rew.Sign() > 0 { 1017 err.RewindToBlock = rew.Uint64() - 1 1018 } 1019 return err 1020 } 1021 1022 func newTimestampCompatError(what string, storedtime, newtime *uint64) *ConfigCompatError { 1023 var rew *uint64 1024 switch { 1025 case storedtime == nil: 1026 rew = newtime 1027 case newtime == nil || *storedtime < *newtime: 1028 rew = storedtime 1029 default: 1030 rew = newtime 1031 } 1032 err := &ConfigCompatError{ 1033 What: what, 1034 StoredTime: storedtime, 1035 NewTime: newtime, 1036 RewindToTime: 0, 1037 } 1038 if rew != nil && *rew != 0 { 1039 err.RewindToTime = *rew - 1 1040 } 1041 return err 1042 } 1043 1044 func (err *ConfigCompatError) Error() string { 1045 if err.StoredBlock != nil { 1046 return fmt.Sprintf("mismatching %s in database (have block %d, want block %d, rewindto block %d)", err.What, err.StoredBlock, err.NewBlock, err.RewindToBlock) 1047 } 1048 1049 if err.StoredTime == nil && err.NewTime == nil { 1050 return "" 1051 } else if err.StoredTime == nil && err.NewTime != nil { 1052 return fmt.Sprintf("mismatching %s in database (have timestamp nil, want timestamp %d, rewindto timestamp %d)", err.What, *err.NewTime, err.RewindToTime) 1053 } else if err.StoredTime != nil && err.NewTime == nil { 1054 return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp nil, rewindto timestamp %d)", err.What, *err.StoredTime, err.RewindToTime) 1055 } 1056 return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp %d, rewindto timestamp %d)", err.What, *err.StoredTime, *err.NewTime, err.RewindToTime) 1057 } 1058 1059 // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions 1060 // that do not have or require information about the block. 1061 // 1062 // Rules is a one time interface meaning that it shouldn't be used in between transition 1063 // phases. 1064 type Rules struct { 1065 ChainID *big.Int 1066 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 1067 IsEIP2929, IsEIP4762 bool 1068 IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool 1069 IsBerlin, IsLondon bool 1070 IsMerge, IsShanghai, IsCancun, IsPrague, IsOsaka bool 1071 IsVerkle bool 1072 } 1073 1074 // Rules ensures c's ChainID is not nil. 1075 func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules { 1076 chainID := c.ChainID 1077 if chainID == nil { 1078 chainID = new(big.Int) 1079 } 1080 // disallow setting Merge out of order 1081 isMerge = isMerge && c.IsLondon(num) 1082 isVerkle := isMerge && c.IsVerkle(num, timestamp) 1083 return Rules{ 1084 ChainID: new(big.Int).Set(chainID), 1085 IsHomestead: c.IsHomestead(num), 1086 IsEIP150: c.IsEIP150(num), 1087 IsEIP155: c.IsEIP155(num), 1088 IsEIP158: c.IsEIP158(num), 1089 IsByzantium: c.IsByzantium(num), 1090 IsConstantinople: c.IsConstantinople(num), 1091 IsPetersburg: c.IsPetersburg(num), 1092 IsIstanbul: c.IsIstanbul(num), 1093 IsBerlin: c.IsBerlin(num), 1094 IsEIP2929: c.IsBerlin(num) && !isVerkle, 1095 IsLondon: c.IsLondon(num), 1096 IsMerge: isMerge, 1097 IsShanghai: isMerge && c.IsShanghai(num, timestamp), 1098 IsCancun: isMerge && c.IsCancun(num, timestamp), 1099 IsPrague: isMerge && c.IsPrague(num, timestamp), 1100 IsOsaka: isMerge && c.IsOsaka(num, timestamp), 1101 IsVerkle: isVerkle, 1102 IsEIP4762: isVerkle, 1103 } 1104 }