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 }