以太坊挖矿源码分析

先看一下流程图
首先在你打开console时,系统会帮你做好一些准备,比如说new好miner,worker等
以太坊挖矿源码分析
文章图片


  1. 入口
以太坊挖矿源码分析
文章图片

可以看到,miner有6个方法,那么对应的源码中就会有6个api。
在eth包中api.go中,可以看到有以下6个api。
以太坊挖矿源码分析
文章图片

那么接下来,就让我们去仔细看一下这6个api的具体功能实现。
  • miner.start()
//有一个参数,即挖矿所需协程数量 func (api *PrivateMinerAPI) Start(threads *int) error { // Set the number of threads if the seal engine supports it //如果协程个数指针为空那么,那么就new一个 if threads == nil { threads = new(int) //如果协程个数为0,那么就让就指定其为-1,接下来挖矿时就无法开启协程 } else if *threads == 0 { *threads = -1 // Disable the miner from within } type threaded interface {SetThreads(threads int) } //断言 if th, ok := api.e.engine.(threaded); ok { log.Info("Updated mining threads", "threads", *threads) th.SetThreads(*threads) } // Start the miner and return //开始挖矿并返回 //如果没有在Mining if !api.e.IsMining() { // Propagate the initial price point to the transaction pool //上锁 api.e.lock.RLock() //获取gasprice price := api.e.gasPrice //解锁 api.e.lock.RUnlock()//设置阈值 //SetGasPrice()通过交易池所需的最低价格,更新新的交易和降低所有交易到这个阈值及以下 api.e.txPool.SetGasPrice(price) //开始挖矿,有错就返回,无错就进行。 return api.e.StartMining(true) } return nil }

通过设置协程数来挖矿,并做一些所需工作,然后开始进行mining。
startmining(true)
func (s *Ethereum) StartMining(local bool) error { //获取挖矿账户地址 eb, err := s.Etherbase() if err != nil { log.Error("Cannot start mining without etherbase", "err", err) return fmt.Errorf("etherbase missing: %v", err) } //断言engine是否PoA共识引擎 if clique, ok := s.engine.(*clique.Clique); ok { //获取存有该账户的wallet wallet, err := s.accountManager.Find(accounts.Account{Address: eb}) if wallet == nil || err != nil { log.Error("Etherbase account unavailable locally", "err", err) return fmt.Errorf("signer missing: %v", err) }//向引擎中注入私钥,以形成新的块,其就是PoA共识做的前期准备 clique.Authorize(eb, wallet.SignHash) } if local {// If local (CPU) mining is started, we can disable the transaction rejection //如果启动了本地(CPU)挖掘,我们可以禁用事务拒绝 // mechanism introduced to speed sync times. CPU mining on mainnet is ludicrous //同步时间加快机制,cpu挖矿是荒谬的// so no one will ever hit this path, whereas marking sync done on CPU mining // will ensure that private networks work in single miner mode too. //所以没有人会走这条路,而在CPU挖掘上标记同步将确保专用网络也在单矿工模式下工作。 atomic.StoreUint32(&s.protocolManager.acceptTxs, 1) } //开一条协程去挖矿 //eb为矿工地址 go s.miner.Start(eb) return nil }

miner.Start(eb)
func (self *Miner) Start(coinbase common.Address) { //赋值给变量新值,无论以前是什么值 atomic.StoreInt32(&self.shouldStart, 1) //设置worker的coinbase属性 self.worker.setEtherbase(coinbase) //设置miner的coinbase属性 self.coinbase = coinbase //加载canStart指令,这个决定是否可以启动挖掘操作 if atomic.LoadInt32(&self.canStart) == 0 { log.Info("Network syncing, will start miner afterwards") return } //赋值给变量新值,无论以前是什么值 atomic.StoreInt32(&self.mining, 1) log.Info("Starting mining operation") //worker.start self.worker.start() self.worker.commitNewWork() }

worker.start()
func (self *worker) start() { self.mu.Lock() defer self.mu.Unlock() atomic.StoreInt32(&self.mining, 1) // spin up agents for agent := range self.agents { agent.Start() } }

worker.commitnetwork()
【以太坊挖矿源码分析】

    推荐阅读