using System; using System.Threading; using sharp.cryptonote; using sharp.cryptonote.rpc; using System.Collections.Generic; using sharp.extensions; using Newtonsoft.Json.Linq; namespace SharpMining { public delegate void NewBlockAvailable(WorkManager workmanager); public class WorkManager { Thread thread; BlockTemplate currentTemplate; UInt64 nextJobID; Dictionary currentJobs; public event NewBlockAvailable OnNewBlockAvailable; public MiningPool MiningPool { get; private set; } public WorkManager(MiningPool pool) { this.MiningPool = pool; this.nextJobID = 1; this.currentJobs = new Dictionary(); this.thread = new Thread(() => Run()); this.thread.Start(); } private void Run(){ while (true){ Thread.Sleep(2000); Daemon daemon = MiningPool.getCheckedDaemon(); if (daemon == null){ Console.WriteLine("WorkManager: no Daemon available"); } else { BlockTemplate newTemplate = daemon.getBlockTemplate(MiningPool.PoolWallet, 8); Console.WriteLine("current target height is {0}",newTemplate.Height); if ((currentTemplate == null) || (currentTemplate.Height != newTemplate.Height)){ changeCurrentBlock(newTemplate); } } } } private void fireNewBlockAvailable(){ if (OnNewBlockAvailable != null){ OnNewBlockAvailable.Invoke(this); } } public void changeCurrentBlock(BlockTemplate blockTemplate){ Monitor.Enter(this); currentTemplate = blockTemplate; Console.WriteLine("new block target height: {0} target difficulty: {1} [0x{1:x}]",blockTemplate.Height,blockTemplate.Difficulty); fireNewBlockAvailable(); Monitor.Exit(this); } public MiningJob createJob() { Monitor.Enter(this); if (this.currentTemplate == null){ return null; } UInt64 jobid = this.nextJobID++; MiningJob job = new MiningJob(this.currentTemplate.generateJobTemplate(jobid.GetBytes()), jobid, this.currentTemplate.Height, this.currentTemplate.Difficulty); this.currentJobs.Add(jobid, job); Monitor.Exit(this); return job; } } }