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