mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
Poll-based miner
This commit is contained in:
parent
b2d29f9e9a
commit
5b0255f05d
1 changed files with 56 additions and 36 deletions
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
|
@ -50,7 +51,7 @@ type Miner struct {
|
||||||
canStart int32 // can start indicates whether we can start the mining operation
|
canStart int32 // can start indicates whether we can start the mining operation
|
||||||
shouldStart int32 // should start indicates whether we should start after sync
|
shouldStart int32 // should start indicates whether we should start after sync
|
||||||
|
|
||||||
sub event.Subscription
|
sub event.Subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(eth core.Backend, config *core.ChainConfig, mux *event.TypeMux, pow pow.PoW) *Miner {
|
func New(eth core.Backend, config *core.ChainConfig, mux *event.TypeMux, pow pow.PoW) *Miner {
|
||||||
|
|
@ -103,56 +104,75 @@ func (m *Miner) SetGasPrice(price *big.Int) {
|
||||||
|
|
||||||
func (self *Miner) Start(coinbase common.Address, threads int) {
|
func (self *Miner) Start(coinbase common.Address, threads int) {
|
||||||
self.sub = self.mux.Subscribe(core.TxPreEvent{}, core.NewBlockEvent{}, core.NewMinedBlockEvent{})
|
self.sub = self.mux.Subscribe(core.TxPreEvent{}, core.NewBlockEvent{}, core.NewMinedBlockEvent{})
|
||||||
go self.filterLoop(coinbase, threads)
|
//go self.filterLoop(coinbase, threads)
|
||||||
|
go self.runLoop(coinbase, threads)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Miner) runLoop(coinbase common.Address, threads int) {
|
||||||
|
for true {
|
||||||
|
if len(self.worker.txQueue) == 0 {
|
||||||
|
if self.Mining() {
|
||||||
|
glog.V(logger.Info).Infoln("Nothing to do. The miner sleeps.")
|
||||||
|
self.Stop()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if self.Mining() == false {
|
||||||
|
glog.V(logger.Info).Infoln("A transaction awaits! Waking up miner.")
|
||||||
|
self.Start(coinbase, threads)
|
||||||
|
}
|
||||||
|
time.Sleep(3000 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) filterLoop(coinbase common.Address, threads int) {
|
func (self *Miner) filterLoop(coinbase common.Address, threads int) {
|
||||||
for event := range self.sub.Chan() {
|
for event := range self.sub.Chan() {
|
||||||
switch event.Data.(type) {
|
switch event.Data.(type) {
|
||||||
case core.TxPreEvent:
|
case core.TxPreEvent:
|
||||||
glog.V(logger.Info).Infoln("New pending tranny yo, start mining!")
|
glog.V(logger.Info).Infoln("New pending tranny yo, start mining!")
|
||||||
self.actuallyStart(coinbase, threads)
|
self.actuallyStart(coinbase, threads)
|
||||||
case core.NewBlockEvent:
|
case core.NewBlockEvent:
|
||||||
glog.V(logger.Info).Infoln("New block event")
|
glog.V(logger.Info).Infoln("New block event")
|
||||||
self.Stop()
|
self.Stop()
|
||||||
self.Start(coinbase, threads)
|
self.Start(coinbase, threads)
|
||||||
case core.NewMinedBlockEvent:
|
case core.NewMinedBlockEvent:
|
||||||
glog.V(logger.Info).Infoln("New MINED block event")
|
glog.V(logger.Info).Infoln("New MINED block event")
|
||||||
self.Stop()
|
self.Stop()
|
||||||
self.Start(coinbase, threads)
|
self.Start(coinbase, threads)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) actuallyStart(coinbase common.Address, threads int) {
|
func (self *Miner) actuallyStart(coinbase common.Address, threads int) {
|
||||||
atomic.StoreInt32(&self.shouldStart, 1)
|
atomic.StoreInt32(&self.shouldStart, 1)
|
||||||
self.threads = threads
|
self.threads = threads
|
||||||
self.worker.coinbase = coinbase
|
self.worker.coinbase = coinbase
|
||||||
self.coinbase = coinbase
|
self.coinbase = coinbase
|
||||||
|
|
||||||
if atomic.LoadInt32(&self.canStart) == 0 {
|
if atomic.LoadInt32(&self.canStart) == 0 {
|
||||||
glog.V(logger.Info).Infoln("Can not start mining operation due to network sync (starts when finished)")
|
glog.V(logger.Info).Infoln("Can not start mining operation due to network sync (starts when finished)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic.StoreInt32(&self.mining, 1)
|
atomic.StoreInt32(&self.mining, 1)
|
||||||
|
|
||||||
for i := 0; i < threads; i++ {
|
for i := 0; i < threads; i++ {
|
||||||
self.worker.register(NewCpuAgent(i, self.pow))
|
self.worker.register(NewCpuAgent(i, self.pow))
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.V(logger.Info).Infof("Starting mining operation (CPU=%d TOT=%d)\n", threads, len(self.worker.agents))
|
glog.V(logger.Info).Infof("Starting mining operation (CPU=%d TOT=%d)\n", threads, len(self.worker.agents))
|
||||||
|
|
||||||
self.worker.start()
|
self.worker.start()
|
||||||
|
|
||||||
self.worker.commitNewWork()
|
self.worker.commitNewWork()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Miner) Stop() {
|
func (self *Miner) Stop() {
|
||||||
if(self.sub != nil) {
|
if self.sub != nil {
|
||||||
self.sub.Unsubscribe();
|
self.sub.Unsubscribe()
|
||||||
}
|
}
|
||||||
self.worker.stop()
|
self.worker.stop()
|
||||||
atomic.StoreInt32(&self.mining, 0)
|
atomic.StoreInt32(&self.mining, 0)
|
||||||
atomic.StoreInt32(&self.shouldStart, 0)
|
atomic.StoreInt32(&self.shouldStart, 0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue