先看一下流程图
首先在你打开console时,系统会帮你做好一些准备,比如说new好miner,worker等
-
入口
可以看到,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()
来源:CSDN
作者:The_Reader
链接:https://blog.csdn.net/The_Reader/article/details/86139571