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  }