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  }