以太坊挖矿源码分析

戏子无情 提交于 2019-12-23 10:59:50

先看一下流程图

首先在你打开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()

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!