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