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