diff options
Diffstat (limited to 'miner')
-rw-r--r-- | miner/miner.go | 2 | ||||
-rw-r--r-- | miner/worker.go | 41 |
2 files changed, 29 insertions, 14 deletions
diff --git a/miner/miner.go b/miner/miner.go index b550ed6d6..769db79d1 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -66,7 +66,7 @@ func (self *Miner) update() { events := self.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{}) out: for ev := range events.Chan() { - switch ev.(type) { + switch ev.Data.(type) { case downloader.StartEvent: atomic.StoreInt32(&self.canStart, 0) if self.Mining() { diff --git a/miner/worker.go b/miner/worker.go index 098f42a72..83653e327 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/logger" @@ -99,7 +100,7 @@ type worker struct { pow pow.PoW eth core.Backend - chain *core.ChainManager + chain *core.BlockChain proc *core.BlockProcessor chainDb ethdb.Database @@ -130,7 +131,7 @@ func newWorker(coinbase common.Address, eth core.Backend) *worker { chainDb: eth.ChainDb(), recv: make(chan *Result, resultQueueSize), gasPrice: new(big.Int), - chain: eth.ChainManager(), + chain: eth.BlockChain(), proc: eth.BlockProcessor(), possibleUncles: make(map[common.Hash]*types.Block), coinbase: coinbase, @@ -214,13 +215,20 @@ func (self *worker) register(agent Agent) { } func (self *worker) update() { - events := self.mux.Subscribe(core.ChainHeadEvent{}, core.ChainSideEvent{}, core.TxPreEvent{}) + eventSub := self.mux.Subscribe(core.ChainHeadEvent{}, core.ChainSideEvent{}, core.TxPreEvent{}) + defer eventSub.Unsubscribe() -out: + eventCh := eventSub.Chan() for { select { - case event := <-events.Chan(): - switch ev := event.(type) { + case event, ok := <-eventCh: + if !ok { + // Event subscription closed, set the channel to nil to stop spinning + eventCh = nil + continue + } + // A real event arrived, process interesting content + switch ev := event.Data.(type) { case core.ChainHeadEvent: self.commitNewWork() case core.ChainSideEvent: @@ -236,11 +244,9 @@ out: } } case <-self.quit: - break out + return } } - - events.Unsubscribe() } func newLocalMinedBlock(blockNumber uint64, prevMinedBlocks *uint64RingBuffer) (minedBlocks *uint64RingBuffer) { @@ -298,7 +304,7 @@ func (self *worker) wait() { } // broadcast before waiting for validation - go func(block *types.Block, logs state.Logs, receipts []*types.Receipt) { + go func(block *types.Block, logs vm.Logs, receipts []*types.Receipt) { self.mux.Post(core.NewMinedBlockEvent{block}) self.mux.Post(core.ChainEvent{block, block.Hash(), logs}) if stat == core.CanonStatTy { @@ -347,8 +353,11 @@ func (self *worker) push(work *Work) { } // makeCurrent creates a new environment for the current cycle. -func (self *worker) makeCurrent(parent *types.Block, header *types.Header) { - state := state.New(parent.Root(), self.eth.ChainDb()) +func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error { + state, err := state.New(parent.Root(), self.eth.ChainDb()) + if err != nil { + return err + } work := &Work{ state: state, ancestors: set.New(), @@ -379,6 +388,7 @@ func (self *worker) makeCurrent(parent *types.Block, header *types.Header) { work.localMinedBlocks = self.current.localMinedBlocks } self.current = work + return nil } func (w *worker) setGasPrice(p *big.Int) { @@ -458,7 +468,12 @@ func (self *worker) commitNewWork() { } previous := self.current - self.makeCurrent(parent, header) + // Could potentially happen if starting to mine in an odd state. + err := self.makeCurrent(parent, header) + if err != nil { + glog.V(logger.Info).Infoln("Could not create new env for mining, retrying on next block.") + return + } work := self.current /* //approach 1 |