package main import ( "fmt" "math" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" ethmineapi "GoEthemineTelegramBot/ethermineapi" ) func (c *Connection) UpdateData() { LogInfo.Println("Updating data!") walletList, err := c.UniqueWallets() if err != nil { LogError.Println(err); return } for _, wallet := range walletList { c.UpdateWallet(wallet) } } func (c *Connection) UpdateWallet(wallet string) { LogInfo.Printf(">> Getting data for wallet %s\n", wallet) LogInfo.Printf("From: %s/miner/%s/currentStats\n", appSettings.ApiUrl, wallet) // Get current stats for miner currentStats, err := ethmineapi.MinerStats(appSettings.ApiUrl, wallet) if err != nil { LogWarn.Println(err); return } if currentStats.Status != "OK" { LogError.Printf("Error getting response from pool for %s!\n", wallet); return } // Line 42 of UpdateData.cs // Search for the latest record for miner lastMinerRecord, err := c.LatestMinerRecord(wallet) if err != nil { LogError.Println(err); return } // Exist previous record with the same time if lastMinerRecord.Time == currentStats.Data.Time { LogInfo.Printf("Row with wallet: %s and time: %d already exists!", wallet, currentStats.Data.Time) return } LogInfo.Printf("Creating new record for miner %s, time %d\n", wallet, currentStats.Data.Time) // Line 28 of UpdateData.cs newMinerRecord := Miner { Wallet: wallet, Time: currentStats.Data.Time, ReportedHashrate: currentStats.Data.ReportedHashrate, CurrentHashrate: currentStats.Data.CurrentHashrate, ValidShares: currentStats.Data.ValidShares, StaleShares: currentStats.Data.StaleShares, InvalidShares: currentStats.Data.InvalidShares, Workers: currentStats.Data.ActiveWorkers, Unpaid: currentStats.Data.Unpaid, } result := c.GormDb.Create(&newMinerRecord) if result.Error != nil { LogError.Println(result.Error) return } LogInfo.Printf("Added new row for miner %s\n", newMinerRecord.Wallet) // Line 54 of UpdateData.cs if lastMinerRecord != (Miner{}) && newMinerRecord.Unpaid < lastMinerRecord.Unpaid { walletChats, err := c.ChatsWithWallet(newMinerRecord.Wallet) if err != nil { LogError.Println(err) } else { for _, chat := range walletChats { LogInfo.Println("Sended 'Payout detected!' message to chat ", chat) go myBotClient.Send(tgbotapi.NewMessage(chat, "Payout detected!")) } } } // Line 64 of UpdateData.cs LogInfo.Printf("Getting workers data for wallet %s\n", wallet) LogInfo.Printf("From: %s/miner/%s", appSettings.ApiUrl, wallet) currentWorker, err := ethmineapi.Workers(appSettings.ApiUrl, wallet) if err != nil { LogWarn.Println(err); return } if currentWorker.Status != "OK" { return } // Unsure is it occurs if len(currentWorker.Data) == 0 { LogInfo.Printf("data in response from %s for workers of wallet %s not an interface!\n", appSettings.ApiUrl, wallet) return } for _, workerData := range currentWorker.Data { LogInfo.Printf("Creating new worker record for %s, time %d\n", workerData.Worker, workerData.Time) newWorkerRecord := Worker{ Wallet: newMinerRecord.Wallet, Time: workerData.Time, Worker: workerData.Worker, ReportedHashrate: workerData.ReportedHashrate, CurrentHashrate: workerData.CurrentHashrate, ValidShares: workerData.ValidShares, StaleShares: workerData.StaleShares, InvalidShares: workerData.InvalidShares, } LogInfo.Printf("New worker record creating complete %s", newWorkerRecord.Worker) //Search for latest record for worker lastWorkerRecord, err := c.LatestWorkerRecord(workerData.Worker) if err != nil { LogError.Println(err); continue } // Line 85 of UpdateData.cs if lastWorkerRecord != (Worker{}) { //check for payout if newMinerRecord.Unpaid < lastMinerRecord.Unpaid { // Adding new payout field to db payouts, err := ethmineapi.Payouts(appSettings.ApiUrl, wallet) if err != nil { LogError.Println(err); continue } if (len(payouts.Data) == 0) { LogWarn.Println("No actual payouts for wallet", wallet) continue } lastPayout := payouts.Data[0] LogInfo.Println("Last payout time =", lastPayout.PaidOn) newPayoutRecord := Payout{ Wallet: wallet, Time: lastPayout.PaidOn, Amount: lastPayout.Amount, Worker: workerData.Worker, } workerAmount := float64(lastWorkerRecord.WorkerUnpaid+ (float64(lastPayout.Amount-lastMinerRecord.Unpaid))) * (float64(workerData.ReportedHashrate) / float64(newMinerRecord.ReportedHashrate)) if math.IsNaN(workerAmount) || math.IsInf(workerAmount, 0) { workerAmount = lastWorkerRecord.WorkerUnpaid } newPayoutRecord.WorkerAmount = workerAmount workerUnpaid := float64(newMinerRecord.Unpaid) * (float64(workerData.ReportedHashrate) / float64(newMinerRecord.ReportedHashrate)) LogDebug.Println("newMinerRecord.Unpaid:", newMinerRecord.Unpaid) LogDebug.Println("lastMinerRecord.Unpaid:", lastMinerRecord.Unpaid) LogDebug.Println("workerData.ReportedHashrate:", workerData.ReportedHashrate) LogDebug.Println("newMinerRecord.ReportedHashrate:", newMinerRecord.ReportedHashrate) LogDebug.Println("workerUnpaid:", workerUnpaid) if math.IsNaN(workerUnpaid) || math.IsInf(workerUnpaid, 0) { LogDebug.Println("workerUnpaid is NaN or Inf") workerUnpaid = 0 } newWorkerRecord.WorkerUnpaid = workerUnpaid result = c.GormDb.Create(&newPayoutRecord) if result.Error != nil { LogError.Println(result.Error) return } LogInfo.Println("Added newPayoutRecord, time =", newPayoutRecord.Time) //removing old records result = c.GormDb. Where("wallet = ? AND time < ?", newPayoutRecord.Wallet, newPayoutRecord.Time). Delete(Worker{}) if result.Error != nil { LogError.Println(result.Error) } result = c.GormDb. Where("wallet = ? AND time < ?", newPayoutRecord.Wallet, newPayoutRecord.Time). Delete(Miner{}) if result.Error != nil { LogError.Println(result.Error) } result = c.GormDb. Where("wallet = ? AND time < ?", newPayoutRecord.Wallet, newPayoutRecord.Time). Delete(Payout{}) if result.Error != nil { LogError.Println(result.Error) } //Line 135 of UpdateData.cs } else { //no check that last balance and prev balance are the same //don't sure > or >= //TODO rewrite this var max int64 result := c.GormDb.Model(&Payout{}). Where("wallet = ?", lastWorkerRecord.Wallet). Order("time desc"). Limit(1). Select("time"). Scan(&max) if result.Error != nil { LogWarn.Printf("No payouts data for %s! Time is set to 0!\n", lastWorkerRecord.Wallet) LogError.Println(result.Error) max = 0 } if lastWorkerRecord.Time > max { workerUnpaid := float64(lastWorkerRecord.WorkerUnpaid+ float64(newMinerRecord.Unpaid-lastMinerRecord.Unpaid)) * (float64(workerData.ReportedHashrate) / float64(newMinerRecord.ReportedHashrate)) if math.IsNaN(workerUnpaid) || math.IsInf(workerUnpaid, 0) { workerUnpaid = lastWorkerRecord.WorkerUnpaid } newWorkerRecord.WorkerUnpaid = workerUnpaid // Line 169 of UpdateData.cs } else { workerUnpaid := float64((newMinerRecord.Unpaid - lastMinerRecord.Unpaid)) * (float64(workerData.ReportedHashrate) / float64(newMinerRecord.ReportedHashrate)) if math.IsNaN(workerUnpaid) || math.IsInf(workerUnpaid, 0) { workerUnpaid = lastWorkerRecord.WorkerUnpaid } newWorkerRecord.WorkerUnpaid = workerUnpaid var targetedChats []int64 result = c.GormDb.Model(&User{}). Where("wallet = ?", newMinerRecord.Wallet). Select("DISTINCT(chat_id)"). Scan(&targetedChats) if result.Error != nil { LogError.Println(result.Error) } else { msg := fmt.Sprintf("Debug info: Your worker %s hasn't been zeroed on payout!", workerData.Worker) for _, chatId := range targetedChats { go myBotClient.Send(tgbotapi.NewMessage(int64(chatId), msg)) } LogDebug.Printf("Worker %s on address %s hasn't been zeroed on payout!\n", workerData.Worker, wallet) } } } // Line 196 of UpdateData.cs } else { LogDebug.Println("Setting WorkerUnpaid to 0") newWorkerRecord.WorkerUnpaid = 0 } rowExists, err := c.IsWorkerRowExists(newWorkerRecord.Worker, newWorkerRecord.Time) if err != nil { LogError.Println(err); return } if rowExists { LogInfo.Printf("Error adding new row: row with worker: %s, time: %d already exists!\n", newWorkerRecord.Worker, newWorkerRecord.Time) return } result = c.GormDb.Create(&newWorkerRecord) if result.Error != nil { LogError.Println(result.Error) return } LogInfo.Printf("Added new row for worker %s\n", newWorkerRecord.Worker) } }