mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
miner: expose consensus engine running status to miner
This commit is contained in:
parent
32555698dd
commit
ecafffbb35
3 changed files with 30 additions and 34 deletions
|
|
@ -18,10 +18,10 @@ package miner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CpuAgent struct {
|
type CpuAgent struct {
|
||||||
|
|
@ -35,27 +35,39 @@ type CpuAgent struct {
|
||||||
chain consensus.ChainReader
|
chain consensus.ChainReader
|
||||||
engine consensus.Engine
|
engine consensus.Engine
|
||||||
|
|
||||||
isMining int32 // isMining indicates whether the agent is currently mining
|
started int32 // started indicates whether the agent is currently started
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCpuAgent(chain consensus.ChainReader, engine consensus.Engine) *CpuAgent {
|
func NewCpuAgent(chain consensus.ChainReader, engine consensus.Engine) *CpuAgent {
|
||||||
miner := &CpuAgent{
|
agent := &CpuAgent{
|
||||||
chain: chain,
|
chain: chain,
|
||||||
engine: engine,
|
engine: engine,
|
||||||
stop: make(chan struct{}, 1),
|
stop: make(chan struct{}, 1),
|
||||||
workCh: make(chan *Work, 1),
|
workCh: make(chan *Work, 1),
|
||||||
}
|
}
|
||||||
return miner
|
return agent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CpuAgent) Work() chan<- *Work { return self.workCh }
|
func (self *CpuAgent) Work() chan<- *Work { return self.workCh }
|
||||||
func (self *CpuAgent) SetReturnCh(ch chan<- *Result) { self.returnCh = ch }
|
func (self *CpuAgent) SetReturnCh(ch chan<- *Result) { self.returnCh = ch }
|
||||||
|
|
||||||
|
func (self *CpuAgent) Start() {
|
||||||
|
if !atomic.CompareAndSwapInt32(&self.started, 0, 1) {
|
||||||
|
return // agent already started
|
||||||
|
}
|
||||||
|
go self.update()
|
||||||
|
}
|
||||||
|
|
||||||
func (self *CpuAgent) Stop() {
|
func (self *CpuAgent) Stop() {
|
||||||
if !atomic.CompareAndSwapInt32(&self.isMining, 1, 0) {
|
if !atomic.CompareAndSwapInt32(&self.started, 1, 0) {
|
||||||
return // agent already stopped
|
return // agent already stopped
|
||||||
}
|
}
|
||||||
self.stop <- struct{}{}
|
// Close the pending routines.
|
||||||
|
select {
|
||||||
|
case self.stop <- struct{}{}:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
// Empty work channel
|
// Empty work channel
|
||||||
for {
|
for {
|
||||||
|
|
@ -67,13 +79,6 @@ done:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CpuAgent) Start() {
|
|
||||||
if !atomic.CompareAndSwapInt32(&self.isMining, 0, 1) {
|
|
||||||
return // agent already started
|
|
||||||
}
|
|
||||||
go self.update()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *CpuAgent) update() {
|
func (self *CpuAgent) update() {
|
||||||
out:
|
out:
|
||||||
for {
|
for {
|
||||||
|
|
@ -103,7 +108,7 @@ func (self *CpuAgent) mine(work *Work, stop <-chan struct{}) {
|
||||||
log.Info("Successfully sealed new block", "number", result.Number(), "hash", result.Hash())
|
log.Info("Successfully sealed new block", "number", result.Number(), "hash", result.Hash())
|
||||||
self.returnCh <- &Result{work, result}
|
self.returnCh <- &Result{work, result}
|
||||||
} else {
|
} else {
|
||||||
if err != nil {
|
if err != nil && err != consensus.ErrEngineNotStart {
|
||||||
log.Warn("Block sealing failed", "err", err)
|
log.Warn("Block sealing failed", "err", err)
|
||||||
}
|
}
|
||||||
self.returnCh <- nil
|
self.returnCh <- nil
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,8 @@ type Backend interface {
|
||||||
// Miner creates blocks and searches for proof-of-work values.
|
// Miner creates blocks and searches for proof-of-work values.
|
||||||
type Miner struct {
|
type Miner struct {
|
||||||
mux *event.TypeMux
|
mux *event.TypeMux
|
||||||
|
|
||||||
worker *worker
|
worker *worker
|
||||||
|
|
||||||
coinbase common.Address
|
coinbase common.Address
|
||||||
mining int32
|
|
||||||
eth Backend
|
eth Backend
|
||||||
engine consensus.Engine
|
engine consensus.Engine
|
||||||
|
|
||||||
|
|
@ -111,23 +108,19 @@ func (self *Miner) Start(coinbase common.Address) {
|
||||||
log.Info("Network syncing, will start miner afterwards")
|
log.Info("Network syncing, will start miner afterwards")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
atomic.StoreInt32(&self.mining, 1)
|
|
||||||
|
|
||||||
log.Info("Starting mining operation")
|
log.Info("Starting mining operation")
|
||||||
|
self.engine.Start()
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
self.worker.commitNewWork()
|
self.worker.commitNewWork()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) Stop() {
|
func (self *Miner) Stop() {
|
||||||
|
self.engine.Stop()
|
||||||
self.worker.stop()
|
self.worker.stop()
|
||||||
atomic.StoreInt32(&self.mining, 0)
|
|
||||||
atomic.StoreInt32(&self.shouldStart, 0)
|
atomic.StoreInt32(&self.shouldStart, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) Register(agent Agent) {
|
func (self *Miner) Register(agent Agent) {
|
||||||
if self.Mining() {
|
|
||||||
agent.Start()
|
|
||||||
}
|
|
||||||
self.worker.register(agent)
|
self.worker.register(agent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,7 +129,7 @@ func (self *Miner) Unregister(agent Agent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) Mining() bool {
|
func (self *Miner) Mining() bool {
|
||||||
return atomic.LoadInt32(&self.mining) > 0
|
return self.engine.IsRunning()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) HashRate() (tot int64) {
|
func (self *Miner) HashRate() (tot int64) {
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,8 @@ const (
|
||||||
type Agent interface {
|
type Agent interface {
|
||||||
Work() chan<- *Work
|
Work() chan<- *Work
|
||||||
SetReturnCh(chan<- *Result)
|
SetReturnCh(chan<- *Result)
|
||||||
Stop()
|
|
||||||
Start()
|
Start()
|
||||||
|
Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Work is the workers current environment and holds
|
// Work is the workers current environment and holds
|
||||||
|
|
@ -231,6 +231,7 @@ func (self *worker) register(agent Agent) {
|
||||||
defer self.mu.Unlock()
|
defer self.mu.Unlock()
|
||||||
self.agents[agent] = struct{}{}
|
self.agents[agent] = struct{}{}
|
||||||
agent.SetReturnCh(self.recv)
|
agent.SetReturnCh(self.recv)
|
||||||
|
agent.Start()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *worker) unregister(agent Agent) {
|
func (self *worker) unregister(agent Agent) {
|
||||||
|
|
@ -342,9 +343,6 @@ func (self *worker) wait() {
|
||||||
|
|
||||||
// push sends a new work task to currently live miner agents.
|
// push sends a new work task to currently live miner agents.
|
||||||
func (self *worker) push(work *Work) {
|
func (self *worker) push(work *Work) {
|
||||||
if atomic.LoadInt32(&self.mining) != 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for agent := range self.agents {
|
for agent := range self.agents {
|
||||||
atomic.AddInt32(&self.atWork, 1)
|
atomic.AddInt32(&self.atWork, 1)
|
||||||
if ch := agent.Work(); ch != nil {
|
if ch := agent.Work(); ch != nil {
|
||||||
|
|
@ -415,8 +413,8 @@ func (self *worker) commitNewWork() {
|
||||||
Extra: self.extra,
|
Extra: self.extra,
|
||||||
Time: big.NewInt(tstamp),
|
Time: big.NewInt(tstamp),
|
||||||
}
|
}
|
||||||
// Only set the coinbase if we are mining (avoid spurious block rewards)
|
// Only set the coinbase if our consensus engine is running (avoid spurious block rewards)
|
||||||
if atomic.LoadInt32(&self.mining) == 1 {
|
if self.engine.IsRunning() {
|
||||||
header.Coinbase = self.coinbase
|
header.Coinbase = self.coinbase
|
||||||
}
|
}
|
||||||
if err := self.engine.Prepare(self.chain, header); err != nil {
|
if err := self.engine.Prepare(self.chain, header); err != nil {
|
||||||
|
|
@ -479,7 +477,7 @@ func (self *worker) commitNewWork() {
|
||||||
// Push empty work in advance without applying pending transaction.
|
// Push empty work in advance without applying pending transaction.
|
||||||
// The reason is transactions execution can cost a lot and sealer need to
|
// The reason is transactions execution can cost a lot and sealer need to
|
||||||
// take advantage of this part time.
|
// take advantage of this part time.
|
||||||
if atomic.LoadInt32(&self.mining) == 1 {
|
if self.engine.IsRunning() {
|
||||||
log.Info("Commit new empty mining work", "number", work.Block.Number(), "uncles", len(uncles))
|
log.Info("Commit new empty mining work", "number", work.Block.Number(), "uncles", len(uncles))
|
||||||
}
|
}
|
||||||
self.push(work)
|
self.push(work)
|
||||||
|
|
@ -500,7 +498,7 @@ func (self *worker) commitNewWork() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// We only care about logging if we're actually mining.
|
// We only care about logging if we're actually mining.
|
||||||
if atomic.LoadInt32(&self.mining) == 1 {
|
if self.engine.IsRunning() {
|
||||||
log.Info("Commit new full mining work", "number", work.Block.Number(), "txs", work.tcount, "uncles", len(uncles), "elapsed", common.PrettyDuration(time.Since(tstart)))
|
log.Info("Commit new full mining work", "number", work.Block.Number(), "txs", work.tcount, "uncles", len(uncles), "elapsed", common.PrettyDuration(time.Since(tstart)))
|
||||||
self.unconfirmed.Shift(work.Block.NumberU64() - 1)
|
self.unconfirmed.Shift(work.Block.NumberU64() - 1)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue