code: func (self *Miner) update() {
  	events := self.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{})
  	defer events.Unsubscribe()
  
  	for {
  		select {
  		case ev := <-events.Chan():
  			if ev == nil {
  				return
  			}
  			switch ev.Data.(type) {
  			case downloader.StartEvent:
  				atomic.StoreInt32(&self.canStart, 0)
  				if self.Mining() {
  					self.Stop()
  					atomic.StoreInt32(&self.shouldStart, 1)
  					log.Info("Mining aborted due to sync")
  				}
  			case downloader.DoneEvent, downloader.FailedEvent:
  				shouldStart := atomic.LoadInt32(&self.shouldStart) == 1
  
  				atomic.StoreInt32(&self.canStart, 1)
  				atomic.StoreInt32(&self.shouldStart, 0)
  				if shouldStart {
  					self.Start(self.coinbase)
  				}
  				// stop immediately and ignore all further pending events
  				return
  			}
  		case <-self.exitCh:
  			return
  		}
  	}
  }
docs: // update keeps track of the downloader events. Please be aware that this is a one shot type of update loop.
  // 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
  // and halt your mining operation for as long as the DOS continues.