github.com/electroneum/electroneum-sc@v0.0.0-20230105223411-3bc1d078281e/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 "github.com/electroneum/electroneum-sc/common" 25 "github.com/electroneum/electroneum-sc/common/math" 26 "golang.org/x/crypto/sha3" 27 ) 28 29 // Genesis hashes to enforce below configs on. 30 var ( 31 MainnetGenesisHash = common.HexToHash("0x4fda998638776057c8c27989bc021aed4b813fcebd483bf7a6b139f6efb324a6") 32 StagenetGenesisHash = common.HexToHash("0x619e6f8fa6e99eb9829e1f0c7fa62a999d47bf8a7da51a72c2af3cd83cb6e4a3") 33 TestnetGenesisHash = common.HexToHash("0xcf1b6615aa11a133442a21cc1bf9fbe935fd146f74123ba4f3f0e107362c3eb4") 34 ) 35 36 // TrustedCheckpoints associates each known checkpoint with the genesis hash of 37 // the chain it belongs to. 38 var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{} 39 40 // CheckpointOracles associates each known checkpoint oracles with the genesis hash of 41 // the chain it belongs to. 42 var CheckpointOracles = map[common.Hash]*CheckpointOracleConfig{} 43 44 var ( 45 // MainnetChainConfig is the chain parameters to run a node on the main network. 46 MainnetChainConfig = &ChainConfig{ 47 ChainID: big.NewInt(52014), 48 HomesteadBlock: big.NewInt(0), 49 DAOForkBlock: nil, 50 DAOForkSupport: true, 51 EIP150Block: big.NewInt(0), 52 EIP155Block: big.NewInt(0), 53 EIP158Block: big.NewInt(0), 54 ByzantiumBlock: big.NewInt(0), 55 ConstantinopleBlock: big.NewInt(0), 56 PetersburgBlock: big.NewInt(0), 57 IstanbulBlock: big.NewInt(0), 58 MuirGlacierBlock: nil, 59 BerlinBlock: big.NewInt(0), 60 LondonBlock: big.NewInt(0), 61 ArrowGlacierBlock: nil, 62 IBFT: &IBFTConfig{ 63 BlockPeriodSeconds: 5, 64 EpochLength: 17280, 65 ProposerPolicy: 0, 66 RequestTimeoutSeconds: 10, 67 }, 68 GenesisETN: math.MustParseBig256("17000000000000000000000000000"), //TODO: Get the exact circulating supply at time of blockchain migration 69 } 70 71 // StagenetChainConfig is the chain parameters to run a node on the test network. 72 StagenetChainConfig = &ChainConfig{ 73 ChainID: big.NewInt(5201419), 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 IBFT: &IBFTConfig{ 89 BlockPeriodSeconds: 5, 90 EpochLength: 17280, 91 ProposerPolicy: 0, 92 RequestTimeoutSeconds: 10, 93 }, 94 GenesisETN: math.MustParseBig256("2000000000000000000000000000"), // 2Bn ETN allocated to developer accounts for testing 95 } 96 97 // TestnetChainConfig is the chain parameters to run a node on the test network. 98 TestnetChainConfig = &ChainConfig{ 99 ChainID: big.NewInt(5201420), 100 HomesteadBlock: big.NewInt(0), 101 DAOForkBlock: nil, 102 DAOForkSupport: true, 103 EIP150Block: big.NewInt(0), 104 EIP155Block: big.NewInt(0), 105 EIP158Block: big.NewInt(0), 106 ByzantiumBlock: big.NewInt(0), 107 ConstantinopleBlock: big.NewInt(0), 108 PetersburgBlock: big.NewInt(0), 109 IstanbulBlock: big.NewInt(0), 110 MuirGlacierBlock: nil, 111 BerlinBlock: big.NewInt(0), 112 LondonBlock: big.NewInt(0), 113 ArrowGlacierBlock: nil, 114 IBFT: &IBFTConfig{ 115 BlockPeriodSeconds: 5, 116 EpochLength: 17280, 117 ProposerPolicy: 0, 118 RequestTimeoutSeconds: 10, 119 }, 120 GenesisETN: math.MustParseBig256("2000000000000000000000000000"), // 2Bn ETN allocated to developer accounts for testing 121 } 122 123 // AllEthashProtocolChanges contains every protocol change (EIPs) introduced 124 // and accepted by the Ethereum core developers into the Ethash consensus. 125 // 126 // This configuration is intentionally not using keyed fields to force anyone 127 // adding flags to the config to also have to set these fields. 128 AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil, big.NewInt(0)} 129 130 // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced 131 // and accepted by the Ethereum core developers into the Clique consensus. 132 // 133 // This configuration is intentionally not using keyed fields to force anyone 134 // adding flags to the config to also have to set these fields. 135 AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil, big.NewInt(0)} 136 137 TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil, big.NewInt(0)} 138 TestRules = TestChainConfig.Rules(new(big.Int), false) 139 ) 140 141 // TrustedCheckpoint represents a set of post-processed trie roots (CHT and 142 // BloomTrie) associated with the appropriate section index and head hash. It is 143 // used to start light syncing from this checkpoint and avoid downloading the 144 // entire header chain while still being able to securely access old headers/logs. 145 type TrustedCheckpoint struct { 146 SectionIndex uint64 `json:"sectionIndex"` 147 SectionHead common.Hash `json:"sectionHead"` 148 CHTRoot common.Hash `json:"chtRoot"` 149 BloomRoot common.Hash `json:"bloomRoot"` 150 } 151 152 // HashEqual returns an indicator comparing the itself hash with given one. 153 func (c *TrustedCheckpoint) HashEqual(hash common.Hash) bool { 154 if c.Empty() { 155 return hash == common.Hash{} 156 } 157 return c.Hash() == hash 158 } 159 160 // Hash returns the hash of checkpoint's four key fields(index, sectionHead, chtRoot and bloomTrieRoot). 161 func (c *TrustedCheckpoint) Hash() common.Hash { 162 var sectionIndex [8]byte 163 binary.BigEndian.PutUint64(sectionIndex[:], c.SectionIndex) 164 165 w := sha3.NewLegacyKeccak256() 166 w.Write(sectionIndex[:]) 167 w.Write(c.SectionHead[:]) 168 w.Write(c.CHTRoot[:]) 169 w.Write(c.BloomRoot[:]) 170 171 var h common.Hash 172 w.Sum(h[:0]) 173 return h 174 } 175 176 // Empty returns an indicator whether the checkpoint is regarded as empty. 177 func (c *TrustedCheckpoint) Empty() bool { 178 return c.SectionHead == (common.Hash{}) || c.CHTRoot == (common.Hash{}) || c.BloomRoot == (common.Hash{}) 179 } 180 181 // CheckpointOracleConfig represents a set of checkpoint contract(which acts as an oracle) 182 // config which used for light client checkpoint syncing. 183 type CheckpointOracleConfig struct { 184 Address common.Address `json:"address"` 185 Signers []common.Address `json:"signers"` 186 Threshold uint64 `json:"threshold"` 187 } 188 189 // ChainConfig is the core config which determines the blockchain settings. 190 // 191 // ChainConfig is stored in the database on a per block basis. This means 192 // that any network, identified by its genesis block, can have its own 193 // set of configuration options. 194 type ChainConfig struct { 195 ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection 196 197 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 198 199 DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) 200 DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork 201 202 // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) 203 EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 204 EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed) 205 206 EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block 207 EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block 208 209 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 210 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 211 PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) 212 IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) 213 MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) 214 BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin) 215 LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london) 216 ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated) 217 MergeForkBlock *big.Int `json:"mergeForkBlock,omitempty"` // EIP-3675 (TheMerge) switch block (nil = no fork, 0 = already in merge proceedings) 218 219 // TerminalTotalDifficulty is the amount of total difficulty reached by 220 // the network that triggers the consensus upgrade. 221 TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"` 222 223 // Various consensus engines 224 Ethash *EthashConfig `json:"ethash,omitempty"` 225 Clique *CliqueConfig `json:"clique,omitempty"` 226 IBFT *IBFTConfig `json:"ibft,omitempty"` 227 228 GenesisETN *big.Int `json:"genesisETN,omitempty"` 229 } 230 231 // EthashConfig is the consensus engine configs for proof-of-work based sealing. 232 type EthashConfig struct{} 233 234 // String implements the stringer interface, returning the consensus engine details. 235 func (c *EthashConfig) String() string { 236 return "ethash" 237 } 238 239 // CliqueConfig is the consensus engine configs for proof-of-authority based sealing. 240 type CliqueConfig struct { 241 Period uint64 `json:"period"` // Number of seconds between blocks to enforce 242 Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint 243 } 244 245 // String implements the stringer interface, returning the consensus engine details. 246 func (c *CliqueConfig) String() string { 247 return "clique" 248 } 249 250 // IBFTConfig is the consensus engine configs for Istanbul based sealing. 251 type IBFTConfig struct { 252 EpochLength uint64 `json:"epochlength"` // Number of blocks that should pass before pending validator votes are reset 253 BlockPeriodSeconds uint64 `json:"blockperiodseconds"` // Minimum time between two consecutive IBFT or QBFT blocks’ timestamps in seconds 254 RequestTimeoutSeconds uint64 `json:"requesttimeoutseconds"` // Minimum request timeout for each IBFT or QBFT round in milliseconds 255 ProposerPolicy uint64 `json:"policy"` // The policy for proposer selection 256 } 257 258 func (c IBFTConfig) String() string { 259 return "IBFT" 260 } 261 262 // String implements the fmt.Stringer interface. 263 func (c *ChainConfig) String() string { 264 var engine interface{} 265 switch { 266 case c.Ethash != nil: 267 engine = c.Ethash 268 case c.Clique != nil: 269 engine = c.Clique 270 case c.IBFT != nil: 271 engine = c.IBFT 272 default: 273 engine = "unknown" 274 } 275 return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, MergeFork: %v, Terminal TD: %v, Engine: %v}", 276 c.ChainID, 277 c.HomesteadBlock, 278 c.DAOForkBlock, 279 c.DAOForkSupport, 280 c.EIP150Block, 281 c.EIP155Block, 282 c.EIP158Block, 283 c.ByzantiumBlock, 284 c.ConstantinopleBlock, 285 c.PetersburgBlock, 286 c.IstanbulBlock, 287 c.MuirGlacierBlock, 288 c.BerlinBlock, 289 c.LondonBlock, 290 c.ArrowGlacierBlock, 291 c.MergeForkBlock, 292 c.TerminalTotalDifficulty, 293 engine, 294 ) 295 } 296 297 // IsHomestead returns whether num is either equal to the homestead block or greater. 298 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 299 return isForked(c.HomesteadBlock, num) 300 } 301 302 // IsDAOFork returns whether num is either equal to the DAO fork block or greater. 303 func (c *ChainConfig) IsDAOFork(num *big.Int) bool { 304 return isForked(c.DAOForkBlock, num) 305 } 306 307 // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater. 308 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 309 return isForked(c.EIP150Block, num) 310 } 311 312 // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater. 313 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 314 return isForked(c.EIP155Block, num) 315 } 316 317 // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater. 318 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 319 return isForked(c.EIP158Block, num) 320 } 321 322 // IsByzantium returns whether num is either equal to the Byzantium fork block or greater. 323 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 324 return isForked(c.ByzantiumBlock, num) 325 } 326 327 // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. 328 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 329 return isForked(c.ConstantinopleBlock, num) 330 } 331 332 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. 333 func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { 334 return isForked(c.MuirGlacierBlock, num) 335 } 336 337 // IsPetersburg returns whether num is either 338 // - equal to or greater than the PetersburgBlock fork block, 339 // - OR is nil, and Constantinople is active 340 func (c *ChainConfig) IsPetersburg(num *big.Int) bool { 341 return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num) 342 } 343 344 // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater. 345 func (c *ChainConfig) IsIstanbul(num *big.Int) bool { 346 return isForked(c.IstanbulBlock, num) 347 } 348 349 // IsBerlin returns whether num is either equal to the Berlin fork block or greater. 350 func (c *ChainConfig) IsBerlin(num *big.Int) bool { 351 return isForked(c.BerlinBlock, num) 352 } 353 354 // IsLondon returns whether num is either equal to the London fork block or greater. 355 func (c *ChainConfig) IsLondon(num *big.Int) bool { 356 return isForked(c.LondonBlock, num) 357 } 358 359 // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater. 360 func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool { 361 return isForked(c.ArrowGlacierBlock, num) 362 } 363 364 // IsTerminalPoWBlock returns whether the given block is the last block of PoW stage. 365 func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool { 366 if c.TerminalTotalDifficulty == nil { 367 return false 368 } 369 return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0 370 } 371 372 // CheckCompatible checks whether scheduled fork transitions have been imported 373 // with a mismatching chain configuration. 374 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { 375 bhead := new(big.Int).SetUint64(height) 376 377 // Iterate checkCompatible to find the lowest conflict. 378 var lasterr *ConfigCompatError 379 for { 380 err := c.checkCompatible(newcfg, bhead) 381 if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { 382 break 383 } 384 lasterr = err 385 bhead.SetUint64(err.RewindTo) 386 } 387 return lasterr 388 } 389 390 // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough 391 // to guarantee that forks can be implemented in a different order than on official networks 392 func (c *ChainConfig) CheckConfigForkOrder() error { 393 type fork struct { 394 name string 395 block *big.Int 396 optional bool // if true, the fork may be nil and next fork is still allowed 397 } 398 var lastFork fork 399 for _, cur := range []fork{ 400 {name: "homesteadBlock", block: c.HomesteadBlock}, 401 {name: "daoForkBlock", block: c.DAOForkBlock, optional: true}, 402 {name: "eip150Block", block: c.EIP150Block}, 403 {name: "eip155Block", block: c.EIP155Block}, 404 {name: "eip158Block", block: c.EIP158Block}, 405 {name: "byzantiumBlock", block: c.ByzantiumBlock}, 406 {name: "constantinopleBlock", block: c.ConstantinopleBlock}, 407 {name: "petersburgBlock", block: c.PetersburgBlock}, 408 {name: "istanbulBlock", block: c.IstanbulBlock}, 409 {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, 410 {name: "berlinBlock", block: c.BerlinBlock}, 411 {name: "londonBlock", block: c.LondonBlock}, 412 {name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true}, 413 {name: "mergeStartBlock", block: c.MergeForkBlock, optional: true}, 414 } { 415 if lastFork.name != "" { 416 // Next one must be higher number 417 if lastFork.block == nil && cur.block != nil { 418 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v", 419 lastFork.name, cur.name, cur.block) 420 } 421 if lastFork.block != nil && cur.block != nil { 422 if lastFork.block.Cmp(cur.block) > 0 { 423 return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v", 424 lastFork.name, lastFork.block, cur.name, cur.block) 425 } 426 } 427 } 428 // If it was optional and not set, then ignore it 429 if !cur.optional || cur.block != nil { 430 lastFork = cur 431 } 432 } 433 return nil 434 } 435 436 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { 437 if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { 438 return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 439 } 440 if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) { 441 return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) 442 } 443 if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport { 444 return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) 445 } 446 if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) { 447 return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 448 } 449 if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) { 450 return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 451 } 452 if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) { 453 return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 454 } 455 if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) { 456 return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 457 } 458 if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { 459 return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 460 } 461 if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { 462 return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 463 } 464 if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) { 465 // the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople 466 // mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set 467 if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, head) { 468 return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock) 469 } 470 } 471 if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) { 472 return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock) 473 } 474 if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) { 475 return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock) 476 } 477 if isForkIncompatible(c.BerlinBlock, newcfg.BerlinBlock, head) { 478 return newCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock) 479 } 480 if isForkIncompatible(c.LondonBlock, newcfg.LondonBlock, head) { 481 return newCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock) 482 } 483 if isForkIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, head) { 484 return newCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock) 485 } 486 if isForkIncompatible(c.MergeForkBlock, newcfg.MergeForkBlock, head) { 487 return newCompatError("Merge Start fork block", c.MergeForkBlock, newcfg.MergeForkBlock) 488 } 489 return nil 490 } 491 492 // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to 493 // block s2 because head is already past the fork. 494 func isForkIncompatible(s1, s2, head *big.Int) bool { 495 return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) 496 } 497 498 // isForked returns whether a fork scheduled at block s is active at the given head block. 499 func isForked(s, head *big.Int) bool { 500 if s == nil || head == nil { 501 return false 502 } 503 return s.Cmp(head) <= 0 504 } 505 506 func configNumEqual(x, y *big.Int) bool { 507 if x == nil { 508 return y == nil 509 } 510 if y == nil { 511 return x == nil 512 } 513 return x.Cmp(y) == 0 514 } 515 516 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 517 // ChainConfig that would alter the past. 518 type ConfigCompatError struct { 519 What string 520 // block numbers of the stored and new configurations 521 StoredConfig, NewConfig *big.Int 522 // the block number to which the local chain must be rewound to correct the error 523 RewindTo uint64 524 } 525 526 func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 527 var rew *big.Int 528 switch { 529 case storedblock == nil: 530 rew = newblock 531 case newblock == nil || storedblock.Cmp(newblock) < 0: 532 rew = storedblock 533 default: 534 rew = newblock 535 } 536 err := &ConfigCompatError{what, storedblock, newblock, 0} 537 if rew != nil && rew.Sign() > 0 { 538 err.RewindTo = rew.Uint64() - 1 539 } 540 return err 541 } 542 543 func (err *ConfigCompatError) Error() string { 544 return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) 545 } 546 547 // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions 548 // that do not have or require information about the block. 549 // 550 // Rules is a one time interface meaning that it shouldn't be used in between transition 551 // phases. 552 type Rules struct { 553 ChainID *big.Int 554 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 555 IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool 556 IsBerlin, IsLondon bool 557 IsMerge bool 558 } 559 560 // Rules ensures c's ChainID is not nil. 561 func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules { 562 chainID := c.ChainID 563 if chainID == nil { 564 chainID = new(big.Int) 565 } 566 return Rules{ 567 ChainID: new(big.Int).Set(chainID), 568 IsHomestead: c.IsHomestead(num), 569 IsEIP150: c.IsEIP150(num), 570 IsEIP155: c.IsEIP155(num), 571 IsEIP158: c.IsEIP158(num), 572 IsByzantium: c.IsByzantium(num), 573 IsConstantinople: c.IsConstantinople(num), 574 IsPetersburg: c.IsPetersburg(num), 575 IsIstanbul: c.IsIstanbul(num), 576 IsBerlin: c.IsBerlin(num), 577 IsLondon: c.IsLondon(num), 578 IsMerge: isMerge, 579 } 580 }