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