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