Browse Source

Merge branch 'inprogress' of Veloe/EthermineBotTelegram into develop

Слияние рабочей версии расчета worker_unpaid #EBT-9
Исправление ошибок #EBT-21 EBT-23
Veloe 4 years ago
parent
commit
0c2006c75c

+ 16 - 0
EthermineBotTelegram/EFDatabase.cs

@@ -16,6 +16,7 @@ namespace EFDatabase
         public DbSet<users> users { get; set; }
         public DbSet<miners> miners { get; set; }
         public DbSet<workers> workers { get; set; }
+        public DbSet<payouts> payouts { get; set; }
 
     }
     
@@ -63,4 +64,19 @@ namespace EFDatabase
         public int invalid_shares { get; set; }
         public double worker_unpaid { get; set; }
     }
+
+    public class payouts
+    {
+        [Key, Column(Order = 0)]
+        [DatabaseGenerated(DatabaseGeneratedOption.None)]
+        public string wallet { get; set; }
+        [Key, Column(Order = 1)]
+        [DatabaseGenerated(DatabaseGeneratedOption.None)]
+        public long time { get; set; }
+        public long amount { get; set; }
+        [Key, Column(Order = 2)]
+        [DatabaseGenerated(DatabaseGeneratedOption.None)]
+        public string worker { get; set; }
+        public double worker_amount { get; set; }
+    }
 }

+ 2 - 0
EthermineBotTelegram/EthermineBotTelegram.csproj

@@ -159,6 +159,8 @@
     <Compile Include="EFDatabase.cs" />
     <Compile Include="JsonCurrentStats.cs" />
     <Compile Include="JsonDownloader.cs" />
+    <Compile Include="JsonEtherscanGas.cs" />
+    <Compile Include="JsonPayouts.cs" />
     <Compile Include="JsonWorker.cs" />
     <Compile Include="NetworkStats.cs" />
     <Compile Include="Program.cs" />

+ 6 - 3
EthermineBotTelegram/JsonCurrentStats.cs

@@ -1,10 +1,10 @@
-namespace EthermineBotTelegram
+namespace JsonCurrentStatsData
 {
     public class Data
     {
         public int time { get; set; }
         public int lastSeen { get; set; }
-        public int reportedHashrate { get; set; }
+        public long reportedHashrate { get; set; }
         public double currentHashrate { get; set; }
         public int validShares { get; set; }
         public int invalidShares { get; set; }
@@ -17,10 +17,13 @@
         public double usdPerMin { get; set; }
         public double btcPerMin { get; set; }
     }
+}
 
+namespace EthermineBotTelegram
+{
     public class JsonCurrentStats
     {
         public string status { get; set; }
-        public Data data { get; set; }
+        public JsonCurrentStatsData.Data data { get; set; }
     }
 }

+ 10 - 0
EthermineBotTelegram/JsonEtherscanGas.cs

@@ -0,0 +1,10 @@
+namespace EthermineBotTelegram
+{
+    public class JsonEtherscanGas
+    {
+        public string status { get; set; }
+        public string message { get; set; }
+        public string result { get; set; }
+    }
+}
+

+ 22 - 0
EthermineBotTelegram/JsonPayouts.cs

@@ -0,0 +1,22 @@
+using System.Collections.Generic;
+
+namespace JsonPayoutsData
+{
+    public class Datа
+    {
+        public int start { get; set; }
+        public int end { get; set; }
+        public long amount { get; set; }
+        public string txHash { get; set; }
+        public int paidOn { get; set; }
+    }
+}
+
+namespace EthermineBotTelegram
+{
+    public class JsonPayouts
+        {
+            public string status { get; set; }
+            public List<JsonPayoutsData.Datа> data { get; set; }
+        }
+}

+ 272 - 158
EthermineBotTelegram/Program.cs

@@ -1,17 +1,12 @@
 using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Data.Entity;
-using System.Data.Entity.Migrations;
 using System.Linq;
-using System.Text;
 using System.Threading.Tasks;
 using Telegram.Bot;
 using Telegram.Bot.Args;
 using Telegram.Bot.Types;
 using Telegram.Bot.Types.Enums;
-using Newtonsoft.Json;
-using System.Net;
+using System.Net.Http;
+using System.Threading;
 using EFDatabase;
 using MySql.Data.MySqlClient;
 using Quartz;
@@ -47,9 +42,6 @@ namespace EthermineBotTelegram
                 Botdb.Database.Connection.Open();
                 Botdb.Database.Connection.Close();
                 
-                
-                //InitUpdater("server=" + AppSettings.dbIp +  ";port=3306;database=botdb;uid=" + user + "; pwd=" + pass);
-            
                 // Grab the Scheduler instance from the Factory
                 StdSchedulerFactory factory = new StdSchedulerFactory();
                 IScheduler scheduler = await factory.GetScheduler();
@@ -73,7 +65,6 @@ namespace EthermineBotTelegram
                 // Tell quartz to schedule the job using our trigger
                 await scheduler.ScheduleJob(job, trigger);
                 
-                
                 Console.WriteLine(("Scheduler started!"));
                 
                 botClient.OnMessage += BotOnMessage;
@@ -121,7 +112,7 @@ namespace EthermineBotTelegram
 
                         // get actual data from ethermine
                         case "/actual":
-                            if (message.Text.Length > 7)
+                            if (message.Text.Split(' ').Length > 1)
                                 GetActualData(e);
                             else
                                 GetActualDataFromDatabase(e.Message.Chat);
@@ -136,7 +127,11 @@ namespace EthermineBotTelegram
                         case "/help":
                             //await SendHelp();
                             break;
-
+                        
+                        case "/gas":
+                            await SendCalcTime(e);
+                            break;
+        
                         default:
                             //await Usage(message);
                             await botClient.SendTextMessageAsync(
@@ -156,27 +151,30 @@ namespace EthermineBotTelegram
                 var currnentStats = JsonDownloader._download_serialized_json_data<JsonCurrentStats>(url);
                 await botClient.SendTextMessageAsync(
                     chatId: e.Message.Chat,
-                    text: "Updated: " + DateTimeOffset.FromUnixTimeSeconds(currnentStats.data.time).LocalDateTime.ToString("f") + "\n"
+                    text: "Updated: " + DateTimeOffset.FromUnixTimeSeconds(currnentStats.data.time).LocalDateTime
+                              .ToString("f") + "\n"
                           + "Reported Hashrate: " + Math.Round(currnentStats.data.reportedHashrate / 1000000D, 3) +
                           " MH/s\n"
                           + "Current Hashrate: " + Math.Round(currnentStats.data.currentHashrate / 1000000D, 3) +
                           " MH/s\n"
                           + "Valid Shares: " + currnentStats.data.validShares + "\n"
                           + "Stale Shares: " + currnentStats.data.staleShares + "\n"
+                          + "Workers: " + currnentStats.data.activeWorkers + "\n"
                           + "Unpaid Balance: " + Math.Round(currnentStats.data.unpaid / Math.Pow(10, 18), 5) + " ETH\n");
             }
-            catch (Exception)
+            catch (Exception exception)
             {
+                await Console.Out.WriteLineAsync(exception.Message);
                 await botClient.SendTextMessageAsync(
                     chatId: e.Message.Chat,
-                    text:   "Something got wrong! Check entered wallet or try later.");
+                    text:   "An exception occurred while executing this command.");
             }
         }
         
         static async void GetActualDataFromDatabase(Chat e)
         {
-            try
-            {
+            //try
+            //{
                 var wallet = Botdb.users.Where(u => u.chat_id == e.Id).Select(u => u.wallet).FirstOrDefault();
                 if (wallet != null)
                 {
@@ -189,14 +187,14 @@ namespace EthermineBotTelegram
                         //var lastWorkerRecord = new workers();
                         var lastTime = Botdb.workers.Where(w => w.wallet == wallet)
                             .Max(w => w.time);
+                        var lastWorkerRecord = Botdb.workers.Where(w => w.wallet == wallet && w.time == lastTime)
+                            .OrderByDescending(w => w.time).ToList();
                         
-                        if (lastTime != null)
+                        if (lastWorkerRecord != null)
                         {
-                            var lastWorkerRecord = Botdb.workers.Where(w => w.wallet == wallet && w.time == lastTime)
-                                .OrderByDescending(w => w.time).ToList();
                             await botClient.SendTextMessageAsync(
                                 chatId: e,
-                                text: $"Miner {lastMinerRecord.wallet} stats\n" +
+                                text: $"Miner {lastMinerRecord.wallet} stats:\n" +
                                       "Updated: " + DateTimeOffset.FromUnixTimeSeconds(lastMinerRecord.time)
                                           .LocalDateTime
                                           .ToString("f") + "\n"
@@ -206,48 +204,67 @@ namespace EthermineBotTelegram
                                       Math.Round(lastMinerRecord.current_hashrate / 1000000D, 3) + " MH/s\n"
                                       + "Valid Shares: " + lastMinerRecord.valid_shares + "\n"
                                       + "Stale Shares: " + lastMinerRecord.stale_shares + "\n"
+                                      + "Workers: " + lastMinerRecord.workers + "\n"
                                       + "Unpaid Balance: " + Math.Round(lastMinerRecord.unpaid / Math.Pow(10, 18), 5) +
                                       " ETH\n");
                             for (int i = 0; i < lastWorkerRecord.Count; i++)
                             {
-                                await botClient.SendTextMessageAsync(
-                                    chatId: e,
-                                    text: $"Worker {lastWorkerRecord[i].worker} stats\n" +
-                                          "Updated: " + DateTimeOffset.FromUnixTimeSeconds(lastWorkerRecord[i].time)
-                                              .LocalDateTime
-                                              .ToString("f") + "\n"
-                                          + "Reported Hashrate: " +
-                                          Math.Round(lastWorkerRecord[i].reported_hashrate / 1000000D, 3) + " MH/s\n"
-                                          + "Current Hashrate: " +
-                                          Math.Round(lastWorkerRecord[i].current_hashrate / 1000000D, 3) + " MH/s\n"
-                                          + "Valid Shares: " + lastWorkerRecord[i].valid_shares + "\n"
-                                          + "Stale Shares: " + lastWorkerRecord[i].stale_shares + "\n"
-                                          + "Unpaid Balance: " +
-                                          Math.Round(lastWorkerRecord[i].worker_unpaid / Math.Pow(10, 18), 5) +
-                                          " ETH\n");
+                                Thread.Sleep(1000);
+                                if (i!=0 && i%20 == 0)                           //TODO SOMETIHNG BETTER THAN USUAL TIMER
+                                    Thread.Sleep(30000);
+                                try
+                                {
+                                    await botClient.SendTextMessageAsync(
+                                        chatId: e,
+                                        text: $"Worker {lastWorkerRecord[i].worker} stats:\n" +
+                                              "Updated: " + DateTimeOffset.FromUnixTimeSeconds(lastWorkerRecord[i].time)
+                                                  .LocalDateTime
+                                                  .ToString("f") + "\n"
+                                              + "Reported Hashrate: " +
+                                              Math.Round(lastWorkerRecord[i].reported_hashrate / 1000000D, 3) + " MH/s\n"
+                                              + "Current Hashrate: " +
+                                              Math.Round(lastWorkerRecord[i].current_hashrate / 1000000D, 3) + " MH/s\n"
+                                              + "Valid Shares: " + lastWorkerRecord[i].valid_shares + "\n"
+                                              + "Stale Shares: " + lastWorkerRecord[i].stale_shares + "\n"
+                                              + "Unpaid Balance: " +
+                                              Math.Round(lastWorkerRecord[i].worker_unpaid / Math.Pow(10, 18), 5) +
+                                              " ETH\n");
+                                }
+                                catch (HttpRequestException exception)
+                                {
+                                    await Console.Out.WriteLineAsync(exception.Message);
+                                }
+                                
                             }
                         }
                         else
                         {
-                            //no worker rows
+                            await botClient.SendTextMessageAsync(
+                                chatId: e,
+                                text:   "No workers data for now!");
                         }
                     }
                     else
                     {
-                        //no miner rows
+                        await botClient.SendTextMessageAsync(
+                            chatId: e,
+                            text:   "No miner data for now!");
                     }
                 }
                 else
                 {
-                    //no wallet exeption
+                    await botClient.SendTextMessageAsync(
+                        chatId: e,
+                        text:   "Set wallet at first! Use /setwallet");
                 }
-            }
-            catch (Exception)
-            {
-                await botClient.SendTextMessageAsync(
-                    chatId: e,
-                    text:   "Something got wrong! Check entered wallet or try later.");
-            }
+            //}
+            //catch (Exception exception)
+            //{
+            //    await Console.Out.WriteLineAsync(exception.Message);
+            //    await botClient.SendTextMessageAsync(
+            //        chatId: e,
+            //        text:   "Something got wrong! Check entered wallet or try later.");
+            //}
         }
         
         static async void GetActualRate(MessageEventArgs e)
@@ -258,7 +275,7 @@ namespace EthermineBotTelegram
                 var networkStats = JsonDownloader._download_serialized_json_data<NetworkStats>(url);
                 await botClient.SendTextMessageAsync(
                     chatId: e.Message.Chat,
-                    text: "ETH: " + networkStats.data.usd + "\n" 
+                    text: "ETH: " + Math.Round(networkStats.data.usd, 2) + "\n" 
                           + "BTC: " + Math.Round(networkStats.data.usd / networkStats.data.btc, 2)
                 );
             }
@@ -266,68 +283,94 @@ namespace EthermineBotTelegram
             {
                 await botClient.SendTextMessageAsync(
                     chatId: e.Message.Chat,
-                    text:   "Something got wrong! Check entered wallet or try later.");
+                    text:   "An exception occurred while executing this command.");
             }
         }
 
         static async void AddUser(Chat e)
         {
-            if (Botdb.users.Where(users => users.chat_id == e.Id).FirstOrDefault() == null)
+            try
             {
-                var newuser = new users();
-                newuser.chat_id = e.Id;
-                Botdb.users.Add(newuser);
-                Botdb.SaveChanges();
-                await botClient.SendTextMessageAsync(
-                    chatId: e,
-                    text:   "Added new user to database. Now you can connect your miner wallet using command /setwallet <address>");
+                if (Botdb.users.Where(users => users.chat_id == e.Id).FirstOrDefault() == null)
+                {
+                    var newuser = new users();
+                    newuser.chat_id = e.Id;
+                    Botdb.users.Add(newuser);
+                    Botdb.SaveChanges();
+                    await botClient.SendTextMessageAsync(
+                        chatId: e,
+                        text:   "Added new user to database. Now you can connect your miner wallet using command /setwallet <address>");
+                }
+                else
+                {
+                    await botClient.SendTextMessageAsync(
+                        chatId: e,
+                        text:   "Already registered");
+                }
             }
-            else
+            catch (Exception exception)
             {
-                await botClient.SendTextMessageAsync(
-                    chatId: e,
-                    text:   "Already registered");
-            
+                await Console.Out.WriteLineAsync(exception.Message);
             }
         }
 
         static async void SetWallet(MessageEventArgs e)
         {
-            if (Botdb.users.Where(u => u.chat_id == e.Message.Chat.Id).FirstOrDefault() != null)
+            try
             {
-                Botdb.users.Where(u => u.chat_id == e.Message.Chat.Id).FirstOrDefault().wallet =
-                    e.Message.Text.Split(' ')[1];
-                Botdb.SaveChanges();
-                await botClient.SendTextMessageAsync(
-                    chatId: e.Message.Chat,
-                    text:   "Wallet set!");
+                if (Botdb.users.Where(u => u.chat_id == e.Message.Chat.Id).FirstOrDefault() != null)
+                {
+                    Botdb.users.Where(u => u.chat_id == e.Message.Chat.Id).FirstOrDefault().wallet = 
+                        e.Message.Text.Split(' ')[1];
+                    Botdb.SaveChanges();
+                    await botClient.SendTextMessageAsync(
+                        chatId: e.Message.Chat,
+                        text:   "Wallet set!");
+                }
+                else
+                {
+                    await botClient.SendTextMessageAsync(
+                        chatId: e.Message.Chat,
+                        text:   "You not registered! Type /start first!");
+                }
             }
-            else
+            catch (Exception exception)
             {
+                await Console.Out.WriteLineAsync(exception.Message);
                 await botClient.SendTextMessageAsync(
                     chatId: e.Message.Chat,
-                    text:   "You not registered! Type /start first!");
+                    text:   "An exception occurred while executing this command.");
             }
         }
 
         static async void DeleteUser(Chat e)
         {
-            if (Botdb.users.Where(users => users.chat_id == e.Id).FirstOrDefault() != null)
+            try
             {
-                var deletableWallet = Botdb.users.Where(u => u.chat_id == e.Id).First().wallet;
-                Botdb.workers.RemoveRange(Botdb.workers.Where(w=> w.wallet == deletableWallet));
-                Botdb.miners.RemoveRange(Botdb.miners.Where(m=> m.wallet == deletableWallet));
-                Botdb.users.RemoveRange(Botdb.users.Where(u=> u.chat_id == e.Id));
-                Botdb.SaveChanges();
-                await botClient.SendTextMessageAsync(
-                    chatId: e,
-                    text:   "Done!");
+                if (Botdb.users.Where(users => users.chat_id == e.Id).FirstOrDefault() != null)
+                {
+                    var deletableWallet = Botdb.users.Where(u => u.chat_id == e.Id).First().wallet;
+                    Botdb.workers.RemoveRange(Botdb.workers.Where(w=> w.wallet == deletableWallet));
+                    Botdb.miners.RemoveRange(Botdb.miners.Where(m=> m.wallet == deletableWallet));
+                    Botdb.users.RemoveRange(Botdb.users.Where(u=> u.chat_id == e.Id));
+                    Botdb.SaveChanges();
+                    await botClient.SendTextMessageAsync(
+                        chatId: e,
+                        text:   "Done!");
+                }
+                else
+                {
+                    await botClient.SendTextMessageAsync(
+                        chatId: e,
+                        text:   "Already deleted");
+                }
             }
-            else
+            catch (Exception exception)
             {
+                await Console.Out.WriteLineAsync(exception.Message);
                 await botClient.SendTextMessageAsync(
                     chatId: e,
-                    text:   "Already deleted");
+                    text:   "An exception occurred while executing this command.");
             }
         }
 
@@ -336,107 +379,178 @@ namespace EthermineBotTelegram
             var usersList = Botdb.users.Where(u=>u.wallet != null).ToList();
             foreach (users u in usersList)
             {
-                var url = AppSettings.poolApiUrl + "/miner/" + u.wallet + "/currentStats";
-                var currnentStats = JsonDownloader._download_serialized_json_data<JsonCurrentStats>(url);
-                
-                if (currnentStats.status == "OK")
+                try
                 {
-                    await Console.Out.WriteLineAsync($"Create new record for {u.wallet}");
-                    miners newMinerRecord = new miners();
-                    newMinerRecord.wallet = u.wallet;
-                    newMinerRecord.time = currnentStats.data.time;
-                    newMinerRecord.reported_hashrate = currnentStats.data.reportedHashrate;
-                    newMinerRecord.current_hashrate = currnentStats.data.currentHashrate;
-                    newMinerRecord.valid_shares = currnentStats.data.validShares;
-                    newMinerRecord.stale_shares = currnentStats.data.staleShares;
-                    newMinerRecord.invalid_shares = currnentStats.data.invalidShares;
-                    newMinerRecord.workers = currnentStats.data.activeWorkers;
-                    newMinerRecord.unpaid = currnentStats.data.unpaid;
-                    await Console.Out.WriteLineAsync($"New record creating complete {newMinerRecord.wallet}");
-                    long lastTime = 0;
-                    if (Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet).FirstOrDefault() != null) 
-                        lastTime = Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet).Max(m => m.time);
-                    var lastMinerRecord = Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet && m.time == lastTime).FirstOrDefault();
-                    if (lastMinerRecord == null || lastMinerRecord.time !=
-                        newMinerRecord.time)
+                    var url = AppSettings.poolApiUrl + "/miner/" + u.wallet + "/currentStats";
+                    var currnentStats = JsonDownloader._download_serialized_json_data<JsonCurrentStats>(url);
+                    
+                    if (currnentStats.status == "OK")
                     {
-                        Botdb.miners.Add(newMinerRecord);
-                        //await Botdb.SaveChangesAsync();
-                        await Console.Out.WriteLineAsync($"Added new row for {newMinerRecord.wallet}");
-                        url = AppSettings.poolApiUrl + "/miner/" + u.wallet + "/workers";
-                        var currentWorker = JsonDownloader._download_serialized_json_data<JsonWorker>(url);
-                        
-                        if (currentWorker.status == "OK")
+                        await Console.Out.WriteLineAsync($"Create new record for {u.wallet}");
+                        miners newMinerRecord = new miners();
+                        newMinerRecord.wallet = u.wallet;
+                        newMinerRecord.time = currnentStats.data.time;
+                        newMinerRecord.reported_hashrate = currnentStats.data.reportedHashrate;
+                        newMinerRecord.current_hashrate = currnentStats.data.currentHashrate;
+                        newMinerRecord.valid_shares = currnentStats.data.validShares;
+                        newMinerRecord.stale_shares = currnentStats.data.staleShares;
+                        newMinerRecord.invalid_shares = currnentStats.data.invalidShares;
+                        newMinerRecord.workers = currnentStats.data.activeWorkers;
+                        newMinerRecord.unpaid = currnentStats.data.unpaid;
+                        await Console.Out.WriteLineAsync($"New record creating complete {newMinerRecord.wallet}");
+                        long lastTime = 0;
+                        if (Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet).FirstOrDefault() != null) 
+                            lastTime = Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet).Max(m => m.time);
+                        var lastMinerRecord = Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet && m.time == lastTime).FirstOrDefault();
+                        if (lastMinerRecord == null || lastMinerRecord.time !=
+                            newMinerRecord.time)
                         {
-                            for (int i = 0; i < currentWorker.data.Count(); i++)
+                            Botdb.miners.Add(newMinerRecord);
+                            //await Botdb.SaveChangesAsync();
+                            await Console.Out.WriteLineAsync($"Added new row for {newMinerRecord.wallet}");
+                            
+                            if (newMinerRecord.unpaid < lastMinerRecord.unpaid)
                             {
-                                await Console.Out.WriteLineAsync($"Create new record for {currentWorker.data[i].worker}");
-                                var newWorkerRecord = new workers();
-                                newWorkerRecord.wallet = newMinerRecord.wallet;
-                                newWorkerRecord.time = currentWorker.data[i].time;
-                                newWorkerRecord.worker = currentWorker.data[i].worker;
-                                newWorkerRecord.reported_hashrate = currentWorker.data[i].reportedHashrate;
-                                newWorkerRecord.current_hashrate = currentWorker.data[i].currentHashrate;
-                                newWorkerRecord.valid_shares = currentWorker.data[i].validShares;
-                                newWorkerRecord.stale_shares = currentWorker.data[i].staleShares;
-                                newWorkerRecord.invalid_shares = currentWorker.data[i].invalidShares;
+                                await botClient.SendTextMessageAsync(
+                                    chatId: Botdb.users.Where(user => user.wallet == newMinerRecord.wallet)
+                                        .FirstOrDefault().chat_id,
+                                    text: "Payout detected!");
+                            }
 
-                                var lastWorkerRecord = Botdb.workers.Where(w => w.worker == newWorkerRecord.worker)
-                                    .OrderByDescending(w => w.time)
-                                    .FirstOrDefault();
-                                if (lastWorkerRecord != null)
+                            url = AppSettings.poolApiUrl + "/miner/" + u.wallet + "/workers";
+                            var currentWorker = JsonDownloader._download_serialized_json_data<JsonWorker>(url);
+                            
+                            if (currentWorker.status == "OK")
+                            {
+                                for (int i = 0; i < currentWorker.data.Count(); i++)
                                 {
-                                    await Console.Out.WriteLineAsync($"lastWorkerRecord time = {lastWorkerRecord.time}");
-                                    lastMinerRecord = Botdb.miners.Where(w => w.wallet == newMinerRecord.wallet)
+                                    await Console.Out.WriteLineAsync($"Create new record for {currentWorker.data[i].worker}");
+                                    var newWorkerRecord = new workers();
+                                    newWorkerRecord.wallet = newMinerRecord.wallet;
+                                    newWorkerRecord.time = currentWorker.data[i].time;
+                                    newWorkerRecord.worker = currentWorker.data[i].worker;
+                                    newWorkerRecord.reported_hashrate = currentWorker.data[i].reportedHashrate;
+                                    newWorkerRecord.current_hashrate = currentWorker.data[i].currentHashrate;
+                                    newWorkerRecord.valid_shares = currentWorker.data[i].validShares;
+                                    newWorkerRecord.stale_shares = currentWorker.data[i].staleShares;
+                                    newWorkerRecord.invalid_shares = currentWorker.data[i].invalidShares;
+
+                                    var lastWorkerRecord = Botdb.workers.Where(w => w.worker == newWorkerRecord.worker)
                                         .OrderByDescending(w => w.time)
                                         .FirstOrDefault();
-                                    if (lastMinerRecord != null)
+                                    if (lastWorkerRecord != null)
                                     {
-                                        await Console.Out.WriteLineAsync($"lastMinerRecord time = {lastMinerRecord.time}");
-                                        //no check that last balance and prev balance are the same
-                                        newWorkerRecord.worker_unpaid = lastWorkerRecord.worker_unpaid +
-                                                                        (newMinerRecord.unpaid -
-                                                                         lastMinerRecord.unpaid) *
-                                                                        (newWorkerRecord.reported_hashrate /
-                                                                         ((double) newMinerRecord.reported_hashrate));
-                                        if (Double.IsNaN(newWorkerRecord.worker_unpaid) ||
-                                            Double.IsInfinity(newWorkerRecord.worker_unpaid))
-                                            newWorkerRecord.worker_unpaid = lastWorkerRecord.worker_unpaid;
-                                        await Console.Out.WriteLineAsync($"newWorkerRecord unpaid change = {newMinerRecord.unpaid - lastMinerRecord.unpaid}");
+                                        await Console.Out.WriteLineAsync($"lastWorkerRecord time = {lastWorkerRecord.time}");
+                                        lastMinerRecord = Botdb.miners.Where(w => w.wallet == newMinerRecord.wallet)
+                                            .OrderByDescending(w => w.time)
+                                            .FirstOrDefault();
+                                        if (lastMinerRecord != null)
+                                        {
+                                            await Console.Out.WriteLineAsync($"lastMinerRecord time = {lastMinerRecord.time}");
+                                            //check for payout
+                                            if (newMinerRecord.unpaid < lastMinerRecord.unpaid)
+                                            {
+                                                url = AppSettings.poolApiUrl + "/miner/" + u.wallet + "/payouts";
+                                                var payouts = JsonDownloader._download_serialized_json_data<JsonPayouts>(url);
+                                                
+                                                await Console.Out.WriteLineAsync($"Last payout time = {DateTimeOffset.FromUnixTimeSeconds(payouts.data[0].paidOn).LocalDateTime.ToString("f")}");
+
+                                                var newPayoutRecord = new payouts();
+                                                newPayoutRecord.wallet = u.wallet;
+                                                newPayoutRecord.time = payouts.data[0].paidOn;
+                                                newPayoutRecord.amount = payouts.data[0].amount;
+                                                newPayoutRecord.worker = newWorkerRecord.worker;
+                                                //calculating payout for worker
+                                                newPayoutRecord.worker_amount = lastWorkerRecord.worker_unpaid +
+                                                    (payouts.data[0].amount -
+                                                     lastMinerRecord.unpaid) *
+                                                    (newWorkerRecord.reported_hashrate /
+                                                     ((double) newMinerRecord.reported_hashrate));
+                                                if (Double.IsNaN(newWorkerRecord.worker_unpaid) ||
+                                                    Double.IsInfinity(newWorkerRecord.worker_unpaid))
+                                                    newPayoutRecord.worker_amount = lastWorkerRecord.worker_unpaid;
+                                                //calculating unpaid for worker
+                                                newWorkerRecord.worker_unpaid = 0 +
+                                                    (newMinerRecord.unpaid) *
+                                                    (newWorkerRecord.reported_hashrate /
+                                                     ((double) newMinerRecord.reported_hashrate));
+                                                if (Double.IsNaN(newWorkerRecord.worker_unpaid) ||
+                                                    Double.IsInfinity(newWorkerRecord.worker_unpaid))
+                                                    newWorkerRecord.worker_unpaid = 0;
+                                            }
+                                            else
+                                            {
+                                                //no check that last balance and prev balance are the same
+                                                newWorkerRecord.worker_unpaid = lastWorkerRecord.worker_unpaid +
+                                                                                (newMinerRecord.unpaid -
+                                                                                 lastMinerRecord.unpaid) *
+                                                                                (newWorkerRecord.reported_hashrate /
+                                                                                 ((double) newMinerRecord.reported_hashrate));
+                                                if (Double.IsNaN(newWorkerRecord.worker_unpaid) ||
+                                                    Double.IsInfinity(newWorkerRecord.worker_unpaid))
+                                                    newWorkerRecord.worker_unpaid = lastWorkerRecord.worker_unpaid;
+                                                await Console.Out.WriteLineAsync($"newWorkerRecord unpaid change = {newMinerRecord.unpaid - lastMinerRecord.unpaid}");
+                                            }
+                                        }
+                                        else
+                                        {
+                                            newWorkerRecord.worker_unpaid = 0;
+                                        }
                                     }
                                     else
                                     {
                                         newWorkerRecord.worker_unpaid = 0;
                                     }
-                                }
-                                else
-                                {
-                                    newWorkerRecord.worker_unpaid = 0;
-                                }
-                                await Console.Out.WriteLineAsync($"newWorkerRecord worker unpaid = {newWorkerRecord.worker_unpaid}");
-                               
-                                if (lastWorkerRecord == null || newWorkerRecord.time != lastWorkerRecord.time)
-                                    Botdb.workers.Add(newWorkerRecord);
-                                //Botdb.SaveChanges();
-                                else
-                                {
-                                    Botdb.workers.Add(newWorkerRecord);
+                                    await Console.Out.WriteLineAsync($"newWorkerRecord worker unpaid = {newWorkerRecord.worker_unpaid}");
+                                    //this if does nothing
+                                    if (lastWorkerRecord == null || newWorkerRecord.time != lastWorkerRecord.time)
+                                    {
+                                        Botdb.workers.Add(newWorkerRecord);
+                                        //await Botdb.SaveChangesAsync();
+                                    }
+                                    //Botdb.SaveChanges();
+                                    else
+                                    {
+                                        Botdb.workers.Add(newWorkerRecord);
+                                        
+                                    }
                                 }
                             }
                         }
+                        else
+                        {
+                            await Console.Out.WriteLineAsync($"Row with wallet: {newMinerRecord.wallet} and time: {newMinerRecord.time} already exists!");
+                        }
+                        
+                        try
+                        {
+                            await Botdb.SaveChangesAsync();
+                            await Console.Out.WriteLineAsync($"Saved");
+                        }
+                        catch (Exception exception)
+                        {
+                            await Console.Out.WriteLineAsync(exception.Message);
+                        }
                     }
                     else
                     {
-                        await Console.Out.WriteLineAsync($"Row with wallet: {newMinerRecord.wallet} and time: {newMinerRecord.time} already exists!");
+                        await Console.Out.WriteLineAsync($"Error response from pool for {u.wallet}!");
                     }
-                    await Botdb.SaveChangesAsync();
-                    await Console.Out.WriteLineAsync($"Saved");
                 }
-                else
+                catch (Exception exception)
                 {
-                    await Console.Out.WriteLineAsync($"Error response from pool for {u.wallet}!");
+                 await Console.Out.WriteLineAsync(exception.Message);
                 }
             }
         }
+
+        static async Task SendCalcTime(MessageEventArgs e)
+        {
+            var url = "https://api.etherscan.io/api?module=gastracker&action=gasestimate&gasprice=" + e.Message.Text.Split(' ')[1] + "000000000";
+            var etherscanGas = JsonDownloader._download_serialized_json_data<JsonEtherscanGas>(url);
+            await botClient.SendTextMessageAsync(
+                chatId: e.Message.Chat,
+                text:   $"Estimated Confirmation Duration: {etherscanGas.result} seconds");
+        }
     }
 }