github.com/MetalBlockchain/subnet-evm@v0.6.3/params/config.go (about) 1 // (c) 2019-2020, Ava Labs, Inc. 2 // 3 // This file is a derived work, based on the go-ethereum library whose original 4 // notices appear below. 5 // 6 // It is distributed under a license compatible with the licensing terms of the 7 // original code from which it is derived. 8 // 9 // Much love to the original authors for their work. 10 // ********** 11 // Copyright 2016 The go-ethereum Authors 12 // This file is part of the go-ethereum library. 13 // 14 // The go-ethereum library is free software: you can redistribute it and/or modify 15 // it under the terms of the GNU Lesser General Public License as published by 16 // the Free Software Foundation, either version 3 of the License, or 17 // (at your option) any later version. 18 // 19 // The go-ethereum library is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU Lesser General Public License for more details. 23 // 24 // You should have received a copy of the GNU Lesser General Public License 25 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 26 27 package params 28 29 import ( 30 "encoding/json" 31 "errors" 32 "fmt" 33 "math/big" 34 "time" 35 36 "github.com/MetalBlockchain/metalgo/utils/constants" 37 "github.com/MetalBlockchain/subnet-evm/commontype" 38 "github.com/MetalBlockchain/subnet-evm/precompile/modules" 39 "github.com/MetalBlockchain/subnet-evm/precompile/precompileconfig" 40 "github.com/MetalBlockchain/subnet-evm/utils" 41 "github.com/ethereum/go-ethereum/common" 42 ) 43 44 const maxJSONLen = 64 * 1024 * 1024 // 64MB 45 46 var ( 47 errNonGenesisForkByHeight = errors.New("subnet-evm only supports forking by height at the genesis block") 48 49 SubnetEVMChainID = big.NewInt(43214) 50 51 // For legacy tests 52 MinGasPrice int64 = 225_000_000_000 53 TestInitialBaseFee int64 = 225_000_000_000 54 TestMaxBaseFee int64 = 225_000_000_000 55 56 DynamicFeeExtraDataSize = 80 57 RollupWindow uint64 = 10 58 59 DefaultFeeConfig = commontype.FeeConfig{ 60 GasLimit: big.NewInt(8_000_000), 61 TargetBlockRate: 2, // in seconds 62 63 MinBaseFee: big.NewInt(25_000_000_000), 64 TargetGas: big.NewInt(15_000_000), 65 BaseFeeChangeDenominator: big.NewInt(36), 66 67 MinBlockGasCost: big.NewInt(0), 68 MaxBlockGasCost: big.NewInt(1_000_000), 69 BlockGasCostStep: big.NewInt(200_000), 70 } 71 ) 72 73 var ( 74 // SubnetEVMDefaultConfig is the default configuration 75 // without any network upgrades. 76 SubnetEVMDefaultChainConfig = &ChainConfig{ 77 ChainID: SubnetEVMChainID, 78 FeeConfig: DefaultFeeConfig, 79 AllowFeeRecipients: false, 80 81 HomesteadBlock: big.NewInt(0), 82 EIP150Block: big.NewInt(0), 83 EIP155Block: big.NewInt(0), 84 EIP158Block: big.NewInt(0), 85 ByzantiumBlock: big.NewInt(0), 86 ConstantinopleBlock: big.NewInt(0), 87 PetersburgBlock: big.NewInt(0), 88 IstanbulBlock: big.NewInt(0), 89 MuirGlacierBlock: big.NewInt(0), 90 NetworkUpgrades: getDefaultNetworkUpgrades(constants.MainnetID), // This can be changed to correct network (local, test) via VM. 91 GenesisPrecompiles: Precompiles{}, 92 } 93 94 TestChainConfig = &ChainConfig{ 95 AvalancheContext: AvalancheContext{utils.TestSnowContext()}, 96 ChainID: big.NewInt(1), 97 FeeConfig: DefaultFeeConfig, 98 AllowFeeRecipients: false, 99 HomesteadBlock: big.NewInt(0), 100 EIP150Block: big.NewInt(0), 101 EIP155Block: big.NewInt(0), 102 EIP158Block: big.NewInt(0), 103 ByzantiumBlock: big.NewInt(0), 104 ConstantinopleBlock: big.NewInt(0), 105 PetersburgBlock: big.NewInt(0), 106 IstanbulBlock: big.NewInt(0), 107 MuirGlacierBlock: big.NewInt(0), 108 NetworkUpgrades: NetworkUpgrades{ 109 SubnetEVMTimestamp: utils.NewUint64(0), 110 DurangoTimestamp: utils.NewUint64(0), 111 }, 112 GenesisPrecompiles: Precompiles{}, 113 UpgradeConfig: UpgradeConfig{}, 114 } 115 116 TestSubnetEVMConfig = &ChainConfig{ 117 AvalancheContext: AvalancheContext{utils.TestSnowContext()}, 118 ChainID: big.NewInt(1), 119 FeeConfig: DefaultFeeConfig, 120 AllowFeeRecipients: false, 121 HomesteadBlock: big.NewInt(0), 122 EIP150Block: big.NewInt(0), 123 EIP155Block: big.NewInt(0), 124 EIP158Block: big.NewInt(0), 125 ByzantiumBlock: big.NewInt(0), 126 ConstantinopleBlock: big.NewInt(0), 127 PetersburgBlock: big.NewInt(0), 128 IstanbulBlock: big.NewInt(0), 129 MuirGlacierBlock: big.NewInt(0), 130 NetworkUpgrades: NetworkUpgrades{ 131 SubnetEVMTimestamp: utils.NewUint64(0), 132 }, 133 GenesisPrecompiles: Precompiles{}, 134 UpgradeConfig: UpgradeConfig{}, 135 } 136 137 TestPreSubnetEVMConfig = &ChainConfig{ 138 AvalancheContext: AvalancheContext{utils.TestSnowContext()}, 139 ChainID: big.NewInt(1), 140 FeeConfig: DefaultFeeConfig, 141 AllowFeeRecipients: false, 142 HomesteadBlock: big.NewInt(0), 143 EIP150Block: big.NewInt(0), 144 EIP155Block: big.NewInt(0), 145 EIP158Block: big.NewInt(0), 146 ByzantiumBlock: big.NewInt(0), 147 ConstantinopleBlock: big.NewInt(0), 148 PetersburgBlock: big.NewInt(0), 149 IstanbulBlock: big.NewInt(0), 150 MuirGlacierBlock: big.NewInt(0), 151 NetworkUpgrades: NetworkUpgrades{}, 152 GenesisPrecompiles: Precompiles{}, 153 UpgradeConfig: UpgradeConfig{}, 154 } 155 156 TestRules = TestChainConfig.Rules(new(big.Int), 0) 157 ) 158 159 func getUpgradeTime(networkID uint32, upgradeTimes map[uint32]time.Time) *uint64 { 160 if upgradeTime, ok := upgradeTimes[networkID]; ok { 161 return utils.TimeToNewUint64(upgradeTime) 162 } 163 // If the upgrade time isn't specified, default being enabled in the 164 // genesis. 165 return utils.NewUint64(0) 166 } 167 168 // ChainConfig is the core config which determines the blockchain settings. 169 // 170 // ChainConfig is stored in the database on a per block basis. This means 171 // that any network, identified by its genesis block, can have its own 172 // set of configuration options. 173 type ChainConfig struct { 174 ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection 175 176 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 177 178 // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) 179 EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 180 EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block 181 EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block 182 183 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 184 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 185 PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) 186 IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) 187 MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) 188 189 // Cancun activates the Cancun upgrade from Ethereum. (nil = no fork, 0 = already activated) 190 CancunTime *uint64 `json:"cancunTime,omitempty"` 191 192 NetworkUpgrades // Config for timestamps that enable network upgrades. Skip encoding/decoding directly into ChainConfig. 193 194 AvalancheContext `json:"-"` // Avalanche specific context set during VM initialization. Not serialized. 195 196 FeeConfig commontype.FeeConfig `json:"feeConfig"` // Set the configuration for the dynamic fee algorithm 197 AllowFeeRecipients bool `json:"allowFeeRecipients,omitempty"` // Allows fees to be collected by block builders. 198 199 GenesisPrecompiles Precompiles `json:"-"` // Config for enabling precompiles from genesis. JSON encode/decode will be handled by the custom marshaler/unmarshaler. 200 UpgradeConfig `json:"-"` // Config specified in upgradeBytes (avalanche network upgrades or enable/disabling precompiles). Skip encoding/decoding directly into ChainConfig. 201 } 202 203 // Description returns a human-readable description of ChainConfig. 204 func (c *ChainConfig) Description() string { 205 var banner string 206 207 banner += fmt.Sprintf("Chain ID: %v\n", c.ChainID) 208 banner += "Consensus: Dummy Consensus Engine\n\n" 209 210 // Create a list of forks with a short description of them. Forks that only 211 // makes sense for mainnet should be optional at printing to avoid bloating 212 // the output for testnets and private networks. 213 banner += "Hard Forks (block based):\n" 214 banner += fmt.Sprintf(" - Homestead: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock) 215 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) 216 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) 217 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) 218 banner += fmt.Sprintf(" - Byzantium: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock) 219 banner += fmt.Sprintf(" - Constantinople: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock) 220 banner += fmt.Sprintf(" - Petersburg: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock) 221 banner += fmt.Sprintf(" - Istanbul: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock) 222 if c.MuirGlacierBlock != nil { 223 banner += fmt.Sprintf(" - Muir Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock) 224 } 225 226 banner += "Hard forks (timestamp based):\n" 227 banner += fmt.Sprintf(" - Cancun Timestamp: @%-10v (https://github.com/MetalBlockchain/metalgo/releases/tag/v1.12.0)\n", ptrToString(c.CancunTime)) 228 229 banner += "Avalanche Upgrades (timestamp based):\n" 230 banner += fmt.Sprintf(" - SubnetEVM Timestamp: @%-10v (https://github.com/MetalBlockchain/metalgo/releases/tag/v1.10.0)\n", ptrToString(c.SubnetEVMTimestamp)) 231 banner += fmt.Sprintf(" - Durango Timestamp: @%-10v (https://github.com/MetalBlockchain/metalgo/releases/tag/v1.11.0)\n", ptrToString(c.DurangoTimestamp)) 232 banner += "\n" 233 234 precompileUpgradeBytes, err := json.Marshal(c.GenesisPrecompiles) 235 if err != nil { 236 precompileUpgradeBytes = []byte("cannot marshal PrecompileUpgrade") 237 } 238 banner += fmt.Sprintf("Precompile Upgrades: %s", string(precompileUpgradeBytes)) 239 banner += "\n" 240 241 upgradeConfigBytes, err := json.Marshal(c.UpgradeConfig) 242 if err != nil { 243 upgradeConfigBytes = []byte("cannot marshal UpgradeConfig") 244 } 245 banner += fmt.Sprintf("Upgrade Config: %s", string(upgradeConfigBytes)) 246 banner += "\n" 247 248 feeBytes, err := json.Marshal(c.FeeConfig) 249 if err != nil { 250 feeBytes = []byte("cannot marshal FeeConfig") 251 } 252 banner += fmt.Sprintf("Fee Config: %s", string(feeBytes)) 253 banner += "\n" 254 255 banner += fmt.Sprintf("Allow Fee Recipients: %v", c.AllowFeeRecipients) 256 banner += "\n" 257 return banner 258 } 259 260 func (c *ChainConfig) SetNetworkUpgradeDefaults() { 261 if c.HomesteadBlock == nil { 262 c.HomesteadBlock = big.NewInt(0) 263 } 264 if c.EIP150Block == nil { 265 c.EIP150Block = big.NewInt(0) 266 } 267 if c.EIP155Block == nil { 268 c.EIP155Block = big.NewInt(0) 269 } 270 if c.EIP158Block == nil { 271 c.EIP158Block = big.NewInt(0) 272 } 273 if c.ByzantiumBlock == nil { 274 c.ByzantiumBlock = big.NewInt(0) 275 } 276 if c.ConstantinopleBlock == nil { 277 c.ConstantinopleBlock = big.NewInt(0) 278 } 279 if c.PetersburgBlock == nil { 280 c.PetersburgBlock = big.NewInt(0) 281 } 282 if c.IstanbulBlock == nil { 283 c.IstanbulBlock = big.NewInt(0) 284 } 285 if c.MuirGlacierBlock == nil { 286 c.MuirGlacierBlock = big.NewInt(0) 287 } 288 289 c.NetworkUpgrades.setDefaults(c.SnowCtx.NetworkID) 290 291 // if c.CancunTime == nil { 292 // c.CancunTime = c.EUpgrade 293 // } 294 } 295 296 // IsHomestead returns whether num is either equal to the homestead block or greater. 297 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 298 return utils.IsBlockForked(c.HomesteadBlock, num) 299 } 300 301 // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater. 302 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 303 return utils.IsBlockForked(c.EIP150Block, num) 304 } 305 306 // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater. 307 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 308 return utils.IsBlockForked(c.EIP155Block, num) 309 } 310 311 // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater. 312 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 313 return utils.IsBlockForked(c.EIP158Block, num) 314 } 315 316 // IsByzantium returns whether num is either equal to the Byzantium fork block or greater. 317 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 318 return utils.IsBlockForked(c.ByzantiumBlock, num) 319 } 320 321 // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. 322 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 323 return utils.IsBlockForked(c.ConstantinopleBlock, num) 324 } 325 326 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. 327 func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { 328 return utils.IsBlockForked(c.MuirGlacierBlock, num) 329 } 330 331 // IsPetersburg returns whether num is either 332 // - equal to or greater than the PetersburgBlock fork block, 333 // - OR is nil, and Constantinople is active 334 func (c *ChainConfig) IsPetersburg(num *big.Int) bool { 335 return utils.IsBlockForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && utils.IsBlockForked(c.ConstantinopleBlock, num) 336 } 337 338 // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater. 339 func (c *ChainConfig) IsIstanbul(num *big.Int) bool { 340 return utils.IsBlockForked(c.IstanbulBlock, num) 341 } 342 343 // IsSubnetEVM returns whether [time] represents a block 344 // with a timestamp after the SubnetEVM upgrade time. 345 func (c *ChainConfig) IsSubnetEVM(time uint64) bool { 346 return utils.IsTimestampForked(c.SubnetEVMTimestamp, time) 347 } 348 349 // TODO: move avalanche hardforks to network_upgrades.go 350 // IsDurango returns whether [time] represents a block 351 // with a timestamp after the Durango upgrade time. 352 func (c *ChainConfig) IsDurango(time uint64) bool { 353 return utils.IsTimestampForked(c.DurangoTimestamp, time) 354 } 355 356 // IsCancun returns whether [time] represents a block 357 // with a timestamp after the Cancun upgrade time. 358 func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool { 359 return utils.IsTimestampForked(c.CancunTime, time) 360 } 361 362 func (r *Rules) PredicatersExist() bool { 363 return len(r.Predicaters) > 0 364 } 365 366 func (r *Rules) PredicaterExists(addr common.Address) bool { 367 _, PredicaterExists := r.Predicaters[addr] 368 return PredicaterExists 369 } 370 371 // IsPrecompileEnabled returns whether precompile with [address] is enabled at [timestamp]. 372 func (c *ChainConfig) IsPrecompileEnabled(address common.Address, timestamp uint64) bool { 373 config := c.getActivePrecompileConfig(address, timestamp) 374 return config != nil && !config.IsDisabled() 375 } 376 377 // CheckCompatible checks whether scheduled fork transitions have been imported 378 // with a mismatching chain configuration. 379 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { 380 var ( 381 bhead = new(big.Int).SetUint64(height) 382 btime = time 383 ) 384 // Iterate checkCompatible to find the lowest conflict. 385 var lasterr *ConfigCompatError 386 for { 387 err := c.checkCompatible(newcfg, bhead, btime) 388 if err == nil || (lasterr != nil && err.RewindToBlock == lasterr.RewindToBlock && err.RewindToTime == lasterr.RewindToTime) { 389 break 390 } 391 lasterr = err 392 393 if err.RewindToTime > 0 { 394 btime = err.RewindToTime 395 } else { 396 bhead.SetUint64(err.RewindToBlock) 397 } 398 } 399 return lasterr 400 } 401 402 // Verify verifies chain config and returns error 403 func (c *ChainConfig) Verify() error { 404 if err := c.FeeConfig.Verify(); err != nil { 405 return err 406 } 407 408 // Verify the precompile upgrades are internally consistent given the existing chainConfig. 409 if err := c.verifyPrecompileUpgrades(); err != nil { 410 return fmt.Errorf("invalid precompile upgrades: %w", err) 411 } 412 413 // Verify the state upgrades are internally consistent given the existing chainConfig. 414 if err := c.verifyStateUpgrades(); err != nil { 415 return fmt.Errorf("invalid state upgrades: %w", err) 416 } 417 418 // Verify the network upgrades are internally consistent given the existing chainConfig. 419 if err := c.VerifyNetworkUpgrades(c.SnowCtx.NetworkID); err != nil { 420 return fmt.Errorf("invalid network upgrades: %w", err) 421 } 422 423 return nil 424 } 425 426 type fork struct { 427 name string 428 block *big.Int // some go-ethereum forks use block numbers 429 timestamp *uint64 // Avalanche forks use timestamps 430 optional bool // if true, the fork may be nil and next fork is still allowed 431 } 432 433 // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough 434 // to guarantee that forks can be implemented in a different order than on official networks 435 func (c *ChainConfig) CheckConfigForkOrder() error { 436 ethForks := []fork{ 437 {name: "homesteadBlock", block: c.HomesteadBlock}, 438 {name: "eip150Block", block: c.EIP150Block}, 439 {name: "eip155Block", block: c.EIP155Block}, 440 {name: "eip158Block", block: c.EIP158Block}, 441 {name: "byzantiumBlock", block: c.ByzantiumBlock}, 442 {name: "constantinopleBlock", block: c.ConstantinopleBlock}, 443 {name: "petersburgBlock", block: c.PetersburgBlock}, 444 {name: "istanbulBlock", block: c.IstanbulBlock}, 445 {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, 446 } 447 448 // Check that forks are enabled in order 449 if err := checkForks(ethForks, true); err != nil { 450 return err 451 } 452 453 // Note: In Avalanche, hard forks must take place via block timestamps instead 454 // of block numbers since blocks are produced asynchronously. Therefore, we do not 455 // check that the block timestamps in the same way as for 456 // the block number forks since it would not be a meaningful comparison. 457 // Instead, we check only that Phases are enabled in order. 458 // Note: we do not add the optional stateful precompile configs in here because they are optional 459 // and independent, such that the ordering they are enabled does not impact the correctness of the 460 // chain config. 461 if err := checkForks(c.forkOrder(), false); err != nil { 462 return err 463 } 464 465 return nil 466 } 467 468 // checkForks checks that forks are enabled in order and returns an error if not 469 // [blockFork] is true if the fork is a block number fork, false if it is a timestamp fork 470 func checkForks(forks []fork, blockFork bool) error { 471 lastFork := fork{} 472 for _, cur := range forks { 473 if blockFork && cur.block != nil && common.Big0.Cmp(cur.block) != 0 { 474 return errNonGenesisForkByHeight 475 } 476 if lastFork.name != "" { 477 // Next one must be higher number 478 if lastFork.timestamp == nil && cur.timestamp != nil { 479 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v", 480 lastFork.name, cur.name, *cur.timestamp) 481 } 482 if lastFork.timestamp != nil && cur.timestamp != nil { 483 if *lastFork.timestamp > *cur.timestamp { 484 return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v", 485 lastFork.name, *lastFork.timestamp, cur.name, *cur.timestamp) 486 } 487 } 488 } 489 // If it was optional and not set, then ignore it 490 if !cur.optional || cur.timestamp != nil { 491 lastFork = cur 492 } 493 } 494 return nil 495 } 496 497 // checkCompatible confirms that [newcfg] is backwards compatible with [c] to upgrade with the given head block height and timestamp. 498 // This confirms that all Ethereum and Avalanche upgrades are backwards compatible as well as that the precompile config is backwards 499 // compatible. 500 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, height *big.Int, time uint64) *ConfigCompatError { 501 if isForkBlockIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, height) { 502 return newBlockCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 503 } 504 if isForkBlockIncompatible(c.EIP150Block, newcfg.EIP150Block, height) { 505 return newBlockCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 506 } 507 if isForkBlockIncompatible(c.EIP155Block, newcfg.EIP155Block, height) { 508 return newBlockCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 509 } 510 if isForkBlockIncompatible(c.EIP158Block, newcfg.EIP158Block, height) { 511 return newBlockCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 512 } 513 if c.IsEIP158(height) && !utils.BigNumEqual(c.ChainID, newcfg.ChainID) { 514 return newBlockCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 515 } 516 if isForkBlockIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, height) { 517 return newBlockCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 518 } 519 if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, height) { 520 return newBlockCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 521 } 522 if isForkBlockIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, height) { 523 // the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople 524 // mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set 525 if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, height) { 526 return newBlockCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock) 527 } 528 } 529 if isForkBlockIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, height) { 530 return newBlockCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock) 531 } 532 if isForkBlockIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, height) { 533 return newBlockCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock) 534 } 535 536 if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, time) { 537 return newTimestampCompatError("Cancun fork block timestamp", c.CancunTime, c.CancunTime) 538 } 539 540 // Check avalanche network upgrades 541 if err := c.CheckNetworkUpgradesCompatible(&newcfg.NetworkUpgrades, time); err != nil { 542 return err 543 } 544 545 // Check that the precompiles on the new config are compatible with the existing precompile config. 546 if err := c.CheckPrecompilesCompatible(newcfg.PrecompileUpgrades, time); err != nil { 547 return err 548 } 549 550 // Check that the state upgrades on the new config are compatible with the existing state upgrade config. 551 if err := c.CheckStateUpgradesCompatible(newcfg.StateUpgrades, time); err != nil { 552 return err 553 } 554 555 // TODO verify that the fee config is fully compatible between [c] and [newcfg]. 556 return nil 557 } 558 559 // isForkBlockIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to 560 // block s2 because head is already past the fork. 561 func isForkBlockIncompatible(s1, s2, head *big.Int) bool { 562 return (utils.IsBlockForked(s1, head) || utils.IsBlockForked(s2, head)) && !configBlockEqual(s1, s2) 563 } 564 565 func configBlockEqual(x, y *big.Int) bool { 566 if x == nil { 567 return y == nil 568 } 569 if y == nil { 570 return x == nil 571 } 572 return x.Cmp(y) == 0 573 } 574 575 // isForkTimestampIncompatible returns true if a fork scheduled at timestamp s1 576 // cannot be rescheduled to timestamp s2 because head is already past the fork. 577 func isForkTimestampIncompatible(s1, s2 *uint64, head uint64) bool { 578 return (utils.IsTimestampForked(s1, head) || utils.IsTimestampForked(s2, head)) && !configTimestampEqual(s1, s2) 579 } 580 581 func configTimestampEqual(x, y *uint64) bool { 582 if x == nil { 583 return y == nil 584 } 585 if y == nil { 586 return x == nil 587 } 588 return *x == *y 589 } 590 591 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 592 // ChainConfig that would alter the past. 593 type ConfigCompatError struct { 594 What string 595 596 // block numbers of the stored and new configurations if block based forking 597 StoredBlock, NewBlock *big.Int 598 599 // timestamps of the stored and new configurations if time based forking 600 StoredTime, NewTime *uint64 601 602 // the block number to which the local chain must be rewound to correct the error 603 RewindToBlock uint64 604 605 // the timestamp to which the local chain must be rewound to correct the error 606 RewindToTime uint64 607 } 608 609 func newBlockCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 610 var rew *big.Int 611 switch { 612 case storedblock == nil: 613 rew = newblock 614 case newblock == nil || storedblock.Cmp(newblock) < 0: 615 rew = storedblock 616 default: 617 rew = newblock 618 } 619 err := &ConfigCompatError{ 620 What: what, 621 StoredBlock: storedblock, 622 NewBlock: newblock, 623 RewindToBlock: 0, 624 } 625 if rew != nil && rew.Sign() > 0 { 626 err.RewindToBlock = rew.Uint64() - 1 627 } 628 return err 629 } 630 631 func newTimestampCompatError(what string, storedtime, newtime *uint64) *ConfigCompatError { 632 var rew *uint64 633 switch { 634 case storedtime == nil: 635 rew = newtime 636 case newtime == nil || *storedtime < *newtime: 637 rew = storedtime 638 default: 639 rew = newtime 640 } 641 err := &ConfigCompatError{ 642 What: what, 643 StoredTime: storedtime, 644 NewTime: newtime, 645 RewindToTime: 0, 646 } 647 if rew != nil && *rew > 0 { 648 err.RewindToTime = *rew - 1 649 } 650 return err 651 } 652 653 func (err *ConfigCompatError) Error() string { 654 if err.StoredBlock != nil { 655 return fmt.Sprintf("mismatching %s in database (have block %d, want block %d, rewindto block %d)", err.What, err.StoredBlock, err.NewBlock, err.RewindToBlock) 656 } 657 return fmt.Sprintf("mismatching %s in database (have timestamp %s, want timestamp %s, rewindto timestamp %d)", err.What, ptrToString(err.StoredTime), ptrToString(err.NewTime), err.RewindToTime) 658 } 659 660 func ptrToString(val *uint64) string { 661 if val == nil { 662 return "nil" 663 } 664 return fmt.Sprintf("%d", *val) 665 } 666 667 // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions 668 // that do not have or require information about the block. 669 // 670 // Rules is a one time interface meaning that it shouldn't be used in between transition 671 // phases. 672 type Rules struct { 673 ChainID *big.Int 674 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 675 IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool 676 IsCancun bool 677 678 // Rules for Avalanche releases 679 IsSubnetEVM bool 680 IsDurango bool 681 682 // ActivePrecompiles maps addresses to stateful precompiled contracts that are enabled 683 // for this rule set. 684 // Note: none of these addresses should conflict with the address space used by 685 // any existing precompiles. 686 ActivePrecompiles map[common.Address]precompileconfig.Config 687 // Predicaters maps addresses to stateful precompile Predicaters 688 // that are enabled for this rule set. 689 Predicaters map[common.Address]precompileconfig.Predicater 690 // AccepterPrecompiles map addresses to stateful precompile accepter functions 691 // that are enabled for this rule set. 692 AccepterPrecompiles map[common.Address]precompileconfig.Accepter 693 } 694 695 // IsPrecompileEnabled returns true if the precompile at [addr] is enabled for this rule set. 696 func (r *Rules) IsPrecompileEnabled(addr common.Address) bool { 697 _, ok := r.ActivePrecompiles[addr] 698 return ok 699 } 700 701 // Rules ensures c's ChainID is not nil. 702 func (c *ChainConfig) rules(num *big.Int, timestamp uint64) Rules { 703 chainID := c.ChainID 704 if chainID == nil { 705 chainID = new(big.Int) 706 } 707 return Rules{ 708 ChainID: new(big.Int).Set(chainID), 709 IsHomestead: c.IsHomestead(num), 710 IsEIP150: c.IsEIP150(num), 711 IsEIP155: c.IsEIP155(num), 712 IsEIP158: c.IsEIP158(num), 713 IsByzantium: c.IsByzantium(num), 714 IsConstantinople: c.IsConstantinople(num), 715 IsPetersburg: c.IsPetersburg(num), 716 IsIstanbul: c.IsIstanbul(num), 717 IsCancun: c.IsCancun(num, timestamp), 718 } 719 } 720 721 // Rules returns the Avalanche modified rules to support Avalanche 722 // network upgrades 723 func (c *ChainConfig) Rules(blockNum *big.Int, timestamp uint64) Rules { 724 rules := c.rules(blockNum, timestamp) 725 726 rules.IsSubnetEVM = c.IsSubnetEVM(timestamp) 727 rules.IsDurango = c.IsDurango(timestamp) 728 729 // Initialize the stateful precompiles that should be enabled at [blockTimestamp]. 730 rules.ActivePrecompiles = make(map[common.Address]precompileconfig.Config) 731 rules.Predicaters = make(map[common.Address]precompileconfig.Predicater) 732 rules.AccepterPrecompiles = make(map[common.Address]precompileconfig.Accepter) 733 for _, module := range modules.RegisteredModules() { 734 if config := c.getActivePrecompileConfig(module.Address, timestamp); config != nil && !config.IsDisabled() { 735 rules.ActivePrecompiles[module.Address] = config 736 if predicater, ok := config.(precompileconfig.Predicater); ok { 737 rules.Predicaters[module.Address] = predicater 738 } 739 if precompileAccepter, ok := config.(precompileconfig.Accepter); ok { 740 rules.AccepterPrecompiles[module.Address] = precompileAccepter 741 } 742 } 743 } 744 745 return rules 746 } 747 748 // GetFeeConfig returns the original FeeConfig contained in the genesis ChainConfig. 749 // Implements precompile.ChainConfig interface. 750 func (c *ChainConfig) GetFeeConfig() commontype.FeeConfig { 751 return c.FeeConfig 752 } 753 754 // AllowedFeeRecipients returns the original AllowedFeeRecipients parameter contained in the genesis ChainConfig. 755 // Implements precompile.ChainConfig interface. 756 func (c *ChainConfig) AllowedFeeRecipients() bool { 757 return c.AllowFeeRecipients 758 }