github.com/ethereum/go-ethereum@v1.16.1/params/config.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package params
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"math"
    23  	"math/big"
    24  
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/params/forks"
    27  )
    28  
    29  // Genesis hashes to enforce below configs on.
    30  var (
    31  	MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
    32  	HoleskyGenesisHash = common.HexToHash("0xb5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4")
    33  	SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9")
    34  	HoodiGenesisHash   = common.HexToHash("0xbbe312868b376a3001692a646dd2d7d1e4406380dfd86b98aa8a34d1557c971b")
    35  )
    36  
    37  func newUint64(val uint64) *uint64 { return &val }
    38  
    39  var (
    40  	MainnetTerminalTotalDifficulty, _ = new(big.Int).SetString("58_750_000_000_000_000_000_000", 0)
    41  
    42  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    43  	MainnetChainConfig = &ChainConfig{
    44  		ChainID:                 big.NewInt(1),
    45  		HomesteadBlock:          big.NewInt(1_150_000),
    46  		DAOForkBlock:            big.NewInt(1_920_000),
    47  		DAOForkSupport:          true,
    48  		EIP150Block:             big.NewInt(2_463_000),
    49  		EIP155Block:             big.NewInt(2_675_000),
    50  		EIP158Block:             big.NewInt(2_675_000),
    51  		ByzantiumBlock:          big.NewInt(4_370_000),
    52  		ConstantinopleBlock:     big.NewInt(7_280_000),
    53  		PetersburgBlock:         big.NewInt(7_280_000),
    54  		IstanbulBlock:           big.NewInt(9_069_000),
    55  		MuirGlacierBlock:        big.NewInt(9_200_000),
    56  		BerlinBlock:             big.NewInt(12_244_000),
    57  		LondonBlock:             big.NewInt(12_965_000),
    58  		ArrowGlacierBlock:       big.NewInt(13_773_000),
    59  		GrayGlacierBlock:        big.NewInt(15_050_000),
    60  		TerminalTotalDifficulty: MainnetTerminalTotalDifficulty, // 58_750_000_000_000_000_000_000
    61  		ShanghaiTime:            newUint64(1681338455),
    62  		CancunTime:              newUint64(1710338135),
    63  		PragueTime:              newUint64(1746612311),
    64  		DepositContractAddress:  common.HexToAddress("0x00000000219ab540356cbb839cbe05303d7705fa"),
    65  		Ethash:                  new(EthashConfig),
    66  		BlobScheduleConfig: &BlobScheduleConfig{
    67  			Cancun: DefaultCancunBlobConfig,
    68  			Prague: DefaultPragueBlobConfig,
    69  		},
    70  	}
    71  	// HoleskyChainConfig contains the chain parameters to run a node on the Holesky test network.
    72  	HoleskyChainConfig = &ChainConfig{
    73  		ChainID:                 big.NewInt(17000),
    74  		HomesteadBlock:          big.NewInt(0),
    75  		DAOForkBlock:            nil,
    76  		DAOForkSupport:          true,
    77  		EIP150Block:             big.NewInt(0),
    78  		EIP155Block:             big.NewInt(0),
    79  		EIP158Block:             big.NewInt(0),
    80  		ByzantiumBlock:          big.NewInt(0),
    81  		ConstantinopleBlock:     big.NewInt(0),
    82  		PetersburgBlock:         big.NewInt(0),
    83  		IstanbulBlock:           big.NewInt(0),
    84  		MuirGlacierBlock:        nil,
    85  		BerlinBlock:             big.NewInt(0),
    86  		LondonBlock:             big.NewInt(0),
    87  		ArrowGlacierBlock:       nil,
    88  		GrayGlacierBlock:        nil,
    89  		TerminalTotalDifficulty: big.NewInt(0),
    90  		MergeNetsplitBlock:      nil,
    91  		ShanghaiTime:            newUint64(1696000704),
    92  		CancunTime:              newUint64(1707305664),
    93  		PragueTime:              newUint64(1740434112),
    94  		DepositContractAddress:  common.HexToAddress("0x4242424242424242424242424242424242424242"),
    95  		Ethash:                  new(EthashConfig),
    96  		BlobScheduleConfig: &BlobScheduleConfig{
    97  			Cancun: DefaultCancunBlobConfig,
    98  			Prague: DefaultPragueBlobConfig,
    99  		},
   100  	}
   101  	// SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network.
   102  	SepoliaChainConfig = &ChainConfig{
   103  		ChainID:                 big.NewInt(11155111),
   104  		HomesteadBlock:          big.NewInt(0),
   105  		DAOForkBlock:            nil,
   106  		DAOForkSupport:          true,
   107  		EIP150Block:             big.NewInt(0),
   108  		EIP155Block:             big.NewInt(0),
   109  		EIP158Block:             big.NewInt(0),
   110  		ByzantiumBlock:          big.NewInt(0),
   111  		ConstantinopleBlock:     big.NewInt(0),
   112  		PetersburgBlock:         big.NewInt(0),
   113  		IstanbulBlock:           big.NewInt(0),
   114  		MuirGlacierBlock:        big.NewInt(0),
   115  		BerlinBlock:             big.NewInt(0),
   116  		LondonBlock:             big.NewInt(0),
   117  		ArrowGlacierBlock:       nil,
   118  		GrayGlacierBlock:        nil,
   119  		TerminalTotalDifficulty: big.NewInt(17_000_000_000_000_000),
   120  		MergeNetsplitBlock:      big.NewInt(1735371),
   121  		ShanghaiTime:            newUint64(1677557088),
   122  		CancunTime:              newUint64(1706655072),
   123  		PragueTime:              newUint64(1741159776),
   124  		DepositContractAddress:  common.HexToAddress("0x7f02c3e3c98b133055b8b348b2ac625669ed295d"),
   125  		Ethash:                  new(EthashConfig),
   126  		BlobScheduleConfig: &BlobScheduleConfig{
   127  			Cancun: DefaultCancunBlobConfig,
   128  			Prague: DefaultPragueBlobConfig,
   129  		},
   130  	}
   131  	// HoodiChainConfig contains the chain parameters to run a node on the Hoodi test network.
   132  	HoodiChainConfig = &ChainConfig{
   133  		ChainID:                 big.NewInt(560048),
   134  		HomesteadBlock:          big.NewInt(0),
   135  		DAOForkBlock:            nil,
   136  		DAOForkSupport:          true,
   137  		EIP150Block:             big.NewInt(0),
   138  		EIP155Block:             big.NewInt(0),
   139  		EIP158Block:             big.NewInt(0),
   140  		ByzantiumBlock:          big.NewInt(0),
   141  		ConstantinopleBlock:     big.NewInt(0),
   142  		PetersburgBlock:         big.NewInt(0),
   143  		IstanbulBlock:           big.NewInt(0),
   144  		MuirGlacierBlock:        big.NewInt(0),
   145  		BerlinBlock:             big.NewInt(0),
   146  		LondonBlock:             big.NewInt(0),
   147  		ArrowGlacierBlock:       nil,
   148  		GrayGlacierBlock:        nil,
   149  		TerminalTotalDifficulty: big.NewInt(0),
   150  		MergeNetsplitBlock:      big.NewInt(0),
   151  		ShanghaiTime:            newUint64(0),
   152  		CancunTime:              newUint64(0),
   153  		PragueTime:              newUint64(1742999832),
   154  		DepositContractAddress:  common.HexToAddress("0x00000000219ab540356cBB839Cbe05303d7705Fa"),
   155  		Ethash:                  new(EthashConfig),
   156  		BlobScheduleConfig: &BlobScheduleConfig{
   157  			Cancun: DefaultCancunBlobConfig,
   158  			Prague: DefaultPragueBlobConfig,
   159  		},
   160  	}
   161  	// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
   162  	// and accepted by the Ethereum core developers into the Ethash consensus.
   163  	AllEthashProtocolChanges = &ChainConfig{
   164  		ChainID:                 big.NewInt(1337),
   165  		HomesteadBlock:          big.NewInt(0),
   166  		DAOForkBlock:            nil,
   167  		DAOForkSupport:          false,
   168  		EIP150Block:             big.NewInt(0),
   169  		EIP155Block:             big.NewInt(0),
   170  		EIP158Block:             big.NewInt(0),
   171  		ByzantiumBlock:          big.NewInt(0),
   172  		ConstantinopleBlock:     big.NewInt(0),
   173  		PetersburgBlock:         big.NewInt(0),
   174  		IstanbulBlock:           big.NewInt(0),
   175  		MuirGlacierBlock:        big.NewInt(0),
   176  		BerlinBlock:             big.NewInt(0),
   177  		LondonBlock:             big.NewInt(0),
   178  		ArrowGlacierBlock:       big.NewInt(0),
   179  		GrayGlacierBlock:        big.NewInt(0),
   180  		TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
   181  		MergeNetsplitBlock:      nil,
   182  		ShanghaiTime:            nil,
   183  		CancunTime:              nil,
   184  		PragueTime:              nil,
   185  		OsakaTime:               nil,
   186  		VerkleTime:              nil,
   187  		Ethash:                  new(EthashConfig),
   188  		Clique:                  nil,
   189  	}
   190  
   191  	AllDevChainProtocolChanges = &ChainConfig{
   192  		ChainID:                 big.NewInt(1337),
   193  		HomesteadBlock:          big.NewInt(0),
   194  		EIP150Block:             big.NewInt(0),
   195  		EIP155Block:             big.NewInt(0),
   196  		EIP158Block:             big.NewInt(0),
   197  		ByzantiumBlock:          big.NewInt(0),
   198  		ConstantinopleBlock:     big.NewInt(0),
   199  		PetersburgBlock:         big.NewInt(0),
   200  		IstanbulBlock:           big.NewInt(0),
   201  		MuirGlacierBlock:        big.NewInt(0),
   202  		BerlinBlock:             big.NewInt(0),
   203  		LondonBlock:             big.NewInt(0),
   204  		ArrowGlacierBlock:       big.NewInt(0),
   205  		GrayGlacierBlock:        big.NewInt(0),
   206  		ShanghaiTime:            newUint64(0),
   207  		CancunTime:              newUint64(0),
   208  		TerminalTotalDifficulty: big.NewInt(0),
   209  		PragueTime:              newUint64(0),
   210  		BlobScheduleConfig: &BlobScheduleConfig{
   211  			Cancun: DefaultCancunBlobConfig,
   212  			Prague: DefaultPragueBlobConfig,
   213  		},
   214  	}
   215  
   216  	// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
   217  	// and accepted by the Ethereum core developers into the Clique consensus.
   218  	AllCliqueProtocolChanges = &ChainConfig{
   219  		ChainID:                 big.NewInt(1337),
   220  		HomesteadBlock:          big.NewInt(0),
   221  		DAOForkBlock:            nil,
   222  		DAOForkSupport:          false,
   223  		EIP150Block:             big.NewInt(0),
   224  		EIP155Block:             big.NewInt(0),
   225  		EIP158Block:             big.NewInt(0),
   226  		ByzantiumBlock:          big.NewInt(0),
   227  		ConstantinopleBlock:     big.NewInt(0),
   228  		PetersburgBlock:         big.NewInt(0),
   229  		IstanbulBlock:           big.NewInt(0),
   230  		MuirGlacierBlock:        big.NewInt(0),
   231  		BerlinBlock:             big.NewInt(0),
   232  		LondonBlock:             big.NewInt(0),
   233  		ArrowGlacierBlock:       nil,
   234  		GrayGlacierBlock:        nil,
   235  		MergeNetsplitBlock:      nil,
   236  		ShanghaiTime:            nil,
   237  		CancunTime:              nil,
   238  		PragueTime:              nil,
   239  		OsakaTime:               nil,
   240  		VerkleTime:              nil,
   241  		TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
   242  		Ethash:                  nil,
   243  		Clique:                  &CliqueConfig{Period: 0, Epoch: 30000},
   244  	}
   245  
   246  	// TestChainConfig contains every protocol change (EIPs) introduced
   247  	// and accepted by the Ethereum core developers for testing purposes.
   248  	TestChainConfig = &ChainConfig{
   249  		ChainID:                 big.NewInt(1),
   250  		HomesteadBlock:          big.NewInt(0),
   251  		DAOForkBlock:            nil,
   252  		DAOForkSupport:          false,
   253  		EIP150Block:             big.NewInt(0),
   254  		EIP155Block:             big.NewInt(0),
   255  		EIP158Block:             big.NewInt(0),
   256  		ByzantiumBlock:          big.NewInt(0),
   257  		ConstantinopleBlock:     big.NewInt(0),
   258  		PetersburgBlock:         big.NewInt(0),
   259  		IstanbulBlock:           big.NewInt(0),
   260  		MuirGlacierBlock:        big.NewInt(0),
   261  		BerlinBlock:             big.NewInt(0),
   262  		LondonBlock:             big.NewInt(0),
   263  		ArrowGlacierBlock:       big.NewInt(0),
   264  		GrayGlacierBlock:        big.NewInt(0),
   265  		MergeNetsplitBlock:      nil,
   266  		ShanghaiTime:            nil,
   267  		CancunTime:              nil,
   268  		PragueTime:              nil,
   269  		OsakaTime:               nil,
   270  		VerkleTime:              nil,
   271  		TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
   272  		Ethash:                  new(EthashConfig),
   273  		Clique:                  nil,
   274  	}
   275  
   276  	// MergedTestChainConfig contains every protocol change (EIPs) introduced
   277  	// and accepted by the Ethereum core developers for testing purposes.
   278  	MergedTestChainConfig = &ChainConfig{
   279  		ChainID:                 big.NewInt(1),
   280  		HomesteadBlock:          big.NewInt(0),
   281  		DAOForkBlock:            nil,
   282  		DAOForkSupport:          false,
   283  		EIP150Block:             big.NewInt(0),
   284  		EIP155Block:             big.NewInt(0),
   285  		EIP158Block:             big.NewInt(0),
   286  		ByzantiumBlock:          big.NewInt(0),
   287  		ConstantinopleBlock:     big.NewInt(0),
   288  		PetersburgBlock:         big.NewInt(0),
   289  		IstanbulBlock:           big.NewInt(0),
   290  		MuirGlacierBlock:        big.NewInt(0),
   291  		BerlinBlock:             big.NewInt(0),
   292  		LondonBlock:             big.NewInt(0),
   293  		ArrowGlacierBlock:       big.NewInt(0),
   294  		GrayGlacierBlock:        big.NewInt(0),
   295  		MergeNetsplitBlock:      big.NewInt(0),
   296  		ShanghaiTime:            newUint64(0),
   297  		CancunTime:              newUint64(0),
   298  		PragueTime:              newUint64(0),
   299  		OsakaTime:               newUint64(0),
   300  		VerkleTime:              nil,
   301  		TerminalTotalDifficulty: big.NewInt(0),
   302  		Ethash:                  new(EthashConfig),
   303  		Clique:                  nil,
   304  		BlobScheduleConfig: &BlobScheduleConfig{
   305  			Cancun: DefaultCancunBlobConfig,
   306  			Prague: DefaultPragueBlobConfig,
   307  			Osaka:  DefaultOsakaBlobConfig,
   308  		},
   309  	}
   310  
   311  	// NonActivatedConfig defines the chain configuration without activating
   312  	// any protocol change (EIPs).
   313  	NonActivatedConfig = &ChainConfig{
   314  		ChainID:                 big.NewInt(1),
   315  		HomesteadBlock:          nil,
   316  		DAOForkBlock:            nil,
   317  		DAOForkSupport:          false,
   318  		EIP150Block:             nil,
   319  		EIP155Block:             nil,
   320  		EIP158Block:             nil,
   321  		ByzantiumBlock:          nil,
   322  		ConstantinopleBlock:     nil,
   323  		PetersburgBlock:         nil,
   324  		IstanbulBlock:           nil,
   325  		MuirGlacierBlock:        nil,
   326  		BerlinBlock:             nil,
   327  		LondonBlock:             nil,
   328  		ArrowGlacierBlock:       nil,
   329  		GrayGlacierBlock:        nil,
   330  		MergeNetsplitBlock:      nil,
   331  		ShanghaiTime:            nil,
   332  		CancunTime:              nil,
   333  		PragueTime:              nil,
   334  		OsakaTime:               nil,
   335  		VerkleTime:              nil,
   336  		TerminalTotalDifficulty: big.NewInt(math.MaxInt64),
   337  		Ethash:                  new(EthashConfig),
   338  		Clique:                  nil,
   339  	}
   340  	TestRules = TestChainConfig.Rules(new(big.Int), false, 0)
   341  )
   342  
   343  var (
   344  	// DefaultCancunBlobConfig is the default blob configuration for the Cancun fork.
   345  	DefaultCancunBlobConfig = &BlobConfig{
   346  		Target:         3,
   347  		Max:            6,
   348  		UpdateFraction: 3338477,
   349  	}
   350  	// DefaultPragueBlobConfig is the default blob configuration for the Prague fork.
   351  	DefaultPragueBlobConfig = &BlobConfig{
   352  		Target:         6,
   353  		Max:            9,
   354  		UpdateFraction: 5007716,
   355  	}
   356  	// DefaultOsakaBlobConfig is the default blob configuration for the Osaka fork.
   357  	DefaultOsakaBlobConfig = &BlobConfig{
   358  		Target:         6,
   359  		Max:            9,
   360  		UpdateFraction: 5007716,
   361  	}
   362  	// DefaultBlobSchedule is the latest configured blob schedule for Ethereum mainnet.
   363  	DefaultBlobSchedule = &BlobScheduleConfig{
   364  		Cancun: DefaultCancunBlobConfig,
   365  		Prague: DefaultPragueBlobConfig,
   366  		Osaka:  DefaultOsakaBlobConfig,
   367  	}
   368  )
   369  
   370  // NetworkNames are user friendly names to use in the chain spec banner.
   371  var NetworkNames = map[string]string{
   372  	MainnetChainConfig.ChainID.String(): "mainnet",
   373  	SepoliaChainConfig.ChainID.String(): "sepolia",
   374  	HoleskyChainConfig.ChainID.String(): "holesky",
   375  	HoodiChainConfig.ChainID.String():   "hoodi",
   376  }
   377  
   378  // ChainConfig is the core config which determines the blockchain settings.
   379  //
   380  // ChainConfig is stored in the database on a per block basis. This means
   381  // that any network, identified by its genesis block, can have its own
   382  // set of configuration options.
   383  type ChainConfig struct {
   384  	ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
   385  
   386  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   387  
   388  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   389  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   390  
   391  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   392  	EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   393  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   394  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   395  
   396  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   397  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   398  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`     // Petersburg switch block (nil = same as Constantinople)
   399  	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)
   400  	MuirGlacierBlock    *big.Int `json:"muirGlacierBlock,omitempty"`    // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
   401  	BerlinBlock         *big.Int `json:"berlinBlock,omitempty"`         // Berlin switch block (nil = no fork, 0 = already on berlin)
   402  	LondonBlock         *big.Int `json:"londonBlock,omitempty"`         // London switch block (nil = no fork, 0 = already on london)
   403  	ArrowGlacierBlock   *big.Int `json:"arrowGlacierBlock,omitempty"`   // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated)
   404  	GrayGlacierBlock    *big.Int `json:"grayGlacierBlock,omitempty"`    // Eip-5133 (bomb delay) switch block (nil = no fork, 0 = already activated)
   405  	MergeNetsplitBlock  *big.Int `json:"mergeNetsplitBlock,omitempty"`  // Virtual fork after The Merge to use as a network splitter
   406  
   407  	// Fork scheduling was switched from blocks to timestamps here
   408  
   409  	ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai)
   410  	CancunTime   *uint64 `json:"cancunTime,omitempty"`   // Cancun switch time (nil = no fork, 0 = already on cancun)
   411  	PragueTime   *uint64 `json:"pragueTime,omitempty"`   // Prague switch time (nil = no fork, 0 = already on prague)
   412  	OsakaTime    *uint64 `json:"osakaTime,omitempty"`    // Osaka switch time (nil = no fork, 0 = already on osaka)
   413  	VerkleTime   *uint64 `json:"verkleTime,omitempty"`   // Verkle switch time (nil = no fork, 0 = already on verkle)
   414  
   415  	// TerminalTotalDifficulty is the amount of total difficulty reached by
   416  	// the network that triggers the consensus upgrade.
   417  	TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"`
   418  
   419  	DepositContractAddress common.Address `json:"depositContractAddress,omitempty"`
   420  
   421  	// EnableVerkleAtGenesis is a flag that specifies whether the network uses
   422  	// the Verkle tree starting from the genesis block. If set to true, the
   423  	// genesis state will be committed using the Verkle tree, eliminating the
   424  	// need for any Verkle transition later.
   425  	//
   426  	// This is a temporary flag only for verkle devnet testing, where verkle is
   427  	// activated at genesis, and the configured activation date has already passed.
   428  	//
   429  	// In production networks (mainnet and public testnets), verkle activation
   430  	// always occurs after the genesis block, making this flag irrelevant in
   431  	// those cases.
   432  	EnableVerkleAtGenesis bool `json:"enableVerkleAtGenesis,omitempty"`
   433  
   434  	// Various consensus engines
   435  	Ethash             *EthashConfig       `json:"ethash,omitempty"`
   436  	Clique             *CliqueConfig       `json:"clique,omitempty"`
   437  	BlobScheduleConfig *BlobScheduleConfig `json:"blobSchedule,omitempty"`
   438  }
   439  
   440  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   441  type EthashConfig struct{}
   442  
   443  // String implements the stringer interface, returning the consensus engine details.
   444  func (c EthashConfig) String() string {
   445  	return "ethash"
   446  }
   447  
   448  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   449  type CliqueConfig struct {
   450  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   451  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   452  }
   453  
   454  // String implements the stringer interface, returning the consensus engine details.
   455  func (c CliqueConfig) String() string {
   456  	return fmt.Sprintf("clique(period: %d, epoch: %d)", c.Period, c.Epoch)
   457  }
   458  
   459  // Description returns a human-readable description of ChainConfig.
   460  func (c *ChainConfig) Description() string {
   461  	var banner string
   462  
   463  	// Create some basic network config output
   464  	network := NetworkNames[c.ChainID.String()]
   465  	if network == "" {
   466  		network = "unknown"
   467  	}
   468  	banner += fmt.Sprintf("Chain ID:  %v (%s)\n", c.ChainID, network)
   469  	switch {
   470  	case c.Ethash != nil:
   471  		banner += "Consensus: Beacon (proof-of-stake), merged from Ethash (proof-of-work)\n"
   472  	case c.Clique != nil:
   473  		banner += "Consensus: Beacon (proof-of-stake), merged from Clique (proof-of-authority)\n"
   474  	default:
   475  		banner += "Consensus: unknown\n"
   476  	}
   477  	banner += "\n"
   478  
   479  	// Create a list of forks with a short description of them. Forks that only
   480  	// makes sense for mainnet should be optional at printing to avoid bloating
   481  	// the output for testnets and private networks.
   482  	banner += "Pre-Merge hard forks (block based):\n"
   483  	banner += fmt.Sprintf(" - Homestead:                   #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock)
   484  	if c.DAOForkBlock != nil {
   485  		banner += fmt.Sprintf(" - DAO Fork:                    #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)\n", c.DAOForkBlock)
   486  	}
   487  	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)
   488  	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)
   489  	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)
   490  	banner += fmt.Sprintf(" - Byzantium:                   #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock)
   491  	banner += fmt.Sprintf(" - Constantinople:              #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock)
   492  	banner += fmt.Sprintf(" - Petersburg:                  #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock)
   493  	banner += fmt.Sprintf(" - Istanbul:                    #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock)
   494  	if c.MuirGlacierBlock != nil {
   495  		banner += fmt.Sprintf(" - Muir Glacier:                #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock)
   496  	}
   497  	banner += fmt.Sprintf(" - Berlin:                      #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)\n", c.BerlinBlock)
   498  	banner += fmt.Sprintf(" - London:                      #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)\n", c.LondonBlock)
   499  	if c.ArrowGlacierBlock != nil {
   500  		banner += fmt.Sprintf(" - Arrow Glacier:               #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)\n", c.ArrowGlacierBlock)
   501  	}
   502  	if c.GrayGlacierBlock != nil {
   503  		banner += fmt.Sprintf(" - Gray Glacier:                #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)\n", c.GrayGlacierBlock)
   504  	}
   505  	banner += "\n"
   506  
   507  	// Add a special section for the merge as it's non-obvious
   508  	banner += "Merge configured:\n"
   509  	banner += " - Hard-fork specification:    https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n"
   510  	banner += " - Network known to be merged\n"
   511  	banner += fmt.Sprintf(" - Total terminal difficulty:  %v\n", c.TerminalTotalDifficulty)
   512  	if c.MergeNetsplitBlock != nil {
   513  		banner += fmt.Sprintf(" - Merge netsplit block:       #%-8v\n", c.MergeNetsplitBlock)
   514  	}
   515  	banner += "\n"
   516  
   517  	// Create a list of forks post-merge
   518  	banner += "Post-Merge hard forks (timestamp based):\n"
   519  	if c.ShanghaiTime != nil {
   520  		banner += fmt.Sprintf(" - Shanghai:                    @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md)\n", *c.ShanghaiTime)
   521  	}
   522  	if c.CancunTime != nil {
   523  		banner += fmt.Sprintf(" - Cancun:                      @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md)\n", *c.CancunTime)
   524  	}
   525  	if c.PragueTime != nil {
   526  		banner += fmt.Sprintf(" - Prague:                      @%-10v\n", *c.PragueTime)
   527  	}
   528  	if c.OsakaTime != nil {
   529  		banner += fmt.Sprintf(" - Osaka:                      @%-10v\n", *c.OsakaTime)
   530  	}
   531  	if c.VerkleTime != nil {
   532  		banner += fmt.Sprintf(" - Verkle:                      @%-10v\n", *c.VerkleTime)
   533  	}
   534  	return banner
   535  }
   536  
   537  // BlobConfig specifies the target and max blobs per block for the associated fork.
   538  type BlobConfig struct {
   539  	Target         int    `json:"target"`
   540  	Max            int    `json:"max"`
   541  	UpdateFraction uint64 `json:"baseFeeUpdateFraction"`
   542  }
   543  
   544  // BlobScheduleConfig determines target and max number of blobs allow per fork.
   545  type BlobScheduleConfig struct {
   546  	Cancun *BlobConfig `json:"cancun,omitempty"`
   547  	Prague *BlobConfig `json:"prague,omitempty"`
   548  	Osaka  *BlobConfig `json:"osaka,omitempty"`
   549  	Verkle *BlobConfig `json:"verkle,omitempty"`
   550  }
   551  
   552  // IsHomestead returns whether num is either equal to the homestead block or greater.
   553  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   554  	return isBlockForked(c.HomesteadBlock, num)
   555  }
   556  
   557  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   558  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   559  	return isBlockForked(c.DAOForkBlock, num)
   560  }
   561  
   562  // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
   563  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   564  	return isBlockForked(c.EIP150Block, num)
   565  }
   566  
   567  // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
   568  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   569  	return isBlockForked(c.EIP155Block, num)
   570  }
   571  
   572  // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
   573  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   574  	return isBlockForked(c.EIP158Block, num)
   575  }
   576  
   577  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   578  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   579  	return isBlockForked(c.ByzantiumBlock, num)
   580  }
   581  
   582  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   583  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   584  	return isBlockForked(c.ConstantinopleBlock, num)
   585  }
   586  
   587  // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
   588  func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
   589  	return isBlockForked(c.MuirGlacierBlock, num)
   590  }
   591  
   592  // IsPetersburg returns whether num is either
   593  // - equal to or greater than the PetersburgBlock fork block,
   594  // - OR is nil, and Constantinople is active
   595  func (c *ChainConfig) IsPetersburg(num *big.Int) bool {
   596  	return isBlockForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isBlockForked(c.ConstantinopleBlock, num)
   597  }
   598  
   599  // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater.
   600  func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
   601  	return isBlockForked(c.IstanbulBlock, num)
   602  }
   603  
   604  // IsBerlin returns whether num is either equal to the Berlin fork block or greater.
   605  func (c *ChainConfig) IsBerlin(num *big.Int) bool {
   606  	return isBlockForked(c.BerlinBlock, num)
   607  }
   608  
   609  // IsLondon returns whether num is either equal to the London fork block or greater.
   610  func (c *ChainConfig) IsLondon(num *big.Int) bool {
   611  	return isBlockForked(c.LondonBlock, num)
   612  }
   613  
   614  // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater.
   615  func (c *ChainConfig) IsArrowGlacier(num *big.Int) bool {
   616  	return isBlockForked(c.ArrowGlacierBlock, num)
   617  }
   618  
   619  // IsGrayGlacier returns whether num is either equal to the Gray Glacier (EIP-5133) fork block or greater.
   620  func (c *ChainConfig) IsGrayGlacier(num *big.Int) bool {
   621  	return isBlockForked(c.GrayGlacierBlock, num)
   622  }
   623  
   624  // IsTerminalPoWBlock returns whether the given block is the last block of PoW stage.
   625  func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool {
   626  	if c.TerminalTotalDifficulty == nil {
   627  		return false
   628  	}
   629  	return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0
   630  }
   631  
   632  // IsShanghai returns whether time is either equal to the Shanghai fork time or greater.
   633  func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool {
   634  	return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time)
   635  }
   636  
   637  // IsCancun returns whether time is either equal to the Cancun fork time or greater.
   638  func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool {
   639  	return c.IsLondon(num) && isTimestampForked(c.CancunTime, time)
   640  }
   641  
   642  // IsPrague returns whether time is either equal to the Prague fork time or greater.
   643  func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool {
   644  	return c.IsLondon(num) && isTimestampForked(c.PragueTime, time)
   645  }
   646  
   647  // IsOsaka returns whether time is either equal to the Osaka fork time or greater.
   648  func (c *ChainConfig) IsOsaka(num *big.Int, time uint64) bool {
   649  	return c.IsLondon(num) && isTimestampForked(c.OsakaTime, time)
   650  }
   651  
   652  // IsVerkle returns whether time is either equal to the Verkle fork time or greater.
   653  func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool {
   654  	return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time)
   655  }
   656  
   657  // IsVerkleGenesis checks whether the verkle fork is activated at the genesis block.
   658  //
   659  // Verkle mode is considered enabled if the verkle fork time is configured,
   660  // regardless of whether the local time has surpassed the fork activation time.
   661  // This is a temporary workaround for verkle devnet testing, where verkle is
   662  // activated at genesis, and the configured activation date has already passed.
   663  //
   664  // In production networks (mainnet and public testnets), verkle activation
   665  // always occurs after the genesis block, making this function irrelevant in
   666  // those cases.
   667  func (c *ChainConfig) IsVerkleGenesis() bool {
   668  	return c.EnableVerkleAtGenesis
   669  }
   670  
   671  // IsEIP4762 returns whether eip 4762 has been activated at given block.
   672  func (c *ChainConfig) IsEIP4762(num *big.Int, time uint64) bool {
   673  	return c.IsVerkle(num, time)
   674  }
   675  
   676  // CheckCompatible checks whether scheduled fork transitions have been imported
   677  // with a mismatching chain configuration.
   678  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError {
   679  	var (
   680  		bhead = new(big.Int).SetUint64(height)
   681  		btime = time
   682  	)
   683  	// Iterate checkCompatible to find the lowest conflict.
   684  	var lasterr *ConfigCompatError
   685  	for {
   686  		err := c.checkCompatible(newcfg, bhead, btime)
   687  		if err == nil || (lasterr != nil && err.RewindToBlock == lasterr.RewindToBlock && err.RewindToTime == lasterr.RewindToTime) {
   688  			break
   689  		}
   690  		lasterr = err
   691  
   692  		if err.RewindToTime > 0 {
   693  			btime = err.RewindToTime
   694  		} else {
   695  			bhead.SetUint64(err.RewindToBlock)
   696  		}
   697  	}
   698  	return lasterr
   699  }
   700  
   701  // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
   702  // to guarantee that forks can be implemented in a different order than on official networks
   703  func (c *ChainConfig) CheckConfigForkOrder() error {
   704  	type fork struct {
   705  		name      string
   706  		block     *big.Int // forks up to - and including the merge - were defined with block numbers
   707  		timestamp *uint64  // forks after the merge are scheduled using timestamps
   708  		optional  bool     // if true, the fork may be nil and next fork is still allowed
   709  	}
   710  	var lastFork fork
   711  	for _, cur := range []fork{
   712  		{name: "homesteadBlock", block: c.HomesteadBlock},
   713  		{name: "daoForkBlock", block: c.DAOForkBlock, optional: true},
   714  		{name: "eip150Block", block: c.EIP150Block},
   715  		{name: "eip155Block", block: c.EIP155Block},
   716  		{name: "eip158Block", block: c.EIP158Block},
   717  		{name: "byzantiumBlock", block: c.ByzantiumBlock},
   718  		{name: "constantinopleBlock", block: c.ConstantinopleBlock},
   719  		{name: "petersburgBlock", block: c.PetersburgBlock},
   720  		{name: "istanbulBlock", block: c.IstanbulBlock},
   721  		{name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true},
   722  		{name: "berlinBlock", block: c.BerlinBlock},
   723  		{name: "londonBlock", block: c.LondonBlock},
   724  		{name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true},
   725  		{name: "grayGlacierBlock", block: c.GrayGlacierBlock, optional: true},
   726  		{name: "mergeNetsplitBlock", block: c.MergeNetsplitBlock, optional: true},
   727  		{name: "shanghaiTime", timestamp: c.ShanghaiTime},
   728  		{name: "cancunTime", timestamp: c.CancunTime, optional: true},
   729  		{name: "pragueTime", timestamp: c.PragueTime, optional: true},
   730  		{name: "osakaTime", timestamp: c.OsakaTime, optional: true},
   731  		{name: "verkleTime", timestamp: c.VerkleTime, optional: true},
   732  	} {
   733  		if lastFork.name != "" {
   734  			switch {
   735  			// Non-optional forks must all be present in the chain config up to the last defined fork
   736  			case lastFork.block == nil && lastFork.timestamp == nil && (cur.block != nil || cur.timestamp != nil):
   737  				if cur.block != nil {
   738  					return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at block %v",
   739  						lastFork.name, cur.name, cur.block)
   740  				} else {
   741  					return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at timestamp %v",
   742  						lastFork.name, cur.name, *cur.timestamp)
   743  				}
   744  
   745  			// Fork (whether defined by block or timestamp) must follow the fork definition sequence
   746  			case (lastFork.block != nil && cur.block != nil) || (lastFork.timestamp != nil && cur.timestamp != nil):
   747  				if lastFork.block != nil && lastFork.block.Cmp(cur.block) > 0 {
   748  					return fmt.Errorf("unsupported fork ordering: %v enabled at block %v, but %v enabled at block %v",
   749  						lastFork.name, lastFork.block, cur.name, cur.block)
   750  				} else if lastFork.timestamp != nil && *lastFork.timestamp > *cur.timestamp {
   751  					return fmt.Errorf("unsupported fork ordering: %v enabled at timestamp %v, but %v enabled at timestamp %v",
   752  						lastFork.name, *lastFork.timestamp, cur.name, *cur.timestamp)
   753  				}
   754  
   755  				// Timestamp based forks can follow block based ones, but not the other way around
   756  				if lastFork.timestamp != nil && cur.block != nil {
   757  					return fmt.Errorf("unsupported fork ordering: %v used timestamp ordering, but %v reverted to block ordering",
   758  						lastFork.name, cur.name)
   759  				}
   760  			}
   761  		}
   762  		// If it was optional and not set, then ignore it
   763  		if !cur.optional || (cur.block != nil || cur.timestamp != nil) {
   764  			lastFork = cur
   765  		}
   766  	}
   767  
   768  	// Check that all forks with blobs explicitly define the blob schedule configuration.
   769  	bsc := c.BlobScheduleConfig
   770  	if bsc == nil {
   771  		bsc = new(BlobScheduleConfig)
   772  	}
   773  	for _, cur := range []struct {
   774  		name      string
   775  		timestamp *uint64
   776  		config    *BlobConfig
   777  	}{
   778  		{name: "cancun", timestamp: c.CancunTime, config: bsc.Cancun},
   779  		{name: "prague", timestamp: c.PragueTime, config: bsc.Prague},
   780  		{name: "osaka", timestamp: c.OsakaTime, config: bsc.Osaka},
   781  	} {
   782  		if cur.config != nil {
   783  			if err := cur.config.validate(); err != nil {
   784  				return fmt.Errorf("invalid chain configuration in blobSchedule for fork %q: %v", cur.name, err)
   785  			}
   786  		}
   787  		if cur.timestamp != nil {
   788  			// If the fork is configured, a blob schedule must be defined for it.
   789  			if cur.config == nil {
   790  				return fmt.Errorf("invalid chain configuration: missing entry for fork %q in blobSchedule", cur.name)
   791  			}
   792  		}
   793  	}
   794  	return nil
   795  }
   796  
   797  func (bc *BlobConfig) validate() error {
   798  	if bc.Max < 0 {
   799  		return errors.New("max < 0")
   800  	}
   801  	if bc.Target < 0 {
   802  		return errors.New("target < 0")
   803  	}
   804  	if bc.UpdateFraction == 0 {
   805  		return errors.New("update fraction must be defined and non-zero")
   806  	}
   807  	return nil
   808  }
   809  
   810  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64) *ConfigCompatError {
   811  	if isForkBlockIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, headNumber) {
   812  		return newBlockCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   813  	}
   814  	if isForkBlockIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, headNumber) {
   815  		return newBlockCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   816  	}
   817  	if c.IsDAOFork(headNumber) && c.DAOForkSupport != newcfg.DAOForkSupport {
   818  		return newBlockCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   819  	}
   820  	if isForkBlockIncompatible(c.EIP150Block, newcfg.EIP150Block, headNumber) {
   821  		return newBlockCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   822  	}
   823  	if isForkBlockIncompatible(c.EIP155Block, newcfg.EIP155Block, headNumber) {
   824  		return newBlockCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   825  	}
   826  	if isForkBlockIncompatible(c.EIP158Block, newcfg.EIP158Block, headNumber) {
   827  		return newBlockCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   828  	}
   829  	if c.IsEIP158(headNumber) && !configBlockEqual(c.ChainID, newcfg.ChainID) {
   830  		return newBlockCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   831  	}
   832  	if isForkBlockIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, headNumber) {
   833  		return newBlockCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   834  	}
   835  	if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, headNumber) {
   836  		return newBlockCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   837  	}
   838  	if isForkBlockIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, headNumber) {
   839  		// the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople
   840  		// mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set
   841  		if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, headNumber) {
   842  			return newBlockCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   843  		}
   844  	}
   845  	if isForkBlockIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, headNumber) {
   846  		return newBlockCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
   847  	}
   848  	if isForkBlockIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, headNumber) {
   849  		return newBlockCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
   850  	}
   851  	if isForkBlockIncompatible(c.BerlinBlock, newcfg.BerlinBlock, headNumber) {
   852  		return newBlockCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock)
   853  	}
   854  	if isForkBlockIncompatible(c.LondonBlock, newcfg.LondonBlock, headNumber) {
   855  		return newBlockCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock)
   856  	}
   857  	if isForkBlockIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, headNumber) {
   858  		return newBlockCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock)
   859  	}
   860  	if isForkBlockIncompatible(c.GrayGlacierBlock, newcfg.GrayGlacierBlock, headNumber) {
   861  		return newBlockCompatError("Gray Glacier fork block", c.GrayGlacierBlock, newcfg.GrayGlacierBlock)
   862  	}
   863  	if isForkBlockIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, headNumber) {
   864  		return newBlockCompatError("Merge netsplit fork block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock)
   865  	}
   866  	if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) {
   867  		return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime)
   868  	}
   869  	if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) {
   870  		return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime)
   871  	}
   872  	if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp) {
   873  		return newTimestampCompatError("Prague fork timestamp", c.PragueTime, newcfg.PragueTime)
   874  	}
   875  	if isForkTimestampIncompatible(c.OsakaTime, newcfg.OsakaTime, headTimestamp) {
   876  		return newTimestampCompatError("Osaka fork timestamp", c.OsakaTime, newcfg.OsakaTime)
   877  	}
   878  	if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) {
   879  		return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime)
   880  	}
   881  	return nil
   882  }
   883  
   884  // BaseFeeChangeDenominator bounds the amount the base fee can change between blocks.
   885  func (c *ChainConfig) BaseFeeChangeDenominator() uint64 {
   886  	return DefaultBaseFeeChangeDenominator
   887  }
   888  
   889  // ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have.
   890  func (c *ChainConfig) ElasticityMultiplier() uint64 {
   891  	return DefaultElasticityMultiplier
   892  }
   893  
   894  // LatestFork returns the latest time-based fork that would be active for the given time.
   895  func (c *ChainConfig) LatestFork(time uint64) forks.Fork {
   896  	// Assume last non-time-based fork has passed.
   897  	london := c.LondonBlock
   898  
   899  	switch {
   900  	case c.IsOsaka(london, time):
   901  		return forks.Osaka
   902  	case c.IsPrague(london, time):
   903  		return forks.Prague
   904  	case c.IsCancun(london, time):
   905  		return forks.Cancun
   906  	case c.IsShanghai(london, time):
   907  		return forks.Shanghai
   908  	default:
   909  		return forks.Paris
   910  	}
   911  }
   912  
   913  // Timestamp returns the timestamp associated with the fork or returns nil if
   914  // the fork isn't defined or isn't a time-based fork.
   915  func (c *ChainConfig) Timestamp(fork forks.Fork) *uint64 {
   916  	switch {
   917  	case fork == forks.Osaka:
   918  		return c.OsakaTime
   919  	case fork == forks.Prague:
   920  		return c.PragueTime
   921  	case fork == forks.Cancun:
   922  		return c.CancunTime
   923  	case fork == forks.Shanghai:
   924  		return c.ShanghaiTime
   925  	default:
   926  		return nil
   927  	}
   928  }
   929  
   930  // isForkBlockIncompatible returns true if a fork scheduled at block s1 cannot be
   931  // rescheduled to block s2 because head is already past the fork.
   932  func isForkBlockIncompatible(s1, s2, head *big.Int) bool {
   933  	return (isBlockForked(s1, head) || isBlockForked(s2, head)) && !configBlockEqual(s1, s2)
   934  }
   935  
   936  // isBlockForked returns whether a fork scheduled at block s is active at the
   937  // given head block. Whilst this method is the same as isTimestampForked, they
   938  // are explicitly separate for clearer reading.
   939  func isBlockForked(s, head *big.Int) bool {
   940  	if s == nil || head == nil {
   941  		return false
   942  	}
   943  	return s.Cmp(head) <= 0
   944  }
   945  
   946  func configBlockEqual(x, y *big.Int) bool {
   947  	if x == nil {
   948  		return y == nil
   949  	}
   950  	if y == nil {
   951  		return x == nil
   952  	}
   953  	return x.Cmp(y) == 0
   954  }
   955  
   956  // isForkTimestampIncompatible returns true if a fork scheduled at timestamp s1
   957  // cannot be rescheduled to timestamp s2 because head is already past the fork.
   958  func isForkTimestampIncompatible(s1, s2 *uint64, head uint64) bool {
   959  	return (isTimestampForked(s1, head) || isTimestampForked(s2, head)) && !configTimestampEqual(s1, s2)
   960  }
   961  
   962  // isTimestampForked returns whether a fork scheduled at timestamp s is active
   963  // at the given head timestamp. Whilst this method is the same as isBlockForked,
   964  // they are explicitly separate for clearer reading.
   965  func isTimestampForked(s *uint64, head uint64) bool {
   966  	if s == nil {
   967  		return false
   968  	}
   969  	return *s <= head
   970  }
   971  
   972  func configTimestampEqual(x, y *uint64) bool {
   973  	if x == nil {
   974  		return y == nil
   975  	}
   976  	if y == nil {
   977  		return x == nil
   978  	}
   979  	return *x == *y
   980  }
   981  
   982  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   983  // ChainConfig that would alter the past.
   984  type ConfigCompatError struct {
   985  	What string
   986  
   987  	// block numbers of the stored and new configurations if block based forking
   988  	StoredBlock, NewBlock *big.Int
   989  
   990  	// timestamps of the stored and new configurations if time based forking
   991  	StoredTime, NewTime *uint64
   992  
   993  	// the block number to which the local chain must be rewound to correct the error
   994  	RewindToBlock uint64
   995  
   996  	// the timestamp to which the local chain must be rewound to correct the error
   997  	RewindToTime uint64
   998  }
   999  
  1000  func newBlockCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
  1001  	var rew *big.Int
  1002  	switch {
  1003  	case storedblock == nil:
  1004  		rew = newblock
  1005  	case newblock == nil || storedblock.Cmp(newblock) < 0:
  1006  		rew = storedblock
  1007  	default:
  1008  		rew = newblock
  1009  	}
  1010  	err := &ConfigCompatError{
  1011  		What:          what,
  1012  		StoredBlock:   storedblock,
  1013  		NewBlock:      newblock,
  1014  		RewindToBlock: 0,
  1015  	}
  1016  	if rew != nil && rew.Sign() > 0 {
  1017  		err.RewindToBlock = rew.Uint64() - 1
  1018  	}
  1019  	return err
  1020  }
  1021  
  1022  func newTimestampCompatError(what string, storedtime, newtime *uint64) *ConfigCompatError {
  1023  	var rew *uint64
  1024  	switch {
  1025  	case storedtime == nil:
  1026  		rew = newtime
  1027  	case newtime == nil || *storedtime < *newtime:
  1028  		rew = storedtime
  1029  	default:
  1030  		rew = newtime
  1031  	}
  1032  	err := &ConfigCompatError{
  1033  		What:         what,
  1034  		StoredTime:   storedtime,
  1035  		NewTime:      newtime,
  1036  		RewindToTime: 0,
  1037  	}
  1038  	if rew != nil && *rew != 0 {
  1039  		err.RewindToTime = *rew - 1
  1040  	}
  1041  	return err
  1042  }
  1043  
  1044  func (err *ConfigCompatError) Error() string {
  1045  	if err.StoredBlock != nil {
  1046  		return fmt.Sprintf("mismatching %s in database (have block %d, want block %d, rewindto block %d)", err.What, err.StoredBlock, err.NewBlock, err.RewindToBlock)
  1047  	}
  1048  
  1049  	if err.StoredTime == nil && err.NewTime == nil {
  1050  		return ""
  1051  	} else if err.StoredTime == nil && err.NewTime != nil {
  1052  		return fmt.Sprintf("mismatching %s in database (have timestamp nil, want timestamp %d, rewindto timestamp %d)", err.What, *err.NewTime, err.RewindToTime)
  1053  	} else if err.StoredTime != nil && err.NewTime == nil {
  1054  		return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp nil, rewindto timestamp %d)", err.What, *err.StoredTime, err.RewindToTime)
  1055  	}
  1056  	return fmt.Sprintf("mismatching %s in database (have timestamp %d, want timestamp %d, rewindto timestamp %d)", err.What, *err.StoredTime, *err.NewTime, err.RewindToTime)
  1057  }
  1058  
  1059  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
  1060  // that do not have or require information about the block.
  1061  //
  1062  // Rules is a one time interface meaning that it shouldn't be used in between transition
  1063  // phases.
  1064  type Rules struct {
  1065  	ChainID                                                 *big.Int
  1066  	IsHomestead, IsEIP150, IsEIP155, IsEIP158               bool
  1067  	IsEIP2929, IsEIP4762                                    bool
  1068  	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
  1069  	IsBerlin, IsLondon                                      bool
  1070  	IsMerge, IsShanghai, IsCancun, IsPrague, IsOsaka        bool
  1071  	IsVerkle                                                bool
  1072  }
  1073  
  1074  // Rules ensures c's ChainID is not nil.
  1075  func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules {
  1076  	chainID := c.ChainID
  1077  	if chainID == nil {
  1078  		chainID = new(big.Int)
  1079  	}
  1080  	// disallow setting Merge out of order
  1081  	isMerge = isMerge && c.IsLondon(num)
  1082  	isVerkle := isMerge && c.IsVerkle(num, timestamp)
  1083  	return Rules{
  1084  		ChainID:          new(big.Int).Set(chainID),
  1085  		IsHomestead:      c.IsHomestead(num),
  1086  		IsEIP150:         c.IsEIP150(num),
  1087  		IsEIP155:         c.IsEIP155(num),
  1088  		IsEIP158:         c.IsEIP158(num),
  1089  		IsByzantium:      c.IsByzantium(num),
  1090  		IsConstantinople: c.IsConstantinople(num),
  1091  		IsPetersburg:     c.IsPetersburg(num),
  1092  		IsIstanbul:       c.IsIstanbul(num),
  1093  		IsBerlin:         c.IsBerlin(num),
  1094  		IsEIP2929:        c.IsBerlin(num) && !isVerkle,
  1095  		IsLondon:         c.IsLondon(num),
  1096  		IsMerge:          isMerge,
  1097  		IsShanghai:       isMerge && c.IsShanghai(num, timestamp),
  1098  		IsCancun:         isMerge && c.IsCancun(num, timestamp),
  1099  		IsPrague:         isMerge && c.IsPrague(num, timestamp),
  1100  		IsOsaka:          isMerge && c.IsOsaka(num, timestamp),
  1101  		IsVerkle:         isVerkle,
  1102  		IsEIP4762:        isVerkle,
  1103  	}
  1104  }