github.com/aquanetwork/aquachain@v1.7.8/params/config.go (about)

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