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