static async Task DoStuff()
        {
            MiningBlockInfoResponse         lastBlockInfo = null;
            Task <Tuple <ulong, DateTime> > t             = null;

            while (true)
            {
                var bi = GetLatestBlockInfo(myAddress);
                if (bi == null)
                {
                    Console.WriteLine("No connection to server, sleeping for a second..");
                    await Task.Delay(1000);

                    continue;
                }

                if (t == null)//nothing here, let's do some mining
                {
                    Console.WriteLine($"[{DateTime.UtcNow}] Mining started, block {bi.Index}, hash: {bi.BlockDataHash}, difficulty: {bi.Difficulty}");
                    t             = MineAsync(bi.BlockDataHash, bi.Difficulty);
                    lastBlockInfo = bi;
                }
                else if (t.IsCompleted) //we're done, let's get some $$
                {
                    if (SubmitMinedBlockInfo(myAddress, t.Result.Item1, t.Result.Item2, lastBlockInfo.BlockDataHash))
                    {
                        Console.WriteLine($"[{DateTime.UtcNow}] Found a result for block {lastBlockInfo.Index}, $$ is on the way");
                    }

                    t = null;
                }
                else if (lastBlockInfo.Index < bi.Index)
                {//new block, start mining it
                    Console.WriteLine($"[{DateTime.UtcNow}] New block, ditching the old one and starting the new one");
                    t = null;
                }
                else if (lastBlockInfo.BlockDataHash != bi.BlockDataHash && lastBlockInfo.Transactions[0].Value < bi.Transactions[0].Value)
                {//better reward, let's cancel and start mining again
                    Console.WriteLine($"[{DateTime.UtcNow}] Higher reward, ditching the old job and starting the new one");
                    t = null;
                }
                else //same block, and we're still mining, so will sit for a second and see what comes next;
                {
                    await Task.Delay(1000);
                }
            }
        }
        public MiningBlockInfo GetMiningBlockInfo(string address)
        {
            lock (dbService.GetTransactionsLockObject())
            {
                var transactions = new List <Transaction>(dbService.GetTransactions().ToArray());//shallow copy, so we can keep a snapshot
                var lbi          = dbService.GetLastBlock().Index + 1;

                //reward for the miner
                var t = new Transaction()
                {
                    DateCreated        = DateTime.UtcNow,
                    Fee                = 0,
                    To                 = address,
                    Value              = appSettings.MinerReward + transactions.Aggregate(0, (sum, tr) => sum + tr.Fee),
                    From               = ZERO_HASH,
                    MinedInBlockIndex  = lbi,
                    TransferSuccessful = true
                };

                t.TransactionHashHex = t.CalculateTransactionHashHex();

                transactions.Insert(0, t);

                var info = new MiningBlockInfo
                {
                    Difficulty        = appSettings.Difficulty,
                    Index             = lbi,
                    MinedBy           = address,
                    PreviousBlockHash = dbService.GetLastBlock().BlockHash,
                    Transactions      = transactions
                };

                dbService.AddMiningInfo(info);

                return(MiningBlockInfoResponse.FromMiningBlockInfo(info));
            }
        }