1/32兄弟连区Go语言+区块链技术培训以太坊源码分析(19)core-blockchain分析从测试案例来看,blockchain的主要功能点有下面几点.1.import.2.GetLastBlock的功能.3.如果有多条区块链,可以选取其中难度最大的一条作为规范的区块链.4.BadHashes可以手工禁止接受一些区块的hash值.在blocks.go里面.5.如果新配置了BadHashes.那么区块启动的时候会自动禁止并进入有效状态.6.错误的nonce会被拒绝.7.支持Fastimporting.8.LightvsFastvsFullprocessing在处理区块头上面的效果相等.可以看到blockchain的主要功能是维护区块链的状态,包括区块的验证,插入和状态查询.名词解释:什么是规范的区块链因为在区块的创建过程中,可能在短时间内产生一些分叉,在我们的数据库里面记录的其实是一颗区块树.我们会认为其中总难度最高的一条路径认为是我们的规范的区块链.这样有很多区块虽然也能形成区块链,但是不是规范的区块链.数据库结构:2/32区块的hash值和区块头的hash值是同样的么。所谓的区块的Hash值其实就是Header的区块值。//key-value//+代表连接LastHeader最新的区块头HeaderChain中使用LastBlock最新的区块头BlockChain中使用LastFast最新的快速同步的区块头h+num+n-hash用来存储规范的区块链的高度和区块头的hash值h+num+hash-header高度+hash值-区块头h+num+hash+t-td高度+hash值-总难度H+hash-num区块体hash-高度b+num+hash-blockbody高度+hash值-区块体r+num+hash-blockreceipts高度+hash值-区块收据l+hash-transaction/receiptlookupmetadatakey|value|说明|插入|删除|3/32----|---|---------------|-----------|-----------|LastHeader|hash|最新的区块头HeaderChain中使用|当区块被认为是当前最新的一个规范的区块链头|当有了更新的区块链头或者是分叉的兄弟区块链替代了它LastBlock|hash|最新的区块头BlockChain中使用|当区块被认为是当前最新的一个规范的区块链头|当有了更新的区块链头或者是分叉的兄弟区块链替代了它LastFast|hash|最新的区块头BlockChain中使用|当区块被认为是当前最新的规范的区块链头|当有了更新的区块链头或者是分叉的兄弟区块链替代了它h+num+n|hash|用来存储规范的区块链的高度和区块头的hash值在HeaderChain中使用|当区块在规范的区块链中|当区块不在规范的区块链中h+num+hash+t|td|总难度|WriteBlockAndState当验证并执行完一个区块之后(不管是不是规范的)|SetHead方法会调用。这种方法只会在两种情况下被调用,1是当前区块链包含了badhashs,需要删除所有从badhashs开始的区块,2.是当前区块的状态错误,需要Reset到genesis。H+hash|num|区块的高度在HeaderChain中使用|WriteBlockAndState当验证并执行完一个区块之后|SetHead中被调用,同上b+num+hash|blockbody|区块数据|WriteBlockAndStateorInsertReceiptChain|SetHead中被删除,同上r+num+hash|blockreceipts|区块收据|WriteBlockAndStateorInsertReceiptChain|同上l+txHash|{hash,num,TxIndex|交易hash可以找到区块和交易|当区块加入规范的区块链|当区块从规范的区块链移除数据结构//BlockChainrepresentsthecanonicalchaingivenadatabasewithagenesis//block.TheBlockchainmanageschainimports,reverts,chainreorganisations.//BlockChain表示了一个规范的链,这个链通过一个包含了创世区块的数据库指定.BlockChain管理了链的插入,还原,重建等操作.4/32//Importingblocksintotheblockchainhappensaccordingtothesetofrules//definedbythetwostageValidator.Processingofblocksisdoneusingthe//Processorwhichprocessestheincludedtransaction.Thevalidationofthestate//isdoneinthesecondpartoftheValidator.Failingresultsinabortingof//theimport.//插入一个区块需要通过一系列指定的规则指定的两阶段的验证器.//使用Processor来对区块的交易进行处理.状态的验证是第二阶段的验证器.错误将导致插入终止.//TheBlockChainalsohelpsinreturningblocksfrom**any**chainincluded//inthedatabaseaswellasblocksthatrepresentsthecanonicalchain.It's//importanttonotethatGetBlockcanreturnanyblockanddoesnotneedtobe//includedinthecanonicalonewhereasGetBlockByNumberalwaysrepresentsthe//canonicalchain.//需要注意的是GetBlock可能返回任意不在当前规范区块链中的区块,//但是GetBlockByNumber总是返回当前规范区块链中的区块.typeBlockChainstruct{config*params.ChainConfig//chain&networkconfigurationhc*HeaderChain//只包含了区块头的区块链chainDbethdb.Database//底层数据库rmLogsFeedevent.Feed//下面是很多消息通知的组件chainFeedevent.FeedchainSideFeedevent.FeedchainHeadFeedevent.FeedlogsFeedevent.Feed5/32scopeevent.SubscriptionScopegenesisBlock*types.Block//创世区块musync.RWMutex//globalmutexforlockingchainoperationschainmusync.RWMutex//blockchaininsertionlockprocmusync.RWMutex//blockprocessorlockcheckpointint//checkpointcountstowardsthenewcheckpointcurrentBlock*types.Block//Currentheadoftheblockchain当前的区块头currentFastBlock*types.Block//Currentheadofthefast-syncchain(maybeabovetheblockchain!)当前的快速同步的区块头.stateCachestate.Database//Statedatabasetoreusebetweenimports(containsstatecache)bodyCache*lru.Cache//CacheforthemostrecentblockbodiesbodyRLPCache*lru.Cache//CacheforthemostrecentblockbodiesinRLPencodedformatblockCache*lru.Cache//CacheforthemostrecententireblocksfutureBlocks*lru.Cache//futureblocksareblocksaddedforlaterprocessing暂时还不能插入的区块存放位置.quitchanstruct{}//blockchainquitchannelrunningint32//runningmustbecalledatomically//procInterruptmustbeatomicallycalledprocInterruptint32//interruptsignalerforblockprocessingwgsync.WaitGroup//chainprocessingwaitgroupforshuttingdown6/32engineconsensus.Engine//一致性引擎processorProcessor//blockprocessorinterface//区块处理器接口validatorValidator//blockandstatevalidatorinterface//区块和状态验证器接口vmConfigvm.Config//虚拟机的配置badBlocks*lru.Cache//Badblockcache错误区块的缓存.}构造,NewBlockChain使用数据库里面的可用信息构造了一个初始化好的区块链.同时初始化了以太坊默认的验证器和处理器(ValidatorandProcessor)//NewBlockChainreturnsafullyinitialisedblockchainusinginformation//availableinthedatabase.ItinitialisesthedefaultEthereumValidatorand//Processor.funcNewBlockChain(chainDbethdb.Database,config*params.ChainConfig,engineconsensus.Engine,vmConfigvm.Config)(*BlockChain,error){bodyCache,_:=lru.New(bodyCacheLimit)bodyRLPCache,_:=lru.New(bodyCacheLimit)blockCache,_:=lru.New(blockCacheLimit)futureBlocks,_:=lru.New(maxFutureBlocks)badBlocks,_:=lru.New(badBlockLimit)bc:=&BlockChain{7/32config:config,chainDb:chainDb,stateCache:state.NewDatabase(chainDb),quit:make(chanstruct{}),bodyCache:bodyCache,bodyRLPCache:bodyRLPCache,blockCache:blockCache,futureBlocks:futureBlocks,engine:engine,vmConfig:vmConfig,badBlocks:badBlocks,}bc.SetValidator(NewBlockValidator(config,bc,engine))bc.SetProcessor(NewStateProcessor(config,bc,engine))varerrerrorbc.hc,err=NewHeader