github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/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/FusionFoundation/efsn/common"
    24  )
    25  
    26  // Genesis hashes to enforce below configs on.
    27  var (
    28  	MainnetGenesisHash = common.HexToHash("0xc2422b1d9d16331be2a5b207c0783027d4419498003f729f4b9e9c5c1838623a")
    29  	TestnetGenesisHash = common.HexToHash("0xbc679bca6ecc3cc41c4d5d3455d72d23991b2770d2f3144043a25e7cb5503f46")
    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(32659),
    37  		HomesteadBlock:      big.NewInt(0),
    38  		DAOForkBlock:        big.NewInt(0),
    39  		DAOForkSupport:      false,
    40  		EIP150Block:         big.NewInt(0),
    41  		EIP150Hash:          common.HexToHash("0x0"),
    42  		EIP155Block:         big.NewInt(0),
    43  		EIP158Block:         big.NewInt(0),
    44  		ByzantiumBlock:      big.NewInt(0),
    45  		ConstantinopleBlock: common.MainnetConstantinopleEnableHeight,
    46  		DaTong: &DaTongConfig{
    47  			Period: 15,
    48  		},
    49  	}
    50  
    51  	// MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network.
    52  	MainnetTrustedCheckpoint = &TrustedCheckpoint{
    53  		Name:         "mainnet",
    54  		SectionIndex: 193,
    55  		SectionHead:  common.HexToHash("0xc2d574295ecedc4d58530ae24c31a5a98be7d2b3327fba0dd0f4ed3913828a55"),
    56  		CHTRoot:      common.HexToHash("0x5d1027dfae688c77376e842679ceada87fd94738feb9b32ef165473bfbbb317b"),
    57  		BloomRoot:    common.HexToHash("0xd38be1a06aabd568e10957fee4fcc523bc64996bcf31bae3f55f86e0a583919f"),
    58  	}
    59  
    60  	// TestnetChainConfig contains the chain parameters to run a node on the fusion test network.
    61  	TestnetChainConfig = &ChainConfig{
    62  		ChainID:             big.NewInt(46688),
    63  		HomesteadBlock:      big.NewInt(0),
    64  		DAOForkBlock:        big.NewInt(0),
    65  		DAOForkSupport:      false,
    66  		EIP150Block:         big.NewInt(0),
    67  		EIP150Hash:          common.HexToHash("0x0"),
    68  		EIP155Block:         big.NewInt(0),
    69  		EIP158Block:         big.NewInt(0),
    70  		ByzantiumBlock:      big.NewInt(0),
    71  		ConstantinopleBlock: common.TestnetConstantinopleEnableHeight,
    72  		DaTong: &DaTongConfig{
    73  			Period: 15,
    74  		},
    75  	}
    76  
    77  	// TestnetTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
    78  	TestnetTrustedCheckpoint = &TrustedCheckpoint{
    79  		Name:         "testnet",
    80  		SectionIndex: 123,
    81  		SectionHead:  common.HexToHash("0xa372a53decb68ce453da12bea1c8ee7b568b276aa2aab94d9060aa7c81fc3dee"),
    82  		CHTRoot:      common.HexToHash("0x6b02e7fada79cd2a80d4b3623df9c44384d6647fc127462e1c188ccd09ece87b"),
    83  		BloomRoot:    common.HexToHash("0xf2d27490914968279d6377d42868928632573e823b5d1d4a944cba6009e16259"),
    84  	}
    85  
    86  	// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
    87  	RinkebyChainConfig = &ChainConfig{
    88  		ChainID:             big.NewInt(4),
    89  		HomesteadBlock:      big.NewInt(1),
    90  		DAOForkBlock:        nil,
    91  		DAOForkSupport:      true,
    92  		EIP150Block:         big.NewInt(2),
    93  		EIP150Hash:          common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
    94  		EIP155Block:         big.NewInt(3),
    95  		EIP158Block:         big.NewInt(3),
    96  		ByzantiumBlock:      big.NewInt(1035301),
    97  		ConstantinopleBlock: nil,
    98  		Clique: &CliqueConfig{
    99  			Period: 15,
   100  			Epoch:  30000,
   101  		},
   102  	}
   103  
   104  	// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
   105  	RinkebyTrustedCheckpoint = &TrustedCheckpoint{
   106  		Name:         "rinkeby",
   107  		SectionIndex: 91,
   108  		SectionHead:  common.HexToHash("0x435b7b2d8a7922f3b9a522f2fb02730e95e0e1782f0f5443894d5415bba37154"),
   109  		CHTRoot:      common.HexToHash("0x0664bf7ecccfb6775c4eca6f0f264fb5282a22754a2135a1ac4bff2ef02898dd"),
   110  		BloomRoot:    common.HexToHash("0x2a64df2400c3a2cb6400639bb6ed29389abdb4d93e2e525aa7c21f38767cd96f"),
   111  	}
   112  
   113  	// DevnetChainConfig is the chain parameters to run a node on the develop network.
   114  	DevnetChainConfig = &ChainConfig{
   115  		ChainID:             big.NewInt(55555),
   116  		HomesteadBlock:      big.NewInt(0),
   117  		DAOForkBlock:        big.NewInt(0),
   118  		DAOForkSupport:      false,
   119  		EIP150Block:         big.NewInt(0),
   120  		EIP150Hash:          common.HexToHash("0x0"),
   121  		EIP155Block:         big.NewInt(0),
   122  		EIP158Block:         big.NewInt(0),
   123  		ByzantiumBlock:      big.NewInt(0),
   124  		ConstantinopleBlock: common.DevnetConstantinopleEnableHeight,
   125  		DaTong: &DaTongConfig{
   126  			Period: 15,
   127  		},
   128  	}
   129  
   130  	// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
   131  	// and accepted by the Ethereum core developers into the Ethash 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  	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, nil, new(EthashConfig), nil, nil}
   136  
   137  	// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
   138  	// and accepted by the Ethereum core developers into the Clique consensus.
   139  	//
   140  	// This configuration is intentionally not using keyed fields to force anyone
   141  	// adding flags to the config to also have to set these fields.
   142  	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, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
   143  
   144  	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, nil, new(EthashConfig), nil, nil}
   145  	TestRules       = TestChainConfig.Rules(new(big.Int))
   146  )
   147  
   148  // TrustedCheckpoint represents a set of post-processed trie roots (CHT and
   149  // BloomTrie) associated with the appropriate section index and head hash. It is
   150  // used to start light syncing from this checkpoint and avoid downloading the
   151  // entire header chain while still being able to securely access old headers/logs.
   152  type TrustedCheckpoint struct {
   153  	Name         string      `json:"-"`
   154  	SectionIndex uint64      `json:"sectionIndex"`
   155  	SectionHead  common.Hash `json:"sectionHead"`
   156  	CHTRoot      common.Hash `json:"chtRoot"`
   157  	BloomRoot    common.Hash `json:"bloomRoot"`
   158  }
   159  
   160  // ChainConfig is the core config which determines the blockchain settings.
   161  //
   162  // ChainConfig is stored in the database on a per block basis. This means
   163  // that any network, identified by its genesis block, can have its own
   164  // set of configuration options.
   165  type ChainConfig struct {
   166  	ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
   167  
   168  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   169  
   170  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   171  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   172  
   173  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   174  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   175  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
   176  
   177  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   178  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   179  
   180  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   181  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   182  	EWASMBlock          *big.Int `json:"ewasmBlock,omitempty"`          // EWASM switch block (nil = no fork, 0 = already activated)
   183  
   184  	// Various consensus engines
   185  	Ethash *EthashConfig `json:"ethash,omitempty"`
   186  	Clique *CliqueConfig `json:"clique,omitempty"`
   187  	DaTong *DaTongConfig `json:"datong,omitempty"`
   188  }
   189  
   190  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   191  type EthashConfig struct{}
   192  
   193  // String implements the stringer interface, returning the consensus engine details.
   194  func (c *EthashConfig) String() string {
   195  	return "ethash"
   196  }
   197  
   198  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   199  type CliqueConfig struct {
   200  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   201  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   202  }
   203  
   204  // String implements the stringer interface, returning the consensus engine details.
   205  func (c *CliqueConfig) String() string {
   206  	return "clique"
   207  }
   208  
   209  // String implements the fmt.Stringer interface.
   210  func (c *ChainConfig) String() string {
   211  	var engine interface{}
   212  	switch {
   213  	case c.Ethash != nil:
   214  		engine = c.Ethash
   215  	case c.Clique != nil:
   216  		engine = c.Clique
   217  	case c.DaTong != nil:
   218  		engine = c.DaTong
   219  	default:
   220  		engine = "unknown"
   221  	}
   222  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Engine: %v}",
   223  		c.ChainID,
   224  		c.HomesteadBlock,
   225  		c.DAOForkBlock,
   226  		c.DAOForkSupport,
   227  		c.EIP150Block,
   228  		c.EIP155Block,
   229  		c.EIP158Block,
   230  		c.ByzantiumBlock,
   231  		c.ConstantinopleBlock,
   232  		engine,
   233  	)
   234  }
   235  
   236  // IsHomestead returns whether num is either equal to the homestead block or greater.
   237  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   238  	return isForked(c.HomesteadBlock, num)
   239  }
   240  
   241  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   242  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   243  	return isForked(c.DAOForkBlock, num)
   244  }
   245  
   246  // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
   247  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   248  	return isForked(c.EIP150Block, num)
   249  }
   250  
   251  // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
   252  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   253  	return isForked(c.EIP155Block, num)
   254  }
   255  
   256  // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
   257  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   258  	return isForked(c.EIP158Block, num)
   259  }
   260  
   261  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   262  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   263  	return isForked(c.ByzantiumBlock, num)
   264  }
   265  
   266  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   267  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   268  	return isForked(c.ConstantinopleBlock, num)
   269  }
   270  
   271  // IsEWASM returns whether num represents a block number after the EWASM fork
   272  func (c *ChainConfig) IsEWASM(num *big.Int) bool {
   273  	return isForked(c.EWASMBlock, num)
   274  }
   275  
   276  // GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
   277  //
   278  // The returned GasTable's fields shouldn't, under any circumstances, be changed.
   279  func (c *ChainConfig) GasTable(num *big.Int) GasTable {
   280  	if num == nil {
   281  		return GasTableHomestead
   282  	}
   283  	switch {
   284  	case c.IsConstantinople(num):
   285  		return GasTableConstantinople
   286  	case c.IsEIP158(num):
   287  		return GasTableEIP158
   288  	case c.IsEIP150(num):
   289  		return GasTableEIP150
   290  	default:
   291  		return GasTableHomestead
   292  	}
   293  }
   294  
   295  // CheckCompatible checks whether scheduled fork transitions have been imported
   296  // with a mismatching chain configuration.
   297  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   298  	bhead := new(big.Int).SetUint64(height)
   299  
   300  	// Iterate checkCompatible to find the lowest conflict.
   301  	var lasterr *ConfigCompatError
   302  	for {
   303  		err := c.checkCompatible(newcfg, bhead)
   304  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   305  			break
   306  		}
   307  		lasterr = err
   308  		bhead.SetUint64(err.RewindTo)
   309  	}
   310  	return lasterr
   311  }
   312  
   313  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   314  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   315  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   316  	}
   317  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   318  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   319  	}
   320  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   321  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   322  	}
   323  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   324  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   325  	}
   326  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   327  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   328  	}
   329  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   330  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   331  	}
   332  	if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   333  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   334  	}
   335  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   336  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   337  	}
   338  	if c.ConstantinopleBlock != nil { // adjust old stored ConstantinopleBlock
   339  		constantinopleEnableHeight := common.GetConstantinopleEnableHeight()
   340  		if constantinopleEnableHeight == nil || c.ConstantinopleBlock.Cmp(constantinopleEnableHeight) < 0 {
   341  			c.ConstantinopleBlock = constantinopleEnableHeight
   342  		}
   343  	}
   344  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   345  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   346  	}
   347  	if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
   348  		return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock)
   349  	}
   350  	return nil
   351  }
   352  
   353  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   354  // block s2 because head is already past the fork.
   355  func isForkIncompatible(s1, s2, head *big.Int) bool {
   356  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   357  }
   358  
   359  // isForked returns whether a fork scheduled at block s is active at the given head block.
   360  func isForked(s, head *big.Int) bool {
   361  	if s == nil || head == nil {
   362  		return false
   363  	}
   364  	return s.Cmp(head) <= 0
   365  }
   366  
   367  func configNumEqual(x, y *big.Int) bool {
   368  	if x == nil {
   369  		return y == nil
   370  	}
   371  	if y == nil {
   372  		return x == nil
   373  	}
   374  	return x.Cmp(y) == 0
   375  }
   376  
   377  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   378  // ChainConfig that would alter the past.
   379  type ConfigCompatError struct {
   380  	What string
   381  	// block numbers of the stored and new configurations
   382  	StoredConfig, NewConfig *big.Int
   383  	// the block number to which the local chain must be rewound to correct the error
   384  	RewindTo uint64
   385  }
   386  
   387  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   388  	var rew *big.Int
   389  	switch {
   390  	case storedblock == nil:
   391  		rew = newblock
   392  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   393  		rew = storedblock
   394  	default:
   395  		rew = newblock
   396  	}
   397  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   398  	if rew != nil && rew.Sign() > 0 {
   399  		err.RewindTo = rew.Uint64() - 1
   400  	}
   401  	return err
   402  }
   403  
   404  func (err *ConfigCompatError) Error() string {
   405  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   406  }
   407  
   408  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
   409  // that do not have or require information about the block.
   410  //
   411  // Rules is a one time interface meaning that it shouldn't be used in between transition
   412  // phases.
   413  type Rules struct {
   414  	ChainID                                   *big.Int
   415  	IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
   416  	IsByzantium, IsConstantinople             bool
   417  }
   418  
   419  // Rules ensures c's ChainID is not nil.
   420  func (c *ChainConfig) Rules(num *big.Int) Rules {
   421  	chainID := c.ChainID
   422  	if chainID == nil {
   423  		chainID = new(big.Int)
   424  	}
   425  	return Rules{
   426  		ChainID:          new(big.Int).Set(chainID),
   427  		IsHomestead:      c.IsHomestead(num),
   428  		IsEIP150:         c.IsEIP150(num),
   429  		IsEIP155:         c.IsEIP155(num),
   430  		IsEIP158:         c.IsEIP158(num),
   431  		IsByzantium:      c.IsByzantium(num),
   432  		IsConstantinople: c.IsConstantinople(num),
   433  	}
   434  }
   435  
   436  // DaTongConfig is the consensus engine configs for proof-of-stake based sealing.
   437  type DaTongConfig struct {
   438  	Period uint64 `json:"period"`
   439  }
   440  
   441  // String implements the stringer interface, returning the consensus engine details.
   442  func (c *DaTongConfig) String() string {
   443  	return "datong"
   444  }