// StartAutoDAG() spawns a go routine that checks the DAG every autoDAGcheckInterval // by default that is 10 times per epoch // in epoch n, if we past autoDAGepochHeight within-epoch blocks, // it calls ethash.MakeDAG to pregenerate the DAG for the next epoch n+1 // if it does not exist yet as well as remove the DAG for epoch n-1 // the loop quits if autodagquit channel is closed, it can safely restart and // stop any number of times. // For any more sophisticated pattern of DAG generation, use CLI subcommand // makedag func (self *Ethereum) StartAutoDAG() { if self.autodagquit != nil { return // already started } go func() { glog.V(logger.Info).Infof("Automatic pregeneration of ethash DAG ON (ethash dir: %s)", ethash.DefaultDir) var nextEpoch uint64 timer := time.After(0) self.autodagquit = make(chan bool) for { select { case <-timer: glog.V(logger.Info).Infof("checking DAG (ethash dir: %s)", ethash.DefaultDir) currentBlock := self.BlockChain().CurrentBlock().NumberU64() thisEpoch := currentBlock / epochLength if nextEpoch <= thisEpoch { if currentBlock%epochLength > autoDAGepochHeight { if thisEpoch > 0 { previousDag, previousDagFull := dagFiles(thisEpoch - 1) os.Remove(filepath.Join(ethash.DefaultDir, previousDag)) os.Remove(filepath.Join(ethash.DefaultDir, previousDagFull)) glog.V(logger.Info).Infof("removed DAG for epoch %d (%s)", thisEpoch-1, previousDag) } nextEpoch = thisEpoch + 1 dag, _ := dagFiles(nextEpoch) if _, err := os.Stat(dag); os.IsNotExist(err) { glog.V(logger.Info).Infof("Pregenerating DAG for epoch %d (%s)", nextEpoch, dag) err := ethash.MakeDAG(nextEpoch*epochLength, "") // "" -> ethash.DefaultDir if err != nil { glog.V(logger.Error).Infof("Error generating DAG for epoch %d (%s)", nextEpoch, dag) return } } else { glog.V(logger.Error).Infof("DAG for epoch %d (%s)", nextEpoch, dag) } } } timer = time.After(autoDAGcheckInterval) case <-self.autodagquit: return } } }() }
// MakeDAG creates the new DAG for the given block number func (s *PrivateMinerAPI) MakeDAG(blockNr rpc.BlockNumber) (bool, error) { if err := ethash.MakeDAG(uint64(blockNr.Int64()), ""); err != nil { return false, err } return true, nil }