github.com/MetalBlockchain/subnet-evm@v0.4.9/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 35 "github.com/MetalBlockchain/metalgo/snow" 36 "github.com/MetalBlockchain/subnet-evm/commontype" 37 "github.com/MetalBlockchain/subnet-evm/precompile" 38 "github.com/MetalBlockchain/subnet-evm/utils" 39 "github.com/ethereum/go-ethereum/common" 40 ) 41 42 var ( 43 errNonGenesisForkByHeight = errors.New("subnet-evm only supports forking by height at the genesis block") 44 45 SubnetEVMChainID = big.NewInt(43214) 46 47 // For legacy tests 48 MinGasPrice int64 = 225_000_000_000 49 TestInitialBaseFee int64 = 225_000_000_000 50 TestMaxBaseFee = big.NewInt(225_000_000_000) 51 52 ExtraDataSize = 80 53 RollupWindow uint64 = 10 54 55 DefaultFeeConfig = commontype.FeeConfig{ 56 GasLimit: big.NewInt(8_000_000), 57 TargetBlockRate: 2, // in seconds 58 59 MinBaseFee: big.NewInt(25_000_000_000), 60 TargetGas: big.NewInt(15_000_000), 61 BaseFeeChangeDenominator: big.NewInt(36), 62 63 MinBlockGasCost: big.NewInt(0), 64 MaxBlockGasCost: big.NewInt(1_000_000), 65 BlockGasCostStep: big.NewInt(200_000), 66 } 67 ) 68 69 var ( 70 // SubnetEVMDefaultChainConfig is the default configuration 71 SubnetEVMDefaultChainConfig = &ChainConfig{ 72 ChainID: SubnetEVMChainID, 73 FeeConfig: DefaultFeeConfig, 74 AllowFeeRecipients: false, 75 76 HomesteadBlock: big.NewInt(0), 77 EIP150Block: big.NewInt(0), 78 EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), 79 EIP155Block: big.NewInt(0), 80 EIP158Block: big.NewInt(0), 81 ByzantiumBlock: big.NewInt(0), 82 ConstantinopleBlock: big.NewInt(0), 83 PetersburgBlock: big.NewInt(0), 84 IstanbulBlock: big.NewInt(0), 85 MuirGlacierBlock: big.NewInt(0), 86 87 NetworkUpgrades: NetworkUpgrades{ 88 SubnetEVMTimestamp: big.NewInt(0), 89 }, 90 } 91 92 TestChainConfig = &ChainConfig{ 93 AvalancheContext: AvalancheContext{snow.DefaultContextTest()}, 94 ChainID: big.NewInt(1), 95 FeeConfig: DefaultFeeConfig, 96 AllowFeeRecipients: false, 97 HomesteadBlock: big.NewInt(0), 98 EIP150Block: big.NewInt(0), 99 EIP150Hash: common.Hash{}, 100 EIP155Block: big.NewInt(0), 101 EIP158Block: big.NewInt(0), 102 ByzantiumBlock: big.NewInt(0), 103 ConstantinopleBlock: big.NewInt(0), 104 PetersburgBlock: big.NewInt(0), 105 IstanbulBlock: big.NewInt(0), 106 MuirGlacierBlock: big.NewInt(0), 107 NetworkUpgrades: NetworkUpgrades{big.NewInt(0)}, 108 PrecompileUpgrade: PrecompileUpgrade{}, 109 UpgradeConfig: UpgradeConfig{}, 110 } 111 112 TestPreSubnetEVMConfig = &ChainConfig{ 113 AvalancheContext: AvalancheContext{snow.DefaultContextTest()}, 114 ChainID: big.NewInt(1), 115 FeeConfig: DefaultFeeConfig, 116 AllowFeeRecipients: false, 117 HomesteadBlock: big.NewInt(0), 118 EIP150Block: big.NewInt(0), 119 EIP150Hash: common.Hash{}, 120 EIP155Block: big.NewInt(0), 121 EIP158Block: big.NewInt(0), 122 ByzantiumBlock: big.NewInt(0), 123 ConstantinopleBlock: big.NewInt(0), 124 PetersburgBlock: big.NewInt(0), 125 IstanbulBlock: big.NewInt(0), 126 MuirGlacierBlock: big.NewInt(0), 127 NetworkUpgrades: NetworkUpgrades{}, 128 PrecompileUpgrade: PrecompileUpgrade{}, 129 UpgradeConfig: UpgradeConfig{}, 130 } 131 ) 132 133 // ChainConfig is the core config which determines the blockchain settings. 134 // 135 // ChainConfig is stored in the database on a per block basis. This means 136 // that any network, identified by its genesis block, can have its own 137 // set of configuration options. 138 type ChainConfig struct { 139 AvalancheContext `json:"-"` // Avalanche specific context set during VM initialization. Not serialized. 140 141 ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection 142 FeeConfig commontype.FeeConfig `json:"feeConfig"` // Set the configuration for the dynamic fee algorithm 143 AllowFeeRecipients bool `json:"allowFeeRecipients,omitempty"` // Allows fees to be collected by block builders. 144 145 HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) 146 147 // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) 148 EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) 149 EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed) 150 151 EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block 152 EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block 153 154 ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) 155 ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) 156 PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) 157 IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) 158 MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) 159 160 NetworkUpgrades // Config for timestamps that enable avalanche network upgrades 161 PrecompileUpgrade // Config for enabling precompiles from genesis 162 UpgradeConfig `json:"-"` // Config specified in upgradeBytes (avalanche network upgrades or enable/disabling precompiles). Skip encoding/decoding directly into ChainConfig. 163 } 164 165 // UpgradeConfig includes the following configs that may be specified in upgradeBytes: 166 // - Timestamps that enable avalanche network upgrades, 167 // - Enabling or disabling precompiles as network upgrades. 168 type UpgradeConfig struct { 169 // Config for blocks/timestamps that enable network upgrades. 170 // Note: if NetworkUpgrades is specified in the JSON all previously activated 171 // forks must be present or upgradeBytes will be rejected. 172 NetworkUpgrades *NetworkUpgrades `json:"networkUpgrades,omitempty"` 173 174 // Config for enabling and disabling precompiles as network upgrades. 175 PrecompileUpgrades []PrecompileUpgrade `json:"precompileUpgrades,omitempty"` 176 } 177 178 // AvalancheContext provides Avalanche specific context directly into the EVM. 179 type AvalancheContext struct { 180 SnowCtx *snow.Context 181 } 182 183 // String implements the fmt.Stringer interface. 184 func (c *ChainConfig) String() string { 185 // convert nested data structures to json 186 feeBytes, err := json.Marshal(c.FeeConfig) 187 if err != nil { 188 feeBytes = []byte("cannot marshal FeeConfig") 189 } 190 networkUpgradesBytes, err := json.Marshal(c.NetworkUpgrades) 191 if err != nil { 192 networkUpgradesBytes = []byte("cannot marshal NetworkUpgrades") 193 } 194 precompileUpgradeBytes, err := json.Marshal(c.PrecompileUpgrade) 195 if err != nil { 196 precompileUpgradeBytes = []byte("cannot marshal PrecompileUpgrade") 197 } 198 upgradeConfigBytes, err := json.Marshal(c.UpgradeConfig) 199 if err != nil { 200 upgradeConfigBytes = []byte("cannot marshal UpgradeConfig") 201 } 202 203 return fmt.Sprintf("{ChainID: %v Homestead: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Subnet EVM: %v, FeeConfig: %v, AllowFeeRecipients: %v, NetworkUpgrades: %v, PrecompileUpgrade: %v, UpgradeConfig: %v, Engine: Dummy Consensus Engine}", 204 c.ChainID, 205 c.HomesteadBlock, 206 c.EIP150Block, 207 c.EIP155Block, 208 c.EIP158Block, 209 c.ByzantiumBlock, 210 c.ConstantinopleBlock, 211 c.PetersburgBlock, 212 c.IstanbulBlock, 213 c.MuirGlacierBlock, 214 c.SubnetEVMTimestamp, 215 string(feeBytes), 216 c.AllowFeeRecipients, 217 string(networkUpgradesBytes), 218 string(precompileUpgradeBytes), 219 string(upgradeConfigBytes), 220 ) 221 } 222 223 // IsHomestead returns whether num is either equal to the homestead block or greater. 224 func (c *ChainConfig) IsHomestead(num *big.Int) bool { 225 return utils.IsForked(c.HomesteadBlock, num) 226 } 227 228 // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater. 229 func (c *ChainConfig) IsEIP150(num *big.Int) bool { 230 return utils.IsForked(c.EIP150Block, num) 231 } 232 233 // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater. 234 func (c *ChainConfig) IsEIP155(num *big.Int) bool { 235 return utils.IsForked(c.EIP155Block, num) 236 } 237 238 // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater. 239 func (c *ChainConfig) IsEIP158(num *big.Int) bool { 240 return utils.IsForked(c.EIP158Block, num) 241 } 242 243 // IsByzantium returns whether num is either equal to the Byzantium fork block or greater. 244 func (c *ChainConfig) IsByzantium(num *big.Int) bool { 245 return utils.IsForked(c.ByzantiumBlock, num) 246 } 247 248 // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. 249 func (c *ChainConfig) IsConstantinople(num *big.Int) bool { 250 return utils.IsForked(c.ConstantinopleBlock, num) 251 } 252 253 // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. 254 func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { 255 return utils.IsForked(c.MuirGlacierBlock, num) 256 } 257 258 // IsPetersburg returns whether num is either 259 // - equal to or greater than the PetersburgBlock fork block, 260 // - OR is nil, and Constantinople is active 261 func (c *ChainConfig) IsPetersburg(num *big.Int) bool { 262 return utils.IsForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && utils.IsForked(c.ConstantinopleBlock, num) 263 } 264 265 // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater. 266 func (c *ChainConfig) IsIstanbul(num *big.Int) bool { 267 return utils.IsForked(c.IstanbulBlock, num) 268 } 269 270 // IsSubnetEVM returns whether [blockTimestamp] is either equal to the SubnetEVM fork block timestamp or greater. 271 func (c *ChainConfig) IsSubnetEVM(blockTimestamp *big.Int) bool { 272 return utils.IsForked(c.getNetworkUpgrades().SubnetEVMTimestamp, blockTimestamp) 273 } 274 275 // PRECOMPILE UPGRADES START HERE 276 277 // IsContractDeployerAllowList returns whether [blockTimestamp] is either equal to the ContractDeployerAllowList fork block timestamp or greater. 278 func (c *ChainConfig) IsContractDeployerAllowList(blockTimestamp *big.Int) bool { 279 config := c.GetContractDeployerAllowListConfig(blockTimestamp) 280 return config != nil && !config.Disable 281 } 282 283 // IsContractNativeMinter returns whether [blockTimestamp] is either equal to the NativeMinter fork block timestamp or greater. 284 func (c *ChainConfig) IsContractNativeMinter(blockTimestamp *big.Int) bool { 285 config := c.GetContractNativeMinterConfig(blockTimestamp) 286 return config != nil && !config.Disable 287 } 288 289 // IsTxAllowList returns whether [blockTimestamp] is either equal to the TxAllowList fork block timestamp or greater. 290 func (c *ChainConfig) IsTxAllowList(blockTimestamp *big.Int) bool { 291 config := c.GetTxAllowListConfig(blockTimestamp) 292 return config != nil && !config.Disable 293 } 294 295 // IsFeeConfigManager returns whether [blockTimestamp] is either equal to the FeeConfigManager fork block timestamp or greater. 296 func (c *ChainConfig) IsFeeConfigManager(blockTimestamp *big.Int) bool { 297 config := c.GetFeeConfigManagerConfig(blockTimestamp) 298 return config != nil && !config.Disable 299 } 300 301 // IsRewardManager returns whether [blockTimestamp] is either equal to the RewardManager fork block timestamp or greater. 302 func (c *ChainConfig) IsRewardManager(blockTimestamp *big.Int) bool { 303 config := c.GetRewardManagerConfig(blockTimestamp) 304 return config != nil && !config.Disable 305 } 306 307 // ADD YOUR PRECOMPILE HERE 308 /* 309 func (c *ChainConfig) Is{YourPrecompile}(blockTimestamp *big.Int) bool { 310 config := c.Get{YourPrecompile}Config(blockTimestamp) 311 return config != nil && !config.Disable 312 } 313 */ 314 315 // CheckCompatible checks whether scheduled fork transitions have been imported 316 // with a mismatching chain configuration. 317 func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, timestamp uint64) *ConfigCompatError { 318 bNumber := new(big.Int).SetUint64(height) 319 bTimestamp := new(big.Int).SetUint64(timestamp) 320 321 // Iterate checkCompatible to find the lowest conflict. 322 var lasterr *ConfigCompatError 323 for { 324 err := c.checkCompatible(newcfg, bNumber, bTimestamp) 325 if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) { 326 break 327 } 328 lasterr = err 329 bNumber.SetUint64(err.RewindTo) 330 } 331 return lasterr 332 } 333 334 // Verify verifies chain config and returns error 335 func (c *ChainConfig) Verify() error { 336 if err := c.FeeConfig.Verify(); err != nil { 337 return err 338 } 339 340 // Verify the precompile upgrades are internally consistent given the existing chainConfig. 341 if err := c.verifyPrecompileUpgrades(); err != nil { 342 return err 343 } 344 345 return nil 346 } 347 348 // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough 349 // to guarantee that forks can be implemented in a different order than on official networks 350 func (c *ChainConfig) CheckConfigForkOrder() error { 351 type fork struct { 352 name string 353 block *big.Int 354 optional bool // if true, the fork may be nil and next fork is still allowed 355 } 356 var lastFork fork 357 for _, cur := range []fork{ 358 {name: "homesteadBlock", block: c.HomesteadBlock}, 359 {name: "eip150Block", block: c.EIP150Block}, 360 {name: "eip155Block", block: c.EIP155Block}, 361 {name: "eip158Block", block: c.EIP158Block}, 362 {name: "byzantiumBlock", block: c.ByzantiumBlock}, 363 {name: "constantinopleBlock", block: c.ConstantinopleBlock}, 364 {name: "petersburgBlock", block: c.PetersburgBlock}, 365 {name: "istanbulBlock", block: c.IstanbulBlock}, 366 {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, 367 } { 368 if cur.block != nil && common.Big0.Cmp(cur.block) != 0 { 369 return errNonGenesisForkByHeight 370 } 371 if lastFork.name != "" { 372 // Next one must be higher number 373 if lastFork.block == nil && cur.block != nil { 374 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v", 375 lastFork.name, cur.name, cur.block) 376 } 377 if lastFork.block != nil && cur.block != nil { 378 if lastFork.block.Cmp(cur.block) > 0 { 379 return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v", 380 lastFork.name, lastFork.block, cur.name, cur.block) 381 } 382 } 383 } 384 // If it was optional and not set, then ignore it 385 if !cur.optional || cur.block != nil { 386 lastFork = cur 387 } 388 } 389 390 // Note: In Avalanche, hard forks must take place via block timestamps instead 391 // of block numbers since blocks are produced asynchronously. Therefore, we do not 392 // check that the block timestamps in the same way as for 393 // the block number forks since it would not be a meaningful comparison. 394 // Instead, we check only that Phases are enabled in order. 395 // Note: we do not add the optional stateful precompile configs in here because they are optional 396 // and independent, such that the ordering they are enabled does not impact the correctness of the 397 // chain config. 398 lastFork = fork{} 399 for _, cur := range []fork{ 400 {name: "subnetEVMTimestamp", block: c.SubnetEVMTimestamp}, 401 } { 402 if lastFork.name != "" { 403 // Next one must be higher number 404 if lastFork.block == nil && cur.block != nil { 405 return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v", 406 lastFork.name, cur.name, cur.block) 407 } 408 if lastFork.block != nil && cur.block != nil { 409 if lastFork.block.Cmp(cur.block) > 0 { 410 return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v", 411 lastFork.name, lastFork.block, cur.name, cur.block) 412 } 413 } 414 } 415 // If it was optional and not set, then ignore it 416 if !cur.optional || cur.block != nil { 417 lastFork = cur 418 } 419 } 420 return nil 421 } 422 423 // checkCompatible confirms that [newcfg] is backwards compatible with [c] to upgrade with the given head block height and timestamp. 424 // This confirms that all Ethereum and Avalanche upgrades are backwards compatible as well as that the precompile config is backwards 425 // compatible. 426 func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, lastHeight *big.Int, lastTimestamp *big.Int) *ConfigCompatError { 427 if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, lastHeight) { 428 return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) 429 } 430 if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, lastHeight) { 431 return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) 432 } 433 if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, lastHeight) { 434 return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) 435 } 436 if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, lastHeight) { 437 return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) 438 } 439 if c.IsEIP158(lastHeight) && !utils.BigNumEqual(c.ChainID, newcfg.ChainID) { 440 return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) 441 } 442 if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, lastHeight) { 443 return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) 444 } 445 if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, lastHeight) { 446 return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) 447 } 448 if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, lastHeight) { 449 // the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople 450 // mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set 451 if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, lastHeight) { 452 return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock) 453 } 454 } 455 if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, lastHeight) { 456 return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock) 457 } 458 if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, lastHeight) { 459 return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock) 460 } 461 462 // Check subnet-evm specific activations 463 newNetworkUpgrades := newcfg.getNetworkUpgrades() 464 if c.UpgradeConfig.NetworkUpgrades != nil && newcfg.UpgradeConfig.NetworkUpgrades == nil { 465 // Note: if the current NetworkUpgrades are set via UpgradeConfig, then a new config 466 // without NetworkUpgrades will be treated as having specified an empty set of network 467 // upgrades (ie., treated as the user intends to cancel scheduled forks) 468 newNetworkUpgrades = &NetworkUpgrades{} 469 } 470 if err := c.getNetworkUpgrades().CheckCompatible(newNetworkUpgrades, lastTimestamp); err != nil { 471 return err 472 } 473 474 // Check that the precompiles on the new config are compatible with the existing precompile config. 475 if err := c.CheckPrecompilesCompatible(newcfg.PrecompileUpgrades, lastTimestamp); err != nil { 476 return err 477 } 478 479 // TODO verify that the fee config is fully compatible between [c] and [newcfg]. 480 return nil 481 } 482 483 // getNetworkUpgrades returns NetworkUpgrades from upgrade config if set there, 484 // otherwise it falls back to the genesis chain config. 485 func (c *ChainConfig) getNetworkUpgrades() *NetworkUpgrades { 486 if upgradeConfigOverride := c.UpgradeConfig.NetworkUpgrades; upgradeConfigOverride != nil { 487 return upgradeConfigOverride 488 } 489 return &c.NetworkUpgrades 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 (utils.IsForked(s1, head) || utils.IsForked(s2, head)) && !utils.BigNumEqual(s1, s2) 496 } 497 498 // ConfigCompatError is raised if the locally-stored blockchain is initialised with a 499 // ChainConfig that would alter the past. 500 type ConfigCompatError struct { 501 What string 502 // block numbers of the stored and new configurations 503 StoredConfig, NewConfig *big.Int 504 // the block number to which the local chain must be rewound to correct the error 505 RewindTo uint64 506 } 507 508 func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { 509 var rew *big.Int 510 switch { 511 case storedblock == nil: 512 rew = newblock 513 case newblock == nil || storedblock.Cmp(newblock) < 0: 514 rew = storedblock 515 default: 516 rew = newblock 517 } 518 err := &ConfigCompatError{what, storedblock, newblock, 0} 519 if rew != nil && rew.Sign() > 0 { 520 err.RewindTo = rew.Uint64() - 1 521 } 522 return err 523 } 524 525 func (err *ConfigCompatError) Error() string { 526 return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo) 527 } 528 529 // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions 530 // that do not have or require information about the block. 531 // 532 // Rules is a one time interface meaning that it shouldn't be used in between transition 533 // phases. 534 type Rules struct { 535 ChainID *big.Int 536 IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool 537 IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool 538 539 // Rules for Avalanche releases 540 IsSubnetEVM bool 541 542 // Optional stateful precompile rules 543 IsContractDeployerAllowListEnabled bool 544 IsContractNativeMinterEnabled bool 545 IsTxAllowListEnabled bool 546 IsFeeConfigManagerEnabled bool 547 IsRewardManagerEnabled bool 548 // ADD YOUR PRECOMPILE HERE 549 // Is{YourPrecompile}Enabled bool 550 551 // Precompiles maps addresses to stateful precompiled contracts that are enabled 552 // for this rule set. 553 // Note: none of these addresses should conflict with the address space used by 554 // any existing precompiles. 555 Precompiles map[common.Address]precompile.StatefulPrecompiledContract 556 } 557 558 // Rules ensures c's ChainID is not nil. 559 func (c *ChainConfig) rules(num *big.Int) Rules { 560 chainID := c.ChainID 561 if chainID == nil { 562 chainID = new(big.Int) 563 } 564 return Rules{ 565 ChainID: new(big.Int).Set(chainID), 566 IsHomestead: c.IsHomestead(num), 567 IsEIP150: c.IsEIP150(num), 568 IsEIP155: c.IsEIP155(num), 569 IsEIP158: c.IsEIP158(num), 570 IsByzantium: c.IsByzantium(num), 571 IsConstantinople: c.IsConstantinople(num), 572 IsPetersburg: c.IsPetersburg(num), 573 IsIstanbul: c.IsIstanbul(num), 574 } 575 } 576 577 // AvalancheRules returns the Avalanche modified rules to support Avalanche 578 // network upgrades 579 func (c *ChainConfig) AvalancheRules(blockNum, blockTimestamp *big.Int) Rules { 580 rules := c.rules(blockNum) 581 582 rules.IsSubnetEVM = c.IsSubnetEVM(blockTimestamp) 583 rules.IsContractDeployerAllowListEnabled = c.IsContractDeployerAllowList(blockTimestamp) 584 rules.IsContractNativeMinterEnabled = c.IsContractNativeMinter(blockTimestamp) 585 rules.IsTxAllowListEnabled = c.IsTxAllowList(blockTimestamp) 586 rules.IsFeeConfigManagerEnabled = c.IsFeeConfigManager(blockTimestamp) 587 rules.IsRewardManagerEnabled = c.IsRewardManager(blockTimestamp) 588 // ADD YOUR PRECOMPILE HERE 589 // rules.Is{YourPrecompile}Enabled = c.{IsYourPrecompile}(blockTimestamp) 590 591 // Initialize the stateful precompiles that should be enabled at [blockTimestamp]. 592 rules.Precompiles = make(map[common.Address]precompile.StatefulPrecompiledContract) 593 for _, config := range c.EnabledStatefulPrecompiles(blockTimestamp) { 594 if config.IsDisabled() { 595 continue 596 } 597 rules.Precompiles[config.Address()] = config.Contract() 598 } 599 600 return rules 601 } 602 603 // GetFeeConfig returns the original FeeConfig contained in the genesis ChainConfig. 604 // Implements precompile.ChainConfig interface. 605 func (c *ChainConfig) GetFeeConfig() commontype.FeeConfig { 606 return c.FeeConfig 607 } 608 609 // AllowedFeeRecipients returns the original AllowedFeeRecipients parameter contained in the genesis ChainConfig. 610 // Implements precompile.ChainConfig interface. 611 func (c *ChainConfig) AllowedFeeRecipients() bool { 612 return c.AllowFeeRecipients 613 }