github.com/bamzi/go-ethereum@v1.6.7-0.20170704111104-138f26c93af1/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"
    22  	"math/big"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  )
    26  
    27  var (
    28  	MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") // Mainnet genesis hash to enforce below configs on
    29  	TestnetGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d") // Testnet genesis hash to enforce below configs on
    30  )
    31  
    32  var (
    33  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    34  	MainnetChainConfig = &ChainConfig{
    35  		ChainId:         big.NewInt(1),
    36  		HomesteadBlock:  big.NewInt(1150000),
    37  		DAOForkBlock:    big.NewInt(1920000),
    38  		DAOForkSupport:  true,
    39  		EIP150Block:     big.NewInt(2463000),
    40  		EIP150Hash:      common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    41  		EIP155Block:     big.NewInt(2675000),
    42  		EIP158Block:     big.NewInt(2675000),
    43  		MetropolisBlock: big.NewInt(math.MaxInt64), // Don't enable yet
    44  
    45  		Ethash: new(EthashConfig),
    46  	}
    47  
    48  	// TestnetChainConfig contains the chain parameters to run a node on the Ropsten test network.
    49  	TestnetChainConfig = &ChainConfig{
    50  		ChainId:         big.NewInt(3),
    51  		HomesteadBlock:  big.NewInt(0),
    52  		DAOForkBlock:    nil,
    53  		DAOForkSupport:  true,
    54  		EIP150Block:     big.NewInt(0),
    55  		EIP150Hash:      common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
    56  		EIP155Block:     big.NewInt(10),
    57  		EIP158Block:     big.NewInt(10),
    58  		MetropolisBlock: big.NewInt(math.MaxInt64), // Don't enable yet
    59  
    60  		Ethash: new(EthashConfig),
    61  	}
    62  
    63  	// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
    64  	RinkebyChainConfig = &ChainConfig{
    65  		ChainId:         big.NewInt(4),
    66  		HomesteadBlock:  big.NewInt(1),
    67  		DAOForkBlock:    nil,
    68  		DAOForkSupport:  true,
    69  		EIP150Block:     big.NewInt(2),
    70  		EIP150Hash:      common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
    71  		EIP155Block:     big.NewInt(3),
    72  		EIP158Block:     big.NewInt(3),
    73  		MetropolisBlock: big.NewInt(math.MaxInt64), // Don't enable yet
    74  
    75  		Clique: &CliqueConfig{
    76  			Period: 15,
    77  			Epoch:  30000,
    78  		},
    79  	}
    80  
    81  	// AllProtocolChanges contains every protocol change (EIPs)
    82  	// introduced and accepted by the Ethereum core developers.
    83  	//
    84  	// This configuration is intentionally not using keyed fields.
    85  	// This configuration must *always* have all forks enabled, which
    86  	// means that all fields must be set at all times. This forces
    87  	// anyone adding flags to the config to also have to set these
    88  	// fields.
    89  	AllProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(math.MaxInt64) /*disabled*/, new(EthashConfig), nil}
    90  	TestChainConfig    = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil}
    91  	TestRules          = TestChainConfig.Rules(new(big.Int))
    92  )
    93  
    94  // ChainConfig is the core config which determines the blockchain settings.
    95  //
    96  // ChainConfig is stored in the database on a per block basis. This means
    97  // that any network, identified by its genesis block, can have its own
    98  // set of configuration options.
    99  type ChainConfig struct {
   100  	ChainId *big.Int `json:"chainId"` // Chain id identifies the current chain and is used for replay protection
   101  
   102  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   103  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   104  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   105  
   106  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   107  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   108  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (fast sync aid)
   109  
   110  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   111  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   112  
   113  	MetropolisBlock *big.Int `json:"metropolisBlock,omitempty"` // Metropolis switch block (nil = no fork, 0 = alraedy on homestead)
   114  
   115  	// Various consensus engines
   116  	Ethash *EthashConfig `json:"ethash,omitempty"`
   117  	Clique *CliqueConfig `json:"clique,omitempty"`
   118  }
   119  
   120  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   121  type EthashConfig struct{}
   122  
   123  // String implements the stringer interface, returning the consensus engine details.
   124  func (c *EthashConfig) String() string {
   125  	return "ethash"
   126  }
   127  
   128  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   129  type CliqueConfig struct {
   130  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   131  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   132  }
   133  
   134  // String implements the stringer interface, returning the consensus engine details.
   135  func (c *CliqueConfig) String() string {
   136  	return "clique"
   137  }
   138  
   139  // String implements the fmt.Stringer interface.
   140  func (c *ChainConfig) String() string {
   141  	var engine interface{}
   142  	switch {
   143  	case c.Ethash != nil:
   144  		engine = c.Ethash
   145  	case c.Clique != nil:
   146  		engine = c.Clique
   147  	default:
   148  		engine = "unknown"
   149  	}
   150  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Metropolis: %v Engine: %v}",
   151  		c.ChainId,
   152  		c.HomesteadBlock,
   153  		c.DAOForkBlock,
   154  		c.DAOForkSupport,
   155  		c.EIP150Block,
   156  		c.EIP155Block,
   157  		c.EIP158Block,
   158  		c.MetropolisBlock,
   159  		engine,
   160  	)
   161  }
   162  
   163  // IsHomestead returns whether num is either equal to the homestead block or greater.
   164  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   165  	return isForked(c.HomesteadBlock, num)
   166  }
   167  
   168  // IsDAO returns whether num is either equal to the DAO fork block or greater.
   169  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   170  	return isForked(c.DAOForkBlock, num)
   171  }
   172  
   173  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   174  	return isForked(c.EIP150Block, num)
   175  }
   176  
   177  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   178  	return isForked(c.EIP155Block, num)
   179  }
   180  
   181  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   182  	return isForked(c.EIP158Block, num)
   183  }
   184  
   185  func (c *ChainConfig) IsMetropolis(num *big.Int) bool {
   186  	return isForked(c.MetropolisBlock, num)
   187  }
   188  
   189  // GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
   190  //
   191  // The returned GasTable's fields shouldn't, under any circumstances, be changed.
   192  func (c *ChainConfig) GasTable(num *big.Int) GasTable {
   193  	if num == nil {
   194  		return GasTableHomestead
   195  	}
   196  	switch {
   197  	case c.IsEIP158(num):
   198  		return GasTableEIP158
   199  	case c.IsEIP150(num):
   200  		return GasTableHomesteadGasRepriceFork
   201  	default:
   202  		return GasTableHomestead
   203  	}
   204  }
   205  
   206  // CheckCompatible checks whether scheduled fork transitions have been imported
   207  // with a mismatching chain configuration.
   208  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   209  	bhead := new(big.Int).SetUint64(height)
   210  
   211  	// Iterate checkCompatible to find the lowest conflict.
   212  	var lasterr *ConfigCompatError
   213  	for {
   214  		err := c.checkCompatible(newcfg, bhead)
   215  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   216  			break
   217  		}
   218  		lasterr = err
   219  		bhead.SetUint64(err.RewindTo)
   220  	}
   221  	return lasterr
   222  }
   223  
   224  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   225  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   226  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   227  	}
   228  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   229  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   230  	}
   231  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   232  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   233  	}
   234  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   235  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   236  	}
   237  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   238  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   239  	}
   240  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   241  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   242  	}
   243  	if c.IsEIP158(head) && !configNumEqual(c.ChainId, newcfg.ChainId) {
   244  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   245  	}
   246  	if isForkIncompatible(c.MetropolisBlock, newcfg.MetropolisBlock, head) {
   247  		return newCompatError("Metropolis fork block", c.MetropolisBlock, newcfg.MetropolisBlock)
   248  	}
   249  	return nil
   250  }
   251  
   252  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   253  // block s2 because head is already past the fork.
   254  func isForkIncompatible(s1, s2, head *big.Int) bool {
   255  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   256  }
   257  
   258  // isForked returns whether a fork scheduled at block s is active at the given head block.
   259  func isForked(s, head *big.Int) bool {
   260  	if s == nil || head == nil {
   261  		return false
   262  	}
   263  	return s.Cmp(head) <= 0
   264  }
   265  
   266  func configNumEqual(x, y *big.Int) bool {
   267  	if x == nil {
   268  		return y == nil
   269  	}
   270  	if y == nil {
   271  		return x == nil
   272  	}
   273  	return x.Cmp(y) == 0
   274  }
   275  
   276  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   277  // ChainConfig that would alter the past.
   278  type ConfigCompatError struct {
   279  	What string
   280  	// block numbers of the stored and new configurations
   281  	StoredConfig, NewConfig *big.Int
   282  	// the block number to which the local chain must be rewound to correct the error
   283  	RewindTo uint64
   284  }
   285  
   286  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   287  	var rew *big.Int
   288  	switch {
   289  	case storedblock == nil:
   290  		rew = newblock
   291  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   292  		rew = storedblock
   293  	default:
   294  		rew = newblock
   295  	}
   296  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   297  	if rew != nil && rew.Sign() > 0 {
   298  		err.RewindTo = rew.Uint64() - 1
   299  	}
   300  	return err
   301  }
   302  
   303  func (err *ConfigCompatError) Error() string {
   304  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   305  }
   306  
   307  // Rules wraps ChainConfig and is merely syntatic sugar or can be used for functions
   308  // that do not have or require information about the block.
   309  //
   310  // Rules is a one time interface meaning that it shouldn't be used in between transition
   311  // phases.
   312  type Rules struct {
   313  	ChainId                                   *big.Int
   314  	IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
   315  	IsMetropolis                              bool
   316  }
   317  
   318  func (c *ChainConfig) Rules(num *big.Int) Rules {
   319  	chainId := c.ChainId
   320  	if chainId == nil {
   321  		chainId = new(big.Int)
   322  	}
   323  	return Rules{ChainId: new(big.Int).Set(chainId), IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), IsEIP155: c.IsEIP155(num), IsEIP158: c.IsEIP158(num), IsMetropolis: c.IsMetropolis(num)}
   324  }