public void MineBlock(double difficulty) { if (!_isMining) { Difficulty = difficulty; _isMining = true; var totalHashesCounter = 0; DateTime startTime = DateTime.Now; Task[] miningTasks = new Task[1]; //#if DEBUG // Task[] miningTasks = new Task[1]; //#else // Task[] miningTasks = new Task[Environment.ProcessorCount]; //#endif var unsigned = new byte[] { 0, 0 }; for (int i = 0; i < miningTasks.Length; i++) { var startNonce = i; miningTasks[i] = Task.Factory.StartNew(() => { var taskHash = GenerateHash(startNonce); while (difficulty < BigInteger.Log(new BigInteger(taskHash.Concat(unsigned).ToArray()))) { if (!_isMining) { taskHash = null; break; } startNonce = startNonce + miningTasks.Length; taskHash = GenerateHash(startNonce); totalHashesCounter++; if (totalHashesCounter % 200000 == 0) { var currentElapsedTime = DateTime.Now - startTime; BlockchainConsole.WriteLive($"MINING BLOCK {Height} - ELAPSED TIME: {currentElapsedTime.TotalSeconds} Seconds, DIFFICULTY: {difficulty}, HASH RATE: {Convert.ToInt64(totalHashesCounter / currentElapsedTime.TotalSeconds)}/Seconds"); } } if (taskHash != null) { Nonce = startNonce; _isMining = false; } }); } Task.WaitAll(miningTasks); var elapsedTime = DateTime.Now - startTime; BlockchainConsole.WriteLive(string.Empty); BlockchainConsole.WriteLine($"ELAPSED TIME: {elapsedTime.TotalSeconds} Seconds, DIFFICULTY: {difficulty}, HASH RATE: {Convert.ToInt64(totalHashesCounter / elapsedTime.TotalSeconds)}/Seconds ", ConsoleEventType.Elapsed); } }
private void miningBlocks() { while (_isMining) { if (_networkSynchronizer.IsSynced) { var lastBlock = LastBlock(); lock (_memPool) { var miningAddress = Wallet.NewAddress(); using (BlockchainDbContext db = new BlockchainDbContext()) { var mempoolHashes = _memPool.Select(m => m.GenerateHash()); var existingTransactionsInBlockchain = db.Transactions.Where(t => mempoolHashes.Contains(t.Hash)).ToList(); existingTransactionsInBlockchain.ForEach(t => _memPool.Remove(_memPool.First(m => m.Hash == t.Hash))); var transactionsInBlock = _memPool.OrderByDescending(t => t.TransactionFee).Take(100).ToList(); transactionsInBlock.Insert(0, new Transaction(null, Wallet, new[] { new Output(miningAddress.Key, MiningReward) }.ToList())); _nextBlock = lastBlock == null ? new Block(1, null, transactionsInBlock) : new Block(lastBlock.Height + 1, HashHelper.ByteArrayToHexString(lastBlock.GenerateHash()), transactionsInBlock); } } _nextBlock.MineBlock(CalculateDifficulty(_nextBlock)); if (AddBlock(_nextBlock)) { BlockchainConsole.WriteLine($"MINED BLOCK: {_nextBlock}", ConsoleEventType.MINEDBLOCK); } else { BlockchainConsole.WriteLine($"MINING FAILED: {_nextBlock}", ConsoleEventType.MININGFAILED); } } else { Task.Delay(500); } } }