From 32c7ebc51dcb31f21efe1b9c75f2b86cd216f510 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 14 Feb 2015 16:52:14 +0100 Subject: Fixed mining & limited hash power --- miner/agent.go | 19 +++++++++++-------- miner/worker.go | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 19 deletions(-) (limited to 'miner') diff --git a/miner/agent.go b/miner/agent.go index ddd8e6675..9046f5d5a 100644 --- a/miner/agent.go +++ b/miner/agent.go @@ -17,32 +17,35 @@ type CpuMiner struct { func NewCpuMiner(index int, pow pow.PoW) *CpuMiner { miner := &CpuMiner{ - c: make(chan *types.Block, 1), - quit: make(chan struct{}), - quitCurrentOp: make(chan struct{}, 1), - pow: pow, - index: index, + pow: pow, + index: index, } - go miner.update() return miner } func (self *CpuMiner) Work() chan<- *types.Block { return self.c } func (self *CpuMiner) Pow() pow.PoW { return self.pow } -func (self *CpuMiner) SetNonceCh(ch chan<- Work) { self.returnCh = ch } +func (self *CpuMiner) SetWorkCh(ch chan<- Work) { self.returnCh = ch } func (self *CpuMiner) Stop() { close(self.quit) close(self.quitCurrentOp) } +func (self *CpuMiner) Start() { + self.quit = make(chan struct{}) + self.quitCurrentOp = make(chan struct{}, 1) + self.c = make(chan *types.Block, 1) + + go self.update() +} + func (self *CpuMiner) update() { out: for { select { case block := <-self.c: - // make sure it's open self.quitCurrentOp <- struct{}{} go self.mine(block) diff --git a/miner/worker.go b/miner/worker.go index 9244e06b9..96c8bdd39 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -48,8 +48,9 @@ type Work struct { type Agent interface { Work() chan<- *types.Block - SetNonceCh(chan<- Work) + SetWorkCh(chan<- Work) Stop() + Start() Pow() pow.PoW } @@ -86,6 +87,11 @@ func (self *worker) start() { self.quit = make(chan struct{}) + // spin up agents + for _, agent := range self.agents { + agent.Start() + } + go self.update() go self.wait() } @@ -98,7 +104,7 @@ func (self *worker) stop() { func (self *worker) register(agent Agent) { self.agents = append(self.agents, agent) - agent.SetNonceCh(self.recv) + agent.SetWorkCh(self.recv) } func (self *worker) update() { @@ -108,15 +114,17 @@ out: for { select { case event := <-events.Chan(): - switch event := event.(type) { + switch event.(type) { case core.ChainEvent: self.commitNewWork() case core.TxPreEvent: - if err := self.commitTransaction(event.Tx); err != nil { - self.push() - } + self.commitNewWork() } case <-self.quit: + // stop all agents + for _, agent := range self.agents { + agent.Stop() + } break out } } @@ -131,8 +139,11 @@ func (self *worker) wait() { if block.Number().Uint64() == work.Number && block.Nonce() == nil { self.current.block.Header().Nonce = work.Nonce - self.chain.InsertChain(types.Blocks{self.current.block}) - self.mux.Post(core.NewMinedBlockEvent{self.current.block}) + if err := self.chain.InsertChain(types.Blocks{self.current.block}); err == nil { + self.mux.Post(core.NewMinedBlockEvent{self.current.block}) + } else { + self.commitNewWork() + } } break } @@ -141,9 +152,10 @@ func (self *worker) wait() { func (self *worker) push() { if self.mining { - self.current.state.Update(ethutil.Big0) + self.current.block.Header().GasUsed = self.current.totalUsedGas self.current.block.SetRoot(self.current.state.Root()) + // push new work to agents for _, agent := range self.agents { agent.Work() <- self.current.block } @@ -169,14 +181,18 @@ func (self *worker) commitNewWork() { // Break on gas limit break default: - minerlogger.Infoln(err) remove = append(remove, tx) } + + if err != nil { + minerlogger.Infoln(err) + } } self.eth.TxPool().RemoveSet(remove) self.current.coinbase.AddAmount(core.BlockReward) + self.current.state.Update(ethutil.Big0) self.push() } @@ -213,7 +229,9 @@ func (self *worker) commitTransaction(tx *types.Transaction) error { snapshot := self.current.state.Copy() receipt, txGas, err := self.proc.ApplyTransaction(self.current.coinbase, self.current.state, self.current.block, tx, self.current.totalUsedGas, true) if err != nil { - self.current.state.Set(snapshot) + if core.IsNonceErr(err) || core.IsGasLimitErr(err) { + self.current.state.Set(snapshot) + } return err } -- cgit v1.2.3