github.com/reapchain/go-reapchain@v0.2.15-0.20210609012950-9735c110c705/params/config.go (about)

     1  package params
     2  
     3  
     4  
     5  // Copyright 2016 The go-ethereum Authors
     6  // This file is part of the go-ethereum library.
     7  //
     8  // The go-ethereum library is free software: you can redistribute it and/or modify
     9  // it under the terms of the GNU Lesser General Public License as published by
    10  // the Free Software Foundation, either version 3 of the License, or
    11  // (at your option) any later version.
    12  //
    13  // The go-ethereum library is distributed in the hope that it will be useful,
    14  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    16  // GNU Lesser General Public License for more details.
    17  //
    18  // You should have received a copy of the GNU Lesser General Public License
    19  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    20  
    21  import (
    22  	"fmt"
    23  	"math/big"
    24  	"errors"
    25  	"github.com/ethereum/go-ethereum/common"
    26  )
    27  
    28  var (
    29  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    30  	 MainnetChainConfig = &ChainConfig{
    31  		ChainId:         MainNetChainID,
    32  		HomesteadBlock:  MainNetHomesteadBlock,
    33  		DAOForkBlock:    MainNetDAOForkBlock,
    34  		DAOForkSupport:  true,
    35  		EIP150Block:     MainNetHomesteadGasRepriceBlock,
    36  		EIP150Hash:      MainNetHomesteadGasRepriceHash,
    37  		EIP155Block:     MainNetSpuriousDragon,
    38  		EIP158Block:     MainNetSpuriousDragon,
    39  		MetropolisBlock: MainNetMetropolisBlock,
    40  
    41  		Ethash: new(EthashConfig),
    42  	}
    43  
    44  	//MainnetChainConfig = &ChainConfig{
    45  	//	ChainId:         big.NewInt(2017),
    46  	//	HomesteadBlock:  big.NewInt(1),
    47  	//	DAOForkBlock:    nil,
    48  	//	DAOForkSupport:  true,
    49  	//	EIP150Block:     big.NewInt(2),
    50  	//	EIP150Hash:      common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
    51  	//	EIP155Block:     big.NewInt(3),
    52  	//	EIP158Block:     big.NewInt(3),
    53  	//	MetropolisBlock: TestNetMetropolisBlock,
    54  	//
    55  	//	/*Istanbul: &IstanbulConfig{
    56  	//		Epoch:          30000,
    57  	//		ProposerPolicy: 0,
    58  	//	}, */
    59  	////	PoDC: &PoDCConfig{
    60  	////		Epoch:          30000,
    61  	////		ProposerPolicy: 0,
    62  	////	},
    63  	////}
    64  
    65  	// TestnetChainConfig contains the chain parameters to run a node on the Ropsten test network.
    66  	TestnetChainConfig = &ChainConfig{
    67  		ChainId:         big.NewInt(3),
    68  		HomesteadBlock:  big.NewInt(0),
    69  		DAOForkBlock:    nil,
    70  		DAOForkSupport:  true,
    71  		EIP150Block:     big.NewInt(0),
    72  		EIP150Hash:      common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
    73  		EIP155Block:     big.NewInt(10),
    74  		EIP158Block:     big.NewInt(10),
    75  		MetropolisBlock: TestNetMetropolisBlock,
    76  
    77  		Ethash: new(EthashConfig),
    78  	}
    79  
    80  	// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
    81  	RinkebyChainConfig = &ChainConfig{
    82  		ChainId:         big.NewInt(4),
    83  		HomesteadBlock:  big.NewInt(1),
    84  		DAOForkBlock:    nil,
    85  		DAOForkSupport:  true,
    86  		EIP150Block:     big.NewInt(2),
    87  		EIP150Hash:      common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
    88  		EIP155Block:     big.NewInt(3),
    89  		EIP158Block:     big.NewInt(3),
    90  		MetropolisBlock: TestNetMetropolisBlock,
    91  
    92  		Clique: &CliqueConfig{
    93  			Period: 15,
    94  			Epoch:  30000,
    95  		},
    96  	}
    97  
    98  	// OttomanChainConfig contains the chain parameters to run a node on the Ottoman test network.
    99  	OttomanChainConfig = &ChainConfig{
   100  		ChainId:         big.NewInt(5),
   101  		HomesteadBlock:  big.NewInt(1),
   102  		DAOForkBlock:    nil,
   103  		DAOForkSupport:  true,
   104  		EIP150Block:     big.NewInt(2),
   105  		EIP150Hash:      common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
   106  		EIP155Block:     big.NewInt(3),
   107  		EIP158Block:     big.NewInt(3),
   108  		MetropolisBlock: TestNetMetropolisBlock,
   109  
   110  
   111  		Istanbul: &IstanbulConfig{
   112  			Epoch:          30000,
   113  			ProposerPolicy: 0,
   114  		},
   115  	}
   116  
   117  	// OttomanChainConfig contains the chain parameters to run a node on the Ottoman test network.
   118  
   119  	ReapChainConfig = &ChainConfig{
   120  		ChainId:         big.NewInt(2017),
   121  		HomesteadBlock:  big.NewInt(1),
   122  		DAOForkBlock:    nil,
   123  		DAOForkSupport:  true,
   124  		EIP150Block:     big.NewInt(2),
   125  		EIP150Hash:      common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
   126  		EIP155Block:     big.NewInt(3),
   127  		EIP158Block:     big.NewInt(3),
   128  		MetropolisBlock: TestNetMetropolisBlock,
   129  
   130  		PoDC: &PoDCConfig{
   131  			Epoch:          30000,
   132  			ProposerPolicy: 0,
   133  		},
   134  	}
   135  
   136  	// AllProtocolChanges contains every protocol change (EIPs)
   137  	// introduced and accepted by the Ethereum core developers.
   138  	//
   139  	// This configuration is intentionally not using keyed fields.
   140  	// This configuration must *always* have all forks enabled, which
   141  	// means that all fields must be set at all times. This forces
   142  	// anyone adding flags to the config to also have to set these
   143  	// fields.
   144  
   145  	AllProtocolChanges = &ChainConfig{big.NewInt(2017), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil, nil, 32}
   146  	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, nil, nil, 32}
   147  
   148  	TestRules          = TestChainConfig.Rules(new(big.Int))
   149  )
   150  
   151  // ChainConfig is the core config which determines the blockchain settings.
   152  //
   153  // ChainConfig is stored in the database on a per block basis. This means
   154  // that any network, identified by its genesis block, can have its own
   155  // set of configuration options.
   156  type ChainConfig struct {
   157  	ChainId *big.Int `json:"chainId"` // Chain id identifies the current chain and is used for replay protection
   158  
   159  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   160  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   161  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   162  
   163  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   164  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   165  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (fast sync aid)
   166  
   167  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   168  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   169  
   170  	MetropolisBlock *big.Int `json:"metropolisBlock,omitempty"` // Metropolis switch block (nil = no fork, 0 = alraedy on homestead)
   171  
   172  	// Various consensus engines
   173  	Ethash   *EthashConfig   `json:"ethash,omitempty"`
   174  	Clique   *CliqueConfig   `json:"clique,omitempty"`
   175      Istanbul *IstanbulConfig `json:"istanbul,omitempty"`
   176  	PoDC     *PoDCConfig     `json:"podc,omitempty"`
   177  	MaxCodeSize       uint64 `json:"maxCodeSize"`
   178  
   179  }
   180  
   181  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   182  type EthashConfig struct{}
   183  
   184  // PoDCConfig is the consensus engine configs for PoDC based sealing.
   185  
   186  // String implements the stringer interface, returning the consensus engine details.
   187  func (c *EthashConfig) String() string {
   188  	return "ethash"
   189  }
   190  
   191  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   192  type CliqueConfig struct {
   193  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   194  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   195  }
   196  
   197  // String implements the stringer interface, returning the consensus engine details.
   198  func (c *CliqueConfig) String() string {
   199  	return "clique"
   200  }
   201  
   202  // IstanbulConfig is the consensus engine configs for Istanbul based sealing.
   203  type IstanbulConfig struct {
   204  	Epoch          uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   205  	ProposerPolicy uint64 `json:"policy"` // The policy for proposer selection
   206  }
   207  
   208  type PoDCConfig struct {
   209  	Epoch          uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   210  	ProposerPolicy uint64 `json:"policy"` // The policy for proposer selection
   211  }
   212  
   213  // String implements the stringer interface, returning the consensus engine details.
   214  func (c *IstanbulConfig) String() string {
   215  	return "istanbul"
   216  }
   217  func (c *PoDCConfig) String() string {  //display ?
   218  	return "podc"
   219  }
   220  
   221  // String implements the fmt.Stringer interface.
   222  func (c *ChainConfig) String() string {
   223  	var engine interface{}
   224  	switch {
   225  	case c.Ethash != nil:
   226  		engine = c.Ethash
   227  	case c.Clique != nil:
   228  		engine = c.Clique
   229   	case c.Istanbul != nil:
   230  		engine = c.Istanbul
   231  	case c.PoDC != nil:
   232  		engine = c.PoDC
   233  
   234  
   235  	default:
   236  		engine = "unknown"
   237  	}
   238  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Metropolis: %v MaxCodeSize: %v Engine: %v}",
   239  		c.ChainId,
   240  		c.HomesteadBlock,
   241  		c.DAOForkBlock,
   242  		c.DAOForkSupport,
   243  		c.EIP150Block,
   244  		c.EIP155Block,
   245  		c.EIP158Block,
   246  		c.MetropolisBlock,
   247  		c.MaxCodeSize,
   248  		engine,
   249  	)
   250  }
   251  
   252  func (c *ChainConfig) IsValid() error {
   253  	if c.MaxCodeSize < 24 || c.MaxCodeSize > 128 {
   254  		return errors.New("Genesis max code size must be between 24 and 128")
   255  	}
   256  	return nil
   257  }
   258  
   259  // IsHomestead returns whether num is either equal to the homestead block or greater.
   260  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   261  	return isForked(c.HomesteadBlock, num)
   262  }
   263  
   264  // IsDAO returns whether num is either equal to the DAO fork block or greater.
   265  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   266  	return isForked(c.DAOForkBlock, num)
   267  }
   268  
   269  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   270  	return isForked(c.EIP150Block, num)
   271  }
   272  
   273  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   274  	return isForked(c.EIP155Block, num)
   275  }
   276  
   277  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   278  	return isForked(c.EIP158Block, num)
   279  }
   280  
   281  func (c *ChainConfig) IsMetropolis(num *big.Int) bool {
   282  	return isForked(c.MetropolisBlock, num)
   283  }
   284  
   285  // GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
   286  //
   287  // The returned GasTable's fields shouldn't, under any circumstances, be changed.
   288  func (c *ChainConfig) GasTable(num *big.Int) GasTable {
   289  	if num == nil {
   290  		return GasTableHomestead
   291  	}
   292  	switch {
   293  	case c.IsEIP158(num):
   294  		return GasTableEIP158
   295  	case c.IsEIP150(num):
   296  		return GasTableHomesteadGasRepriceFork
   297  	default:
   298  		return GasTableHomestead
   299  	}
   300  }
   301  
   302  // CheckCompatible checks whether scheduled fork transitions have been imported
   303  // with a mismatching chain configuration.
   304  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   305  	bhead := new(big.Int).SetUint64(height)
   306  
   307  	// Iterate checkCompatible to find the lowest conflict.
   308  	var lasterr *ConfigCompatError
   309  	for {
   310  		err := c.checkCompatible(newcfg, bhead)
   311  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   312  			break
   313  		}
   314  		lasterr = err
   315  		bhead.SetUint64(err.RewindTo)
   316  	}
   317  	return lasterr
   318  }
   319  
   320  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   321  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   322  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   323  	}
   324  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   325  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   326  	}
   327  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   328  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   329  	}
   330  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   331  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   332  	}
   333  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   334  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   335  	}
   336  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   337  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   338  	}
   339  	if c.IsEIP158(head) && !configNumEqual(c.ChainId, newcfg.ChainId) {
   340  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   341  	}
   342  	if isForkIncompatible(c.MetropolisBlock, newcfg.MetropolisBlock, head) {
   343  		return newCompatError("Metropolis fork block", c.MetropolisBlock, newcfg.MetropolisBlock)
   344  	}
   345  	return nil
   346  }
   347  
   348  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   349  // block s2 because head is already past the fork.
   350  func isForkIncompatible(s1, s2, head *big.Int) bool {
   351  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   352  }
   353  
   354  // isForked returns whether a fork scheduled at block s is active at the given head block.
   355  func isForked(s, head *big.Int) bool {
   356  	if s == nil || head == nil {
   357  		return false
   358  	}
   359  	return s.Cmp(head) <= 0
   360  }
   361  
   362  func configNumEqual(x, y *big.Int) bool {
   363  	if x == nil {
   364  		return y == nil
   365  	}
   366  	if y == nil {
   367  		return x == nil
   368  	}
   369  	return x.Cmp(y) == 0
   370  }
   371  
   372  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   373  // ChainConfig that would alter the past.
   374  type ConfigCompatError struct {
   375  	What string
   376  	// block numbers of the stored and new configurations
   377  	StoredConfig, NewConfig *big.Int
   378  	// the block number to which the local chain must be rewound to correct the error
   379  	RewindTo uint64
   380  }
   381  
   382  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   383  	var rew *big.Int
   384  	switch {
   385  	case storedblock == nil:
   386  		rew = newblock
   387  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   388  		rew = storedblock
   389  	default:
   390  		rew = newblock
   391  	}
   392  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   393  	if rew != nil && rew.Sign() > 0 {
   394  		err.RewindTo = rew.Uint64() - 1
   395  	}
   396  	return err
   397  }
   398  
   399  func (err *ConfigCompatError) Error() string {
   400  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   401  }
   402  
   403  // Rules wraps ChainConfig and is merely syntatic sugar or can be used for functions
   404  // that do not have or require information about the block.
   405  //
   406  // Rules is a one time interface meaning that it shouldn't be used in between transition
   407  // phases.
   408  type Rules struct {
   409  	ChainId                                   *big.Int
   410  	IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
   411  	IsMetropolis                              bool
   412  }
   413  
   414  func (c *ChainConfig) Rules(num *big.Int) Rules {
   415  	chainId := c.ChainId
   416  	if chainId == nil {
   417  		chainId = new(big.Int)
   418  	}
   419  	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)}
   420  }
   421