github.com/ontio/ontology@v1.14.4/vm/evm/params/config.go (about)

     1  // Copyright (C) 2021 The Ontology Authors
     2  // Copyright 2016 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package params
    19  
    20  import (
    21  	"fmt"
    22  	"math/big"
    23  
    24  	"github.com/ontio/ontology/common/constants"
    25  )
    26  
    27  func GetChainConfig(chainId uint32) *ChainConfig {
    28  	return &ChainConfig{
    29  		ChainID:             big.NewInt(int64(chainId)),
    30  		HomesteadBlock:      big.NewInt(0),
    31  		DAOForkBlock:        nil,
    32  		DAOForkSupport:      true,
    33  		EIP150Block:         big.NewInt(0),
    34  		EIP155Block:         big.NewInt(0),
    35  		EIP158Block:         big.NewInt(0),
    36  		ByzantiumBlock:      big.NewInt(0),
    37  		ConstantinopleBlock: big.NewInt(0),
    38  		PetersburgBlock:     big.NewInt(0),
    39  		IstanbulBlock:       big.NewInt(0),
    40  		MuirGlacierBlock:    big.NewInt(0),
    41  	}
    42  
    43  }
    44  
    45  var (
    46  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    47  	MainnetChainConfig = &ChainConfig{
    48  		ChainID:             big.NewInt(constants.EIP155_CHAINID_MAINNET),
    49  		HomesteadBlock:      big.NewInt(0),
    50  		DAOForkBlock:        nil,
    51  		DAOForkSupport:      true,
    52  		EIP150Block:         big.NewInt(0),
    53  		EIP155Block:         big.NewInt(0),
    54  		EIP158Block:         big.NewInt(0),
    55  		ByzantiumBlock:      big.NewInt(0),
    56  		ConstantinopleBlock: big.NewInt(0),
    57  		PetersburgBlock:     big.NewInt(0),
    58  		IstanbulBlock:       big.NewInt(0),
    59  		MuirGlacierBlock:    big.NewInt(0),
    60  	}
    61  
    62  	// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
    63  	// and accepted by the Ethereum core developers into the Ethash consensus.
    64  	//
    65  	// This configuration is intentionally not using keyed fields to force anyone
    66  	// adding flags to the config to also have to set these fields.
    67  	AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil}
    68  
    69  	TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil}
    70  	TestRules       = TestChainConfig.Rules(new(big.Int))
    71  )
    72  
    73  // ChainConfig is the core config which determines the blockchain settings.
    74  //
    75  // ChainConfig is stored in the database on a per block basis. This means
    76  // that any network, identified by its genesis block, can have its own
    77  // set of configuration options.
    78  type ChainConfig struct {
    79  	ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
    80  
    81  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
    82  
    83  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
    84  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
    85  
    86  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
    87  	EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
    88  
    89  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
    90  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
    91  
    92  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
    93  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
    94  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`     // Petersburg switch block (nil = same as Constantinople)
    95  	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)
    96  	MuirGlacierBlock    *big.Int `json:"muirGlacierBlock,omitempty"`    // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
    97  
    98  	YoloV2Block *big.Int `json:"yoloV2Block,omitempty"` // YOLO v2: Gas repricings TODO @holiman add EIP references
    99  }
   100  
   101  // String implements the fmt.Stringer interface.
   102  func (c *ChainConfig) String() string {
   103  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, YOLO v2: %v}",
   104  		c.ChainID,
   105  		c.HomesteadBlock,
   106  		c.DAOForkBlock,
   107  		c.DAOForkSupport,
   108  		c.EIP150Block,
   109  		c.EIP155Block,
   110  		c.EIP158Block,
   111  		c.ByzantiumBlock,
   112  		c.ConstantinopleBlock,
   113  		c.PetersburgBlock,
   114  		c.IstanbulBlock,
   115  		c.MuirGlacierBlock,
   116  		c.YoloV2Block,
   117  	)
   118  }
   119  
   120  // IsHomestead returns whether num is either equal to the homestead block or greater.
   121  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   122  	return isForked(c.HomesteadBlock, num)
   123  }
   124  
   125  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   126  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   127  	return isForked(c.DAOForkBlock, num)
   128  }
   129  
   130  // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
   131  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   132  	return isForked(c.EIP150Block, num)
   133  }
   134  
   135  // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
   136  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   137  	return isForked(c.EIP155Block, num)
   138  }
   139  
   140  // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
   141  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   142  	return isForked(c.EIP158Block, num)
   143  }
   144  
   145  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   146  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   147  	return isForked(c.ByzantiumBlock, num)
   148  }
   149  
   150  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   151  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   152  	return isForked(c.ConstantinopleBlock, num)
   153  }
   154  
   155  // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
   156  func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
   157  	return isForked(c.MuirGlacierBlock, num)
   158  }
   159  
   160  // IsPetersburg returns whether num is either
   161  // - equal to or greater than the PetersburgBlock fork block,
   162  // - OR is nil, and Constantinople is active
   163  func (c *ChainConfig) IsPetersburg(num *big.Int) bool {
   164  	return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num)
   165  }
   166  
   167  // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater.
   168  func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
   169  	return isForked(c.IstanbulBlock, num)
   170  }
   171  
   172  // IsYoloV2 returns whether num is either equal to the YoloV1 fork block or greater.
   173  func (c *ChainConfig) IsYoloV2(num *big.Int) bool {
   174  	return isForked(c.YoloV2Block, num)
   175  }
   176  
   177  // CheckCompatible checks whether scheduled fork transitions have been imported
   178  // with a mismatching chain configuration.
   179  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   180  	bhead := new(big.Int).SetUint64(height)
   181  
   182  	// Iterate checkCompatible to find the lowest conflict.
   183  	var lasterr *ConfigCompatError
   184  	for {
   185  		err := c.checkCompatible(newcfg, bhead)
   186  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   187  			break
   188  		}
   189  		lasterr = err
   190  		bhead.SetUint64(err.RewindTo)
   191  	}
   192  	return lasterr
   193  }
   194  
   195  // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
   196  // to guarantee that forks can be implemented in a different order than on official networks
   197  func (c *ChainConfig) CheckConfigForkOrder() error {
   198  	type fork struct {
   199  		name     string
   200  		block    *big.Int
   201  		optional bool // if true, the fork may be nil and next fork is still allowed
   202  	}
   203  	var lastFork fork
   204  	for _, cur := range []fork{
   205  		{name: "homesteadBlock", block: c.HomesteadBlock},
   206  		{name: "daoForkBlock", block: c.DAOForkBlock, optional: true},
   207  		{name: "eip150Block", block: c.EIP150Block},
   208  		{name: "eip155Block", block: c.EIP155Block},
   209  		{name: "eip158Block", block: c.EIP158Block},
   210  		{name: "byzantiumBlock", block: c.ByzantiumBlock},
   211  		{name: "constantinopleBlock", block: c.ConstantinopleBlock},
   212  		{name: "petersburgBlock", block: c.PetersburgBlock},
   213  		{name: "istanbulBlock", block: c.IstanbulBlock},
   214  		{name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true},
   215  		{name: "yoloV2Block", block: c.YoloV2Block},
   216  	} {
   217  		if lastFork.name != "" {
   218  			// Next one must be higher number
   219  			if lastFork.block == nil && cur.block != nil {
   220  				return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
   221  					lastFork.name, cur.name, cur.block)
   222  			}
   223  			if lastFork.block != nil && cur.block != nil {
   224  				if lastFork.block.Cmp(cur.block) > 0 {
   225  					return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
   226  						lastFork.name, lastFork.block, cur.name, cur.block)
   227  				}
   228  			}
   229  		}
   230  		// If it was optional and not set, then ignore it
   231  		if !cur.optional || cur.block != nil {
   232  			lastFork = cur
   233  		}
   234  	}
   235  	return nil
   236  }
   237  
   238  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   239  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   240  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   241  	}
   242  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   243  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   244  	}
   245  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   246  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   247  	}
   248  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   249  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   250  	}
   251  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   252  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   253  	}
   254  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   255  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   256  	}
   257  	if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   258  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   259  	}
   260  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   261  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   262  	}
   263  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   264  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   265  	}
   266  	if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) {
   267  		// the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople
   268  		// mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set
   269  		if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, head) {
   270  			return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   271  		}
   272  	}
   273  	if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) {
   274  		return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
   275  	}
   276  	if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) {
   277  		return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
   278  	}
   279  	if isForkIncompatible(c.YoloV2Block, newcfg.YoloV2Block, head) {
   280  		return newCompatError("YOLOv2 fork block", c.YoloV2Block, newcfg.YoloV2Block)
   281  	}
   282  	return nil
   283  }
   284  
   285  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   286  // block s2 because head is already past the fork.
   287  func isForkIncompatible(s1, s2, head *big.Int) bool {
   288  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   289  }
   290  
   291  // isForked returns whether a fork scheduled at block s is active at the given head block.
   292  func isForked(s, head *big.Int) bool {
   293  	if s == nil || head == nil {
   294  		return false
   295  	}
   296  	return s.Cmp(head) <= 0
   297  }
   298  
   299  func configNumEqual(x, y *big.Int) bool {
   300  	if x == nil {
   301  		return y == nil
   302  	}
   303  	if y == nil {
   304  		return false
   305  	}
   306  	return x.Cmp(y) == 0
   307  }
   308  
   309  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   310  // ChainConfig that would alter the past.
   311  type ConfigCompatError struct {
   312  	What string
   313  	// block numbers of the stored and new configurations
   314  	StoredConfig, NewConfig *big.Int
   315  	// the block number to which the local chain must be rewound to correct the error
   316  	RewindTo uint64
   317  }
   318  
   319  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   320  	var rew *big.Int
   321  	switch {
   322  	case storedblock == nil:
   323  		rew = newblock
   324  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   325  		rew = storedblock
   326  	default:
   327  		rew = newblock
   328  	}
   329  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   330  	if rew != nil && rew.Sign() > 0 {
   331  		err.RewindTo = rew.Uint64() - 1
   332  	}
   333  	return err
   334  }
   335  
   336  func (err *ConfigCompatError) Error() string {
   337  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   338  }
   339  
   340  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
   341  // that do not have or require information about the block.
   342  //
   343  // Rules is a one time interface meaning that it shouldn't be used in between transition
   344  // phases.
   345  type Rules struct {
   346  	ChainID                                                 *big.Int
   347  	IsHomestead, IsEIP150, IsEIP155, IsEIP158               bool
   348  	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
   349  	IsYoloV2                                                bool
   350  }
   351  
   352  // Rules ensures c's ChainID is not nil.
   353  func (c *ChainConfig) Rules(num *big.Int) Rules {
   354  	chainID := c.ChainID
   355  	if chainID == nil {
   356  		chainID = new(big.Int)
   357  	}
   358  	return Rules{
   359  		ChainID:          new(big.Int).Set(chainID),
   360  		IsHomestead:      c.IsHomestead(num),
   361  		IsEIP150:         c.IsEIP150(num),
   362  		IsEIP155:         c.IsEIP155(num),
   363  		IsEIP158:         c.IsEIP158(num),
   364  		IsByzantium:      c.IsByzantium(num),
   365  		IsConstantinople: c.IsConstantinople(num),
   366  		IsPetersburg:     c.IsPetersburg(num),
   367  		IsIstanbul:       c.IsIstanbul(num),
   368  		IsYoloV2:         c.IsYoloV2(num),
   369  	}
   370  }