public async Task GetBlockCount()
        {
            while (true)
            {
                try
                {
                    ApiResponse response = await BlockChainEngineApi.GetBlockCount();

                    if (response.HasError)
                    {
                        throw new Exception();
                    }
                    else
                    {
                        long result = response.GetResult <long>();
                        Assert.IsNotNull(result);
                    }
                    Thread.Sleep(8000);
                }
                catch (Exception ex)
                {
                    Assert.Fail();
                }
            }
        }
Пример #2
0
        static void Run(string[] args)
        {
            var app = new CommandLineApplication(false);

            app.HelpOption("-?|-h|--help");
            app.OnExecute(() =>
            {
                app.ShowHelp();
                return;
            });
            app.Command("mining", command =>
            {
                command.Description = "begin mining";
                command.HelpOption("-?|-h|--help");
                CommandArgument nameArgument    = command.Argument("[minerName]", "minerName");
                CommandArgument addressArgument = command.Argument("[walletAddress]", "walletAddress");
                command.OnExecute(async() =>
                {
                    if (nameArgument != null && !string.IsNullOrEmpty(nameArgument.Value) && addressArgument != null && !string.IsNullOrEmpty(addressArgument.Value))
                    {
                        string name     = nameArgument.Value;
                        string address  = addressArgument.Value;
                        Program program = new Program();
                        BlockChainStatus chainStatus = await program.GetChainStatus();
                        if (chainStatus == null)
                        {
                            app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain");
                            return;
                        }
                        //验证本地区块高度和网络区块高度
                        ApiResponse response = await NetworkApi.GetBlockChainInfo();
                        if (!response.HasError)
                        {
                            BlockChainInfo info = response.GetResult <BlockChainInfo>();
                            if (info.IsRunning)
                            {
                                if (info.RemoteLatestBlockHeight <= info.LocalLastBlockHeight)
                                {
                                    command.Out.WriteLine($"current network is {chainStatus.ChainNetwork}");
                                    //validate wallet address
                                    if (AddressTools.AddressVerfy(chainStatus.ChainNetwork, address))
                                    {
                                        command.Out.WriteLine($"address verify success. prepare to mine");
                                        await BlockMining.MiningAsync(name, address);
                                    }
                                    else
                                    {
                                        command.Out.WriteLine($"address verify fail. address: {address} is invalid");
                                        return;
                                    }
                                }
                                else
                                {
                                    command.Out.WriteLine("Block Chain is in sync, please try it later");
                                    return;
                                }
                            }
                            else
                            {
                                command.Out.WriteLine("Block Chain has stopped");
                                return;
                            }
                        }
                        else
                        {
                            command.Out.WriteLine(response.Error.Message);
                            return;
                        }
                    }
                    else
                    {
                        command.ShowHelp();
                        return;
                    }
                });
            });
            app.Command("height", command =>
            {
                command.Description = "view current block height";
                command.OnExecute(async() =>
                {
                    Program program = new Program();
                    BlockChainStatus chainStatus = await program.GetChainStatus();
                    if (chainStatus == null)
                    {
                        app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain");
                        return;
                    }
                    ApiResponse response = await BlockChainEngineApi.GetBlockCount();
                    if (!response.HasError)
                    {
                        long result = response.GetResult <long>();
                        command.Out.WriteLine($"current block height is {result}");
                    }
                    else
                    {
                        command.Out.WriteLine($"{response.Error.Message}");
                    }
                });
            });
            app.Command("balance", command =>
            {
                command.Description = "view wallet balance";
                command.OnExecute(async() =>
                {
                    Program program = new Program();
                    BlockChainStatus chainStatus = await program.GetChainStatus();
                    if (chainStatus == null)
                    {
                        app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain");
                        return;
                    }
                    ApiResponse response = await UtxoApi.GetTxOutSetInfo();
                    if (!response.HasError)
                    {
                        TxOutSet set = response.GetResult <TxOutSet>();
                        command.Out.WriteLine($"wallet balance is :{set.Total_amount}");
                    }
                });
            });
            app.Command("transaction", command =>
            {
                command.Description            = "view recent transaction record(default 5 content)";
                CommandArgument recordArgument = command.Argument("[count]", "record content");
                command.OnExecute(async() =>
                {
                    if (recordArgument != null && !string.IsNullOrEmpty(recordArgument.Value))
                    {
                        if (int.TryParse(recordArgument.Value, out int count))
                        {
                            Program program = new Program();
                            BlockChainStatus chainStatus = await program.GetChainStatus();
                            if (chainStatus == null)
                            {
                                app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain");
                                return;
                            }
                            ApiResponse response = await TransactionApi.ListTransactions("*", count);
                            if (!response.HasError)
                            {
                                List <Payment> result = response.GetResult <List <Payment> >();
                                if (result != null && result.Count > 0)
                                {
                                    command.Out.WriteLine("recent transaction record blow:");
                                    foreach (var item in result)
                                    {
                                        //time(需要转换为DataTime), comment, amount
                                        string time = new DateTime(1970, 1, 1).AddMilliseconds(item.Time).ToString("yyyy-MM-dd HH:mm:ss");
                                        command.Out.WriteLine($"Time:{time}; Comment:{item.Comment}; Amount:{item.Amount}");
                                    }
                                }
                                else
                                {
                                    command.Out.WriteLine("no recent transaction record.");
                                }
                            }
                        }
                        else
                        {
                            command.ShowHelp();
                        }
                    }
                    else
                    {
                        Program program = new Program();
                        BlockChainStatus chainStatus = await program.GetChainStatus();
                        if (chainStatus == null)
                        {
                            app.Out.WriteLine("there is something wrong with the api, you should check the fiiichain");
                            return;
                        }
                        ApiResponse response = await TransactionApi.ListTransactions();
                        if (!response.HasError)
                        {
                            List <Payment> result = response.GetResult <List <Payment> >();
                            if (result != null && result.Count > 0)
                            {
                                command.Out.WriteLine("recent transaction record blow:");
                                foreach (var item in result)
                                {
                                    //time(需要转换为DataTime), comment, amount
                                    string time = new DateTime(1970, 1, 1).AddMilliseconds(item.Time).ToString("yyyy-MM-dd HH:mm:ss");
                                    command.Out.WriteLine($"Time:{time}; Comment:{item.Comment}; Amount:{item.Amount}");
                                }
                            }
                            else
                            {
                                command.Out.WriteLine("no recent transaction record.");
                            }
                        }
                    }
                });
            });

            /*
             * if (args.Length > 1 && args[0].ToLower() == "fiiipay" && IsContainsCommand(args[1]))
             * {
             *  List<string> list = new List<string>(args);
             *  list.RemoveAt(0);
             *  app.Execute(list.ToArray());
             * }
             */
            if (args != null && args.Length > 0 && IsContainsCommand(args[0]))
            {
                app.Execute(args);
            }
            else
            {
                app.Execute(new[] { "-?" });
            }
        }
Пример #3
0
        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();
                    }
                });
            }
        }