gitlab.com/aquachain/aquachain@v1.17.16-rc3.0.20221018032414-e3ddf1e1c055/params/config.go (about)

     1  // Copyright 2018 The aquachain Authors
     2  // This file is part of the aquachain library.
     3  //
     4  // The aquachain 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 aquachain 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 aquachain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package params
    18  
    19  import (
    20  	"fmt"
    21  	"math/big"
    22  
    23  	"gitlab.com/aquachain/aquachain/common"
    24  )
    25  
    26  var (
    27  	MainnetGenesisHash  = common.HexToHash("0x381c8d2c3e3bc702533ee504d7621d510339cafd830028337a4b532ff27cd505") // Mainnet genesis hash to enforce below configs on
    28  	TestnetGenesisHash  = common.HexToHash("0xa8773cb7d32b8f7e1b32b0c2c8b735c293b8936dd3760c15afc291a23eb0cf88") // Testnet genesis hash to enforce below configs on
    29  	Testnet2GenesisHash = common.HexToHash("0xde434983d3ada19cd43c44d8ad5511bad01ed12b3cc9a99b1717449a245120df") // Testnet2 genesis hash to enforce below configs on
    30  	EthnetGenesisHash   = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
    31  )
    32  
    33  // KnownHF is the highest hard fork that is known by this version of Aquachain.
    34  const KnownHF = 9
    35  
    36  var (
    37  	// AquachainHF is the map of hard forks (mainnet)
    38  	AquachainHF = ForkMap{
    39  		1: big.NewInt(3600),  // HF1 (difficulty algo) increase min difficulty to the next multiple of 2048
    40  		2: big.NewInt(7200),  // HF2 (difficulty algo) use simple difficulty algo (240 seconds)
    41  		3: big.NewInt(13026), // HF3 (difficulty) increase min difficulty for anticipation of gpu mining
    42  		4: big.NewInt(21800), // HF4 (supply) remove ethereum genesis allocation
    43  		5: big.NewInt(22800), // HF5 (POW) argonated (algo #2) (argon2id)
    44  		6: big.NewInt(36000), // HF6 (difficulty algo) divisor increase
    45  		7: big.NewInt(36050), // HF7 (EIP 155, 158)
    46  		8: nil,               // HF8 (m_cost=16, diff algo, jump diff) // activated with flag
    47  	}
    48  
    49  	// TestnetHF is the map of hard forks (testnet)
    50  	TestnetHF = ForkMap{
    51  		1: big.NewInt(1),   // increase min difficulty to the next multiple of 2048
    52  		2: big.NewInt(2),   // use simple difficulty algo (240 seconds)
    53  		3: big.NewInt(3),   // increase min difficulty for anticipation of gpu mining
    54  		4: big.NewInt(4),   // HF4
    55  		5: big.NewInt(5),   // HF5
    56  		6: big.NewInt(6),   // noop in testnet
    57  		7: big.NewInt(25),  // eip 155, 158
    58  		8: big.NewInt(650), // HF8
    59  	}
    60  
    61  	// Testnet2HF is the map of hard forks (testnet2 private network
    62  	Testnet2HF = ForkMap{
    63  		5: big.NewInt(0),
    64  		6: big.NewInt(0),
    65  		7: big.NewInt(0),
    66  		8: big.NewInt(8),
    67  		9: big.NewInt(19),
    68  	}
    69  
    70  	// Testnet3HF is the map of hard forks (testnet2 private network
    71  	Testnet3HF = ForkMap{
    72  		5: big.NewInt(1),
    73  		6: big.NewInt(0),
    74  		7: big.NewInt(0),
    75  		8: nil,
    76  		9: nil,
    77  	}
    78  
    79  	// TestHF is the map of hard forks (for testing suite)
    80  	TestHF = ForkMap{
    81  		4: big.NewInt(12),
    82  		5: big.NewInt(13),
    83  		7: big.NewInt(30),
    84  	}
    85  
    86  	NoHF = ForkMap{}
    87  )
    88  var (
    89  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    90  	MainnetChainConfig = &ChainConfig{
    91  		ChainId:        big.NewInt(61717561),
    92  		HomesteadBlock: big.NewInt(0),
    93  		EIP150Block:    big.NewInt(0),
    94  		EIP155Block:    AquachainHF[7],
    95  		EIP158Block:    AquachainHF[7],
    96  		ByzantiumBlock: AquachainHF[7],
    97  		Aquahash:       new(AquahashConfig),
    98  		HF:             AquachainHF,
    99  	}
   100  
   101  	// TestnetChainConfig contains the chain parameters to run a node on the Aquachain test network.
   102  	TestnetChainConfig = &ChainConfig{
   103  		ChainId:        big.NewInt(3),
   104  		HomesteadBlock: big.NewInt(0),
   105  		EIP150Block:    big.NewInt(0),
   106  		EIP155Block:    TestnetHF[7],
   107  		EIP158Block:    TestnetHF[7],
   108  		ByzantiumBlock: TestnetHF[7],
   109  		Aquahash:       new(AquahashConfig),
   110  		HF:             TestnetHF,
   111  	}
   112  
   113  	// Testnet2ChainConfig contains the chain parameters to run a node on the Testnet2 test network.
   114  	Testnet2ChainConfig = &ChainConfig{
   115  		ChainId:        big.NewInt(4096),
   116  		HomesteadBlock: big.NewInt(0),
   117  		EIP150Block:    big.NewInt(0),
   118  		EIP155Block:    Testnet2HF[7],
   119  		EIP158Block:    Testnet2HF[7],
   120  		ByzantiumBlock: Testnet2HF[7],
   121  		Aquahash:       new(AquahashConfig),
   122  		HF:             Testnet2HF,
   123  	}
   124  	// Testnet3ChainConfig contains the chain parameters to run a node on the Testnet2 test network.
   125  	Testnet3ChainConfig = &ChainConfig{
   126  		ChainId:        big.NewInt(11110),
   127  		HomesteadBlock: big.NewInt(0),
   128  		EIP150Block:    big.NewInt(0),
   129  		EIP155Block:    Testnet3HF[7],
   130  		EIP158Block:    Testnet3HF[7],
   131  		ByzantiumBlock: Testnet3HF[7],
   132  		Aquahash:       new(AquahashConfig),
   133  		HF:             Testnet3HF,
   134  	}
   135  	EthnetChainConfig = &ChainConfig{
   136  		ChainId:             big.NewInt(1),
   137  		HomesteadBlock:      big.NewInt(1150000),
   138  		DAOForkBlock:        big.NewInt(1920000),
   139  		DAOForkSupport:      true,
   140  		EIP150Block:         big.NewInt(2463000),
   141  		EIP150Hash:          common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
   142  		EIP155Block:         big.NewInt(2675000),
   143  		EIP158Block:         big.NewInt(2675000),
   144  		ByzantiumBlock:      big.NewInt(4370000),
   145  		ConstantinopleBlock: nil,
   146  		Aquahash:            new(AquahashConfig),
   147  		HF:                  NoHF,
   148  	}
   149  
   150  	// AllAquahashProtocolChanges contains every protocol change (EIPs) introduced
   151  	// and accepted by the Aquachain core developers into the Aquahash consensus.
   152  	//
   153  	// This configuration is intentionally not using keyed fields to force anyone
   154  	// adding flags to the config to also have to set these fields.
   155  	AllAquahashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(AquahashConfig), TestHF}
   156  
   157  	TestChainConfig = &ChainConfig{big.NewInt(3), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(AquahashConfig), TestHF}
   158  	TestRules       = TestChainConfig.Rules(new(big.Int))
   159  )
   160  
   161  // ChainConfig is the core config which determines the blockchain settings.
   162  //
   163  // ChainConfig is stored in the database on a per block basis. This means
   164  // that any network, identified by its genesis block, can have its own
   165  // set of configuration options.
   166  type ChainConfig struct {
   167  	ChainId *big.Int `json:"chainId"` // Chain id identifies the current chain and is used for replay protection
   168  
   169  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   170  
   171  	// et junk to remove
   172  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   173  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   174  
   175  	// EIP150 implements the Gas price changes (https://github.com/aquanetwork/EIPs/issues/150)
   176  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   177  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
   178  
   179  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   180  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   181  
   182  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   183  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   184  
   185  	// Various consensus engines
   186  	Aquahash *AquahashConfig `json:"aquahash,omitempty"`
   187  
   188  	// HF Scheduled Maintenance Hardforks
   189  	HF ForkMap `json:"hf,omitempty"`
   190  }
   191  
   192  func GetChainConfig(name string) *ChainConfig {
   193  	switch name {
   194  	default:
   195  		return nil
   196  	case "aqua":
   197  		return MainnetChainConfig
   198  	case "testnet":
   199  		return TestnetChainConfig
   200  	case "testnet2":
   201  		return Testnet2ChainConfig
   202  	case "testnet3":
   203  		return Testnet3ChainConfig
   204  	}
   205  }
   206  
   207  // AquahashConfig is the consensus engine configs for proof-of-work based sealing.
   208  type AquahashConfig struct{}
   209  
   210  // String implements the stringer interface, returning the consensus engine details.
   211  func (c *AquahashConfig) String() string {
   212  	return "aquahash"
   213  }
   214  
   215  // String implements the fmt.Stringer interface.
   216  func (c *ChainConfig) String() string {
   217  	var engine interface{}
   218  	switch {
   219  	case c.Aquahash != nil:
   220  		engine = c.Aquahash
   221  	default:
   222  		engine = "unknown"
   223  	}
   224  	return fmt.Sprintf("{ChainID: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Engine: %v}",
   225  		c.ChainId,
   226  		c.EIP150Block,
   227  		c.EIP155Block,
   228  		c.EIP158Block,
   229  		c.ByzantiumBlock,
   230  		engine,
   231  	)
   232  }
   233  
   234  // IsHomestead returns whether num is either equal to the homestead block or greater.
   235  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   236  	return isForked(c.HomesteadBlock, num)
   237  }
   238  
   239  // IsDAO returns whether num is either equal to the DAO fork block or greater.
   240  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   241  	return isForked(c.DAOForkBlock, num)
   242  }
   243  
   244  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   245  	return isForked(c.EIP150Block, num)
   246  }
   247  
   248  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   249  	return isForked(c.EIP155Block, num)
   250  }
   251  
   252  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   253  	return isForked(c.EIP158Block, num)
   254  }
   255  
   256  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   257  	return isForked(c.ByzantiumBlock, num)
   258  }
   259  
   260  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   261  	return isForked(c.ConstantinopleBlock, num)
   262  }
   263  
   264  // GasTable returns the gas table corresponding to the current phase.
   265  //
   266  // The returned GasTable's fields shouldn't, under any circumstances, be changed.
   267  func (c *ChainConfig) GasTable(num *big.Int) GasTable {
   268  	if num == nil {
   269  		return GasTableHomestead
   270  	}
   271  	switch {
   272  	case c.IsHF(1, num):
   273  		return GasTableHF1
   274  	default:
   275  		return GasTableHomestead
   276  	}
   277  }
   278  
   279  // CheckCompatible checks whether scheduled fork transitions have been imported
   280  // with a mismatching chain configuration.
   281  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   282  	bhead := new(big.Int).SetUint64(height)
   283  
   284  	// Iterate checkCompatible to find the lowest conflict.
   285  	var lasterr *ConfigCompatError
   286  	for {
   287  		err := c.checkCompatible(newcfg, bhead)
   288  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   289  			break
   290  		}
   291  		lasterr = err
   292  		bhead.SetUint64(err.RewindTo)
   293  	}
   294  	return lasterr
   295  }
   296  
   297  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   298  	for i := 1; i < KnownHF; i++ {
   299  		if c.HF[i] == nil && newcfg.HF[i] == nil {
   300  			continue
   301  		}
   302  		if isForkIncompatible(c.HF[i], newcfg.HF[i], head) {
   303  			return newCompatError(fmt.Sprintf("Aquachain HF%v block", i), c.HF[i], newcfg.HF[i])
   304  		}
   305  	}
   306  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   307  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   308  	}
   309  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   310  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   311  	}
   312  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   313  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   314  	}
   315  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   316  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   317  	}
   318  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   319  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   320  	}
   321  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   322  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   323  	}
   324  	if c.IsEIP158(head) && !configNumEqual(c.ChainId, newcfg.ChainId) {
   325  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   326  	}
   327  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   328  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   329  	}
   330  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   331  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   332  	}
   333  	return nil
   334  }
   335  
   336  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   337  // block s2 because head is already past the fork.
   338  func isForkIncompatible(s1, s2, head *big.Int) bool {
   339  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   340  }
   341  
   342  // isForked returns whether a fork scheduled at block s is active at the given head block.
   343  func isForked(s, head *big.Int) bool {
   344  	if s == nil || head == nil {
   345  		return false
   346  	}
   347  	return s.Cmp(head) <= 0
   348  }
   349  
   350  func configNumEqual(x, y *big.Int) bool {
   351  	if x == nil {
   352  		return y == nil
   353  	}
   354  	if y == nil {
   355  		return x == nil
   356  	}
   357  	return x.Cmp(y) == 0
   358  }
   359  
   360  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   361  // ChainConfig that would alter the past.
   362  type ConfigCompatError struct {
   363  	What string
   364  	// block numbers of the stored and new configurations
   365  	StoredConfig, NewConfig *big.Int
   366  	// the block number to which the local chain must be rewound to correct the error
   367  	RewindTo uint64
   368  }
   369  
   370  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   371  	var rew *big.Int
   372  	switch {
   373  	case storedblock == nil:
   374  		rew = newblock
   375  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   376  		rew = storedblock
   377  	default:
   378  		rew = newblock
   379  	}
   380  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   381  	if rew != nil && rew.Sign() > 0 {
   382  		err.RewindTo = rew.Uint64() - 1
   383  	}
   384  	return err
   385  }
   386  
   387  func (err *ConfigCompatError) Error() string {
   388  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   389  }
   390  
   391  // Rules wraps ChainConfig and is merely syntatic sugar or can be used for functions
   392  // that do not have or require information about the block.
   393  //
   394  // Rules is a one time interface meaning that it shouldn't be used in between transition
   395  // phases.
   396  type Rules struct {
   397  	ChainId                                   *big.Int
   398  	IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
   399  	IsByzantium                               bool
   400  }
   401  
   402  func (c *ChainConfig) Rules(num *big.Int) Rules {
   403  	chainId := c.ChainId
   404  	if chainId == nil {
   405  		chainId = new(big.Int)
   406  	}
   407  	return Rules{ChainId: new(big.Int).Set(chainId), IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), IsEIP155: c.IsEIP155(num), IsEIP158: c.IsEIP158(num), IsByzantium: c.IsByzantium(num)}
   408  }