public static async Task <ApiResponse> GetDifficulty() { ApiResponse response = new ApiResponse(); try { BlockChainEngine engine = new BlockChainEngine(); BlockDifficultyOM result = await engine.GetDifficulty(); if (result != null) { response.Result = Newtonsoft.Json.Linq.JToken.FromObject(result); } else { response.Result = null; } } catch (ApiCustomException ex) { Logger.Singleton.Error(ex.Message); Logger.Singleton.Error("Api error code is:" + ex.ErrorCode.ToString()); Logger.Singleton.Error("Api error reason is:" + ex.InnerException.ToString()); response.Error = new ApiError(ex.ErrorCode, ex.Message); } catch (Exception ex) { Logger.Singleton.Error(ex.Message); Logger.Singleton.Error("Custom error code is:" + ex.HResult); Logger.Singleton.Error("Custom error reason is:" + ex.InnerException); response.Error = new ApiError(ex.HResult, ex.Message); } return(response); }
public async Task GetDifficulty() { BlockChainEngine engine = new BlockChainEngine(); BlockDifficultyOM result = await engine.GetDifficulty(); Assert.IsNotNull(result); }
public async Task GetDifficulty() { ApiResponse response = await BlockChainEngineApi.GetDifficulty(); Assert.IsFalse(response.HasError); BlockDifficultyOM result = response.GetResult <BlockDifficultyOM>(); Assert.IsNotNull(result); }
public async Task <BlockDifficultyOM> GetDifficulty() { AuthenticationHeaderValue authHeaderValue = null; RpcClient client = new RpcClient(new Uri(WalletNetwork.NetWork), authHeaderValue, null, null, "application/json"); RpcRequest request = RpcRequest.WithNoParameters("GetDifficulty", 1); RpcResponse response = await client.SendRequestAsync(request); if (response.HasError) { throw new ApiCustomException(response.Error.Code, response.Error.Message); } BlockDifficultyOM responseValue = response.GetResult <BlockDifficultyOM>(); return(responseValue); }
public static async Task MiningAsync(string minerName, string walletAddress) { while (true) { try { Console.WriteLine("new mining start"); bool isStop = false; bool isHeightChanged = false; ApiResponse response = await BlockChainEngineApi.GenerateNewBlock(minerName, walletAddress, 1); if (!response.HasError) { BlockInfoOM block = response.GetResult <BlockInfoOM>(); List <byte> blockData = new List <byte>(); foreach (BlockTransactionsOM tx in block.Transactions) { blockData.AddRange(tx.Serialize()); } string strDifficulty = string.Empty; ApiResponse difficultyResponse = await BlockChainEngineApi.GetDifficulty(); if (!difficultyResponse.HasError) { BlockDifficultyOM blockDifficulty = difficultyResponse.GetResult <BlockDifficultyOM>(); strDifficulty = blockDifficulty.HashTarget; } else { Logger.Singleton.Error(difficultyResponse.Error.Code.ToString()); Logger.Singleton.Error(difficultyResponse.Error.Message); Console.WriteLine(response.Error.Message); return; } //var cts = new CancellationTokenSource(); //var ct = cts.Token; //开启新线程 /* * Task task1 = Task.Run(async () => * { * try * { * Console.WriteLine("new thread validate block height"); * int count = 0; * while (!isStop) * { * ApiResponse tempResponse = await BlockChainEngineApi.GetBlockCount(); * if (!tempResponse.HasError) * { * count = 0; * Logger.Singleton.Info($"current count is {count}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); * long height = tempResponse.GetResult<long>(); * Console.WriteLine($"current height of the chain is {height}"); * if (height >= block.Header.Height) * { * isStop = true; * isHeightChanged = true; * ct.ThrowIfCancellationRequested(); * cts.Cancel(); * } * } * else * { * count++; * Logger.Singleton.Warn($"current count is {count}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); * if (count >= 5) * { * Logger.Singleton.Error(tempResponse.Error.Code.ToString()); * Logger.Singleton.Error(tempResponse.Error.Message); * isStop = true; * ct.ThrowIfCancellationRequested(); * cts.Cancel(); * } * } * * Console.WriteLine("thread will sleep 5 seconds"); * Thread.Sleep(3000); * } * } * catch (Exception ex) * { * cts.Cancel(); * Console.WriteLine($"something wrong with the application interface, {ex.ToString()}"); * isStop = true; * } * }, ct); */ Thread checkHeightThread = new Thread(async() => { try { Console.WriteLine("new thread validate block height"); int count = 0; while (!isStop) { ApiResponse tempResponse = await BlockChainEngineApi.GetBlockCount(); if (!tempResponse.HasError) { count = 0; //Logger.Singleton.Info($"current count is {count}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); long height = tempResponse.GetResult <long>(); Console.WriteLine($"current height of the chain is {height}"); if (height >= block.Header.Height) { isStop = true; isHeightChanged = true; //ct.ThrowIfCancellationRequested(); //cts.Cancel(); } } else { count++; Logger.Singleton.Warn($"current count is {count}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); if (count >= 3) { Logger.Singleton.Error(tempResponse.Error.Code.ToString()); Logger.Singleton.Error(tempResponse.Error.Message); isStop = true; //ct.ThrowIfCancellationRequested(); //cts.Cancel(); } } Console.WriteLine("thread will sleep 5 seconds"); Thread.Sleep(3000); } } catch (Exception ex) { //cts.Cancel(); Console.WriteLine($"something wrong with the application interface, {ex.ToString()}"); isStop = true; } }); checkHeightThread.Priority = ThreadPriority.Highest; checkHeightThread.Start(); Parallel.For(0L, Int64.MaxValue, new ParallelOptions { MaxDegreeOfParallelism = 10 }, async(i, loopState) => { if (isStop) { Console.WriteLine($"new thread has been stopped, stop main thread"); loopState.Stop(); return; } List <byte> newBuffer = new List <byte>(blockData.ToArray()); byte[] nonceBytes = BitConverter.GetBytes(i); if (BitConverter.IsLittleEndian) { Array.Reverse(nonceBytes); } newBuffer.AddRange(nonceBytes); string result = Base16.Encode( HashHelper.Hash( newBuffer.ToArray() )); Console.WriteLine($"current nonce is {i}, current datetime is {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ms")}"); if (BlockInfoOM.Verify(strDifficulty, result)) { loopState.Stop(); //区块头的时间戳 block.Header.Timestamp = TimeHelper.EpochTime; //区块头的随机数 block.Header.Nonce = i; //区块头的hash block.Header.Hash = block.Header.GetHash(); //提交区块 Console.WriteLine($"verify success. nonce is {i}, block hash is {block.Header.Hash}"); ApiResponse submitResponse = await BlockChainEngineApi.SubmitBlock(Base16.Encode(block.Serialize())); if (!submitResponse.HasError) { //停止循环 //break; Logger.Singleton.Debug("A New Block " + block.Header.Height + "has been created, the correct nonce is " + i); } else { Console.WriteLine(submitResponse.Error.Message); Console.WriteLine(submitResponse.Error.Code.ToString()); if (submitResponse.Error.Code == 2060001) { isStop = true; isHeightChanged = true; } else { Environment.Exit(0); } } } }); if (isStop) { if (isHeightChanged) { Console.WriteLine("block height changed, new loop will start"); continue; } else { Console.WriteLine("something wrong with the application interface, system exit"); Environment.Exit(0); return; } } } else { Logger.Singleton.Error(response.Error.Code.ToString()); Logger.Singleton.Error(response.Error.Message); Console.WriteLine(response.Error.Message); Environment.Exit(0); return; } } catch (Exception ex) { Logger.Singleton.Error(ex.ToString()); Logger.Singleton.Error(ex.ToString()); Environment.Exit(0); return; } } }
public async Task BlockMining() { bool isStop = false; ApiResponse response = await BlockChainEngineApi.GenerateNewBlock("Zhangsan", "", 1); if (!response.HasError) { BlockInfoOM block = response.GetResult <BlockInfoOM>(); List <byte> blockData = new List <byte>(); foreach (BlockTransactionsOM tx in block.Transactions) { blockData.AddRange(tx.Serialize()); } string strDifficulty = string.Empty; //long blockHeight = 0; ApiResponse difficultyResponse = await BlockChainEngineApi.GetDifficulty(); if (!difficultyResponse.HasError) { BlockDifficultyOM blockDifficulty = difficultyResponse.GetResult <BlockDifficultyOM>(); strDifficulty = blockDifficulty.HashTarget; } //ApiResponse heightResponse = await BlockChainEngineApi.GetBlockCount(); //if (!heightResponse.HasError) //{ // blockHeight = heightResponse.GetResult<long>(); //} var cts = new CancellationTokenSource(); var ct = cts.Token; //开启新线程 Task task1 = Task.Run(async() => { Console.WriteLine("New Task Start"); while (!isStop) { Console.WriteLine("Loop is start"); ApiResponse tempResponse = await BlockChainEngineApi.GetBlockCount(); if (!tempResponse.HasError) { long height = tempResponse.GetResult <long>(); if (height >= block.Header.Height) { isStop = true; cts.Cancel(); } } Console.WriteLine("I will sleep 5000 millseconds"); Thread.Sleep(5000); } }, ct); Parallel.For(0L, Int64.MaxValue, new ParallelOptions { MaxDegreeOfParallelism = 2 }, async(i, loopState) => { Console.WriteLine("Parallel start"); //根据BlockData初始化一个List<byte> List <byte> newBuffer = new List <byte>(blockData.ToArray()); //获取随机的64位数的字节 byte[] nonceBytes = BitConverter.GetBytes(i); //存储在此计算机体系结构中的字节顺序 if (BitConverter.IsLittleEndian) { //翻转整个byte[]顺序 Array.Reverse(nonceBytes); } //随机数添加到List<byte>的末尾 newBuffer.AddRange(nonceBytes); //List<byte>转化为byte[]数组先Hash后Base16编码 string result = Base16.Encode( HashHelper.Hash( newBuffer.ToArray() )); Console.WriteLine("begin verify data"); //block头验证,校验不成功,继续循环 if (BlockInfoOM.Verify(strDifficulty, result)) { Console.WriteLine("Verify success"); //区块头的时间戳 block.Header.Timestamp = TimeHelper.EpochTime; //区块头的随机数 block.Header.Nonce = i; //区块头的hash block.Header.Hash = block.Header.GetHash(); //提交区块 ApiResponse submitResponse = await BlockChainEngineApi.SubmitBlock(Base16.Encode(block.Serialize())); if (!submitResponse.HasError) { //停止循环 loopState.Stop(); Logger.Singleton.Debug("A New Block " + block.Header.Height + "has been created, the correct nonce is " + i); } } if (isStop) { ct.ThrowIfCancellationRequested(); cts.Cancel(); await BlockMining(); } }); } }