go-ethereum源码分析-miner-挖矿

源码包路径:github.com/ethereum/go-ethereum/miner


A。 Miner.New 创建一个miner对象

  1. 需要启动挖矿cpuagent
  2. 监听事件(订阅sync新块的start,done,failed三个事件)(要注意防止别人dos攻击)一次性的啊
    1. start事件:先关闭miner,记住此时挖矿的标记
    2. done或者failed事件:根据标记启动miner;取消事件订阅(接下来的所有sync消息全部忽略)
  3. 创建worker对象
    1. update :订阅TxPreEvent, blockchain head和side 等事件

      1. chainHeadCh :commitNewWork 提交新的work

      2. chainSide : 记录可能的叔块
      3. TxPreEvent : 收到交易后,如果不在mining,就放到pending池子里面;否在啥都不做
    2. wait() : 接受agent挖矿成功的块
    3. commitNewWork :提交一个打包的任务

A.3.c : commitNewWork 提交一个打包的任务

  1. 计算新块时间戳,如果上一个块时间戳超过当前时间戳,需要等待;如果恶意延后呢?
  2. 调用共识引擎的prepare方法,计算新块难度  (参考.consensus – 共识)
  3. 获取txpool中的pending状态的交易,同一个addr下按照account nonce排序
  4. 再按照账户的gasprice将交易做排序(大堆排序法)
  5. work.commitTransactions - 提交交易

    1. 获取一个当前gasprice最大的交易
    2. state.prepare修改statedb
    3. state快照,执行交易(会修改state), 如果失败则state回滚
    4. 依次循环,直到所有交易处理完(不符合条件的跳过)
  6. 处理叔块相关的打包
  7. 调用共识引擎的Finalize方法,将交易等等打包成块(除了nonce之外的所有信息)

  8. push给挖矿agent,去做”解题“的事情

 

 

A.3.b wait()  接受agent解题成功的块,也就是自己成功的挖了一个块了
  1. 写块数据和state数据
  2. 广播当前挖矿成功的块  NewMinedBlockEvent
  3. 发送 ChainEvent ChainHeadEvent(会触发commitNewWork)
  4. 当前块记录为未确认的块

 

你可能感兴趣的:(golang,grpc,ethereum,区块链,源码分析)