miner/*: golint updates for this or self warning

This commit is contained in:
Kiel barry 2018-04-27 16:48:31 -07:00
parent 4f6aea31d0
commit 0040e916cc
3 changed files with 194 additions and 194 deletions

View file

@ -49,70 +49,70 @@ func NewCpuAgent(chain consensus.ChainReader, engine consensus.Engine) *CpuAgent
return miner return miner
} }
func (self *CpuAgent) Work() chan<- *Work { return self.workCh } func (a *CpuAgent) Work() chan<- *Work { return a.workCh }
func (self *CpuAgent) SetReturnCh(ch chan<- *Result) { self.returnCh = ch } func (a *CpuAgent) SetReturnCh(ch chan<- *Result) { a.returnCh = ch }
func (self *CpuAgent) Stop() { func (a *CpuAgent) Stop() {
if !atomic.CompareAndSwapInt32(&self.isMining, 1, 0) { if !atomic.CompareAndSwapInt32(&a.isMining, 1, 0) {
return // agent already stopped return // agent already stopped
} }
self.stop <- struct{}{} a.stop <- struct{}{}
done: done:
// Empty work channel // Empty work channel
for { for {
select { select {
case <-self.workCh: case <-a.workCh:
default: default:
break done break done
} }
} }
} }
func (self *CpuAgent) Start() { func (a *CpuAgent) Start() {
if !atomic.CompareAndSwapInt32(&self.isMining, 0, 1) { if !atomic.CompareAndSwapInt32(&a.isMining, 0, 1) {
return // agent already started return // agent already started
} }
go self.update() go a.update()
} }
func (self *CpuAgent) update() { func (a *CpuAgent) update() {
out: out:
for { for {
select { select {
case work := <-self.workCh: case work := <-a.workCh:
self.mu.Lock() a.mu.Lock()
if self.quitCurrentOp != nil { if a.quitCurrentOp != nil {
close(self.quitCurrentOp) close(a.quitCurrentOp)
} }
self.quitCurrentOp = make(chan struct{}) a.quitCurrentOp = make(chan struct{})
go self.mine(work, self.quitCurrentOp) go a.mine(work, a.quitCurrentOp)
self.mu.Unlock() a.mu.Unlock()
case <-self.stop: case <-a.stop:
self.mu.Lock() a.mu.Lock()
if self.quitCurrentOp != nil { if a.quitCurrentOp != nil {
close(self.quitCurrentOp) close(a.quitCurrentOp)
self.quitCurrentOp = nil a.quitCurrentOp = nil
} }
self.mu.Unlock() a.mu.Unlock()
break out break out
} }
} }
} }
func (self *CpuAgent) mine(work *Work, stop <-chan struct{}) { func (a *CpuAgent) mine(work *Work, stop <-chan struct{}) {
if result, err := self.engine.Seal(self.chain, work.Block, stop); result != nil { if result, err := a.engine.Seal(a.chain, work.Block, stop); result != nil {
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} a.returnCh <- &Result{work, result}
} else { } else {
if err != nil { if err != nil {
log.Warn("Block sealing failed", "err", err) log.Warn("Block sealing failed", "err", err)
} }
self.returnCh <- nil a.returnCh <- nil
} }
} }
func (self *CpuAgent) GetHashRate() int64 { func (a *CpuAgent) GetHashRate() int64 {
if pow, ok := self.engine.(consensus.PoW); ok { if pow, ok := a.engine.(consensus.PoW); ok {
return int64(pow.Hashrate()) return int64(pow.Hashrate())
} }
return 0 return 0

View file

@ -75,25 +75,25 @@ func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, engine con
// It's entered once and as soon as `Done` or `Failed` has been broadcasted the events are unregistered and // It's entered once and as soon as `Done` or `Failed` has been broadcasted the events are unregistered and
// the loop is exited. This to prevent a major security vuln where external parties can DOS you with blocks // the loop is exited. This to prevent a major security vuln where external parties can DOS you with blocks
// and halt your mining operation for as long as the DOS continues. // and halt your mining operation for as long as the DOS continues.
func (self *Miner) update() { func (m *Miner) update() {
events := self.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{}) events := m.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{})
out: out:
for ev := range events.Chan() { for ev := range events.Chan() {
switch ev.Data.(type) { switch ev.Data.(type) {
case downloader.StartEvent: case downloader.StartEvent:
atomic.StoreInt32(&self.canStart, 0) atomic.StoreInt32(&m.canStart, 0)
if self.Mining() { if m.Mining() {
self.Stop() m.Stop()
atomic.StoreInt32(&self.shouldStart, 1) atomic.StoreInt32(&m.shouldStart, 1)
log.Info("Mining aborted due to sync") log.Info("Mining aborted due to sync")
} }
case downloader.DoneEvent, downloader.FailedEvent: case downloader.DoneEvent, downloader.FailedEvent:
shouldStart := atomic.LoadInt32(&self.shouldStart) == 1 shouldStart := atomic.LoadInt32(&m.shouldStart) == 1
atomic.StoreInt32(&self.canStart, 1) atomic.StoreInt32(&m.canStart, 1)
atomic.StoreInt32(&self.shouldStart, 0) atomic.StoreInt32(&m.shouldStart, 0)
if shouldStart { if shouldStart {
self.Start(self.coinbase) m.Start(m.coinbase)
} }
// unsubscribe. we're only interested in this event once // unsubscribe. we're only interested in this event once
events.Unsubscribe() events.Unsubscribe()
@ -103,50 +103,50 @@ out:
} }
} }
func (self *Miner) Start(coinbase common.Address) { func (m *Miner) Start(coinbase common.Address) {
atomic.StoreInt32(&self.shouldStart, 1) atomic.StoreInt32(&m.shouldStart, 1)
self.SetEtherbase(coinbase) m.SetEtherbase(coinbase)
if atomic.LoadInt32(&self.canStart) == 0 { if atomic.LoadInt32(&m.canStart) == 0 {
log.Info("Network syncing, will start miner afterwards") log.Info("Network syncing, will start miner afterwards")
return return
} }
atomic.StoreInt32(&self.mining, 1) atomic.StoreInt32(&m.mining, 1)
log.Info("Starting mining operation") log.Info("Starting mining operation")
self.worker.start() m.worker.start()
self.worker.commitNewWork() m.worker.commitNewWork()
} }
func (self *Miner) Stop() { func (m *Miner) Stop() {
self.worker.stop() m.worker.stop()
atomic.StoreInt32(&self.mining, 0) atomic.StoreInt32(&m.mining, 0)
atomic.StoreInt32(&self.shouldStart, 0) atomic.StoreInt32(&m.shouldStart, 0)
} }
func (self *Miner) Register(agent Agent) { func (m *Miner) Register(agent Agent) {
if self.Mining() { if m.Mining() {
agent.Start() agent.Start()
} }
self.worker.register(agent) m.worker.register(agent)
} }
func (self *Miner) Unregister(agent Agent) { func (m *Miner) Unregister(agent Agent) {
self.worker.unregister(agent) m.worker.unregister(agent)
} }
func (self *Miner) Mining() bool { func (m *Miner) Mining() bool {
return atomic.LoadInt32(&self.mining) > 0 return atomic.LoadInt32(&m.mining) > 0
} }
func (self *Miner) HashRate() (tot int64) { func (m *Miner) HashRate() (tot int64) {
if pow, ok := self.engine.(consensus.PoW); ok { if pow, ok := m.engine.(consensus.PoW); ok {
tot += int64(pow.Hashrate()) tot += int64(pow.Hashrate())
} }
// do we care this might race? is it worth we're rewriting some // do we care this might race? is it worth we're rewriting some
// aspects of the worker/locking up agents so we can get an accurate // aspects of the worker/locking up agents so we can get an accurate
// hashrate? // hashrate?
for agent := range self.worker.agents { for agent := range m.worker.agents {
if _, ok := agent.(*CpuAgent); !ok { if _, ok := agent.(*CpuAgent); !ok {
tot += agent.GetHashRate() tot += agent.GetHashRate()
} }
@ -154,17 +154,17 @@ func (self *Miner) HashRate() (tot int64) {
return return
} }
func (self *Miner) SetExtra(extra []byte) error { func (m *Miner) SetExtra(extra []byte) error {
if uint64(len(extra)) > params.MaximumExtraDataSize { if uint64(len(extra)) > params.MaximumExtraDataSize {
return fmt.Errorf("Extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize) return fmt.Errorf("Extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize)
} }
self.worker.setExtra(extra) m.worker.setExtra(extra)
return nil return nil
} }
// Pending returns the currently pending block and associated state. // Pending returns the currently pending block and associated state.
func (self *Miner) Pending() (*types.Block, *state.StateDB) { func (m *Miner) Pending() (*types.Block, *state.StateDB) {
return self.worker.pending() return m.worker.pending()
} }
// PendingBlock returns the currently pending block. // PendingBlock returns the currently pending block.
@ -172,11 +172,11 @@ func (self *Miner) Pending() (*types.Block, *state.StateDB) {
// Note, to access both the pending block and the pending state // Note, to access both the pending block and the pending state
// simultaneously, please use Pending(), as the pending state can // simultaneously, please use Pending(), as the pending state can
// change between multiple method calls // change between multiple method calls
func (self *Miner) PendingBlock() *types.Block { func (m *Miner) PendingBlock() *types.Block {
return self.worker.pendingBlock() return m.worker.pendingBlock()
} }
func (self *Miner) SetEtherbase(addr common.Address) { func (m *Miner) SetEtherbase(addr common.Address) {
self.coinbase = addr m.coinbase = addr
self.worker.setEtherbase(addr) m.worker.setEtherbase(addr)
} }

View file

@ -162,137 +162,137 @@ func newWorker(config *params.ChainConfig, engine consensus.Engine, coinbase com
return worker return worker
} }
func (self *worker) setEtherbase(addr common.Address) { func (w *worker) setEtherbase(addr common.Address) {
self.mu.Lock() w.mu.Lock()
defer self.mu.Unlock() defer w.mu.Unlock()
self.coinbase = addr w.coinbase = addr
} }
func (self *worker) setExtra(extra []byte) { func (w *worker) setExtra(extra []byte) {
self.mu.Lock() w.mu.Lock()
defer self.mu.Unlock() defer w.mu.Unlock()
self.extra = extra w.extra = extra
} }
func (self *worker) pending() (*types.Block, *state.StateDB) { func (w *worker) pending() (*types.Block, *state.StateDB) {
if atomic.LoadInt32(&self.mining) == 0 { if atomic.LoadInt32(&w.mining) == 0 {
// return a snapshot to avoid contention on currentMu mutex // return a snapshot to avoid contention on currentMu mutex
self.snapshotMu.RLock() w.snapshotMu.RLock()
defer self.snapshotMu.RUnlock() defer w.snapshotMu.RUnlock()
return self.snapshotBlock, self.snapshotState.Copy() return w.snapshotBlock, w.snapshotState.Copy()
} }
self.currentMu.Lock() w.currentMu.Lock()
defer self.currentMu.Unlock() defer w.currentMu.Unlock()
return self.current.Block, self.current.state.Copy() return w.current.Block, w.current.state.Copy()
} }
func (self *worker) pendingBlock() *types.Block { func (w *worker) pendingBlock() *types.Block {
if atomic.LoadInt32(&self.mining) == 0 { if atomic.LoadInt32(&w.mining) == 0 {
// return a snapshot to avoid contention on currentMu mutex // return a snapshot to avoid contention on currentMu mutex
self.snapshotMu.RLock() w.snapshotMu.RLock()
defer self.snapshotMu.RUnlock() defer w.snapshotMu.RUnlock()
return self.snapshotBlock return w.snapshotBlock
} }
self.currentMu.Lock() w.currentMu.Lock()
defer self.currentMu.Unlock() defer w.currentMu.Unlock()
return self.current.Block return w.current.Block
} }
func (self *worker) start() { func (w *worker) start() {
self.mu.Lock() w.mu.Lock()
defer self.mu.Unlock() defer w.mu.Unlock()
atomic.StoreInt32(&self.mining, 1) atomic.StoreInt32(&w.mining, 1)
// spin up agents // spin up agents
for agent := range self.agents { for agent := range w.agents {
agent.Start() agent.Start()
} }
} }
func (self *worker) stop() { func (w *worker) stop() {
self.wg.Wait() w.wg.Wait()
self.mu.Lock() w.mu.Lock()
defer self.mu.Unlock() defer w.mu.Unlock()
if atomic.LoadInt32(&self.mining) == 1 { if atomic.LoadInt32(&w.mining) == 1 {
for agent := range self.agents { for agent := range w.agents {
agent.Stop() agent.Stop()
} }
} }
atomic.StoreInt32(&self.mining, 0) atomic.StoreInt32(&w.mining, 0)
atomic.StoreInt32(&self.atWork, 0) atomic.StoreInt32(&w.atWork, 0)
} }
func (self *worker) register(agent Agent) { func (w *worker) register(agent Agent) {
self.mu.Lock() w.mu.Lock()
defer self.mu.Unlock() defer w.mu.Unlock()
self.agents[agent] = struct{}{} w.agents[agent] = struct{}{}
agent.SetReturnCh(self.recv) agent.SetReturnCh(w.recv)
} }
func (self *worker) unregister(agent Agent) { func (w *worker) unregister(agent Agent) {
self.mu.Lock() w.mu.Lock()
defer self.mu.Unlock() defer w.mu.Unlock()
delete(self.agents, agent) delete(w.agents, agent)
agent.Stop() agent.Stop()
} }
func (self *worker) update() { func (w *worker) update() {
defer self.txSub.Unsubscribe() defer w.txSub.Unsubscribe()
defer self.chainHeadSub.Unsubscribe() defer w.chainHeadSub.Unsubscribe()
defer self.chainSideSub.Unsubscribe() defer w.chainSideSub.Unsubscribe()
for { for {
// A real event arrived, process interesting content // A real event arrived, process interesting content
select { select {
// Handle ChainHeadEvent // Handle ChainHeadEvent
case <-self.chainHeadCh: case <-w.chainHeadCh:
self.commitNewWork() w.commitNewWork()
// Handle ChainSideEvent // Handle ChainSideEvent
case ev := <-self.chainSideCh: case ev := <-w.chainSideCh:
self.uncleMu.Lock() w.uncleMu.Lock()
self.possibleUncles[ev.Block.Hash()] = ev.Block w.possibleUncles[ev.Block.Hash()] = ev.Block
self.uncleMu.Unlock() w.uncleMu.Unlock()
// Handle TxPreEvent // Handle TxPreEvent
case ev := <-self.txCh: case ev := <-w.txCh:
// Apply transaction to the pending state if we're not mining // Apply transaction to the pending state if we're not mining
if atomic.LoadInt32(&self.mining) == 0 { if atomic.LoadInt32(&w.mining) == 0 {
self.currentMu.Lock() w.currentMu.Lock()
acc, _ := types.Sender(self.current.signer, ev.Tx) acc, _ := types.Sender(w.current.signer, ev.Tx)
txs := map[common.Address]types.Transactions{acc: {ev.Tx}} txs := map[common.Address]types.Transactions{acc: {ev.Tx}}
txset := types.NewTransactionsByPriceAndNonce(self.current.signer, txs) txset := types.NewTransactionsByPriceAndNonce(w.current.signer, txs)
self.current.commitTransactions(self.mux, txset, self.chain, self.coinbase) w.current.commitTransactions(w.mux, txset, w.chain, w.coinbase)
self.updateSnapshot() w.updateSnapshot()
self.currentMu.Unlock() w.currentMu.Unlock()
} else { } else {
// If we're mining, but nothing is being processed, wake on new transactions // If we're mining, but nothing is being processed, wake on new transactions
if self.config.Clique != nil && self.config.Clique.Period == 0 { if w.config.Clique != nil && w.config.Clique.Period == 0 {
self.commitNewWork() w.commitNewWork()
} }
} }
// System stopped // System stopped
case <-self.txSub.Err(): case <-w.txSub.Err():
return return
case <-self.chainHeadSub.Err(): case <-w.chainHeadSub.Err():
return return
case <-self.chainSideSub.Err(): case <-w.chainSideSub.Err():
return return
} }
} }
} }
func (self *worker) wait() { func (w *worker) wait() {
for { for {
mustCommitNewWork := true mustCommitNewWork := true
for result := range self.recv { for result := range w.recv {
atomic.AddInt32(&self.atWork, -1) atomic.AddInt32(&w.atWork, -1)
if result == nil { if result == nil {
continue continue
@ -310,7 +310,7 @@ func (self *worker) wait() {
for _, log := range work.state.Logs() { for _, log := range work.state.Logs() {
log.BlockHash = block.Hash() log.BlockHash = block.Hash()
} }
stat, err := self.chain.WriteBlockWithState(block, work.receipts, work.state) stat, err := w.chain.WriteBlockWithState(block, work.receipts, work.state)
if err != nil { if err != nil {
log.Error("Failed writing block to chain", "err", err) log.Error("Failed writing block to chain", "err", err)
continue continue
@ -321,7 +321,7 @@ func (self *worker) wait() {
mustCommitNewWork = false mustCommitNewWork = false
} }
// Broadcast the block and announce chain insertion event // Broadcast the block and announce chain insertion event
self.mux.Post(core.NewMinedBlockEvent{Block: block}) w.mux.Post(core.NewMinedBlockEvent{Block: block})
var ( var (
events []interface{} events []interface{}
logs = work.state.Logs() logs = work.state.Logs()
@ -330,25 +330,25 @@ func (self *worker) wait() {
if stat == core.CanonStatTy { if stat == core.CanonStatTy {
events = append(events, core.ChainHeadEvent{Block: block}) events = append(events, core.ChainHeadEvent{Block: block})
} }
self.chain.PostChainEvents(events, logs) w.chain.PostChainEvents(events, logs)
// Insert the block into the set of pending ones to wait for confirmations // Insert the block into the set of pending ones to wait for confirmations
self.unconfirmed.Insert(block.NumberU64(), block.Hash()) w.unconfirmed.Insert(block.NumberU64(), block.Hash())
if mustCommitNewWork { if mustCommitNewWork {
self.commitNewWork() w.commitNewWork()
} }
} }
} }
} }
// 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 (w *worker) push(work *Work) {
if atomic.LoadInt32(&self.mining) != 1 { if atomic.LoadInt32(&w.mining) != 1 {
return return
} }
for agent := range self.agents { for agent := range w.agents {
atomic.AddInt32(&self.atWork, 1) atomic.AddInt32(&w.atWork, 1)
if ch := agent.Work(); ch != nil { if ch := agent.Work(); ch != nil {
ch <- work ch <- work
} }
@ -356,14 +356,14 @@ func (self *worker) push(work *Work) {
} }
// makeCurrent creates a new environment for the current cycle. // makeCurrent creates a new environment for the current cycle.
func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error { func (w *worker) makeCurrent(parent *types.Block, header *types.Header) error {
state, err := self.chain.StateAt(parent.Root()) state, err := w.chain.StateAt(parent.Root())
if err != nil { if err != nil {
return err return err
} }
work := &Work{ work := &Work{
config: self.config, config: w.config,
signer: types.NewEIP155Signer(self.config.ChainId), signer: types.NewEIP155Signer(w.config.ChainId),
state: state, state: state,
ancestors: set.New(), ancestors: set.New(),
family: set.New(), family: set.New(),
@ -373,7 +373,7 @@ func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error
} }
// when 08 is processed ancestors contain 07 (quick block) // when 08 is processed ancestors contain 07 (quick block)
for _, ancestor := range self.chain.GetBlocksFromHash(parent.Hash(), 7) { for _, ancestor := range w.chain.GetBlocksFromHash(parent.Hash(), 7) {
for _, uncle := range ancestor.Uncles() { for _, uncle := range ancestor.Uncles() {
work.family.Add(uncle.Hash()) work.family.Add(uncle.Hash())
} }
@ -383,20 +383,20 @@ func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error
// Keep track of transactions which return errors so they can be removed // Keep track of transactions which return errors so they can be removed
work.tcount = 0 work.tcount = 0
self.current = work w.current = work
return nil return nil
} }
func (self *worker) commitNewWork() { func (w *worker) commitNewWork() {
self.mu.Lock() w.mu.Lock()
defer self.mu.Unlock() defer w.mu.Unlock()
self.uncleMu.Lock() w.uncleMu.Lock()
defer self.uncleMu.Unlock() defer w.uncleMu.Unlock()
self.currentMu.Lock() w.currentMu.Lock()
defer self.currentMu.Unlock() defer w.currentMu.Unlock()
tstart := time.Now() tstart := time.Now()
parent := self.chain.CurrentBlock() parent := w.chain.CurrentBlock()
tstamp := tstart.Unix() tstamp := tstart.Unix()
if parent.Time().Cmp(new(big.Int).SetInt64(tstamp)) >= 0 { if parent.Time().Cmp(new(big.Int).SetInt64(tstamp)) >= 0 {
@ -414,24 +414,24 @@ func (self *worker) commitNewWork() {
ParentHash: parent.Hash(), ParentHash: parent.Hash(),
Number: num.Add(num, common.Big1), Number: num.Add(num, common.Big1),
GasLimit: core.CalcGasLimit(parent), GasLimit: core.CalcGasLimit(parent),
Extra: self.extra, Extra: w.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 we are mining (avoid spurious block rewards)
if atomic.LoadInt32(&self.mining) == 1 { if atomic.LoadInt32(&w.mining) == 1 {
header.Coinbase = self.coinbase header.Coinbase = w.coinbase
} }
if err := self.engine.Prepare(self.chain, header); err != nil { if err := w.engine.Prepare(w.chain, header); err != nil {
log.Error("Failed to prepare header for mining", "err", err) log.Error("Failed to prepare header for mining", "err", err)
return return
} }
// If we are care about TheDAO hard-fork check whether to override the extra-data or not // If we are care about TheDAO hard-fork check whether to override the extra-data or not
if daoBlock := self.config.DAOForkBlock; daoBlock != nil { if daoBlock := w.config.DAOForkBlock; daoBlock != nil {
// Check whether the block is among the fork extra-override range // Check whether the block is among the fork extra-override range
limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange) limit := new(big.Int).Add(daoBlock, params.DAOForkExtraRange)
if header.Number.Cmp(daoBlock) >= 0 && header.Number.Cmp(limit) < 0 { if header.Number.Cmp(daoBlock) >= 0 && header.Number.Cmp(limit) < 0 {
// Depending whether we support or oppose the fork, override differently // Depending whether we support or oppose the fork, override differently
if self.config.DAOForkSupport { if w.config.DAOForkSupport {
header.Extra = common.CopyBytes(params.DAOForkBlockExtra) header.Extra = common.CopyBytes(params.DAOForkBlockExtra)
} else if bytes.Equal(header.Extra, params.DAOForkBlockExtra) { } else if bytes.Equal(header.Extra, params.DAOForkBlockExtra) {
header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data header.Extra = []byte{} // If miner opposes, don't let it use the reserved extra-data
@ -439,34 +439,34 @@ func (self *worker) commitNewWork() {
} }
} }
// Could potentially happen if starting to mine in an odd state. // Could potentially happen if starting to mine in an odd state.
err := self.makeCurrent(parent, header) err := w.makeCurrent(parent, header)
if err != nil { if err != nil {
log.Error("Failed to create mining context", "err", err) log.Error("Failed to create mining context", "err", err)
return return
} }
// Create the current work task and check any fork transitions needed // Create the current work task and check any fork transitions needed
work := self.current work := w.current
if self.config.DAOForkSupport && self.config.DAOForkBlock != nil && self.config.DAOForkBlock.Cmp(header.Number) == 0 { if w.config.DAOForkSupport && w.config.DAOForkBlock != nil && w.config.DAOForkBlock.Cmp(header.Number) == 0 {
misc.ApplyDAOHardFork(work.state) misc.ApplyDAOHardFork(work.state)
} }
pending, err := self.eth.TxPool().Pending() pending, err := w.eth.TxPool().Pending()
if err != nil { if err != nil {
log.Error("Failed to fetch pending transactions", "err", err) log.Error("Failed to fetch pending transactions", "err", err)
return return
} }
txs := types.NewTransactionsByPriceAndNonce(self.current.signer, pending) txs := types.NewTransactionsByPriceAndNonce(w.current.signer, pending)
work.commitTransactions(self.mux, txs, self.chain, self.coinbase) work.commitTransactions(w.mux, txs, w.chain, w.coinbase)
// compute uncles for the new block. // compute uncles for the new block.
var ( var (
uncles []*types.Header uncles []*types.Header
badUncles []common.Hash badUncles []common.Hash
) )
for hash, uncle := range self.possibleUncles { for hash, uncle := range w.possibleUncles {
if len(uncles) == 2 { if len(uncles) == 2 {
break break
} }
if err := self.commitUncle(work, uncle.Header()); err != nil { if err := w.commitUncle(work, uncle.Header()); err != nil {
log.Trace("Bad uncle found and will be removed", "hash", hash) log.Trace("Bad uncle found and will be removed", "hash", hash)
log.Trace(fmt.Sprint(uncle)) log.Trace(fmt.Sprint(uncle))
@ -477,23 +477,23 @@ func (self *worker) commitNewWork() {
} }
} }
for _, hash := range badUncles { for _, hash := range badUncles {
delete(self.possibleUncles, hash) delete(w.possibleUncles, hash)
} }
// Create the new block to seal with the consensus engine // Create the new block to seal with the consensus engine
if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts); err != nil { if work.Block, err = w.engine.Finalize(w.chain, header, work.state, work.txs, uncles, work.receipts); err != nil {
log.Error("Failed to finalize block for sealing", "err", err) log.Error("Failed to finalize block for sealing", "err", err)
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 atomic.LoadInt32(&w.mining) == 1 {
log.Info("Commit new mining work", "number", work.Block.Number(), "txs", work.tcount, "uncles", len(uncles), "elapsed", common.PrettyDuration(time.Since(tstart))) log.Info("Commit new 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) w.unconfirmed.Shift(work.Block.NumberU64() - 1)
} }
self.push(work) w.push(work)
self.updateSnapshot() w.updateSnapshot()
} }
func (self *worker) commitUncle(work *Work, uncle *types.Header) error { func (w *worker) commitUncle(work *Work, uncle *types.Header) error {
hash := uncle.Hash() hash := uncle.Hash()
if work.uncles.Has(hash) { if work.uncles.Has(hash) {
return fmt.Errorf("uncle not unique") return fmt.Errorf("uncle not unique")
@ -508,17 +508,17 @@ func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
return nil return nil
} }
func (self *worker) updateSnapshot() { func (w *worker) updateSnapshot() {
self.snapshotMu.Lock() w.snapshotMu.Lock()
defer self.snapshotMu.Unlock() defer w.snapshotMu.Unlock()
self.snapshotBlock = types.NewBlock( w.snapshotBlock = types.NewBlock(
self.current.header, w.current.header,
self.current.txs, w.current.txs,
nil, nil,
self.current.receipts, w.current.receipts,
) )
self.snapshotState = self.current.state.Copy() w.snapshotState = w.current.state.Copy()
} }
func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsByPriceAndNonce, bc *core.BlockChain, coinbase common.Address) { func (env *Work) commitTransactions(mux *event.TypeMux, txs *types.TransactionsByPriceAndNonce, bc *core.BlockChain, coinbase common.Address) {
@ -616,4 +616,4 @@ func (env *Work) commitTransaction(tx *types.Transaction, bc *core.BlockChain, c
env.receipts = append(env.receipts, receipt) env.receipts = append(env.receipts, receipt)
return nil, receipt.Logs return nil, receipt.Logs
} }