兄弟连区块链技术培训以太坊源码分析(11)eth目前的共识算法pow的整理###eth目前的共识算法pow的整理#####涉及的代码子包主要有consensus,miner,core,geth```/consensus共识算法consensus.go1.Prepare方法2.CalcDifficulty方法:计算工作量3.AccumulateRewards方法:计算每个块的出块奖励4.VerifySeal方法:校验pow的工作量难度是否符合要求,返回nil则通过5.verifyHeader方法:校验区块头是否符合共识规则```/miner挖矿work.gocommitNewWork():提交新的块,新的交易,从交易池中获取未打包的交易,然后提交交易,进行打包__核心代码__:```//Createthecurrentworktaskandcheckanyforktransitionsneededwork:=self.currentifself.config.DAOForkSupport&&self.config.DAOForkBlock!=nil&&self.config.DAOForkBlock.Cmp(header.Number)==0{misc.ApplyDAOHardFork(work.state)}pending,err:=self.eth.TxPool().Pending()iferr!=nil{log.Error("Failedtofetchpendingtransactions","err",err)return}txs:=types.NewTransactionsByPriceAndNonce(self.current.signer,pending)work.commitTransactions(self.mux,txs,self.chain,self.coinbase)```1/69```eth/handler.goNewProtocolManager-->verifyHeader-->VerifySeal```__整条链的运行,打包交易,出块的流程__```/cmd/geth/main.go/mainmakeFullNode-->RegisterEthService-->eth.New-->NewProtocolManager-->verifyHeader-->VerifySeal```#####eth的共识算法pow调用栈详解######核心的逻辑需要从/eth/handler.go/NewProtocolManager方法下开始,关键代码:```manager.downloader=downloader.New(mode,chaindb,manager.eventMux,blockchain,nil,manager.removePeer)validator:=func(header*types.Header)error{returnengine.VerifyHeader(blockchain,header,true)}heighter:=func()uint64{returnblockchain.CurrentBlock().NumberU64()}inserter:=func(blockstypes.Blocks)(int,error){//Iffastsyncisrunning,denyimportingweirdblocksifatomic.LoadUint32(&manager.fastSync)==1{log.Warn("Discardedbadpropagatedblock","number",blocks[0].Number(),"hash",blocks[0].Hash())return0,nil}atomic.StoreUint32(&manager.acceptTxs,1)//Markinitialsyncdoneonanyfetcherimportreturnmanager.blockchain.InsertChain(blocks)}2/69manager.fetcher=fetcher.New(blockchain.GetBlockByHash,validator,manager.BroadcastBlock,heighter,inserter,manager.removePeer)returnmanager,nil```######该方法中生成了一个校验区块头部的对象`validator`######让我们继续跟进`engine.VerifyHeader(blockchain,header,true)`方法:```//VerifyHeadercheckswhetheraheaderconformstotheconsensusrulesofthe//stockEthereumethashengine.func(ethash*Ethash)VerifyHeader(chainconsensus.ChainReader,header*types.Header,sealbool)error{//Ifwe'rerunningafullenginefaking,acceptanyinputasvalidifethash.fakeFull{returnnil}//Shortcircuitiftheheaderisknown,orit'sparentnotnumber:=header.Number.Uint64()ifchain.GetHeader(header.Hash(),number)!=nil{returnnil}parent:=chain.GetHeader(header.ParentHash,number-1)ifparent==nil{returnconsensus.ErrUnknownAncestor}//Sanitycheckspassed,doaproperverificationreturnethash.verifyHeader(chain,header,parent,false,seal)}```######首先看第一个if,它的逻辑判断是如果为true,那么就关闭所有的共识规则校验,紧跟着两个if判断是只要该block的header的hash和number或者上一个header的hash和number存在链上,那么它header的共识规则校验就通过,如果都不通过,那么该区块校验失败跑出错误.如果走到最后一个return,那么就需要做一些其他额外验证```//verifyHeadercheckswhetheraheaderconformstotheconsensusrulesofthe3/69//stockEthereumethashengine.//SeeYPsection4.3.4."BlockHeaderValidity"func(ethash*Ethash)verifyHeader(chainconsensus.ChainReader,header,parent*types.Header,unclebool,seal...