github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/params/config.go (about)

     1  package params
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  
     7  	"github.com/neatlab/neatio/chain/log"
     8  
     9  	"github.com/neatlab/neatio/utilities/common"
    10  	"github.com/neatlab/neatio/utilities/crypto"
    11  )
    12  
    13  var (
    14  	MainnetGenesisHash = common.HexToHash("0x2819c8cb1eae983ff4da7019a99a7aca7db9e08741c53dcd7c4a7017d0a299f7")
    15  	TestnetGenesisHash = common.HexToHash("0x473e0300dc12441d4d7450033a4ca4ba5c003547f6ffb7ef6cdeb2d02f475c39")
    16  )
    17  
    18  var (
    19  	MainnetChainConfig = &ChainConfig{
    20  		NeatChainId:         "neatio",
    21  		ChainId:             big.NewInt(515),
    22  		HomesteadBlock:      big.NewInt(0),
    23  		EIP150Block:         big.NewInt(0),
    24  		EIP150Hash:          common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
    25  		EIP155Block:         big.NewInt(0),
    26  		EIP158Block:         big.NewInt(0),
    27  		ByzantiumBlock:      big.NewInt(0),
    28  		PetersburgBlock:     big.NewInt(0),
    29  		IstanbulBlock:       big.NewInt(0),
    30  		ConstantinopleBlock: nil,
    31  		NeatCon: &NeatConConfig{
    32  			Epoch:          30000,
    33  			ProposerPolicy: 0,
    34  		},
    35  	}
    36  
    37  	TestnetChainConfig = &ChainConfig{
    38  		NeatChainId:         "testnet",
    39  		ChainId:             big.NewInt(525),
    40  		HomesteadBlock:      big.NewInt(0),
    41  		EIP150Block:         big.NewInt(0),
    42  		EIP150Hash:          common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
    43  		EIP155Block:         big.NewInt(0),
    44  		EIP158Block:         big.NewInt(0),
    45  		ByzantiumBlock:      big.NewInt(0),
    46  		PetersburgBlock:     big.NewInt(0),
    47  		IstanbulBlock:       big.NewInt(0),
    48  		ConstantinopleBlock: nil,
    49  		NeatCon: &NeatConConfig{
    50  			Epoch:          30000,
    51  			ProposerPolicy: 0,
    52  		},
    53  	}
    54  
    55  	TestChainConfig = &ChainConfig{"", big.NewInt(1), big.NewInt(0), big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil}
    56  	TestRules       = TestChainConfig.Rules(new(big.Int))
    57  )
    58  
    59  func init() {
    60  
    61  }
    62  
    63  type ChainConfig struct {
    64  	NeatChainId string   `json:"neatChainId"`
    65  	ChainId     *big.Int `json:"chainId"`
    66  
    67  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"`
    68  
    69  	EIP150Block *big.Int    `json:"eip150Block,omitempty"`
    70  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`
    71  
    72  	EIP155Block *big.Int `json:"eip155Block,omitempty"`
    73  	EIP158Block *big.Int `json:"eip158Block,omitempty"`
    74  
    75  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`
    76  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"`
    77  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`
    78  	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`
    79  
    80  	NeatCon *NeatConConfig `json:"neatcon,omitempty"`
    81  
    82  	ChainLogger log.Logger `json:"-"`
    83  }
    84  
    85  type NeatConConfig struct {
    86  	Epoch          uint64 `json:"epoch"`
    87  	ProposerPolicy uint64 `json:"policy"`
    88  }
    89  
    90  func (c *NeatConConfig) String() string {
    91  	return "neatcon"
    92  }
    93  
    94  func NewSideChainConfig(sideChainID string) *ChainConfig {
    95  	config := &ChainConfig{
    96  		NeatChainId:         sideChainID,
    97  		HomesteadBlock:      big.NewInt(0),
    98  		EIP150Block:         big.NewInt(0),
    99  		EIP150Hash:          common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
   100  		EIP155Block:         big.NewInt(0),
   101  		EIP158Block:         big.NewInt(0),
   102  		ByzantiumBlock:      big.NewInt(0),
   103  		ConstantinopleBlock: big.NewInt(0),
   104  		PetersburgBlock:     big.NewInt(0),
   105  		IstanbulBlock:       big.NewInt(0),
   106  		NeatCon: &NeatConConfig{
   107  			Epoch:          30000,
   108  			ProposerPolicy: 0,
   109  		},
   110  	}
   111  
   112  	digest := crypto.Keccak256([]byte(config.NeatChainId))
   113  	config.ChainId = new(big.Int).SetBytes(digest[:])
   114  
   115  	return config
   116  }
   117  
   118  func (c *ChainConfig) String() string {
   119  	var engine interface{}
   120  	switch {
   121  	case c.NeatCon != nil:
   122  		engine = c.NeatCon
   123  	default:
   124  		engine = "unknown"
   125  	}
   126  	return fmt.Sprintf("{NeatChainId: %s ChainID: %v Homestead: %v  EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v Engine: %v}",
   127  		c.NeatChainId,
   128  		c.ChainId,
   129  		c.HomesteadBlock,
   130  		c.EIP150Block,
   131  		c.EIP155Block,
   132  		c.EIP158Block,
   133  		c.ByzantiumBlock,
   134  		c.ConstantinopleBlock,
   135  		c.PetersburgBlock,
   136  		c.IstanbulBlock,
   137  		engine,
   138  	)
   139  }
   140  
   141  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   142  	return isForked(c.HomesteadBlock, num)
   143  }
   144  
   145  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   146  	return isForked(c.EIP150Block, num)
   147  }
   148  
   149  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   150  	return isForked(c.EIP155Block, num)
   151  }
   152  
   153  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   154  	return isForked(c.EIP158Block, num)
   155  }
   156  
   157  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   158  	return isForked(c.ByzantiumBlock, num)
   159  }
   160  
   161  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   162  	return isForked(c.ConstantinopleBlock, num)
   163  }
   164  
   165  func (c *ChainConfig) IsPetersburg(num *big.Int) bool {
   166  	return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num)
   167  }
   168  
   169  func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
   170  	return isForked(c.IstanbulBlock, num)
   171  }
   172  
   173  func (c *ChainConfig) IsEWASM(num *big.Int) bool {
   174  	return false
   175  }
   176  
   177  func (c *ChainConfig) IsMainChain() bool {
   178  	return c.NeatChainId == MainnetChainConfig.NeatChainId || c.NeatChainId == TestnetChainConfig.NeatChainId
   179  }
   180  
   181  func IsMainChain(chainId string) bool {
   182  	return chainId == MainnetChainConfig.NeatChainId || chainId == TestnetChainConfig.NeatChainId
   183  }
   184  
   185  func (c *ChainConfig) GasTable(num *big.Int) GasTable {
   186  	if num == nil {
   187  		return GasTableHomestead
   188  	}
   189  	switch {
   190  	case c.IsEIP158(num):
   191  		return GasTableEIP158
   192  	case c.IsEIP150(num):
   193  		return GasTableEIP150
   194  	default:
   195  		return GasTableHomestead
   196  	}
   197  }
   198  
   199  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   200  	bhead := new(big.Int).SetUint64(height)
   201  
   202  	var lasterr *ConfigCompatError
   203  	for {
   204  		err := c.checkCompatible(newcfg, bhead)
   205  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   206  			break
   207  		}
   208  		lasterr = err
   209  		bhead.SetUint64(err.RewindTo)
   210  	}
   211  	return lasterr
   212  }
   213  
   214  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   215  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   216  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   217  	}
   218  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   219  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   220  	}
   221  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   222  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   223  	}
   224  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   225  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   226  	}
   227  	if c.IsEIP158(head) && !configNumEqual(c.ChainId, newcfg.ChainId) {
   228  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   229  	}
   230  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   231  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   232  	}
   233  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   234  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   235  	}
   236  	if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) {
   237  		return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   238  	}
   239  	if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) {
   240  		return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
   241  	}
   242  	return nil
   243  }
   244  
   245  func isForkIncompatible(s1, s2, head *big.Int) bool {
   246  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   247  }
   248  
   249  func isForked(s, head *big.Int) bool {
   250  	if s == nil || head == nil {
   251  		return false
   252  	}
   253  	return s.Cmp(head) <= 0
   254  }
   255  
   256  func configNumEqual(x, y *big.Int) bool {
   257  	if x == nil {
   258  		return y == nil
   259  	}
   260  	if y == nil {
   261  		return x == nil
   262  	}
   263  	return x.Cmp(y) == 0
   264  }
   265  
   266  type ConfigCompatError struct {
   267  	What string
   268  
   269  	StoredConfig, NewConfig *big.Int
   270  
   271  	RewindTo uint64
   272  }
   273  
   274  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   275  	var rew *big.Int
   276  	switch {
   277  	case storedblock == nil:
   278  		rew = newblock
   279  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   280  		rew = storedblock
   281  	default:
   282  		rew = newblock
   283  	}
   284  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   285  	if rew != nil && rew.Sign() > 0 {
   286  		err.RewindTo = rew.Uint64() - 1
   287  	}
   288  	return err
   289  }
   290  
   291  func (err *ConfigCompatError) Error() string {
   292  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   293  }
   294  
   295  type Rules struct {
   296  	ChainId                                                 *big.Int
   297  	IsHomestead, IsEIP150, IsEIP155, IsEIP158               bool
   298  	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
   299  }
   300  
   301  func (c *ChainConfig) Rules(num *big.Int) Rules {
   302  	chainId := c.ChainId
   303  	if chainId == nil {
   304  		chainId = new(big.Int)
   305  	}
   306  	return Rules{
   307  		ChainId:          new(big.Int).Set(chainId),
   308  		IsHomestead:      c.IsHomestead(num),
   309  		IsEIP150:         c.IsEIP150(num),
   310  		IsEIP155:         c.IsEIP155(num),
   311  		IsEIP158:         c.IsEIP158(num),
   312  		IsByzantium:      c.IsByzantium(num),
   313  		IsConstantinople: c.IsConstantinople(num),
   314  		IsPetersburg:     c.IsPetersburg(num),
   315  		IsIstanbul:       c.IsIstanbul(num),
   316  	}
   317  }