Changed miner

* Instead of delivering `Work` to the `Worker`, push a complete Block to
  the `Worker` so that each agent can work on their own block.
pull/559/head
obscuren 10 years ago
parent d8e21b39b3
commit a59ea7ce29
  1. 16
      miner/agent.go
  2. 7
      miner/miner.go
  3. 11
      miner/remote_agent.go
  4. 52
      miner/worker.go

@ -1,6 +1,7 @@
package miner package miner
import ( import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/pow"
) )
@ -9,7 +10,7 @@ type CpuMiner struct {
c chan *types.Block c chan *types.Block
quit chan struct{} quit chan struct{}
quitCurrentOp chan struct{} quitCurrentOp chan struct{}
returnCh chan<- Work returnCh chan<- *types.Block
index int index int
pow pow.PoW pow pow.PoW
@ -24,9 +25,9 @@ func NewCpuMiner(index int, pow pow.PoW) *CpuMiner {
return miner return miner
} }
func (self *CpuMiner) Work() chan<- *types.Block { return self.c } func (self *CpuMiner) Work() chan<- *types.Block { return self.c }
func (self *CpuMiner) Pow() pow.PoW { return self.pow } func (self *CpuMiner) Pow() pow.PoW { return self.pow }
func (self *CpuMiner) SetWorkCh(ch chan<- Work) { self.returnCh = ch } func (self *CpuMiner) SetReturnCh(ch chan<- *types.Block) { self.returnCh = ch }
func (self *CpuMiner) Stop() { func (self *CpuMiner) Stop() {
close(self.quit) close(self.quit)
@ -74,9 +75,12 @@ done:
func (self *CpuMiner) mine(block *types.Block) { func (self *CpuMiner) mine(block *types.Block) {
minerlogger.Infof("(re)started agent[%d]. mining...\n", self.index) minerlogger.Infof("(re)started agent[%d]. mining...\n", self.index)
nonce, mixDigest, seedHash := self.pow.Search(block, self.quitCurrentOp) nonce, mixDigest, _ := self.pow.Search(block, self.quitCurrentOp)
if nonce != 0 { if nonce != 0 {
self.returnCh <- Work{block.Number().Uint64(), nonce, mixDigest, seedHash} block.SetNonce(nonce)
block.Header().MixDigest = common.BytesToHash(mixDigest)
self.returnCh <- block
//self.returnCh <- Work{block.Number().Uint64(), nonce, mixDigest, seedHash}
} }
} }

@ -26,7 +26,11 @@ type Miner struct {
func New(eth core.Backend, pow pow.PoW, minerThreads int) *Miner { func New(eth core.Backend, pow pow.PoW, minerThreads int) *Miner {
// note: minerThreads is currently ignored because // note: minerThreads is currently ignored because
// ethash is not thread safe. // ethash is not thread safe.
return &Miner{eth: eth, pow: pow, worker: newWorker(common.Address{}, eth)} miner := &Miner{eth: eth, pow: pow, worker: newWorker(common.Address{}, eth)}
for i := 0; i < minerThreads; i++ {
miner.worker.register(NewCpuMiner(i, pow))
}
return miner
} }
func (self *Miner) Mining() bool { func (self *Miner) Mining() bool {
@ -36,7 +40,6 @@ func (self *Miner) Mining() bool {
func (self *Miner) Start(coinbase common.Address) { func (self *Miner) Start(coinbase common.Address) {
self.mining = true self.mining = true
self.worker.coinbase = coinbase self.worker.coinbase = coinbase
self.worker.register(NewCpuMiner(0, self.pow))
self.pow.(*ethash.Ethash).UpdateDAG() self.pow.(*ethash.Ethash).UpdateDAG()

@ -12,7 +12,7 @@ type RemoteAgent struct {
quit chan struct{} quit chan struct{}
workCh chan *types.Block workCh chan *types.Block
returnCh chan<- Work returnCh chan<- *types.Block
} }
func NewRemoteAgent() *RemoteAgent { func NewRemoteAgent() *RemoteAgent {
@ -25,7 +25,7 @@ func (a *RemoteAgent) Work() chan<- *types.Block {
return a.workCh return a.workCh
} }
func (a *RemoteAgent) SetWorkCh(returnCh chan<- Work) { func (a *RemoteAgent) SetReturnCh(returnCh chan<- *types.Block) {
a.returnCh = returnCh a.returnCh = returnCh
} }
@ -72,8 +72,11 @@ func (a *RemoteAgent) SubmitWork(nonce uint64, mixDigest, seedHash common.Hash)
// Return true or false, but does not indicate if the PoW was correct // Return true or false, but does not indicate if the PoW was correct
// Make sure the external miner was working on the right hash // Make sure the external miner was working on the right hash
if a.currentWork != nil && a.work != nil && a.currentWork.Hash() == a.work.Hash() { if a.currentWork != nil && a.work != nil {
a.returnCh <- Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()} a.currentWork.SetNonce(nonce)
a.currentWork.Header().MixDigest = mixDigest
a.returnCh <- a.currentWork
//a.returnCh <- Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()}
return true return true
} }

@ -51,7 +51,7 @@ type Work struct {
type Agent interface { type Agent interface {
Work() chan<- *types.Block Work() chan<- *types.Block
SetWorkCh(chan<- Work) SetReturnCh(chan<- *types.Block)
Stop() Stop()
Start() Start()
GetHashRate() int64 GetHashRate() int64
@ -60,7 +60,7 @@ type Agent interface {
type worker struct { type worker struct {
mu sync.Mutex mu sync.Mutex
agents []Agent agents []Agent
recv chan Work recv chan *types.Block
mux *event.TypeMux mux *event.TypeMux
quit chan struct{} quit chan struct{}
pow pow.PoW pow pow.PoW
@ -82,7 +82,7 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker {
return &worker{ return &worker{
eth: eth, eth: eth,
mux: eth.EventMux(), mux: eth.EventMux(),
recv: make(chan Work), recv: make(chan *types.Block),
chain: eth.ChainManager(), chain: eth.ChainManager(),
proc: eth.BlockProcessor(), proc: eth.BlockProcessor(),
possibleUncles: make(map[common.Hash]*types.Block), possibleUncles: make(map[common.Hash]*types.Block),
@ -112,7 +112,7 @@ func (self *worker) stop() {
func (self *worker) register(agent Agent) { func (self *worker) register(agent Agent) {
self.agents = append(self.agents, agent) self.agents = append(self.agents, agent)
agent.SetWorkCh(self.recv) agent.SetReturnCh(self.recv)
} }
func (self *worker) update() { func (self *worker) update() {
@ -155,30 +155,30 @@ func (self *worker) addUncle(uncle *types.Block) {
func (self *worker) wait() { func (self *worker) wait() {
for { for {
for work := range self.recv { for block := range self.recv {
// Someone Successfully Mined! // Someone Successfully Mined!
block := self.current.block //block := self.current.block
if block.Number().Uint64() == work.Number && block.Nonce() == 0 { //if block.Number().Uint64() == work.Number && block.Nonce() == 0 {
self.current.block.SetNonce(work.Nonce) //self.current.block.SetNonce(work.Nonce)
self.current.block.Header().MixDigest = common.BytesToHash(work.MixDigest) //self.current.block.Header().MixDigest = common.BytesToHash(work.MixDigest)
jsonlogger.LogJson(&logger.EthMinerNewBlock{ jsonlogger.LogJson(&logger.EthMinerNewBlock{
BlockHash: block.Hash().Hex(), BlockHash: block.Hash().Hex(),
BlockNumber: block.Number(), BlockNumber: block.Number(),
ChainHeadHash: block.ParentHeaderHash.Hex(), ChainHeadHash: block.ParentHeaderHash.Hex(),
BlockPrevHash: block.ParentHeaderHash.Hex(), BlockPrevHash: block.ParentHeaderHash.Hex(),
}) })
if err := self.chain.InsertChain(types.Blocks{self.current.block}); err == nil { if err := self.chain.InsertChain(types.Blocks{block}); err == nil {
for _, uncle := range self.current.block.Uncles() { for _, uncle := range block.Uncles() {
delete(self.possibleUncles, uncle.Hash()) delete(self.possibleUncles, uncle.Hash())
}
self.mux.Post(core.NewMinedBlockEvent{self.current.block})
} else {
self.commitNewWork()
} }
self.mux.Post(core.NewMinedBlockEvent{block})
} else {
self.commitNewWork()
} }
//}
break break
} }
} }
@ -191,7 +191,7 @@ func (self *worker) push() {
// push new work to agents // push new work to agents
for _, agent := range self.agents { for _, agent := range self.agents {
agent.Work() <- self.current.block agent.Work() <- self.current.block.Copy()
} }
} }
} }

Loading…
Cancel
Save