mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
miner/*: golint updates for this or self warning
This commit is contained in:
parent
4f6aea31d0
commit
0040e916cc
3 changed files with 194 additions and 194 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
248
miner/worker.go
248
miner/worker.go
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue