newWorkLoop is a standalone goroutine to do the following upon received events: 1) start new task loop 2) submit new mining work
()
| 238 | // 1) start new task loop |
| 239 | // 2) submit new mining work |
| 240 | func (w *worker) newWorkLoop() { |
| 241 | defer w.wg.Done() |
| 242 | |
| 243 | for { |
| 244 | select { |
| 245 | case shardIdx := <-w.startCh: |
| 246 | miner, _ := w.storageMgr.GetShardMiner(shardIdx) |
| 247 | var taskChs []chan *taskItem |
| 248 | for i := uint64(0); i < w.config.ThreadsPerShard; i++ { |
| 249 | taskCh := make(chan *taskItem, taskQueueSize) |
| 250 | taskChs = append(taskChs, taskCh) |
| 251 | w.wg.Add(1) |
| 252 | w.lg.Debug("Worker is starting task loop", "shard", shardIdx, "thread", i) |
| 253 | go w.taskLoop(taskCh) |
| 254 | } |
| 255 | w.lg.Info("Worker is starting task loops", "shard", shardIdx, "threads", w.config.ThreadsPerShard) |
| 256 | |
| 257 | if w.config.EmailEnabled { |
| 258 | emailSubject := fmt.Sprintf("EthStorage Mining Task Started: Shard %d", shardIdx) |
| 259 | msg := fmt.Sprintf("A new mining task has been initiated for shard %d on es-node.\r\n\r\n", shardIdx) |
| 260 | msg += fmt.Sprintf("Chain ID: %d\r\n", w.config.ChainID) |
| 261 | msg += fmt.Sprintf("Contract: %s\r\n", w.storageMgr.ContractAddress().Hex()) |
| 262 | msg += fmt.Sprintf("Miner: %s\r\n", miner.Hex()) |
| 263 | msg += fmt.Sprintf("Threads per shard: %d\r\n", w.config.ThreadsPerShard) |
| 264 | msg += fmt.Sprintf("Minimum profit: %s wei\r\n", w.config.MinimumProfit) |
| 265 | msg += fmt.Sprintf("Maximum gas price: %s gwei\r\n", fmtGwei(w.config.MaxGasPrice)) |
| 266 | go func() { |
| 267 | email.SendEmail(emailSubject, msg, w.config.EmailConfig, w.lg) |
| 268 | }() |
| 269 | } |
| 270 | task := task{ |
| 271 | miner: miner, |
| 272 | shardIdx: shardIdx, |
| 273 | taskChs: taskChs, |
| 274 | } |
| 275 | w.shardTaskMap[shardIdx] = task |
| 276 | |
| 277 | case block := <-w.chainHeadCh: |
| 278 | if !w.isRunning() { |
| 279 | break |
| 280 | } |
| 281 | w.lg.Debug("Updating tasks with L1 new head", "blockNumber", block.Number, "blockTime", block.Time, "blockHash", block.Hash, "now", uint64(time.Now().Unix())) |
| 282 | // TODO suspend mining if: |
| 283 | // 1) a mining tx is already submitted; or |
| 284 | // 2) if the last mining time is too close (the reward is not enough). |
| 285 | for shardIdx, task := range w.shardTaskMap { |
| 286 | reqDiff, err := w.updateDifficulty(shardIdx, block) |
| 287 | if err != nil { |
| 288 | continue |
| 289 | } |
| 290 | w.assignTasks(task, block, reqDiff) |
| 291 | } |
| 292 | case <-w.exitCh: |
| 293 | w.lg.Warn("Worker is exiting from work loop...") |
| 294 | return |
| 295 | } |
| 296 | } |
| 297 | } |
no test coverage detected