github.com/XinFinOrg/xdcchain@v1.1.0/params/config.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package params
    18  
    19  import (
    20  	"fmt"
    21  	"math/big"
    22  
    23  	"github.com/ethereum/go-ethereum/common"
    24  )
    25  
    26  // Genesis hashes to enforce below configs on.
    27  var (
    28  	MainnetGenesisHash = common.HexToHash("8d13370621558f4ed0da587934473c0404729f28b0ff1d50e5fdd840457a2f17") // Mainnet genesis hash to enforce below configs on
    29  	TestnetGenesisHash = common.HexToHash("dffc8ae3b45965404b4fd73ce7f0e13e822ac0fc23ce7e95b42bc5f1e57023a5") // Testnet genesis hash to enforce below configs on
    30  )
    31  
    32  // TrustedCheckpoints associates each known checkpoint with the genesis hash of
    33  // the chain it belongs to.
    34  var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{
    35  	MainnetGenesisHash: MainnetTrustedCheckpoint,
    36  	TestnetGenesisHash: TestnetTrustedCheckpoint,
    37  }
    38  
    39  var (
    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(1150000),
    44  		DAOForkBlock:        big.NewInt(1920000),
    45  		DAOForkSupport:      true,
    46  		EIP150Block:         big.NewInt(2463000),
    47  		EIP150Hash:          common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    48  		EIP155Block:         big.NewInt(2675000),
    49  		EIP158Block:         big.NewInt(2675000),
    50  		ByzantiumBlock:      big.NewInt(4370000),
    51  		ConstantinopleBlock: nil,
    52  		PetersburgBlock:     nil,
    53  		Ethash:              new(EthashConfig),
    54  	}
    55  
    56  	// TODO: calculate trusted checkpoint for our chain
    57  	// MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network.
    58  	MainnetTrustedCheckpoint = &TrustedCheckpoint{
    59  		Name:         "mainnet",
    60  		SectionIndex: 227,
    61  		SectionHead:  common.HexToHash("0xa2e0b25d72c2fc6e35a7f853cdacb193b4b4f95c606accf7f8fa8415283582c7"),
    62  		CHTRoot:      common.HexToHash("0xf69bdd4053b95b61a27b106a0e86103d791edd8574950dc96aa351ab9b9f1aa0"),
    63  		BloomRoot:    common.HexToHash("0xec1b454d4c6322c78ccedf76ac922a8698c3cac4d98748a84af4995b7bd3d744"),
    64  	}
    65  
    66  	// TestnetChainConfig contains the chain parameters to run a node on the Ropsten test network.
    67  	TestnetChainConfig = &ChainConfig{
    68  		ChainID:             big.NewInt(3),
    69  		HomesteadBlock:      big.NewInt(0),
    70  		DAOForkBlock:        nil,
    71  		DAOForkSupport:      true,
    72  		EIP150Block:         big.NewInt(0),
    73  		EIP150Hash:          common.HexToHash("0x62e0fde86e34c263e250fbcd5ca4598ba8ca10a1d166c8526bb127e10b313311"),
    74  		EIP155Block:         big.NewInt(10),
    75  		EIP158Block:         big.NewInt(10),
    76  		ByzantiumBlock:      big.NewInt(1700000),
    77  		ConstantinopleBlock: nil,
    78  		PetersburgBlock:     nil,
    79  		Ethash:              new(EthashConfig),
    80  	}
    81  
    82  	// TODO: calculate trusted checkpoint for our chain
    83  	// TestnetTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
    84  	TestnetTrustedCheckpoint = &TrustedCheckpoint{
    85  		Name:         "testnet",
    86  		SectionIndex: 161,
    87  		SectionHead:  common.HexToHash("0x5378afa734e1feafb34bcca1534c4d96952b754579b96a4afb23d5301ecececc"),
    88  		CHTRoot:      common.HexToHash("0x1cf2b071e7443a62914362486b613ff30f60cea0d9c268ed8c545f876a3ee60c"),
    89  		BloomRoot:    common.HexToHash("0x5ac25c84bd18a9cbe878d4609a80220f57f85037a112644532412ba0d498a31b"),
    90  	}
    91  
    92  	// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
    93  	RinkebyChainConfig = &ChainConfig{
    94  		ChainID:             big.NewInt(4),
    95  		HomesteadBlock:      big.NewInt(1),
    96  		DAOForkBlock:        nil,
    97  		DAOForkSupport:      true,
    98  		EIP150Block:         big.NewInt(2),
    99  		EIP150Hash:          common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
   100  		EIP155Block:         big.NewInt(3),
   101  		EIP158Block:         big.NewInt(3),
   102  		ByzantiumBlock:      big.NewInt(1035301),
   103  		ConstantinopleBlock: nil,
   104  		PetersburgBlock:     nil,
   105  		XDPoS: &XDPoSConfig{
   106  			Period: 15,
   107  			Epoch:  30000,
   108  		},
   109  	}
   110  
   111  	// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
   112  	RinkebyTrustedCheckpoint = &TrustedCheckpoint{
   113  		Name:         "rinkeby",
   114  		SectionIndex: 125,
   115  		SectionHead:  common.HexToHash("0x8a738386f6bb34add15846f8f49c4c519a2f32519096e792b9f43bcb407c831c"),
   116  		CHTRoot:      common.HexToHash("0xa1e5720a9bad4dce794f129e4ac6744398197b652868011486a6f89c8ec84a75"),
   117  		BloomRoot:    common.HexToHash("0xa3048fe8b7e30f77f11bc755a88478363d7d3e71c2bdfe4e8ab9e269cd804ba2"),
   118  	}
   119  
   120  	// GoerliChainConfig contains the chain parameters to run a node on the Görli test network.
   121  	GoerliChainConfig = &ChainConfig{
   122  		ChainID:             big.NewInt(5),
   123  		HomesteadBlock:      big.NewInt(0),
   124  		DAOForkBlock:        nil,
   125  		DAOForkSupport:      true,
   126  		EIP150Block:         big.NewInt(0),
   127  		EIP155Block:         big.NewInt(0),
   128  		EIP158Block:         big.NewInt(0),
   129  		ByzantiumBlock:      big.NewInt(0),
   130  		ConstantinopleBlock: big.NewInt(0),
   131  		PetersburgBlock:     big.NewInt(0),
   132  		Clique: &CliqueConfig{
   133  			Period: 15,
   134  			Epoch:  30000,
   135  		},
   136  	}
   137  
   138  	// GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network.
   139  	GoerliTrustedCheckpoint = &TrustedCheckpoint{
   140  		Name:         "goerli",
   141  		SectionIndex: 9,
   142  		SectionHead:  common.HexToHash("0x8e223d827391eee53b07cb8ee057dbfa11c93e0b45352188c783affd7840a921"),
   143  		CHTRoot:      common.HexToHash("0xe0a817ac69b36c1e437c5b0cff9e764853f5115702b5f66d451b665d6afb7e78"),
   144  		BloomRoot:    common.HexToHash("0x50d672aeb655b723284969c7c1201fb6ca003c23ed144bcb9f2d1b30e2971c1b"),
   145  	}
   146  
   147  	// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
   148  	// and accepted by the Ethereum core developers into the Ethash consensus.
   149  	//
   150  	// This configuration is intentionally not using keyed fields to force anyone
   151  	// adding flags to the config to also have to set these fields.
   152  	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), nil, new(EthashConfig), nil, nil}
   153  
   154  	// AllXDPoSProtocolChanges contains every protocol change (EIPs) introduced
   155  	// and accepted by the Ethereum core developers into the XDPoS consensus.
   156  	//
   157  	// This configuration is intentionally not using keyed fields to force anyone
   158  	// adding flags to the config to also have to set these fields.
   159  	AllXDPoSProtocolChanges  = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, &XDPoSConfig{Period: 0, Epoch: 30000}}
   160  	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), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
   161  
   162  	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), nil, new(EthashConfig), nil, nil}
   163  	TestRules       = TestChainConfig.Rules(new(big.Int))
   164  )
   165  
   166  // TrustedCheckpoint represents a set of post-processed trie roots (CHT and
   167  // BloomTrie) associated with the appropriate section index and head hash. It is
   168  // used to start light syncing from this checkpoint and avoid downloading the
   169  // entire header chain while still being able to securely access old headers/logs.
   170  type TrustedCheckpoint struct {
   171  	Name         string      `json:"-"`
   172  	SectionIndex uint64      `json:"sectionIndex"`
   173  	SectionHead  common.Hash `json:"sectionHead"`
   174  	CHTRoot      common.Hash `json:"chtRoot"`
   175  	BloomRoot    common.Hash `json:"bloomRoot"`
   176  }
   177  
   178  // ChainConfig is the core config which determines the blockchain settings.
   179  //
   180  // ChainConfig is stored in the database on a per block basis. This means
   181  // that any network, identified by its genesis block, can have its own
   182  // set of configuration options.
   183  type ChainConfig struct {
   184  	ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
   185  
   186  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   187  
   188  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   189  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   190  
   191  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   192  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   193  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
   194  
   195  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   196  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   197  
   198  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   199  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   200  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`     // Petersburg switch block (nil = same as Constantinople)
   201  	EWASMBlock          *big.Int `json:"ewasmBlock,omitempty"`          // EWASM switch block (nil = no fork, 0 = already activated)
   202  
   203  	// Various consensus engines
   204  	Ethash *EthashConfig `json:"ethash,omitempty"`
   205  	Clique *CliqueConfig `json:"clique,omitempty"`
   206  	XDPoS  *XDPoSConfig  `json:"XDPoS,omitempty"`
   207  }
   208  
   209  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   210  type EthashConfig struct{}
   211  
   212  // String implements the stringer interface, returning the consensus engine details.
   213  func (c *EthashConfig) String() string {
   214  	return "ethash"
   215  }
   216  
   217  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   218  type CliqueConfig struct {
   219  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   220  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   221  }
   222  
   223  // String implements the stringer interface, returning the consensus engine details.
   224  func (c *CliqueConfig) String() string {
   225  	return "clique"
   226  }
   227  
   228  // XDPoSConfig is the consensus engine configs for delegated-proof-of-stake based sealing.
   229  type XDPoSConfig 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  	Reward              uint64         `json:"reward"`              // Block reward - unit Ether
   233  	RewardCheckpoint    uint64         `json:"rewardCheckpoint"`    // Checkpoint block for calculate rewards.
   234  	Gap                 uint64         `json:"gap"`                 // Gap time preparing for the next epoch
   235  	FoudationWalletAddr common.Address `json:"foudationWalletAddr"` // Foundation Address Wallet
   236  }
   237  
   238  // String implements the stringer interface, returning the consensus engine details.
   239  func (c *XDPoSConfig) String() string {
   240  	return "XDPoS"
   241  }
   242  
   243  // String implements the fmt.Stringer interface.
   244  func (c *ChainConfig) String() string {
   245  	var engine interface{}
   246  	switch {
   247  	case c.Ethash != nil:
   248  		engine = c.Ethash
   249  	case c.XDPoS != nil:
   250  		engine = c.XDPoS
   251  	default:
   252  		engine = "unknown"
   253  	}
   254  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v  ConstantinopleFix: %v Engine: %v}",
   255  		c.ChainID,
   256  		c.HomesteadBlock,
   257  		c.DAOForkBlock,
   258  		c.DAOForkSupport,
   259  		c.EIP150Block,
   260  		c.EIP155Block,
   261  		c.EIP158Block,
   262  		c.ByzantiumBlock,
   263  		c.ConstantinopleBlock,
   264  		c.PetersburgBlock,
   265  		engine,
   266  	)
   267  }
   268  
   269  // IsHomestead returns whether num is either equal to the homestead block or greater.
   270  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   271  	return isForked(c.HomesteadBlock, num)
   272  }
   273  
   274  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   275  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   276  	return isForked(c.DAOForkBlock, num)
   277  }
   278  
   279  // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
   280  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   281  	return isForked(c.EIP150Block, num)
   282  }
   283  
   284  // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
   285  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   286  	return isForked(c.EIP155Block, num)
   287  }
   288  
   289  // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
   290  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   291  	return isForked(c.EIP158Block, num)
   292  }
   293  
   294  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   295  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   296  	return isForked(c.ByzantiumBlock, num)
   297  }
   298  
   299  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   300  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   301  	return isForked(c.ConstantinopleBlock, num)
   302  }
   303  
   304  // IsPetersburg returns whether num is either
   305  // - equal to or greater than the PetersburgBlock fork block,
   306  // - OR is nil, and Constantinople is active
   307  func (c *ChainConfig) IsPetersburg(num *big.Int) bool {
   308  	return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num)
   309  }
   310  
   311  // IsEWASM returns whether num represents a block number after the EWASM fork
   312  func (c *ChainConfig) IsEWASM(num *big.Int) bool {
   313  	return isForked(c.EWASMBlock, num)
   314  }
   315  
   316  func (c *ChainConfig) IsTIP2019(num *big.Int) bool {
   317  	return isForked(common.TIP2019Block, num)
   318  }
   319  
   320  func (c *ChainConfig) IsTIPSigning(num *big.Int) bool {
   321  	return isForked(common.TIPSigning, num)
   322  }
   323  
   324  func (c *ChainConfig) IsTIPRandomize(num *big.Int) bool {
   325  	return isForked(common.TIPRandomize, num)
   326  }
   327  
   328  // IsTIPIncreaseMasternodes using for increase masternodes from 18 to 40
   329  // Time update: 23-07-2019
   330  func (c *ChainConfig) IsTIPIncreaseMasternodes(num *big.Int) bool {
   331  	return isForked(common.TIPIncreaseMasternodes, num)
   332  }
   333  
   334  // GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
   335  //
   336  // The returned GasTable's fields shouldn't, under any circumstances, be changed.
   337  func (c *ChainConfig) GasTable(num *big.Int) GasTable {
   338  	if num == nil {
   339  		return GasTableHomestead
   340  	}
   341  	switch {
   342  	case c.IsConstantinople(num):
   343  		return GasTableConstantinople
   344  	case c.IsEIP158(num):
   345  		return GasTableEIP158
   346  	case c.IsEIP150(num):
   347  		return GasTableEIP150
   348  	default:
   349  		return GasTableHomestead
   350  	}
   351  }
   352  
   353  // CheckCompatible checks whether scheduled fork transitions have been imported
   354  // with a mismatching chain configuration.
   355  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   356  	bhead := new(big.Int).SetUint64(height)
   357  
   358  	// Iterate checkCompatible to find the lowest conflict.
   359  	var lasterr *ConfigCompatError
   360  	for {
   361  		err := c.checkCompatible(newcfg, bhead)
   362  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   363  			break
   364  		}
   365  		lasterr = err
   366  		bhead.SetUint64(err.RewindTo)
   367  	}
   368  	return lasterr
   369  }
   370  
   371  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   372  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   373  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   374  	}
   375  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   376  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   377  	}
   378  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   379  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   380  	}
   381  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   382  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   383  	}
   384  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   385  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   386  	}
   387  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   388  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   389  	}
   390  	if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   391  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   392  	}
   393  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   394  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   395  	}
   396  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   397  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   398  	}
   399  	if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) {
   400  		return newCompatError("ConstantinopleFix fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   401  	}
   402  	if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
   403  		return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock)
   404  	}
   405  	return nil
   406  }
   407  
   408  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   409  // block s2 because head is already past the fork.
   410  func isForkIncompatible(s1, s2, head *big.Int) bool {
   411  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   412  }
   413  
   414  // isForked returns whether a fork scheduled at block s is active at the given head block.
   415  func isForked(s, head *big.Int) bool {
   416  	if s == nil || head == nil {
   417  		return false
   418  	}
   419  	return s.Cmp(head) <= 0
   420  }
   421  
   422  func configNumEqual(x, y *big.Int) bool {
   423  	if x == nil {
   424  		return y == nil
   425  	}
   426  	if y == nil {
   427  		return x == nil
   428  	}
   429  	return x.Cmp(y) == 0
   430  }
   431  
   432  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   433  // ChainConfig that would alter the past.
   434  type ConfigCompatError struct {
   435  	What string
   436  	// block numbers of the stored and new configurations
   437  	StoredConfig, NewConfig *big.Int
   438  	// the block number to which the local chain must be rewound to correct the error
   439  	RewindTo uint64
   440  }
   441  
   442  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   443  	var rew *big.Int
   444  	switch {
   445  	case storedblock == nil:
   446  		rew = newblock
   447  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   448  		rew = storedblock
   449  	default:
   450  		rew = newblock
   451  	}
   452  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   453  	if rew != nil && rew.Sign() > 0 {
   454  		err.RewindTo = rew.Uint64() - 1
   455  	}
   456  	return err
   457  }
   458  
   459  func (err *ConfigCompatError) Error() string {
   460  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   461  }
   462  
   463  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
   464  // that do not have or require information about the block.
   465  //
   466  // Rules is a one time interface meaning that it shouldn't be used in between transition
   467  // phases.
   468  type Rules struct {
   469  	ChainID                                     *big.Int
   470  	IsHomestead, IsEIP150, IsEIP155, IsEIP158   bool
   471  	IsByzantium, IsConstantinople, IsPetersburg bool
   472  }
   473  
   474  // Rules ensures c's ChainID is not nil.
   475  func (c *ChainConfig) Rules(num *big.Int) Rules {
   476  	chainID := c.ChainID
   477  	if chainID == nil {
   478  		chainID = new(big.Int)
   479  	}
   480  	return Rules{
   481  		ChainID:          new(big.Int).Set(chainID),
   482  		IsHomestead:      c.IsHomestead(num),
   483  		IsEIP150:         c.IsEIP150(num),
   484  		IsEIP155:         c.IsEIP155(num),
   485  		IsEIP158:         c.IsEIP158(num),
   486  		IsByzantium:      c.IsByzantium(num),
   487  		IsConstantinople: c.IsConstantinople(num),
   488  		IsPetersburg:     c.IsPetersburg(num),
   489  	}
   490  }