using System; using System.Linq; using EFDatabase; using Microsoft.EntityFrameworkCore; using System.Threading.Tasks; namespace EthermineBotTelegramCore { partial class Program { public static async Task UpdateData() { var walletList = Botdb.users.Where(u=>u.wallet != null).Select(u=> u.wallet).Distinct().ToList(); foreach (string wallet in walletList) { try { var url = AppSettings.poolApiUrl + "/miner/" + wallet + "/currentStats"; var currentStats = JsonDownloader._download_serialized_json_data(url); if (currentStats.status == "OK") { { string message = $"Create new record for {wallet}, time {currentStats.data.time}"; await Console.Out.WriteLineAsync(message); await Logger.LogInfo(message); } var newMinerRecord = new miners(); newMinerRecord.wallet = wallet; newMinerRecord.time = currentStats.data.time; newMinerRecord.reported_hashrate = currentStats.data.reportedHashrate; newMinerRecord.current_hashrate = currentStats.data.currentHashrate; newMinerRecord.valid_shares = currentStats.data.validShares; newMinerRecord.stale_shares = currentStats.data.staleShares; newMinerRecord.invalid_shares = currentStats.data.invalidShares; newMinerRecord.workers = currentStats.data.activeWorkers; newMinerRecord.unpaid = currentStats.data.unpaid; await Logger.LogInfo($"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) { Botdb.miners.Add(newMinerRecord); //await Botdb.SaveChangesAsync(); { string message = $"Added new row for {newMinerRecord.wallet}"; await Logger.LogInfo(message); await Console.Out.WriteLineAsync(message); } if (lastMinerRecord != null && newMinerRecord.unpaid < lastMinerRecord.unpaid) { foreach (var chat_id in Botdb.users.Where(user => user.wallet == newMinerRecord.wallet).Select(u=> u.chat_id)) { await botClient.SendTextMessageAsync( chatId: chat_id, text: "Payout detected!"); } } url = AppSettings.poolApiUrl + "/miner/" + wallet + "/workers"; var currentWorker = JsonDownloader._download_serialized_json_data(url); if (currentWorker.status == "OK") { for (int i = 0; i < currentWorker.data.Count(); i++) { await Logger.LogInfo($"Create new record for {currentWorker.data[i].worker}, time {currentWorker.data[i].time}"); 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 (lastWorkerRecord != null) { //await Logger.LogInfo($"lastWorkerRecord time = {lastWorkerRecord.time}"); lastMinerRecord = Botdb.miners.Where(w => w.wallet == newMinerRecord.wallet) .OrderByDescending(w => w.time) .FirstOrDefault(); if (lastMinerRecord != null) { //await Logger.LogInfo($"lastMinerRecord time = {lastMinerRecord.time}"); //check for payout if (newMinerRecord.unpaid < lastMinerRecord.unpaid) { url = AppSettings.poolApiUrl + "/miner/" + wallet + "/payouts"; var payouts = JsonDownloader._download_serialized_json_data(url); await Logger.LogInfo($"Last payout time = {payouts.data[0].paidOn}"); var newPayoutRecord = new payouts(); newPayoutRecord.wallet = 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; Botdb.payouts.Add(newPayoutRecord); string message = $"Add newPayoutRecord, time = {newPayoutRecord.time}"; await Logger.LogInfo(message); await Console.Out.WriteLineAsync(message); //removing old records Botdb.workers.RemoveRange(Botdb.workers.Where(w=> w.wallet == newPayoutRecord.wallet && w.time < newPayoutRecord.time)); Botdb.miners.RemoveRange(Botdb.miners.Where(m=> m.wallet == newPayoutRecord.wallet && m.time < newPayoutRecord.time)); Botdb.payouts.RemoveRange(Botdb.payouts.Where(p=> p.wallet == newPayoutRecord.wallet)); } else { //no check that last balance and prev balance are the same //don't sure > or >= //TODO rewrite this long max; try { max = Botdb.payouts.Where(p => p.wallet == lastWorkerRecord.wallet).Select(p => p.time).MaxAsync().Result; } catch (Exception exception) { string message = $"No payouts data for {lastWorkerRecord.wallet}! Time is set to 0!"; await Console.Out.WriteLineAsync(message); await Logger.LogWarn(message); //await Logger.LogError(exception.Message); //await Logger.LogError(exception.Source); //await Logger.LogError(exception.StackTrace); max = 0; } //await Console.Out.WriteLineAsync(max..ToString()); if (lastWorkerRecord.time > max) { 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 Logger.LogInfo($"newWorkerRecord unpaid change = {newMinerRecord.unpaid - lastMinerRecord.unpaid}"); } else { newWorkerRecord.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 Logger.LogInfo($"newWorkerRecord unpaid change = {newMinerRecord.unpaid - lastMinerRecord.unpaid}"); foreach (var chat_id in Botdb.users.Where(u=> u.wallet == newMinerRecord.wallet).Select(u=> u.wallet)) { await botClient.SendTextMessageAsync( chatId: chat_id, text: $"Debug info: Your worker {newWorkerRecord.worker} hasn't been zeroed on payout!\n"); await Logger.LogDebug($"Worker {newWorkerRecord.worker} on address {newWorkerRecord.wallet} hasn't been zeroed on payout!"); } } } } else { newWorkerRecord.worker_unpaid = 0; } } else { newWorkerRecord.worker_unpaid = 0; } //await Logger.LogInfo($"newWorkerRecord worker unpaid = {newWorkerRecord.worker_unpaid}"); //this if does nothing if (newWorkerRecord.reported_hashrate != 0) { if (lastWorkerRecord == null || newWorkerRecord.time != lastWorkerRecord.time) { Botdb.workers.Add(newWorkerRecord); //await Botdb.SaveChangesAsync(); } //Botdb.SaveChanges(); else { Botdb.workers.Add(newWorkerRecord); } string message = $"Added new row for {newWorkerRecord.worker}"; await Logger.LogInfo(message); await Console.Out.WriteLineAsync(message); } } } } else { string message = $"Row with wallet: {newMinerRecord.wallet} and time: {newMinerRecord.time} already exists!"; await Console.Out.WriteLineAsync(message); await Logger.LogInfo(message); } try { await Botdb.SaveChangesAsync(); string message = $"Saved data for {newMinerRecord.wallet}"; await Console.Out.WriteLineAsync(message); await Logger.LogInfo(message); } catch (Exception exception) { foreach (var entity in Botdb.payouts.Local) { var entry = Botdb.Entry(entity); if (entry.State == EntityState.Added) entry.State = EntityState.Detached; } foreach (var entity in Botdb.workers.Local) { var entry = Botdb.Entry(entity); if (entry.State == EntityState.Added) entry.State = EntityState.Detached; } foreach (var entity in Botdb.miners.Local) { var entry = Botdb.Entry(entity); if (entry.State == EntityState.Added) entry.State = EntityState.Detached; } await Console.Out.WriteLineAsync("An exception occurred while updating data. See log file to get full info."); await Logger.LogError(exception.Message); await Logger.LogError(exception.Source); await Logger.LogError(exception.StackTrace); } } else { await Console.Out.WriteLineAsync($"Error response from pool for {wallet}!"); await Logger.LogError($"Error response from pool for {wallet}!"); } } catch (Exception exception) { await Console.Out.WriteLineAsync("An exception occurred while updating data. See log file to get full info."); await Logger.LogError(exception.Message); await Logger.LogError(exception.Source); await Logger.LogError(exception.StackTrace); } } } } }