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