github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/core/block_validator.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2015 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package core
    26  
    27  import (
    28  	"fmt"
    29  
    30  	"github.com/ethereum/go-ethereum/consensus"
    31  	"github.com/ethereum/go-ethereum/core/state"
    32  	"github.com/ethereum/go-ethereum/core/types"
    33  	"github.com/ethereum/go-ethereum/params"
    34  )
    35  
    36  //blockvalidator负责验证块头、uncles和
    37  //已处理状态。
    38  //
    39  //BlockValidator实现验证程序。
    40  type BlockValidator struct {
    41  config *params.ChainConfig //链配置选项
    42  bc     *BlockChain         //规范区块链
    43  engine consensus.Engine    //用于验证的共识引擎
    44  }
    45  
    46  //new block validator返回一个可安全重用的新块验证程序
    47  /*
    48  func newblockvalidator(config*params.chainconfig,区块链*区块链,引擎共识.engine)*blockvalidator
    49   验证程序:=&blockvalidator_
    50    配置:
    51    发动机:发动机,
    52    BC:区块链,
    53   }
    54   返回验证器
    55  */
    56  
    57  func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engine consensus.Engine) *BlockValidator {
    58  	validator := &BlockValidator{
    59  		config: config,
    60  		engine: engine,
    61  		bc:     blockchain,
    62  	}
    63  	return validator
    64  }
    65  func (v *BlockValidator) ValidateDposState(block *types.Block) error {
    66  	header := block.Header()
    67  	localRoot := block.DposCtx().Root()
    68  	remoteRoot := header.DposContext.Root()
    69  	if remoteRoot != localRoot {
    70  		return fmt.Errorf("invalid dpos root (remote: %x local: %x)", remoteRoot, localRoot)
    71  	}
    72  	return nil
    73  }
    74  //validateBody验证给定块的叔叔并验证该块
    75  //头的事务和叔叔根。假定标题已经
    76  //此时已验证。
    77  func (v *BlockValidator) ValidateBody(block *types.Block) error {
    78  //检查块是否已知,如果不知道,它是否可链接
    79  	if v.bc.HasBlockAndState(block.Hash(), block.NumberU64()) {
    80  		return ErrKnownBlock
    81  	}
    82  	if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
    83  		if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) {
    84  			return consensus.ErrUnknownAncestor
    85  		}
    86  		return consensus.ErrPrunedAncestor
    87  	}
    88  //此时知道头的有效性,检查叔叔和事务
    89  	header := block.Header()
    90  	if err := v.engine.VerifyUncles(v.bc, block); err != nil {
    91  		return err
    92  	}
    93  	if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash {
    94  		return fmt.Errorf("uncle root hash mismatch: have %x, want %x", hash, header.UncleHash)
    95  	}
    96  	if hash := types.DeriveSha(block.Transactions()); hash != header.TxHash {
    97  		return fmt.Errorf("transaction root hash mismatch: have %x, want %x", hash, header.TxHash)
    98  	}
    99  	return nil
   100  }
   101  
   102  //validateState验证状态之后发生的各种更改
   103  //过渡,如已用气体量、接收根和状态根
   104  //本身。如果验证成功,则validateState返回数据库批处理
   105  //否则为零,返回错误。
   106  func (v *BlockValidator) ValidateState(block, parent *types.Block, statedb *state.StateDB, receipts types.Receipts, usedGas uint64) error {
   107  	header := block.Header()
   108  	if block.GasUsed() != usedGas {
   109  		return fmt.Errorf("invalid gas used (remote: %d local: %d)", block.GasUsed(), usedGas)
   110  	}
   111  //使用从生成的收据中派生的块验证接收到的块的Bloom。
   112  //对于有效块,应始终验证为真。
   113  	rbloom := types.CreateBloom(receipts)
   114  	if rbloom != header.Bloom {
   115  		return fmt.Errorf("invalid bloom (remote: %x  local: %x)", header.Bloom, rbloom)
   116  	}
   117  //tre receipt trie's root(r=(tr[[h1,r1),……[HN,R1])
   118  	receiptSha := types.DeriveSha(receipts)
   119  	if receiptSha != header.ReceiptHash {
   120  		return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash, receiptSha)
   121  	}
   122  //根据接收到的状态根验证状态根并引发
   123  //如果不匹配则为错误。
   124  	if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
   125  		return fmt.Errorf("invalid merkle root (remote: %x local: %x)", header.Root, root)
   126  	}
   127  	return nil
   128  }
   129  
   130  //CalcGasLimit计算父块后面下一个块的气体限制。
   131  //这是矿工战略,而不是共识协议。
   132  func CalcGasLimit(parent *types.Block) uint64 {
   133  //contrib=(parentgasused*3/2)/1024
   134  	contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor
   135  
   136  //衰变=父气体极限/1024-1
   137  	decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1
   138  
   139   /*
   140    策略:区块到矿井的气限是根据母公司的
   141    气体使用值。如果parentgasused>parentgaslimit*(2/3),那么我们
   142    增加它,否则降低它(或者如果它是正确的话保持不变
   143    使用时)增加/减少的数量取决于距离
   144    来自parentgaslimit*(2/3)parentgasused是。
   145   **/
   146  
   147  	limit := parent.GasLimit() - decay + contrib
   148  	if limit < params.MinGasLimit {
   149  		limit = params.MinGasLimit
   150  	}
   151  //但是,如果我们现在低于目标(TargetGasLimit),我们会增加
   152  //尽可能限制(parentgaslimit/1024-1)
   153  	if limit < params.TargetGasLimit {
   154  		limit = parent.GasLimit() + decay
   155  		if limit > params.TargetGasLimit {
   156  			limit = params.TargetGasLimit
   157  		}
   158  	}
   159  	return limit
   160  }