UpdateData.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. using System;
  2. using System.Linq;
  3. using EFDatabase;
  4. using Microsoft.EntityFrameworkCore;
  5. using System.Threading.Tasks;
  6. namespace EthermineBotTelegramCore
  7. {
  8. partial class Program
  9. {
  10. public static async Task UpdateData()
  11. {
  12. var walletList = Botdb.users.Where(u=>u.wallet != null).Select(u=> u.wallet).Distinct().ToList();
  13. foreach (string wallet in walletList)
  14. {
  15. try
  16. {
  17. var url = AppSettings.poolApiUrl + "/miner/" + wallet + "/currentStats";
  18. var currentStats = JsonDownloader._download_serialized_json_data<JsonCurrentStats>(url);
  19. if (currentStats.status == "OK")
  20. {
  21. {
  22. string message = $"Create new record for {wallet}, time {currentStats.data.time}";
  23. await Console.Out.WriteLineAsync(message);
  24. await Logger.LogInfo(message);
  25. }
  26. var newMinerRecord = new miners();
  27. newMinerRecord.wallet = wallet;
  28. newMinerRecord.time = currentStats.data.time;
  29. newMinerRecord.reported_hashrate = currentStats.data.reportedHashrate;
  30. newMinerRecord.current_hashrate = currentStats.data.currentHashrate;
  31. newMinerRecord.valid_shares = currentStats.data.validShares;
  32. newMinerRecord.stale_shares = currentStats.data.staleShares;
  33. newMinerRecord.invalid_shares = currentStats.data.invalidShares;
  34. newMinerRecord.workers = currentStats.data.activeWorkers;
  35. newMinerRecord.unpaid = currentStats.data.unpaid;
  36. await Logger.LogInfo($"New record creating complete {newMinerRecord.wallet}");
  37. long lastTime = 0;
  38. if (Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet).FirstOrDefault() != null)
  39. lastTime = Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet).Max(m => m.time);
  40. var lastMinerRecord = Botdb.miners.Where(m => m.wallet == newMinerRecord.wallet && m.time == lastTime).FirstOrDefault();
  41. if (lastMinerRecord == null || lastMinerRecord.time !=
  42. newMinerRecord.time)
  43. {
  44. Botdb.miners.Add(newMinerRecord);
  45. //await Botdb.SaveChangesAsync();
  46. {
  47. string message = $"Added new row for {newMinerRecord.wallet}";
  48. await Logger.LogInfo(message);
  49. await Console.Out.WriteLineAsync(message);
  50. }
  51. if (lastMinerRecord != null && newMinerRecord.unpaid < lastMinerRecord.unpaid)
  52. {
  53. foreach (var chat_id in Botdb.users.Where(user => user.wallet == newMinerRecord.wallet).Select(u=> u.chat_id))
  54. {
  55. await botClient.SendTextMessageAsync(
  56. chatId: chat_id,
  57. text: "Payout detected!");
  58. }
  59. }
  60. url = AppSettings.poolApiUrl + "/miner/" + wallet + "/workers";
  61. var currentWorker = JsonDownloader._download_serialized_json_data<JsonWorker>(url);
  62. if (currentWorker.status == "OK")
  63. {
  64. for (int i = 0; i < currentWorker.data.Count(); i++)
  65. {
  66. await Logger.LogInfo($"Create new record for {currentWorker.data[i].worker}, time {currentWorker.data[i].time}");
  67. var newWorkerRecord = new workers();
  68. newWorkerRecord.wallet = newMinerRecord.wallet;
  69. newWorkerRecord.time = currentWorker.data[i].time;
  70. newWorkerRecord.worker = currentWorker.data[i].worker;
  71. newWorkerRecord.reported_hashrate = currentWorker.data[i].reportedHashrate;
  72. newWorkerRecord.current_hashrate = currentWorker.data[i].currentHashrate;
  73. newWorkerRecord.valid_shares = currentWorker.data[i].validShares;
  74. newWorkerRecord.stale_shares = currentWorker.data[i].staleShares;
  75. newWorkerRecord.invalid_shares = currentWorker.data[i].invalidShares;
  76. var lastWorkerRecord = Botdb.workers.Where(w => w.worker == newWorkerRecord.worker)
  77. .OrderByDescending(w => w.time)
  78. .FirstOrDefault();
  79. if (lastWorkerRecord != null)
  80. {
  81. //await Logger.LogInfo($"lastWorkerRecord time = {lastWorkerRecord.time}");
  82. lastMinerRecord = Botdb.miners.Where(w => w.wallet == newMinerRecord.wallet)
  83. .OrderByDescending(w => w.time)
  84. .FirstOrDefault();
  85. if (lastMinerRecord != null)
  86. {
  87. //await Logger.LogInfo($"lastMinerRecord time = {lastMinerRecord.time}");
  88. //check for payout
  89. if (newMinerRecord.unpaid < lastMinerRecord.unpaid)
  90. {
  91. url = AppSettings.poolApiUrl + "/miner/" + wallet + "/payouts";
  92. var payouts = JsonDownloader._download_serialized_json_data<JsonPayouts>(url);
  93. await Logger.LogInfo($"Last payout time = {payouts.data[0].paidOn}");
  94. var newPayoutRecord = new payouts();
  95. newPayoutRecord.wallet = wallet;
  96. newPayoutRecord.time = payouts.data[0].paidOn;
  97. newPayoutRecord.amount = payouts.data[0].amount;
  98. newPayoutRecord.worker = newWorkerRecord.worker;
  99. //calculating payout for worker
  100. newPayoutRecord.worker_amount = lastWorkerRecord.worker_unpaid +
  101. (payouts.data[0].amount -
  102. lastMinerRecord.unpaid) *
  103. (newWorkerRecord.reported_hashrate /
  104. ((double) newMinerRecord.reported_hashrate));
  105. if (Double.IsNaN(newWorkerRecord.worker_unpaid) ||
  106. Double.IsInfinity(newWorkerRecord.worker_unpaid))
  107. newPayoutRecord.worker_amount = lastWorkerRecord.worker_unpaid;
  108. //calculating unpaid for worker
  109. newWorkerRecord.worker_unpaid = 0 +
  110. (newMinerRecord.unpaid) *
  111. (newWorkerRecord.reported_hashrate /
  112. ((double) newMinerRecord.reported_hashrate));
  113. if (Double.IsNaN(newWorkerRecord.worker_unpaid) ||
  114. Double.IsInfinity(newWorkerRecord.worker_unpaid))
  115. newWorkerRecord.worker_unpaid = 0;
  116. Botdb.payouts.Add(newPayoutRecord);
  117. string message = $"Add newPayoutRecord, time = {newPayoutRecord.time}";
  118. await Logger.LogInfo(message);
  119. await Console.Out.WriteLineAsync(message);
  120. //removing old records
  121. Botdb.workers.RemoveRange(Botdb.workers.Where(w=> w.wallet == newPayoutRecord.wallet && w.time < newPayoutRecord.time));
  122. Botdb.miners.RemoveRange(Botdb.miners.Where(m=> m.wallet == newPayoutRecord.wallet && m.time < newPayoutRecord.time));
  123. Botdb.payouts.RemoveRange(Botdb.payouts.Where(p=> p.wallet == newPayoutRecord.wallet));
  124. }
  125. else
  126. {
  127. //no check that last balance and prev balance are the same
  128. //don't sure > or >=
  129. //TODO rewrite this
  130. long max;
  131. try
  132. {
  133. max = Botdb.payouts.Where(p => p.wallet == lastWorkerRecord.wallet).Select(p => p.time).MaxAsync().Result;
  134. }
  135. catch (Exception exception)
  136. {
  137. string message = $"No payouts data for {lastWorkerRecord.wallet}! Time is set to 0!";
  138. await Console.Out.WriteLineAsync(message);
  139. await Logger.LogWarn(message);
  140. //await Logger.LogError(exception.Message);
  141. //await Logger.LogError(exception.Source);
  142. //await Logger.LogError(exception.StackTrace);
  143. max = 0;
  144. }
  145. //await Console.Out.WriteLineAsync(max..ToString());
  146. if (lastWorkerRecord.time > max)
  147. {
  148. newWorkerRecord.worker_unpaid = lastWorkerRecord.worker_unpaid +
  149. (newMinerRecord.unpaid -
  150. lastMinerRecord.unpaid) *
  151. (newWorkerRecord.reported_hashrate /
  152. ((double) newMinerRecord.reported_hashrate));
  153. if (Double.IsNaN(newWorkerRecord.worker_unpaid) ||
  154. Double.IsInfinity(newWorkerRecord.worker_unpaid))
  155. newWorkerRecord.worker_unpaid = lastWorkerRecord.worker_unpaid;
  156. //await Logger.LogInfo($"newWorkerRecord unpaid change = {newMinerRecord.unpaid - lastMinerRecord.unpaid}");
  157. }
  158. else
  159. {
  160. newWorkerRecord.worker_unpaid =
  161. (newMinerRecord.unpaid -
  162. lastMinerRecord.unpaid) *
  163. (newWorkerRecord.reported_hashrate /
  164. ((double) newMinerRecord.reported_hashrate));
  165. if (Double.IsNaN(newWorkerRecord.worker_unpaid) ||
  166. Double.IsInfinity(newWorkerRecord.worker_unpaid))
  167. newWorkerRecord.worker_unpaid = lastWorkerRecord.worker_unpaid;
  168. //await Logger.LogInfo($"newWorkerRecord unpaid change = {newMinerRecord.unpaid - lastMinerRecord.unpaid}");
  169. foreach (var chat_id in Botdb.users.Where(u=> u.wallet == newMinerRecord.wallet).Select(u=> u.wallet))
  170. {
  171. await botClient.SendTextMessageAsync(
  172. chatId: chat_id,
  173. text: $"Debug info: Your worker {newWorkerRecord.worker} hasn't been zeroed on payout!\n");
  174. await Logger.LogDebug($"Worker {newWorkerRecord.worker} on address {newWorkerRecord.wallet} hasn't been zeroed on payout!");
  175. }
  176. }
  177. }
  178. }
  179. else
  180. {
  181. newWorkerRecord.worker_unpaid = 0;
  182. }
  183. }
  184. else
  185. {
  186. newWorkerRecord.worker_unpaid = 0;
  187. }
  188. //await Logger.LogInfo($"newWorkerRecord worker unpaid = {newWorkerRecord.worker_unpaid}");
  189. //this if does nothing
  190. if (newWorkerRecord.reported_hashrate != 0)
  191. {
  192. if (lastWorkerRecord == null || newWorkerRecord.time != lastWorkerRecord.time)
  193. {
  194. Botdb.workers.Add(newWorkerRecord);
  195. //await Botdb.SaveChangesAsync();
  196. }
  197. //Botdb.SaveChanges();
  198. else
  199. {
  200. Botdb.workers.Add(newWorkerRecord);
  201. }
  202. string message = $"Added new row for {newWorkerRecord.worker}";
  203. await Logger.LogInfo(message);
  204. await Console.Out.WriteLineAsync(message);
  205. }
  206. }
  207. }
  208. }
  209. else
  210. {
  211. string message =
  212. $"Row with wallet: {newMinerRecord.wallet} and time: {newMinerRecord.time} already exists!";
  213. await Console.Out.WriteLineAsync(message);
  214. await Logger.LogInfo(message);
  215. }
  216. try
  217. {
  218. await Botdb.SaveChangesAsync();
  219. string message = $"Saved data for {newMinerRecord.wallet}";
  220. await Console.Out.WriteLineAsync(message);
  221. await Logger.LogInfo(message);
  222. }
  223. catch (Exception exception)
  224. {
  225. foreach (var entity in Botdb.payouts.Local)
  226. {
  227. var entry = Botdb.Entry(entity);
  228. if (entry.State == EntityState.Added)
  229. entry.State = EntityState.Detached;
  230. }
  231. foreach (var entity in Botdb.workers.Local)
  232. {
  233. var entry = Botdb.Entry(entity);
  234. if (entry.State == EntityState.Added)
  235. entry.State = EntityState.Detached;
  236. }
  237. foreach (var entity in Botdb.miners.Local)
  238. {
  239. var entry = Botdb.Entry(entity);
  240. if (entry.State == EntityState.Added)
  241. entry.State = EntityState.Detached;
  242. }
  243. await Console.Out.WriteLineAsync("An exception occurred while updating data. See log file to get full info.");
  244. await Logger.LogError(exception.Message);
  245. await Logger.LogError(exception.Source);
  246. await Logger.LogError(exception.StackTrace);
  247. }
  248. }
  249. else
  250. {
  251. await Console.Out.WriteLineAsync($"Error response from pool for {wallet}!");
  252. await Logger.LogError($"Error response from pool for {wallet}!");
  253. }
  254. }
  255. catch (Exception exception)
  256. {
  257. await Console.Out.WriteLineAsync("An exception occurred while updating data. See log file to get full info.");
  258. await Logger.LogError(exception.Message);
  259. await Logger.LogError(exception.Source);
  260. await Logger.LogError(exception.StackTrace);
  261. }
  262. }
  263. }
  264. }
  265. }