Filecoin技术架构分析之十四:服务层链同步、共识协议及挖矿

[复制链接]
12821 |0
发表于 2019-5-8 11:59:56 | 显示全部楼层 |阅读模式
目录14.filecoin源码分析之服务层链同步、共识协议及挖矿
14.4.1 消息池
14.4.2 钱包
14.3.1 挖矿的主要逻辑
14.3.2 其他细节源码简析
14.1.1 基础结构
14.1.2 链同步
14.1.3 链存储
14.1 chain
14.2 consensus
14.3 mining
14.4 服务层之其他服务
14.1 chain同步14.1.1 基础结构TipIndex 定义定义了tipset的基础结构及方法
▼package
chain
▼+TipIndex:struct
[fields]
-mu:sync.Mutex//根据id来获取tipset及其状态根
-tsasByID:tsasByTipSetID//根据父块来获取tipset及其状态根
-tsasByParentsAndHeight:map[string]tsasByTipSetID
[methods]//根据id来获取tipset及其状态根
+Get(tsKeystring):*TipSetAndState,error//根据父块来获取tipset及其状态根
+GetByParentsAndHeight(pKeystring,huint64):[]*TipSetAndState,error//根据Id判断是否有此tipset
+Has(tsKeystring):bool
//根据父块判断是否有此tipset
+HasByParentsAndHeight(pKeystring,huint64):bool
//设置tipset和状态根
+Put(tsas*TipSetAndState):error
[functions]
+NewTipIndex():*TipIndex
▼+TipSetAndState:struct
[fields]
//tipset
+TipSet:types.TipSet//相当于区块的rootcid
+TipSetStateRoot:cid.Cid
14.1.2 链同步chain同步的接口定义
location:chain/syncer.go
▼package
chain
▼+Syncer:interface
[methods]//处理新区块的接口定义
+HandleNewBlocks(ctxcontext.Context,blkCids[]cid.Cid):error
具体接口实现在location:chain/defalut_syncer.go中
特殊情况的错误
location:chain/reorg.go//如果当前区块头不包含在最新的区块头之上时候,会报此错误▼functions
+IsReorg(curHeadtypes.TipSet,newChain[]types.TipSet):bool
14.1.3 链存储其中
Readstore是一个通用接口
Store的设计基本是给ChainSync使用的
location:chain/store.go
▼package
chain
▼constants//用于发布新的区块头的主题"new-head"
+NewHeadTopic
▼variables//创世块的key
+GenesisKey
▼+ReadStore:interface
[methods]//获取历史区块,通过channel实现
+BlockHistory(ctxcontext.Context,tipstypes.TipSet):chaninterface{}//获取创世区块cid
+GenesisCid():cid.Cid//通过cid获取具体的block
+GetBlock(ctxcontext.Context,idcid.Cid):*types.Block,error//通过cid获取具体的block
+GetTipSetAndState(ctxcontext.Context,tsKeystring):*TipSetAndState,error//获取最新区块
+Head():types.TipSet//最新区块变更事件
+HeadEvents():*pubsub.PubSub//最新合约状态
+LatestState(ctxcontext.Context):state.Tree,error//加载chain
+Load(ctxcontext.Context):error//停止
+Stop()//这个接口只是chain同步使用▼+Store:interface
[embedded]
+ReadStore
[methods]
+GetBlocks(ctxcontext.Context,idstypes.SortedCidSet):[]*types.Block,error
+GetTipSetAndStatesByParentsAndHeight(ctxcontext.Context,pTsKeystring,huint64):[]*TipSetAndState,error
+HasAllBlocks(ctxcontext.Context,cs[]cid.Cid):bool
+HasBlock(ctxcontext.Context,ccid.Cid):bool
+HasTipSetAndState(ctxcontext.Context,tsKeystring):bool
+HasTipSetAndStatesWithParentsAndHeight(ctxcontext.Context,pTsKeystring,huint64):bool
//存储并更新最新区块信息
+PutTipSetAndState(ctxcontext.Context,tsas*TipSetAndState):error
+SetHead(ctxcontext.Context,stypes.TipSet):error
14.2 consensus主要功能
提供创建选票方法,验证中奖选票方法,确定最终的tipset
将合法的tipset消息取出,生效actor状态
▼package
consensus
▶imports
▼constants
+ECPrM:uint64
+ECV:uint64
+LookBackParameter
▼variables
+AncestorRoundsNeeded
+ErrInvalidBase
+ErrStateRootMismatch
+ErrUnorderedTipSets
-log
-ticketDomain:*big.Int//Expected实现EC共识▼+Expected:struct
[fields]
//全局功率表
+PwrTableView:PowerTableView
-bstore:blockstore.Blockstore
-cstore:*hamt.CborIpldStore
-genesisCid:cid.Cid
-processor:Processor
-verifier:proofs.Verifier
[methods]//比较两个tipset的权重
+IsHeavier(ctxcontext.Context,a,btypes.TipSet,aSt,bStstate.Tree):bool,error//建立新的tipset
+NewValidTipSet(ctxcontext.Context,blks[]*types.Block):types.TipSet,error//运行状态转换
//1新区块到来的时候出发状态转换(chainsync逻辑)
//2进入后判断tipset的有效性,包括验证选票是否中奖
//3逐一执行消息,切换状态
+RunStateTransition(ctxcontext.Context,tstypes.TipSet,ancestors[]types.TipSet,pStstate.Tree):state.Tree,error//计算tipset权重
+Weight(ctxcontext.Context,tstypes.TipSet,pStstate.Tree):uint64,error
-runMessages(ctxcontext.Context,ststate.Tree,vmsvm.StorageMap,tstypes.TipSet,ancestors[]types.TipSet):state.Tree,error
-validateBlockStructure(ctxcontext.Context,b*types.Block):error
-validateMining(ctxcontext.Context,ststate.Tree,tstypes.TipSet,parentTstypes.TipSet):error
▼+Processor:interface//会被RunStateTransition间接掉用,进行状态切换(生效挖矿成功的tipset消息)
[methods]//从tipset中逐一取出block处理
+ProcessBlock(ctxcontext.Context,ststate.Tree,vmsvm.StorageMap,blk*types.Block,ancestors[]types.TipSet):[]*ApplicationResult,error
+ProcessTipSet(ctxcontext.Context,ststate.Tree,vmsvm.StorageMap,tstypes.TipSet,ancestors[]types.TipSet):*ProcessTipSetResponse,error
▼functions//与白皮书描述一致,按照存储功率出块,用以判断是否中奖
+CompareTicketPower(tickettypes.Signature,minerPoweruint64,totalPoweruint64):bool
//产生随机挑战种子,针对时空证明
+CreateChallengeSeed(parentstypes.TipSet,nullBlkCountuint64):proofs.PoStChallengeSeed,error//生成选票
//用上一个区块的时空证明+矿工地址(目前直接用的矿工地址,issue1054讨论中)生成256bit哈希
+CreateTicket(proofproofs.PoStProof,minerAddraddress.Address):[]byte//判断是否中奖,调用CompareTicketPower
+IsWinningTicket(ctxcontext.Context,bsblockstore.Blockstore,ptvPowerTableView,ststate.Tree,tickettypes.Signature,mineraddress.Address):bool,error//实例化Expected
+NewExpected(cs*hamt.CborIpldStore,bsblockstore.Blockstore,processorProcessor,ptPowerTableView,gCidcid.Cid,verifierproofs.Verifier):Protocol
-init()
14.3 mining14.3.1 挖矿的主要逻辑1 不能将空块最为基准块
2 基于上一个Tipset信息(如果上一个为空块,必须找到空块之前高度最高的Tipset,并记录中间空块数据)和空块数目生成合法的时空证明挑战参数
3 生成时空证明
4 时空证明成功,调用共识协议创建奖票
5 如果奖票中奖,将未打包的消息打包区块
location:mining/working//这里是挖矿逻辑的真正入口//MineimplementstheDefaultWorkersmainminingfunction..//Thereturnedboolindicatesifthisminercreatedanewblockornot.func(w*DefaultWorker)Mine(ctxcontext.Context,basetypes.TipSet,nullBlkCountint,outChchan
14.3.2 其他细节源码简析消息队列(交易消息集)的处理
location:mining/mqueue.go
▼package
mining
▶imports
▼+MessageQueue:struct
[fields]
-senderQueues:queueHeap
[methods]//取出消息切片,即多条消息
+Drain():[]*types.SignedMessage
+Empty():bool
//从队列取出一条消息
+Pop():*types.SignedMessage,bool
[functions]//实例化消息队列
+NewMessageQueue(msgs[]*types.SignedMessage):MessageQueue
-nonceQueue:[]*types.SignedMessage//一些队列的基本操作
//1长度、push、pop功能
//2Less主要是比较两条交易中的Gas价格,大家可以回头看看type中的消息定义,这里不赘述了
//3为什么要提供Less接口,留给大家思索一下,熟悉以太坊的可能一眼就看出了▼-queueHeap:[]nonceQueue
[methods]
+Len():int
+Less(i,jint):bool
+Pop():interface{}
+Push(xinterface{})
+Swap(i,jint)
调度器
入口
node实例会调用NewScheduler创建相关实例并启动挖矿
▼package
mining
▶imports
▼constants
+MineDelayConversionFactor
▼-timingScheduler:struct
[fields]
-isStarted:bool
-mineDelay:time.Duration//查找权重最高的Tipset
-pollHeadFunc:func()types.TipSet//底层的挖矿逻辑,在下面会分析Worker
-worker:Worker
[methods]//判断是否启动挖矿
+IsStarted():bool
//启动挖矿
+Start(miningCtxcontext.Context):chanOutput,*sync.WaitGroup
▼+Scheduler:interface
[methods]
+IsStarted():bool
+Start(miningCtxcontext.Context):chanOutput,*sync.WaitGroup
▼functions
+MineOnce(ctxcontext.Context,wWorker,mdtime.Duration,tstypes.TipSet):Output,error//实例化timingScheduler
+NewScheduler(wWorker,mdtime.Duration,ffunc()types.TipSet):Scheduler
-nextNullBlkCount(prevNullBlkCountint,prevBase,currBasetypes.TipSet):int
打包区块
具体见如下注释,可对应此查阅源码。
location:mining/block_generate.go
▼package
mining
▶imports
▼DefaultWorker*:ctype
[methods]//1如果节点没有产生过有效存储,无法参与挖矿
//2计算区块高度=基准Tipset高度+空块数目
//3取出未打包消息,调用vm执行,生成收据,并更新状态
//4打包区块信息,返回
+Generate(ctxcontext.Context,baseTipSettypes.TipSet,tickettypes.Signature,proofproofs.PoStProof,nullBlockCountuint64):*types.Block,error
14.4 服务层之其他服务14.4.1 消息池location: core/message_pool.go
消息池相关方法
14.4.2 钱包location:./wallet
钱包相关操作方法

gtt2ylkprlc.png

gtt2ylkprlc.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表