github.com/dim4egster/coreth@v0.10.2/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  	"errors"
    31  	"fmt"
    32  	"math/big"
    33  	"time"
    34  
    35  	"github.com/dim4egster/coreth/precompile"
    36  	"github.com/dim4egster/coreth/utils"
    37  	"github.com/ethereum/go-ethereum/common"
    38  )
    39  
    40  // Avalanche ChainIDs
    41  var (
    42  	// AvalancheMainnetChainID ...
    43  	AvalancheMainnetChainID = big.NewInt(43114)
    44  	// AvalancheFujiChainID ...
    45  	AvalancheFujiChainID = big.NewInt(43113)
    46  	// AvalancheLocalChainID ...
    47  	AvalancheLocalChainID = big.NewInt(43112)
    48  
    49  	errNonGenesisForkByHeight = errors.New("coreth only supports forking by height at the genesis block")
    50  )
    51  
    52  var (
    53  	// AvalancheMainnetChainConfig is the configuration for Avalanche Main Network
    54  	AvalancheMainnetChainConfig = &ChainConfig{
    55  		ChainID:                         AvalancheMainnetChainID,
    56  		HomesteadBlock:                  big.NewInt(0),
    57  		DAOForkBlock:                    big.NewInt(0),
    58  		DAOForkSupport:                  true,
    59  		EIP150Block:                     big.NewInt(0),
    60  		EIP150Hash:                      common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    61  		EIP155Block:                     big.NewInt(0),
    62  		EIP158Block:                     big.NewInt(0),
    63  		ByzantiumBlock:                  big.NewInt(0),
    64  		ConstantinopleBlock:             big.NewInt(0),
    65  		PetersburgBlock:                 big.NewInt(0),
    66  		IstanbulBlock:                   big.NewInt(0),
    67  		MuirGlacierBlock:                big.NewInt(0),
    68  		ApricotPhase1BlockTimestamp:     big.NewInt(time.Date(2021, time.March, 31, 14, 0, 0, 0, time.UTC).Unix()),
    69  		ApricotPhase2BlockTimestamp:     big.NewInt(time.Date(2021, time.May, 10, 11, 0, 0, 0, time.UTC).Unix()),
    70  		ApricotPhase3BlockTimestamp:     big.NewInt(time.Date(2021, time.August, 24, 14, 0, 0, 0, time.UTC).Unix()),
    71  		ApricotPhase4BlockTimestamp:     big.NewInt(time.Date(2021, time.September, 22, 21, 0, 0, 0, time.UTC).Unix()),
    72  		ApricotPhase5BlockTimestamp:     big.NewInt(time.Date(2021, time.December, 2, 18, 0, 0, 0, time.UTC).Unix()),
    73  		ApricotPhasePre6BlockTimestamp:  big.NewInt(time.Date(2022, time.September, 5, 1, 30, 0, 0, time.UTC).Unix()),
    74  		ApricotPhase6BlockTimestamp:     big.NewInt(time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC).Unix()),
    75  		ApricotPhasePost6BlockTimestamp: big.NewInt(time.Date(2022, time.September, 7, 3, 0, 0, 0, time.UTC).Unix()),
    76  		// TODO Add Banff
    77  		// TODO Add Clementine
    78  	}
    79  
    80  	// AvalancheFujiChainConfig is the configuration for the Fuji Test Network
    81  	AvalancheFujiChainConfig = &ChainConfig{
    82  		ChainID:                         AvalancheFujiChainID,
    83  		HomesteadBlock:                  big.NewInt(0),
    84  		DAOForkBlock:                    big.NewInt(0),
    85  		DAOForkSupport:                  true,
    86  		EIP150Block:                     big.NewInt(0),
    87  		EIP150Hash:                      common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    88  		EIP155Block:                     big.NewInt(0),
    89  		EIP158Block:                     big.NewInt(0),
    90  		ByzantiumBlock:                  big.NewInt(0),
    91  		ConstantinopleBlock:             big.NewInt(0),
    92  		PetersburgBlock:                 big.NewInt(0),
    93  		IstanbulBlock:                   big.NewInt(0),
    94  		MuirGlacierBlock:                big.NewInt(0),
    95  		ApricotPhase1BlockTimestamp:     big.NewInt(time.Date(2021, time.March, 26, 14, 0, 0, 0, time.UTC).Unix()),
    96  		ApricotPhase2BlockTimestamp:     big.NewInt(time.Date(2021, time.May, 5, 14, 0, 0, 0, time.UTC).Unix()),
    97  		ApricotPhase3BlockTimestamp:     big.NewInt(time.Date(2021, time.August, 16, 19, 0, 0, 0, time.UTC).Unix()),
    98  		ApricotPhase4BlockTimestamp:     big.NewInt(time.Date(2021, time.September, 16, 21, 0, 0, 0, time.UTC).Unix()),
    99  		ApricotPhase5BlockTimestamp:     big.NewInt(time.Date(2021, time.November, 24, 15, 0, 0, 0, time.UTC).Unix()),
   100  		ApricotPhasePre6BlockTimestamp:  big.NewInt(time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC).Unix()),
   101  		ApricotPhase6BlockTimestamp:     big.NewInt(time.Date(2022, time.September, 6, 20, 0, 0, 0, time.UTC).Unix()),
   102  		ApricotPhasePost6BlockTimestamp: big.NewInt(time.Date(2022, time.September, 7, 6, 0, 0, 0, time.UTC).Unix()),
   103  		BanffBlockTimestamp:             big.NewInt(time.Date(2022, time.October, 3, 14, 0, 0, 0, time.UTC).Unix()),
   104  		// TODO Add Clementine
   105  	}
   106  
   107  	// AvalancheLocalChainConfig is the configuration for the Avalanche Local Network
   108  	AvalancheLocalChainConfig = &ChainConfig{
   109  		ChainID:                         AvalancheLocalChainID,
   110  		HomesteadBlock:                  big.NewInt(0),
   111  		DAOForkBlock:                    big.NewInt(0),
   112  		DAOForkSupport:                  true,
   113  		EIP150Block:                     big.NewInt(0),
   114  		EIP150Hash:                      common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
   115  		EIP155Block:                     big.NewInt(0),
   116  		EIP158Block:                     big.NewInt(0),
   117  		ByzantiumBlock:                  big.NewInt(0),
   118  		ConstantinopleBlock:             big.NewInt(0),
   119  		PetersburgBlock:                 big.NewInt(0),
   120  		IstanbulBlock:                   big.NewInt(0),
   121  		MuirGlacierBlock:                big.NewInt(0),
   122  		ApricotPhase1BlockTimestamp:     big.NewInt(0),
   123  		ApricotPhase2BlockTimestamp:     big.NewInt(0),
   124  		ApricotPhase3BlockTimestamp:     big.NewInt(0),
   125  		ApricotPhase4BlockTimestamp:     big.NewInt(0),
   126  		ApricotPhase5BlockTimestamp:     big.NewInt(0),
   127  		ApricotPhasePre6BlockTimestamp:  big.NewInt(0),
   128  		ApricotPhase6BlockTimestamp:     big.NewInt(0),
   129  		ApricotPhasePost6BlockTimestamp: big.NewInt(0),
   130  		BanffBlockTimestamp:             big.NewInt(0),
   131  		ClementineBlockTimestamp:        big.NewInt(0),
   132  	}
   133  
   134  	TestChainConfig             = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0)}
   135  	TestLaunchConfig            = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil}
   136  	TestApricotPhase1Config     = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, nil, nil}
   137  	TestApricotPhase2Config     = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil, nil}
   138  	TestApricotPhase3Config     = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, nil}
   139  	TestApricotPhase4Config     = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil}
   140  	TestApricotPhase5Config     = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil}
   141  	TestApricotPhasePre6Config  = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil}
   142  	TestApricotPhase6Config     = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil}
   143  	TestApricotPhasePost6Config = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil}
   144  	TestBanffChainConfig        = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil}
   145  	TestClementineChainConfig   = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0)}
   146  	TestRules                   = TestChainConfig.AvalancheRules(new(big.Int), new(big.Int))
   147  )
   148  
   149  // ChainConfig is the core config which determines the blockchain settings.
   150  //
   151  // ChainConfig is stored in the database on a per block basis. This means
   152  // that any network, identified by its genesis block, can have its own
   153  // set of configuration options.
   154  type ChainConfig struct {
   155  	ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
   156  
   157  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   158  
   159  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   160  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   161  
   162  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   163  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   164  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
   165  
   166  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   167  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   168  
   169  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   170  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   171  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`     // Petersburg switch block (nil = same as Constantinople)
   172  	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)
   173  	MuirGlacierBlock    *big.Int `json:"muirGlacierBlock,omitempty"`    // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
   174  
   175  	// Avalanche Network Upgrades
   176  	ApricotPhase1BlockTimestamp *big.Int `json:"apricotPhase1BlockTimestamp,omitempty"` // Apricot Phase 1 Block Timestamp (nil = no fork, 0 = already activated)
   177  	// Apricot Phase 2 Block Timestamp (nil = no fork, 0 = already activated)
   178  	// Apricot Phase 2 includes a modified version of the Berlin Hard Fork from Ethereum
   179  	ApricotPhase2BlockTimestamp *big.Int `json:"apricotPhase2BlockTimestamp,omitempty"`
   180  	// Apricot Phase 3 introduces dynamic fees and a modified version of the London Hard Fork from Ethereum (nil = no fork, 0 = already activated)
   181  	ApricotPhase3BlockTimestamp *big.Int `json:"apricotPhase3BlockTimestamp,omitempty"`
   182  	// Apricot Phase 4 introduces the notion of a block fee to the dynamic fee algorithm (nil = no fork, 0 = already activated)
   183  	ApricotPhase4BlockTimestamp *big.Int `json:"apricotPhase4BlockTimestamp,omitempty"`
   184  	// Apricot Phase 5 introduces a batch of atomic transactions with a maximum atomic gas limit per block. (nil = no fork, 0 = already activated)
   185  	ApricotPhase5BlockTimestamp *big.Int `json:"apricotPhase5BlockTimestamp,omitempty"`
   186  	// Apricot Phase Pre-6 deprecates the NativeAssetCall precompile (soft). (nil = no fork, 0 = already activated)
   187  	ApricotPhasePre6BlockTimestamp *big.Int `json:"apricotPhasePre6BlockTimestamp,omitempty"`
   188  	// Apricot Phase 6 deprecates the NativeAssetBalance and NativeAssetCall precompiles. (nil = no fork, 0 = already activated)
   189  	ApricotPhase6BlockTimestamp *big.Int `json:"apricotPhase6BlockTimestamp,omitempty"`
   190  	// Apricot Phase Post-6 deprecates the NativeAssetCall precompile (soft). (nil = no fork, 0 = already activated)
   191  	ApricotPhasePost6BlockTimestamp *big.Int `json:"apricotPhasePost6BlockTimestamp,omitempty"`
   192  	// Banff TODO comment. (nil = no fork, 0 = already activated)
   193  	BanffBlockTimestamp *big.Int `json:"banffBlockTimestamp,omitempty"`
   194  	// Clementine TODO comment. (nil = no fork, 0 = already activated)
   195  	ClementineBlockTimestamp *big.Int `json:"clementineBlockTimestamp,omitempty"`
   196  }
   197  
   198  // String implements the fmt.Stringer interface.
   199  func (c *ChainConfig) String() string {
   200  	var banner string
   201  
   202  	banner += fmt.Sprintf("Chain ID:  %v\n", c.ChainID)
   203  	banner += "Consensus: Dummy Consensus Engine\n\n"
   204  
   205  	// Create a list of forks with a short description of them. Forks that only
   206  	// makes sense for mainnet should be optional at printing to avoid bloating
   207  	// the output for testnets and private networks.
   208  	banner += "Hard Forks:\n"
   209  	banner += fmt.Sprintf(" - Homestead:                   %-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock)
   210  	if c.DAOForkBlock != nil {
   211  		banner += fmt.Sprintf(" - DAO Fork:                    %-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)\n", c.DAOForkBlock)
   212  	}
   213  	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)
   214  	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)
   215  	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)
   216  	banner += fmt.Sprintf(" - Byzantium:                   %-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock)
   217  	banner += fmt.Sprintf(" - Constantinople:              %-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock)
   218  	banner += fmt.Sprintf(" - Petersburg:                  %-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock)
   219  	banner += fmt.Sprintf(" - Istanbul:                    %-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock)
   220  	if c.MuirGlacierBlock != nil {
   221  		banner += fmt.Sprintf(" - Muir Glacier:                %-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock)
   222  	}
   223  	banner += fmt.Sprintf(" - Apricot Phase 1 Timestamp:        %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.3.0)\n", c.ApricotPhase1BlockTimestamp)
   224  	banner += fmt.Sprintf(" - Apricot Phase 2 Timestamp:        %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.4.0)\n", c.ApricotPhase2BlockTimestamp)
   225  	banner += fmt.Sprintf(" - Apricot Phase 3 Timestamp:        %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.5.0)\n", c.ApricotPhase3BlockTimestamp)
   226  	banner += fmt.Sprintf(" - Apricot Phase 4 Timestamp:        %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.6.0)\n", c.ApricotPhase4BlockTimestamp)
   227  	banner += fmt.Sprintf(" - Apricot Phase 5 Timestamp:        %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.7.0)\n", c.ApricotPhase5BlockTimestamp)
   228  	banner += fmt.Sprintf(" - Apricot Phase P6 Timestamp        %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.8.0)\n", c.ApricotPhasePre6BlockTimestamp)
   229  	banner += fmt.Sprintf(" - Apricot Phase 6 Timestamp:        %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.8.0)\n", c.ApricotPhase6BlockTimestamp)
   230  	banner += fmt.Sprintf(" - Apricot Phase Post-6 Timestamp:   %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.8.0\n", c.ApricotPhasePost6BlockTimestamp)
   231  	banner += fmt.Sprintf(" - Banff Timestamp:              %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.9.0)\n", c.BanffBlockTimestamp)
   232  	banner += fmt.Sprintf(" - Clementine Timestamp:             %-8v (https://github.com/dim4egster/qmallgo/releases/tag/v1.10.0)\n", c.ClementineBlockTimestamp)
   233  	banner += "\n"
   234  	return banner
   235  }
   236  
   237  // IsHomestead returns whether num is either equal to the homestead block or greater.
   238  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   239  	return utils.IsForked(c.HomesteadBlock, num)
   240  }
   241  
   242  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   243  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   244  	return utils.IsForked(c.DAOForkBlock, num)
   245  }
   246  
   247  // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
   248  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   249  	return utils.IsForked(c.EIP150Block, num)
   250  }
   251  
   252  // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
   253  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   254  	return utils.IsForked(c.EIP155Block, num)
   255  }
   256  
   257  // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
   258  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   259  	return utils.IsForked(c.EIP158Block, num)
   260  }
   261  
   262  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   263  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   264  	return utils.IsForked(c.ByzantiumBlock, num)
   265  }
   266  
   267  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   268  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   269  	return utils.IsForked(c.ConstantinopleBlock, num)
   270  }
   271  
   272  // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
   273  func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
   274  	return utils.IsForked(c.MuirGlacierBlock, num)
   275  }
   276  
   277  // IsPetersburg returns whether num is either
   278  // - equal to or greater than the PetersburgBlock fork block,
   279  // - OR is nil, and Constantinople is active
   280  func (c *ChainConfig) IsPetersburg(num *big.Int) bool {
   281  	return utils.IsForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && utils.IsForked(c.ConstantinopleBlock, num)
   282  }
   283  
   284  // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater.
   285  func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
   286  	return utils.IsForked(c.IstanbulBlock, num)
   287  }
   288  
   289  // Avalanche Upgrades:
   290  
   291  // IsApricotPhase1 returns whether [blockTimestamp] represents a block
   292  // with a timestamp after the Apricot Phase 1 upgrade time.
   293  func (c *ChainConfig) IsApricotPhase1(blockTimestamp *big.Int) bool {
   294  	return utils.IsForked(c.ApricotPhase1BlockTimestamp, blockTimestamp)
   295  }
   296  
   297  // IsApricotPhase2 returns whether [blockTimestamp] represents a block
   298  // with a timestamp after the Apricot Phase 2 upgrade time.
   299  func (c *ChainConfig) IsApricotPhase2(blockTimestamp *big.Int) bool {
   300  	return utils.IsForked(c.ApricotPhase2BlockTimestamp, blockTimestamp)
   301  }
   302  
   303  // IsApricotPhase3 returns whether [blockTimestamp] represents a block
   304  // with a timestamp after the Apricot Phase 3 upgrade time.
   305  func (c *ChainConfig) IsApricotPhase3(blockTimestamp *big.Int) bool {
   306  	return utils.IsForked(c.ApricotPhase3BlockTimestamp, blockTimestamp)
   307  }
   308  
   309  // IsApricotPhase4 returns whether [blockTimestamp] represents a block
   310  // with a timestamp after the Apricot Phase 4 upgrade time.
   311  func (c *ChainConfig) IsApricotPhase4(blockTimestamp *big.Int) bool {
   312  	return utils.IsForked(c.ApricotPhase4BlockTimestamp, blockTimestamp)
   313  }
   314  
   315  // IsApricotPhase5 returns whether [blockTimestamp] represents a block
   316  // with a timestamp after the Apricot Phase 5 upgrade time.
   317  func (c *ChainConfig) IsApricotPhase5(blockTimestamp *big.Int) bool {
   318  	return utils.IsForked(c.ApricotPhase5BlockTimestamp, blockTimestamp)
   319  }
   320  
   321  // IsApricotPhasePre6 returns whether [blockTimestamp] represents a block
   322  // with a timestamp after the Apricot Phase Pre 6 upgrade time.
   323  func (c *ChainConfig) IsApricotPhasePre6(blockTimestamp *big.Int) bool {
   324  	return utils.IsForked(c.ApricotPhasePre6BlockTimestamp, blockTimestamp)
   325  }
   326  
   327  // IsApricotPhase6 returns whether [blockTimestamp] represents a block
   328  // with a timestamp after the Apricot Phase 6 upgrade time.
   329  func (c *ChainConfig) IsApricotPhase6(blockTimestamp *big.Int) bool {
   330  	return utils.IsForked(c.ApricotPhase6BlockTimestamp, blockTimestamp)
   331  }
   332  
   333  // IsApricotPhasePost6 returns whether [blockTimestamp] represents a block
   334  // with a timestamp after the Apricot Phase 6 Post upgrade time.
   335  func (c *ChainConfig) IsApricotPhasePost6(blockTimestamp *big.Int) bool {
   336  	return utils.IsForked(c.ApricotPhasePost6BlockTimestamp, blockTimestamp)
   337  }
   338  
   339  // IsBanff returns whether [blockTimestamp] represents a block
   340  // with a timestamp after the Banff upgrade time.
   341  func (c *ChainConfig) IsBanff(blockTimestamp *big.Int) bool {
   342  	return utils.IsForked(c.BanffBlockTimestamp, blockTimestamp)
   343  }
   344  
   345  // IsClementine returns whether [blockTimestamp] represents a block
   346  // with a timestamp after the Clementine upgrade time.
   347  func (c *ChainConfig) IsClementine(blockTimestamp *big.Int) bool {
   348  	return utils.IsForked(c.ClementineBlockTimestamp, blockTimestamp)
   349  }
   350  
   351  // CheckCompatible checks whether scheduled fork transitions have been imported
   352  // with a mismatching chain configuration.
   353  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, timestamp uint64) *ConfigCompatError {
   354  	bhead := new(big.Int).SetUint64(height)
   355  	bheadTimestamp := new(big.Int).SetUint64(timestamp)
   356  
   357  	// Iterate checkCompatible to find the lowest conflict.
   358  	var lasterr *ConfigCompatError
   359  	for {
   360  		err := c.checkCompatible(newcfg, bhead, bheadTimestamp)
   361  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   362  			break
   363  		}
   364  		lasterr = err
   365  		bhead.SetUint64(err.RewindTo)
   366  	}
   367  	return lasterr
   368  }
   369  
   370  // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
   371  // to guarantee that forks can be implemented in a different order than on official networks
   372  func (c *ChainConfig) CheckConfigForkOrder() error {
   373  	type fork struct {
   374  		name     string
   375  		block    *big.Int
   376  		optional bool // if true, the fork may be nil and next fork is still allowed
   377  	}
   378  	var lastFork fork
   379  	for _, cur := range []fork{
   380  		{name: "homesteadBlock", block: c.HomesteadBlock},
   381  		{name: "daoForkBlock", block: c.DAOForkBlock, optional: true},
   382  		{name: "eip150Block", block: c.EIP150Block},
   383  		{name: "eip155Block", block: c.EIP155Block},
   384  		{name: "eip158Block", block: c.EIP158Block},
   385  		{name: "byzantiumBlock", block: c.ByzantiumBlock},
   386  		{name: "constantinopleBlock", block: c.ConstantinopleBlock},
   387  		{name: "petersburgBlock", block: c.PetersburgBlock},
   388  		{name: "istanbulBlock", block: c.IstanbulBlock},
   389  		{name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true},
   390  	} {
   391  		if cur.block != nil && common.Big0.Cmp(cur.block) != 0 {
   392  			return errNonGenesisForkByHeight
   393  		}
   394  		if lastFork.name != "" {
   395  			// Next one must be higher number
   396  			if lastFork.block == nil && cur.block != nil {
   397  				return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
   398  					lastFork.name, cur.name, cur.block)
   399  			}
   400  			if lastFork.block != nil && cur.block != nil {
   401  				if lastFork.block.Cmp(cur.block) > 0 {
   402  					return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
   403  						lastFork.name, lastFork.block, cur.name, cur.block)
   404  				}
   405  			}
   406  		}
   407  		// If it was optional and not set, then ignore it
   408  		if !cur.optional || cur.block != nil {
   409  			lastFork = cur
   410  		}
   411  	}
   412  
   413  	// Note: ApricotPhase1 and ApricotPhase2 override the rules set by block number
   414  	// hard forks. In Avalanche, hard forks must take place via block timestamps instead
   415  	// of block numbers since blocks are produced asynchronously. Therefore, we do not
   416  	// check that the block timestamps for Apricot Phase1 and Phase2 in the same way as for
   417  	// the block number forks since it would not be a meaningful comparison.
   418  	// Instead, we check only that Apricot Phases are enabled in order.
   419  	lastFork = fork{}
   420  	for _, cur := range []fork{
   421  		{name: "apricotPhase1BlockTimestamp", block: c.ApricotPhase1BlockTimestamp},
   422  		{name: "apricotPhase2BlockTimestamp", block: c.ApricotPhase2BlockTimestamp},
   423  		{name: "apricotPhase3BlockTimestamp", block: c.ApricotPhase3BlockTimestamp},
   424  		{name: "apricotPhase4BlockTimestamp", block: c.ApricotPhase4BlockTimestamp},
   425  		{name: "apricotPhase5BlockTimestamp", block: c.ApricotPhase5BlockTimestamp},
   426  		{name: "apricotPhasePre6BlockTimestamp", block: c.ApricotPhasePre6BlockTimestamp},
   427  		{name: "apricotPhase6BlockTimestamp", block: c.ApricotPhase6BlockTimestamp},
   428  		{name: "apricotPhasePost6BlockTimestamp", block: c.ApricotPhasePost6BlockTimestamp},
   429  		{name: "banffBlockTimestamp", block: c.BanffBlockTimestamp},
   430  		{name: "clementineBlockTimestamp", block: c.ClementineBlockTimestamp},
   431  	} {
   432  		if lastFork.name != "" {
   433  			// Next one must be higher number
   434  			if lastFork.block == nil && cur.block != nil {
   435  				return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
   436  					lastFork.name, cur.name, cur.block)
   437  			}
   438  			if lastFork.block != nil && cur.block != nil {
   439  				if lastFork.block.Cmp(cur.block) > 0 {
   440  					return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
   441  						lastFork.name, lastFork.block, cur.name, cur.block)
   442  				}
   443  			}
   444  		}
   445  		// If it was optional and not set, then ignore it
   446  		if !cur.optional || cur.block != nil {
   447  			lastFork = cur
   448  		}
   449  	}
   450  	// TODO(aaronbuchwald) check that avalanche block timestamps are at least possible with the other rule set changes
   451  	// additional change: require that block number hard forks are either 0 or nil since they should not
   452  	// be enabled at a specific block number.
   453  
   454  	return nil
   455  }
   456  
   457  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headHeight *big.Int, headTimestamp *big.Int) *ConfigCompatError {
   458  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, headHeight) {
   459  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   460  	}
   461  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, headHeight) {
   462  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   463  	}
   464  	if c.IsDAOFork(headHeight) && c.DAOForkSupport != newcfg.DAOForkSupport {
   465  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   466  	}
   467  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, headHeight) {
   468  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   469  	}
   470  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, headHeight) {
   471  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   472  	}
   473  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, headHeight) {
   474  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   475  	}
   476  	if c.IsEIP158(headHeight) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   477  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   478  	}
   479  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, headHeight) {
   480  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   481  	}
   482  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, headHeight) {
   483  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   484  	}
   485  	if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, headHeight) {
   486  		// the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople
   487  		// mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set
   488  		if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, headHeight) {
   489  			return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   490  		}
   491  	}
   492  	if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, headHeight) {
   493  		return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
   494  	}
   495  	if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, headHeight) {
   496  		return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
   497  	}
   498  	if isForkIncompatible(c.ApricotPhase1BlockTimestamp, newcfg.ApricotPhase1BlockTimestamp, headTimestamp) {
   499  		return newCompatError("ApricotPhase1 fork block timestamp", c.ApricotPhase1BlockTimestamp, newcfg.ApricotPhase1BlockTimestamp)
   500  	}
   501  	if isForkIncompatible(c.ApricotPhase2BlockTimestamp, newcfg.ApricotPhase2BlockTimestamp, headTimestamp) {
   502  		return newCompatError("ApricotPhase2 fork block timestamp", c.ApricotPhase2BlockTimestamp, newcfg.ApricotPhase2BlockTimestamp)
   503  	}
   504  	if isForkIncompatible(c.ApricotPhase3BlockTimestamp, newcfg.ApricotPhase3BlockTimestamp, headTimestamp) {
   505  		return newCompatError("ApricotPhase3 fork block timestamp", c.ApricotPhase3BlockTimestamp, newcfg.ApricotPhase3BlockTimestamp)
   506  	}
   507  	if isForkIncompatible(c.ApricotPhase4BlockTimestamp, newcfg.ApricotPhase4BlockTimestamp, headTimestamp) {
   508  		return newCompatError("ApricotPhase4 fork block timestamp", c.ApricotPhase4BlockTimestamp, newcfg.ApricotPhase4BlockTimestamp)
   509  	}
   510  	if isForkIncompatible(c.ApricotPhase5BlockTimestamp, newcfg.ApricotPhase5BlockTimestamp, headTimestamp) {
   511  		return newCompatError("ApricotPhase5 fork block timestamp", c.ApricotPhase5BlockTimestamp, newcfg.ApricotPhase5BlockTimestamp)
   512  	}
   513  	// TODO: add Phase 6 checks
   514  
   515  	if isForkIncompatible(c.BanffBlockTimestamp, newcfg.BanffBlockTimestamp, headTimestamp) {
   516  		return newCompatError("Banff fork block timestamp", c.BanffBlockTimestamp, newcfg.BanffBlockTimestamp)
   517  	}
   518  	if isForkIncompatible(c.ClementineBlockTimestamp, newcfg.ClementineBlockTimestamp, headTimestamp) {
   519  		return newCompatError("Clementine fork block timestamp", c.ClementineBlockTimestamp, newcfg.ClementineBlockTimestamp)
   520  	}
   521  	return nil
   522  }
   523  
   524  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   525  // block s2 because head is already past the fork.
   526  func isForkIncompatible(s1, s2, head *big.Int) bool {
   527  	return (utils.IsForked(s1, head) || utils.IsForked(s2, head)) && !configNumEqual(s1, s2)
   528  }
   529  
   530  func configNumEqual(x, y *big.Int) bool {
   531  	if x == nil {
   532  		return y == nil
   533  	}
   534  	if y == nil {
   535  		return x == nil
   536  	}
   537  	return x.Cmp(y) == 0
   538  }
   539  
   540  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   541  // ChainConfig that would alter the past.
   542  type ConfigCompatError struct {
   543  	What string
   544  	// block numbers of the stored and new configurations
   545  	StoredConfig, NewConfig *big.Int
   546  	// the block number to which the local chain must be rewound to correct the error
   547  	RewindTo uint64
   548  }
   549  
   550  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   551  	var rew *big.Int
   552  	switch {
   553  	case storedblock == nil:
   554  		rew = newblock
   555  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   556  		rew = storedblock
   557  	default:
   558  		rew = newblock
   559  	}
   560  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   561  	if rew != nil && rew.Sign() > 0 {
   562  		err.RewindTo = rew.Uint64() - 1
   563  	}
   564  	return err
   565  }
   566  
   567  func (err *ConfigCompatError) Error() string {
   568  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   569  }
   570  
   571  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
   572  // that do not have or require information about the block.
   573  //
   574  // Rules is a one time interface meaning that it shouldn't be used in between transition
   575  // phases.
   576  type Rules struct {
   577  	ChainID                                                 *big.Int
   578  	IsHomestead, IsEIP150, IsEIP155, IsEIP158               bool
   579  	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
   580  
   581  	// Rules for Avalanche releases
   582  	IsApricotPhase1, IsApricotPhase2, IsApricotPhase3, IsApricotPhase4, IsApricotPhase5 bool
   583  	IsApricotPhasePre6, IsApricotPhase6, IsApricotPhasePost6                            bool
   584  	IsBanff                                                                             bool
   585  	IsClementine                                                                        bool
   586  
   587  	// Precompiles maps addresses to stateful precompiled contracts that are enabled
   588  	// for this rule set.
   589  	// Note: none of these addresses should conflict with the address space used by
   590  	// any existing precompiles.
   591  	Precompiles map[common.Address]precompile.StatefulPrecompiledContract
   592  }
   593  
   594  // Rules ensures c's ChainID is not nil.
   595  func (c *ChainConfig) rules(num *big.Int) Rules {
   596  	chainID := c.ChainID
   597  	if chainID == nil {
   598  		chainID = new(big.Int)
   599  	}
   600  	return Rules{
   601  		ChainID:          new(big.Int).Set(chainID),
   602  		IsHomestead:      c.IsHomestead(num),
   603  		IsEIP150:         c.IsEIP150(num),
   604  		IsEIP155:         c.IsEIP155(num),
   605  		IsEIP158:         c.IsEIP158(num),
   606  		IsByzantium:      c.IsByzantium(num),
   607  		IsConstantinople: c.IsConstantinople(num),
   608  		IsPetersburg:     c.IsPetersburg(num),
   609  		IsIstanbul:       c.IsIstanbul(num),
   610  	}
   611  }
   612  
   613  // AvalancheRules returns the Avalanche modified rules to support Avalanche
   614  // network upgrades
   615  func (c *ChainConfig) AvalancheRules(blockNum, blockTimestamp *big.Int) Rules {
   616  	rules := c.rules(blockNum)
   617  
   618  	rules.IsApricotPhase1 = c.IsApricotPhase1(blockTimestamp)
   619  	rules.IsApricotPhase2 = c.IsApricotPhase2(blockTimestamp)
   620  	rules.IsApricotPhase3 = c.IsApricotPhase3(blockTimestamp)
   621  	rules.IsApricotPhase4 = c.IsApricotPhase4(blockTimestamp)
   622  	rules.IsApricotPhase5 = c.IsApricotPhase5(blockTimestamp)
   623  	rules.IsApricotPhasePre6 = c.IsApricotPhasePre6(blockTimestamp)
   624  	rules.IsApricotPhase6 = c.IsApricotPhase6(blockTimestamp)
   625  	rules.IsApricotPhasePost6 = c.IsApricotPhasePost6(blockTimestamp)
   626  	rules.IsBanff = c.IsBanff(blockTimestamp)
   627  	rules.IsClementine = c.IsClementine(blockTimestamp)
   628  
   629  	// Initialize the stateful precompiles that should be enabled at [blockTimestamp].
   630  	rules.Precompiles = make(map[common.Address]precompile.StatefulPrecompiledContract)
   631  	for _, config := range c.enabledStatefulPrecompiles() {
   632  		if utils.IsForked(config.Timestamp(), blockTimestamp) {
   633  			rules.Precompiles[config.Address()] = config.Contract()
   634  		}
   635  	}
   636  
   637  	return rules
   638  }
   639  
   640  // enabledStatefulPrecompiles returns a list of stateful precompile configs in the order that they are enabled
   641  // by block timestamp.
   642  // Note: the return value does not include the native precompiles [nativeAssetCall] and [nativeAssetBalance].
   643  // These are handled in [evm.precompile] directly.
   644  func (c *ChainConfig) enabledStatefulPrecompiles() []precompile.StatefulPrecompileConfig {
   645  	statefulPrecompileConfigs := make([]precompile.StatefulPrecompileConfig, 0)
   646  
   647  	return statefulPrecompileConfigs
   648  }
   649  
   650  // CheckConfigurePrecompiles checks if any of the precompiles specified in the chain config are enabled by the block
   651  // transition from [parentTimestamp] to the timestamp set in [blockContext]. If this is the case, it calls [Configure]
   652  // to apply the necessary state transitions for the upgrade.
   653  // This function is called:
   654  // - within genesis setup to configure the starting state for precompiles enabled at genesis,
   655  // - during block processing to update the state before processing the given block.
   656  func (c *ChainConfig) CheckConfigurePrecompiles(parentTimestamp *big.Int, blockContext precompile.BlockContext, statedb precompile.StateDB) {
   657  	// Iterate the enabled stateful precompiles and configure them if needed
   658  	for _, config := range c.enabledStatefulPrecompiles() {
   659  		precompile.CheckConfigure(c, parentTimestamp, blockContext, config, statedb)
   660  	}
   661  }