github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/params/config.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:42</date>
    10  //</624450107558858752>
    11  
    12  
    13  package params
    14  
    15  import (
    16  	"fmt"
    17  	"math/big"
    18  
    19  	"github.com/ethereum/go-ethereum/common"
    20  )
    21  
    22  //Genesis散列以强制执行下面的配置。
    23  var (
    24  	MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
    25  	TestnetGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
    26  	RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
    27  )
    28  
    29  var (
    30  //mainnetchainconfig是在主网络上运行节点的链参数。
    31  	MainnetChainConfig = &ChainConfig{
    32  		ChainID:             big.NewInt(1),
    33  		HomesteadBlock:      big.NewInt(1150000),
    34  		DAOForkBlock:        big.NewInt(1920000),
    35  		DAOForkSupport:      true,
    36  		EIP150Block:         big.NewInt(2463000),
    37  		EIP150Hash:          common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    38  		EIP155Block:         big.NewInt(2675000),
    39  		EIP158Block:         big.NewInt(2675000),
    40  		ByzantiumBlock:      big.NewInt(4370000),
    41  		ConstantinopleBlock: nil,
    42  		Ethash:              new(EthashConfig),
    43  	}
    44  
    45  //mainnettrustedcheckpoint包含主网络的轻型客户端受信任检查点。
    46  	MainnetTrustedCheckpoint = &TrustedCheckpoint{
    47  		Name:         "mainnet",
    48  		SectionIndex: 208,
    49  		SectionHead:  common.HexToHash("0x5e9f7696c397d9df8f3b1abda857753575c6f5cff894e1a3d9e1a2af1bd9d6ac"),
    50  		CHTRoot:      common.HexToHash("0x954a63134f6897f015f026387c59c98c4dae7b336610ff5a143455aac9153e9d"),
    51  		BloomRoot:    common.HexToHash("0x8006c5e44b14d90d7cc9cd5fa1cb48cf53697ee3bbbf4b76fdfa70b0242500a9"),
    52  	}
    53  
    54  //testNetChainConfig包含在Ropsten测试网络上运行节点的链参数。
    55  	TestnetChainConfig = &ChainConfig{
    56  		ChainID:             big.NewInt(3),
    57  		HomesteadBlock:      big.NewInt(0),
    58  		DAOForkBlock:        nil,
    59  		DAOForkSupport:      true,
    60  		EIP150Block:         big.NewInt(0),
    61  		EIP150Hash:          common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
    62  		EIP155Block:         big.NewInt(10),
    63  		EIP158Block:         big.NewInt(10),
    64  		ByzantiumBlock:      big.NewInt(1700000),
    65  		ConstantinopleBlock: big.NewInt(4230000),
    66  		Ethash:              new(EthashConfig),
    67  	}
    68  
    69  //TestNetTrustedCheckpoint包含用于Ropsten测试网络的轻型客户端受信任检查点。
    70  	TestnetTrustedCheckpoint = &TrustedCheckpoint{
    71  		Name:         "testnet",
    72  		SectionIndex: 139,
    73  		SectionHead:  common.HexToHash("0x9fad89a5e3b993c8339b9cf2cbbeb72cd08774ea6b71b105b3dd880420c618f4"),
    74  		CHTRoot:      common.HexToHash("0xc815833881989c5d2035147e1a79a33d22cbc5313e104ff01e6ab405bd28b317"),
    75  		BloomRoot:    common.HexToHash("0xd94ee9f3c480858f53ec5d059aebdbb2e8d904702f100875ee59ec5f366e841d"),
    76  	}
    77  
    78  //rinkebychainconfig包含在rinkeby测试网络上运行节点的链参数。
    79  	RinkebyChainConfig = &ChainConfig{
    80  		ChainID:             big.NewInt(4),
    81  		HomesteadBlock:      big.NewInt(1),
    82  		DAOForkBlock:        nil,
    83  		DAOForkSupport:      true,
    84  		EIP150Block:         big.NewInt(2),
    85  		EIP150Hash:          common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
    86  		EIP155Block:         big.NewInt(3),
    87  		EIP158Block:         big.NewInt(3),
    88  		ByzantiumBlock:      big.NewInt(1035301),
    89  		ConstantinopleBlock: big.NewInt(3660663),
    90  		Clique: &CliqueConfig{
    91  			Period: 15,
    92  			Epoch:  30000,
    93  		},
    94  	}
    95  
    96  //rinkeby trusted checkpoint包含rinkeby测试网络的轻型客户端信任检查点。
    97  	RinkebyTrustedCheckpoint = &TrustedCheckpoint{
    98  		Name:         "rinkeby",
    99  		SectionIndex: 105,
   100  		SectionHead:  common.HexToHash("0xec8147d43f936258aaf1b9b9ec91b0a853abf7109f436a23649be809ea43d507"),
   101  		CHTRoot:      common.HexToHash("0xd92703b444846a3db928e87e450770e5d5cbe193131dc8f7c4cf18b4de925a75"),
   102  		BloomRoot:    common.HexToHash("0xff45a6f807138a2cde0cea0c209d9ce5ad8e43ccaae5a7c41af801bb72a1ef96"),
   103  	}
   104  
   105  //AllethashProtocolChanges包含所有引入的协议更改(EIP)
   106  //并被以太坊核心开发者接受进入了ethash共识。
   107  //
   108  //此配置有意不使用键字段强制任何人
   109  //向配置中添加标志也必须设置这些字段。
   110  	AllEthashProtocolChanges = &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), nil, new(EthashConfig), nil}
   111  
   112  //AllCliqueProtocolChanges包含引入的每个协议更改(EIP)
   113  //并被以太坊核心开发者接纳为集团共识。
   114  //
   115  //此配置有意不使用键字段强制任何人
   116  //向配置中添加标志也必须设置这些字段。
   117  	AllCliqueProtocolChanges = &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), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
   118  
   119  	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), nil, new(EthashConfig), nil}
   120  	TestRules       = TestChainConfig.Rules(new(big.Int))
   121  )
   122  
   123  //trustedcheckpoint表示一组后处理的trie根(cht和
   124  //与适当的节索引和头散列关联的。它是
   125  //用于从此检查点开始灯光同步,并避免下载
   126  //整个收割台链,同时仍然能够安全地访问旧的收割台/日志。
   127  type TrustedCheckpoint struct {
   128  	Name         string      `json:"-"`
   129  	SectionIndex uint64      `json:"sectionIndex"`
   130  	SectionHead  common.Hash `json:"sectionHead"`
   131  	CHTRoot      common.Hash `json:"chtRoot"`
   132  	BloomRoot    common.Hash `json:"bloomRoot"`
   133  }
   134  
   135  //chainconfig是决定区块链设置的核心配置。
   136  //
   137  //chainconfig以块为单位存储在数据库中。这意味着
   138  //任何一个网络,通过它的起源块来识别,都可以有它自己的
   139  //一组配置选项。
   140  type ChainConfig struct {
   141  ChainID *big.Int `json:"chainId"` //chainID标识当前链并用于重播保护
   142  
   143  HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` //宅基地开关块(零=无叉,0=已宅基地)
   144  
   145  DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   //道硬叉开关块(零=无叉)
   146  DAOForkSupport bool     `json:"daoForkSupport,omitempty"` //节点是支持还是反对DAO硬叉
   147  
   148  //EIP150实施天然气价格变化(https://github.com/ethereum/eips/issues/150)
   149  EIP150Block *big.Int    `json:"eip150Block,omitempty"` //EIP150 HF模块(零=无拨叉)
   150  EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  //EIP150 HF哈希(仅限于标题客户,因为只有天然气价格发生变化)
   151  
   152  EIP155Block *big.Int `json:"eip155Block,omitempty"` //EIP155高频阻滞
   153  EIP158Block *big.Int `json:"eip158Block,omitempty"` //EIP158高频阻滞
   154  
   155  ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      //拜占庭开关块(nil=无分叉,0=已在拜占庭)
   156  ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` //君士坦丁堡开关块(nil=无叉,0=已激活)
   157  EWASMBlock          *big.Int `json:"ewasmBlock,omitempty"`          //ewasm开关块(nil=无分叉,0=已激活)
   158  
   159  //各种共识引擎
   160  	Ethash *EthashConfig `json:"ethash,omitempty"`
   161  	Clique *CliqueConfig `json:"clique,omitempty"`
   162  }
   163  
   164  //ethashconfig是基于工作证明的密封的共识引擎配置。
   165  type EthashConfig struct{}
   166  
   167  //字符串实现Stringer接口,返回共识引擎详细信息。
   168  func (c *EthashConfig) String() string {
   169  	return "ethash"
   170  }
   171  
   172  //cliqueconfig是基于权威的密封证明的共识引擎配置。
   173  type CliqueConfig struct {
   174  Period uint64 `json:"period"` //要强制执行的块之间的秒数
   175  Epoch  uint64 `json:"epoch"`  //重置投票和检查点的epoch长度
   176  }
   177  
   178  //字符串实现Stringer接口,返回共识引擎详细信息。
   179  func (c *CliqueConfig) String() string {
   180  	return "clique"
   181  }
   182  
   183  //字符串实现fmt.Stringer接口。
   184  func (c *ChainConfig) String() string {
   185  	var engine interface{}
   186  	switch {
   187  	case c.Ethash != nil:
   188  		engine = c.Ethash
   189  	case c.Clique != nil:
   190  		engine = c.Clique
   191  	default:
   192  		engine = "unknown"
   193  	}
   194  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Engine: %v}",
   195  		c.ChainID,
   196  		c.HomesteadBlock,
   197  		c.DAOForkBlock,
   198  		c.DAOForkSupport,
   199  		c.EIP150Block,
   200  		c.EIP155Block,
   201  		c.EIP158Block,
   202  		c.ByzantiumBlock,
   203  		c.ConstantinopleBlock,
   204  		engine,
   205  	)
   206  }
   207  
   208  //is homestead返回num是否等于homestead块或更大。
   209  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   210  	return isForked(c.HomesteadBlock, num)
   211  }
   212  
   213  //IsDaoFork返回num是否等于或大于dao fork块。
   214  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   215  	return isForked(c.DAOForkBlock, num)
   216  }
   217  
   218  //ISEIP150返回num是否等于eip150 fork块或更大。
   219  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   220  	return isForked(c.EIP150Block, num)
   221  }
   222  
   223  //ISEIP155返回num是否等于eip155 fork块或更大。
   224  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   225  	return isForked(c.EIP155Block, num)
   226  }
   227  
   228  //ISEIP158返回num是否等于eip158 fork块或更大。
   229  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   230  	return isForked(c.EIP158Block, num)
   231  }
   232  
   233  //IsByzantium返回num是否等于或大于Byzantium fork块。
   234  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   235  	return isForked(c.ByzantiumBlock, num)
   236  }
   237  
   238  //is constantinople返回num是否等于或大于constantinople fork块。
   239  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   240  	return isForked(c.ConstantinopleBlock, num)
   241  }
   242  
   243  //isewasm返回num是否表示ewasm fork之后的块号
   244  func (c *ChainConfig) IsEWASM(num *big.Int) bool {
   245  	return isForked(c.EWASMBlock, num)
   246  }
   247  
   248  //Gastable返回与当前阶段(宅基地或宅基地重印)对应的气体表。
   249  //
   250  //在任何情况下,返回的加斯塔布尔的字段都不应该更改。
   251  func (c *ChainConfig) GasTable(num *big.Int) GasTable {
   252  	if num == nil {
   253  		return GasTableHomestead
   254  	}
   255  	switch {
   256  	case c.IsConstantinople(num):
   257  		return GasTableConstantinople
   258  	case c.IsEIP158(num):
   259  		return GasTableEIP158
   260  	case c.IsEIP150(num):
   261  		return GasTableEIP150
   262  	default:
   263  		return GasTableHomestead
   264  	}
   265  }
   266  
   267  //检查兼容检查是否已导入计划的分叉转换
   268  //链配置不匹配。
   269  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   270  	bhead := new(big.Int).SetUint64(height)
   271  
   272  //迭代checkCompatible以查找最低的冲突。
   273  	var lasterr *ConfigCompatError
   274  	for {
   275  		err := c.checkCompatible(newcfg, bhead)
   276  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   277  			break
   278  		}
   279  		lasterr = err
   280  		bhead.SetUint64(err.RewindTo)
   281  	}
   282  	return lasterr
   283  }
   284  
   285  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   286  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   287  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   288  	}
   289  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   290  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   291  	}
   292  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   293  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   294  	}
   295  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   296  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   297  	}
   298  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   299  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   300  	}
   301  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   302  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   303  	}
   304  	if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   305  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   306  	}
   307  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   308  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   309  	}
   310  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   311  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   312  	}
   313  	if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
   314  		return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock)
   315  	}
   316  	return nil
   317  }
   318  
   319  //如果无法将在s1上计划的分叉重新计划为,则IsForkCompatible返回true
   320  //阻塞s2,因为头已经过了分叉。
   321  func isForkIncompatible(s1, s2, head *big.Int) bool {
   322  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   323  }
   324  
   325  //isforked返回在块S调度的分叉在给定的头块是否处于活动状态。
   326  func isForked(s, head *big.Int) bool {
   327  	if s == nil || head == nil {
   328  		return false
   329  	}
   330  	return s.Cmp(head) <= 0
   331  }
   332  
   333  func configNumEqual(x, y *big.Int) bool {
   334  	if x == nil {
   335  		return y == nil
   336  	}
   337  	if y == nil {
   338  		return x == nil
   339  	}
   340  	return x.Cmp(y) == 0
   341  }
   342  
   343  //如果本地存储的区块链初始化为
   344  //可以改变过去的chainconfig。
   345  type ConfigCompatError struct {
   346  	What string
   347  //存储和新配置的块编号
   348  	StoredConfig, NewConfig *big.Int
   349  //要更正错误,必须将本地链重绕到的块编号
   350  	RewindTo uint64
   351  }
   352  
   353  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   354  	var rew *big.Int
   355  	switch {
   356  	case storedblock == nil:
   357  		rew = newblock
   358  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   359  		rew = storedblock
   360  	default:
   361  		rew = newblock
   362  	}
   363  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   364  	if rew != nil && rew.Sign() > 0 {
   365  		err.RewindTo = rew.Uint64() - 1
   366  	}
   367  	return err
   368  }
   369  
   370  func (err *ConfigCompatError) Error() string {
   371  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   372  }
   373  
   374  //规则包装了chainconfig,只是语法上的糖分,也可以用于函数
   375  //不包含或不需要有关块的信息的。
   376  //
   377  //规则是一次性接口,这意味着不应在转换之间使用它
   378  //阶段。
   379  type Rules struct {
   380  	ChainID                                   *big.Int
   381  	IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
   382  	IsByzantium, IsConstantinople             bool
   383  }
   384  
   385  //规则确保C的chainID不为零。
   386  func (c *ChainConfig) Rules(num *big.Int) Rules {
   387  	chainID := c.ChainID
   388  	if chainID == nil {
   389  		chainID = new(big.Int)
   390  	}
   391  	return Rules{
   392  		ChainID:          new(big.Int).Set(chainID),
   393  		IsHomestead:      c.IsHomestead(num),
   394  		IsEIP150:         c.IsEIP150(num),
   395  		IsEIP155:         c.IsEIP155(num),
   396  		IsEIP158:         c.IsEIP158(num),
   397  		IsByzantium:      c.IsByzantium(num),
   398  		IsConstantinople: c.IsConstantinople(num),
   399  	}
   400  }
   401