以太坊小知识(二)——区块生成机制

下面的代码都是基于go-ethereum v1.6.7。

Q:以太坊go-ethereum中,当一个miner找到一个新区块时,会将结果Result发送到管道returnCh中。那接下来的逻辑是怎样的呢?

//miner/agent.go
func (self *CpuAgent) mine(work *Work, stop <-chan struct{}) {
    if result, err := self.engine.Seal(self.chain, work.Block, stop); result != nil {
        log.Info("Successfully sealed new block", "number", result.Number(), "hash", result.Hash())
        //send操作
        self.returnCh <- &Result{work, result}
    } else {
        //...
    }
}

那是否有miners监听该管道returnCh呢?答案是:Yes!worker的wait方法一直迭代管道recv。只要拿到不为nil的数据,则将新区块写入本地数据库中,同时发送事件NewMinedBlockEvent。

下面负责持久化,发送相应事件等功能的协程一直处于阻塞之中。

//miner/worker.go
func (self *worker) wait() {
    for {
        mustCommitNewWork := true
        for result := range self.recv {  //从self实例的管道中接收结果
            atomic.AddInt32(&self.atWork, -1)

        if result == nil {
            continue
        }
        block := result.Block
        work := result.Work

        if self.fullValidation {
            //...
            go self.mux.Post(core.NewMinedBlockEvent{Block: block}) //发送事件NewMinedBlockEvent
        } else {
        //...
            stat, err := self.chain.WriteBlock(block)  //持久化新区块到本地数据库中
        //...
            }
            //...
            // broadcast before waiting for validation
            go func(block *types.Block, logs []*types.Log, receipts []*types.Receipt) {
                self.mux.Post(core.NewMinedBlockEvent{Block: block}) //发送NewMinedBlockEvent事件,/eth/handler.go#(pm *ProtocolManager) Start()方法会订阅该事件并同时开一个协程【go pm.minedBroadcastLoop()】监听该事件
                self.mux.Post(core.ChainEvent{Block: block, Hash: block.Hash(), Logs: logs})

                if stat == core.CanonStatTy {
                    self.mux.Post(core.ChainHeadEvent{Block: block}) //发送ChainHeadEvent事件,/miner/worker.go#(self *worker) update() 方法会读取该事件
                    self.mux.Post(logs)
                }
                //...
            }(block, work.state.Logs(), work.receipts) //匿名函数调用
        }
        // Insert the block into the set of pending ones to wait for confirmations
        //矿工将自己开采的区块放进一个循环列表中,待达到五个确认后,再移除
        
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值