github.com/DxChainNetwork/dxc@v0.8.1-0.20220824085222-1162e304b6e7/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  	"encoding/binary"
    21  	"fmt"
    22  	"math/big"
    23  
    24  	"github.com/DxChainNetwork/dxc/common"
    25  	"golang.org/x/crypto/sha3"
    26  )
    27  
    28  // Genesis hashes to enforce below configs on. TODO: update hash
    29  var (
    30  	MainnetGenesisHash = common.HexToHash("0x498b4f36dbe76df2b4b753c0c1ca07fd7ff222dafccedcbbaa3daa0ea3a05957")
    31  	TestnetGenesisHash = common.HexToHash("0x6fb87d6747e81ff634562eba76184b0e4969552e4d99645601c231d9e2ea653c")
    32  )
    33  
    34  // TrustedCheckpoints associates each known checkpoint with the genesis hash of
    35  // the chain it belongs to.
    36  var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{}
    37  
    38  // CheckpointOracles associates each known checkpoint oracles with the genesis hash of
    39  // the chain it belongs to.
    40  var CheckpointOracles = map[common.Hash]*CheckpointOracleConfig{}
    41  
    42  var (
    43  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    44  	MainnetChainConfig = &ChainConfig{
    45  		ChainID:             big.NewInt(36),
    46  		HomesteadBlock:      big.NewInt(0),
    47  		DAOForkBlock:        nil,
    48  		DAOForkSupport:      true,
    49  		EIP150Block:         big.NewInt(0),
    50  		EIP155Block:         big.NewInt(0),
    51  		EIP158Block:         big.NewInt(0),
    52  		ByzantiumBlock:      big.NewInt(0),
    53  		ConstantinopleBlock: big.NewInt(0),
    54  		PetersburgBlock:     big.NewInt(0),
    55  		IstanbulBlock:       big.NewInt(0),
    56  		MuirGlacierBlock:    nil,
    57  		RedCoastBlock:       big.NewInt(0),
    58  		BerlinBlock:         big.NewInt(0),
    59  		LondonBlock:         big.NewInt(0),
    60  		SophonBlock:         big.NewInt(0),
    61  
    62  		Dpos: &DposConfig{
    63  			Period: 6,
    64  			Epoch:  14400,
    65  
    66  			EnableDevVerification: true,
    67  		},
    68  	}
    69  
    70  	// TestnetChainConfig contains the chain parameters to run a node on the YOLOv1 test network.
    71  	TestnetChainConfig = &ChainConfig{
    72  		ChainID:             big.NewInt(72),
    73  		HomesteadBlock:      big.NewInt(0),
    74  		DAOForkBlock:        nil,
    75  		DAOForkSupport:      true,
    76  		EIP150Block:         big.NewInt(0),
    77  		EIP155Block:         big.NewInt(0),
    78  		EIP158Block:         big.NewInt(0),
    79  		ByzantiumBlock:      big.NewInt(0),
    80  		ConstantinopleBlock: big.NewInt(0),
    81  		PetersburgBlock:     big.NewInt(0),
    82  		IstanbulBlock:       big.NewInt(0),
    83  		MuirGlacierBlock:    nil,
    84  		RedCoastBlock:       big.NewInt(0),
    85  		BerlinBlock:         big.NewInt(0),
    86  		LondonBlock:         big.NewInt(0),
    87  		SophonBlock:         big.NewInt(0),
    88  		Dpos: &DposConfig{
    89  			Period: 3,
    90  			Epoch:  28800,
    91  
    92  			EnableDevVerification: true,
    93  		},
    94  	}
    95  
    96  	// RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network.
    97  	RopstenChainConfig = &ChainConfig{
    98  		ChainID:             big.NewInt(3),
    99  		HomesteadBlock:      big.NewInt(0),
   100  		DAOForkBlock:        nil,
   101  		DAOForkSupport:      true,
   102  		EIP150Block:         big.NewInt(0),
   103  		EIP150Hash:          common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
   104  		EIP155Block:         big.NewInt(10),
   105  		EIP158Block:         big.NewInt(10),
   106  		ByzantiumBlock:      big.NewInt(1_700_000),
   107  		ConstantinopleBlock: big.NewInt(4_230_000),
   108  		PetersburgBlock:     big.NewInt(4_939_394),
   109  		IstanbulBlock:       big.NewInt(6_485_846),
   110  		MuirGlacierBlock:    big.NewInt(7_117_117),
   111  		BerlinBlock:         big.NewInt(9_812_189),
   112  		Ethash:              new(EthashConfig),
   113  	}
   114  
   115  	// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
   116  	// and accepted by the Ethereum core developers into the Ethash consensus.
   117  	//
   118  	// This configuration is intentionally not using keyed fields to force anyone
   119  	// adding flags to the config to also have to set these fields.
   120  	AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil, nil}
   121  
   122  	// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
   123  	// and accepted by the Ethereum core developers into the Clique consensus.
   124  	//
   125  	// This configuration is intentionally not using keyed fields to force anyone
   126  	// adding flags to the config to also have to set these fields.
   127  	AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
   128  
   129  	TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, new(EthashConfig), nil, nil}
   130  	TestRules       = TestChainConfig.Rules(new(big.Int))
   131  )
   132  
   133  // TrustedCheckpoint represents a set of post-processed trie roots (CHT and
   134  // BloomTrie) associated with the appropriate section index and head hash. It is
   135  // used to start light syncing from this checkpoint and avoid downloading the
   136  // entire header chain while still being able to securely access old headers/logs.
   137  type TrustedCheckpoint struct {
   138  	SectionIndex uint64      `json:"sectionIndex"`
   139  	SectionHead  common.Hash `json:"sectionHead"`
   140  	CHTRoot      common.Hash `json:"chtRoot"`
   141  	BloomRoot    common.Hash `json:"bloomRoot"`
   142  }
   143  
   144  // HashEqual returns an indicator comparing the hash with given one.
   145  func (c *TrustedCheckpoint) HashEqual(hash common.Hash) bool {
   146  	if c.Empty() {
   147  		return hash == common.Hash{}
   148  	}
   149  	return c.Hash() == hash
   150  }
   151  
   152  // Hash returns the hash of checkpoint's four key fields(index, sectionHead, chtRoot and bloomTrieRoot).
   153  func (c *TrustedCheckpoint) Hash() common.Hash {
   154  	var sectionIndex [8]byte
   155  	binary.BigEndian.PutUint64(sectionIndex[:], c.SectionIndex)
   156  
   157  	w := sha3.NewLegacyKeccak256()
   158  	w.Write(sectionIndex[:])
   159  	w.Write(c.SectionHead[:])
   160  	w.Write(c.CHTRoot[:])
   161  	w.Write(c.BloomRoot[:])
   162  
   163  	var h common.Hash
   164  	w.Sum(h[:0])
   165  	return h
   166  }
   167  
   168  // Empty returns an indicator whether the checkpoint is regarded as empty.
   169  func (c *TrustedCheckpoint) Empty() bool {
   170  	return c.SectionHead == (common.Hash{}) || c.CHTRoot == (common.Hash{}) || c.BloomRoot == (common.Hash{})
   171  }
   172  
   173  // CheckpointOracleConfig represents a set of checkpoint contract(which acts as an oracle)
   174  // config which used for light client checkpoint syncing.
   175  type CheckpointOracleConfig struct {
   176  	Address   common.Address   `json:"address"`
   177  	Signers   []common.Address `json:"signers"`
   178  	Threshold uint64           `json:"threshold"`
   179  }
   180  
   181  // ChainConfig is the core config which determines the blockchain settings.
   182  //
   183  // ChainConfig is stored in the database on a per-block basis. This means
   184  // that any network, identified by its genesis block, can have its own
   185  // set of configuration options.
   186  type ChainConfig struct {
   187  	ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
   188  
   189  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   190  
   191  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   192  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   193  
   194  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   195  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   196  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
   197  
   198  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   199  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   200  
   201  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   202  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   203  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`     // Petersburg switch block (nil = same as Constantinople)
   204  	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)
   205  	MuirGlacierBlock    *big.Int `json:"muirGlacierBlock,omitempty"`    // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
   206  	BerlinBlock         *big.Int `json:"berlinBlock,omitempty"`         // Berlin switch block (nil = no fork, 0 = already on berlin)
   207  	LondonBlock         *big.Int `json:"londonBlock,omitempty"`         // London switch block (nil = no fork, 0 = already on london)
   208  
   209  	CatalystBlock *big.Int `json:"catalystBlock,omitempty"` // Catalyst switch block (nil = no fork, 0 = already on catalyst)
   210  
   211  	RedCoastBlock *big.Int `json:"redCoastBlock,omitempty"` // RedCoast switch block (nil = no fork, 0 = already activated)
   212  	SophonBlock   *big.Int `json:"sophonBlock,omitempty"`
   213  
   214  	// Various consensus engines
   215  	Ethash *EthashConfig `json:"ethash,omitempty"`
   216  	Clique *CliqueConfig `json:"clique,omitempty"`
   217  	Dpos   *DposConfig   `json:"dpos,omitempty"`
   218  }
   219  
   220  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   221  type EthashConfig struct{}
   222  
   223  // String implements the stringer interface, returning the consensus engine details.
   224  func (c *EthashConfig) String() string {
   225  	return "ethash"
   226  }
   227  
   228  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   229  type CliqueConfig struct {
   230  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   231  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   232  }
   233  
   234  // String implements the stringer interface, returning the consensus engine details.
   235  func (c *CliqueConfig) String() string {
   236  	return "clique"
   237  }
   238  
   239  // DposConfig is the consensus engine configs for proof-of-stake-authority based sealing.
   240  type DposConfig struct {
   241  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   242  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   243  
   244  	EnableDevVerification bool `json:"enableDevVerification"` // Enable developer address verification
   245  }
   246  
   247  // String implements the stringer interface, returning the consensus engine details.
   248  func (d *DposConfig) String() string {
   249  	return "dpos"
   250  }
   251  
   252  // String implements the fmt.Stringer interface.
   253  func (c *ChainConfig) String() string {
   254  	var engine interface{}
   255  	switch {
   256  	case c.Ethash != nil:
   257  		engine = c.Ethash
   258  	case c.Clique != nil:
   259  		engine = c.Clique
   260  	case c.Dpos != nil:
   261  		engine = c.Dpos
   262  	default:
   263  		engine = "unknown"
   264  	}
   265  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, RedCoastBlock: %v, Berlin: %v, London: %v, Engine: %v}",
   266  		c.ChainID,
   267  		c.HomesteadBlock,
   268  		c.DAOForkBlock,
   269  		c.DAOForkSupport,
   270  		c.EIP150Block,
   271  		c.EIP155Block,
   272  		c.EIP158Block,
   273  		c.ByzantiumBlock,
   274  		c.ConstantinopleBlock,
   275  		c.PetersburgBlock,
   276  		c.IstanbulBlock,
   277  		c.MuirGlacierBlock,
   278  		c.RedCoastBlock,
   279  		c.BerlinBlock,
   280  		c.LondonBlock,
   281  		engine,
   282  	)
   283  }
   284  
   285  // IsHomestead returns whether num is either equal to the homestead block or greater.
   286  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   287  	return isForked(c.HomesteadBlock, num)
   288  }
   289  
   290  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   291  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   292  	return isForked(c.DAOForkBlock, num)
   293  }
   294  
   295  // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
   296  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   297  	return isForked(c.EIP150Block, num)
   298  }
   299  
   300  // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
   301  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   302  	return isForked(c.EIP155Block, num)
   303  }
   304  
   305  // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
   306  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   307  	return isForked(c.EIP158Block, num)
   308  }
   309  
   310  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   311  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   312  	return isForked(c.ByzantiumBlock, num)
   313  }
   314  
   315  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   316  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   317  	return isForked(c.ConstantinopleBlock, num)
   318  }
   319  
   320  // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
   321  func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
   322  	return isForked(c.MuirGlacierBlock, num)
   323  }
   324  
   325  // IsPetersburg returns whether num is either
   326  // - equal to or greater than the PetersburgBlock fork block,
   327  // - OR is nil, and Constantinople is active
   328  func (c *ChainConfig) IsPetersburg(num *big.Int) bool {
   329  	return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num)
   330  }
   331  
   332  // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater.
   333  func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
   334  	return isForked(c.IstanbulBlock, num)
   335  }
   336  
   337  // IsBerlin returns whether num is either equal to the Berlin fork block or greater.
   338  func (c *ChainConfig) IsBerlin(num *big.Int) bool {
   339  	return isForked(c.BerlinBlock, num)
   340  }
   341  
   342  // IsLondon returns whether num is either equal to the London fork block or greater.
   343  func (c *ChainConfig) IsLondon(num *big.Int) bool {
   344  	return isForked(c.LondonBlock, num)
   345  }
   346  
   347  // IsCatalyst returns whether num is either equal to the Merge fork block or greater.
   348  func (c *ChainConfig) IsCatalyst(num *big.Int) bool {
   349  	return isForked(c.CatalystBlock, num)
   350  }
   351  
   352  // IsRedCoast returns whether num represents a block number after the RedCoast fork
   353  func (c *ChainConfig) IsRedCoast(num *big.Int) bool {
   354  	return isForked(c.RedCoastBlock, num)
   355  }
   356  
   357  // IsSophon returns whether num represents a block number after the SophonBlock fork
   358  func (c *ChainConfig) IsSophon(num *big.Int) bool {
   359  	return isForked(c.SophonBlock, num)
   360  }
   361  
   362  // CheckCompatible checks whether scheduled fork transitions have been imported
   363  // with a mismatching chain configuration.
   364  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   365  	bhead := new(big.Int).SetUint64(height)
   366  
   367  	// Iterate checkCompatible to find the lowest conflict.
   368  	var lasterr *ConfigCompatError
   369  	for {
   370  		err := c.checkCompatible(newcfg, bhead)
   371  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   372  			break
   373  		}
   374  		lasterr = err
   375  		bhead.SetUint64(err.RewindTo)
   376  	}
   377  	return lasterr
   378  }
   379  
   380  // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
   381  // to guarantee that forks can be implemented in a different order than on official networks
   382  func (c *ChainConfig) CheckConfigForkOrder() error {
   383  	type fork struct {
   384  		name     string
   385  		block    *big.Int
   386  		optional bool // if true, the fork may be nil and next fork is still allowed
   387  	}
   388  	var lastFork fork
   389  	for _, cur := range []fork{
   390  		{name: "homesteadBlock", block: c.HomesteadBlock},
   391  		{name: "daoForkBlock", block: c.DAOForkBlock, optional: true},
   392  		{name: "eip150Block", block: c.EIP150Block},
   393  		{name: "eip155Block", block: c.EIP155Block},
   394  		{name: "eip158Block", block: c.EIP158Block},
   395  		{name: "byzantiumBlock", block: c.ByzantiumBlock},
   396  		{name: "constantinopleBlock", block: c.ConstantinopleBlock},
   397  		{name: "petersburgBlock", block: c.PetersburgBlock},
   398  		{name: "istanbulBlock", block: c.IstanbulBlock},
   399  		{name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true},
   400  		{name: "redCoastBlock", block: c.RedCoastBlock, optional: true},
   401  		{name: "berlinBlock", block: c.BerlinBlock},
   402  		{name: "londonBlock", block: c.LondonBlock},
   403  		{name: "sophonBlock", block: c.SophonBlock},
   404  	} {
   405  		if lastFork.name != "" {
   406  			// Next one must be higher number
   407  			if lastFork.block == nil && cur.block != nil {
   408  				return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
   409  					lastFork.name, cur.name, cur.block)
   410  			}
   411  			if lastFork.block != nil && cur.block != nil {
   412  				if lastFork.block.Cmp(cur.block) > 0 {
   413  					return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
   414  						lastFork.name, lastFork.block, cur.name, cur.block)
   415  				}
   416  			}
   417  		}
   418  		// If it was optional and not set, then ignore it
   419  		if !cur.optional || cur.block != nil {
   420  			lastFork = cur
   421  		}
   422  	}
   423  	return nil
   424  }
   425  
   426  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   427  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   428  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   429  	}
   430  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   431  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   432  	}
   433  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   434  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   435  	}
   436  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   437  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   438  	}
   439  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   440  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   441  	}
   442  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   443  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   444  	}
   445  	if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   446  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   447  	}
   448  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   449  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   450  	}
   451  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   452  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   453  	}
   454  	if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) {
   455  		// the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople
   456  		// mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set
   457  		if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, head) {
   458  			return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   459  		}
   460  	}
   461  	if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) {
   462  		return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
   463  	}
   464  	if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) {
   465  		return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
   466  	}
   467  	if isForkIncompatible(c.BerlinBlock, newcfg.BerlinBlock, head) {
   468  		return newCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock)
   469  	}
   470  	if isForkIncompatible(c.LondonBlock, newcfg.LondonBlock, head) {
   471  		return newCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock)
   472  	}
   473  	if isForkIncompatible(c.RedCoastBlock, newcfg.RedCoastBlock, head) {
   474  		return newCompatError("RedCoast fork block", c.RedCoastBlock, newcfg.RedCoastBlock)
   475  	}
   476  	return nil
   477  }
   478  
   479  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   480  // block s2 because head is already past the fork.
   481  func isForkIncompatible(s1, s2, head *big.Int) bool {
   482  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   483  }
   484  
   485  // isForked returns whether a fork scheduled at block s is active at the given head block.
   486  func isForked(s, head *big.Int) bool {
   487  	if s == nil || head == nil {
   488  		return false
   489  	}
   490  	return s.Cmp(head) <= 0
   491  }
   492  
   493  func configNumEqual(x, y *big.Int) bool {
   494  	if x == nil {
   495  		return y == nil
   496  	}
   497  	if y == nil {
   498  		return x == nil
   499  	}
   500  	return x.Cmp(y) == 0
   501  }
   502  
   503  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   504  // ChainConfig that would alter the past.
   505  type ConfigCompatError struct {
   506  	What string
   507  	// block numbers of the stored and new configurations
   508  	StoredConfig, NewConfig *big.Int
   509  	// the block number to which the local chain must be rewound to correct the error
   510  	RewindTo uint64
   511  }
   512  
   513  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   514  	var rew *big.Int
   515  	switch {
   516  	case storedblock == nil:
   517  		rew = newblock
   518  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   519  		rew = storedblock
   520  	default:
   521  		rew = newblock
   522  	}
   523  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   524  	if rew != nil && rew.Sign() > 0 {
   525  		err.RewindTo = rew.Uint64() - 1
   526  	}
   527  	return err
   528  }
   529  
   530  func (err *ConfigCompatError) Error() string {
   531  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   532  }
   533  
   534  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
   535  // that do not have or require information about the block.
   536  //
   537  // Rules is a one time interface meaning that it shouldn't be used in between transition
   538  // phases.
   539  type Rules struct {
   540  	ChainID                                                 *big.Int
   541  	IsHomestead, IsEIP150, IsEIP155, IsEIP158               bool
   542  	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
   543  	IsBerlin, IsLondon, IsCatalyst                          bool
   544  }
   545  
   546  // Rules ensures c's ChainID is not nil.
   547  func (c *ChainConfig) Rules(num *big.Int) Rules {
   548  	chainID := c.ChainID
   549  	if chainID == nil {
   550  		chainID = new(big.Int)
   551  	}
   552  	return Rules{
   553  		ChainID:          new(big.Int).Set(chainID),
   554  		IsHomestead:      c.IsHomestead(num),
   555  		IsEIP150:         c.IsEIP150(num),
   556  		IsEIP155:         c.IsEIP155(num),
   557  		IsEIP158:         c.IsEIP158(num),
   558  		IsByzantium:      c.IsByzantium(num),
   559  		IsConstantinople: c.IsConstantinople(num),
   560  		IsPetersburg:     c.IsPetersburg(num),
   561  		IsIstanbul:       c.IsIstanbul(num),
   562  		IsBerlin:         c.IsBerlin(num),
   563  		IsLondon:         c.IsLondon(num),
   564  		IsCatalyst:       c.IsCatalyst(num),
   565  	}
   566  }