func (c *Controller) ChangeCreditor() (string, error) { txType := "ChangeCreditor" txTypeId := utils.TypeInt(txType) timeNow := time.Now().Unix() creditId := utils.Round(utils.StrToFloat64(c.Parameters["credit_id"]), 0) log.Debug("creditId", creditId) TemplateStr, err := makeTemplate("change_creditor", "changeCreditor", &changeCreditorPage{ Alert: c.Alert, Lang: c.Lang, CountSignArr: c.CountSignArr, ShowSignData: c.ShowSignData, UserId: c.SessUserId, TimeNow: timeNow, TxType: txType, TxTypeId: txTypeId, SignData: "", CreditId: creditId}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) RepaymentCredit() (string, error) { txType := "RepaymentCredit" txTypeId := utils.TypeInt(txType) timeNow := time.Now().Unix() creditId := utils.Round(utils.StrToFloat64(c.Parameters["credit_id"]), 0) TemplateStr, err := makeTemplate("repayment_credit", "repaymentCredit", &repaymentCreditPage{ Alert: c.Alert, Lang: c.Lang, CountSignArr: c.CountSignArr, ShowSignData: c.ShowSignData, UserId: c.SessUserId, TimeNow: timeNow, TxType: txType, TxTypeId: txTypeId, SignData: "", CreditId: creditId, CurrencyList: c.CurrencyList}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) SaveGeolocation() (string, error) { if c.SessRestricted != 0 { return "", utils.ErrInfo(errors.New("Permission denied")) } c.r.ParseForm() geolocation := c.r.FormValue("geolocation") if len(geolocation) > 0 { x := strings.Split(geolocation, ", ") if len(x) == 2 { geolocationLat := utils.Round(utils.StrToFloat64(x[0]), 5) geolocationLon := utils.Round(utils.StrToFloat64(x[1]), 5) err := c.ExecSql("UPDATE "+c.MyPrefix+"my_table SET geolocation = ?", utils.Float64ToStrGeo(geolocationLat)+", "+utils.Float64ToStrGeo(geolocationLon)) if err != nil { return "", utils.ErrInfo(err) } } } return `{"error":"0"}`, nil }
func (c *Controller) Points() (string, error) { // список отравленных нами запросов pointsStatus, err := c.GetAll("SELECT * FROM "+c.MyPrefix+"points_status WHERE user_id = ? ORDER BY time_start DESC", -1, c.SessUserId) myPoints, err := c.Single("SELECT points FROM points WHERE user_id = ?", c.SessUserId).Int64() if err != nil { return "", utils.ErrInfo(err) } // среднее значение mean, err := c.Single("SELECT sum(points)/count(points) FROM points WHERE points > 0").Float64() if err != nil { return "", utils.ErrInfo(err) } mean = utils.Round(mean*c.Variables.Float64["points_factor"], 0) // есть ли тр-ия с голосованием votes_complex за послдение 4 недели count, err := c.Single("SELECT count(user_id) FROM votes_miner_pct WHERE user_id = ? AND time > ?", c.SessUserId, utils.Time()-c.Variables.Int64["limit_votes_complex_period"]*2).Int64() if err != nil { return "", utils.ErrInfo(err) } votesOk := "NO" if count > 0 { votesOk = "YES" } TemplateStr, err := makeTemplate("points", "points", &PointsPage{ Alert: c.Alert, Lang: c.Lang, CountSignArr: c.CountSignArr, ShowSignData: c.ShowSignData, UserId: c.SessUserId, SignData: "", VotesOk: votesOk, MyPoints: myPoints, PointsStatus: pointsStatus, Mean: mean}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (p *Parser) ChangePromisedAmount() error { // возможно нужно обновить таблицу points_status err := p.pointsUpdateMain(p.TxUserID) if err != nil { return p.ErrInfo(err) } pct, err := p.GetPct() if err != nil { return p.ErrInfo(err) } maxPromisedAmounts, err := p.GetMaxPromisedAmounts() if err != nil { return p.ErrInfo(err) } // логируем предыдущее var prevLogId, currencyId, tdcAmountUpdate int64 var amount, tdcAmount float64 err = p.QueryRow(p.FormatQuery("SELECT log_id, currency_id, amount, tdc_amount, tdc_amount_update FROM promised_amount WHERE id = ?"), p.TxMaps.Int64["promised_amount_id"]).Scan(&prevLogId, ¤cyId, &amount, &tdcAmount, &tdcAmountUpdate) if err != nil && err != sql.ErrNoRows { return p.ErrInfo(err) } logId, err := p.ExecSqlGetLastInsertId("INSERT INTO log_promised_amount ( amount, tdc_amount, tdc_amount_update, block_id, prev_log_id ) VALUES ( ?, ?, ?, ?, ? )", "log_id", amount, tdcAmount, tdcAmountUpdate, p.BlockData.BlockId, prevLogId) if err != nil { return p.ErrInfo(err) } userHolidays, err := p.GetHolidays(p.TxUserID) if err != nil { return p.ErrInfo(err) } pointsStatus, err := p.GetPointsStatus(p.TxUserID, p.Variables.Int64["points_update_time"], p.BlockData) if err != nil { return p.ErrInfo(err) } // то, от чего будем вычислять набежавшие % tdcSum := amount + tdcAmount // то, что успело набежать repaidAmount, err := p.GetRepaidAmount(currencyId, p.TxUserID) calcProfit, err := p.calcProfit_(tdcSum, tdcAmountUpdate, p.BlockData.Time, pct[currencyId], pointsStatus, userHolidays, maxPromisedAmounts[currencyId], currencyId, repaidAmount) newTdc := tdcAmount + calcProfit if err != nil { return p.ErrInfo(err) } err = p.ExecSql("UPDATE promised_amount SET amount = ?, tdc_amount = ?, tdc_amount_update = ?, log_id = ? WHERE id = ?", p.TxMaps.Money["amount"], utils.Round(newTdc, 2), p.BlockData.Time, logId, p.TxMaps.Int64["promised_amount_id"]) if err != nil { return p.ErrInfo(err) } return nil }
func (c *Controller) WalletsListCfProject() (string, error) { var err error c.r.ParseForm() projectId := utils.StrToInt64(c.r.FormValue("project_id")) if projectId == 0 { return "", errors.New("projectId == 0") } cfProject, err := c.OneRow("SELECT id, amount, currency_id, end_time FROM cf_projects WHERE del_block_id = 0 AND id = ?", projectId).String() if err != nil { return "", utils.ErrInfo(err) } //id, endTime, langId int64, amount float64, levelUp string CfProjectData, err := c.GetCfProjectData(projectId, utils.StrToInt64(cfProject["end_time"]), c.LangInt, utils.StrToFloat64(cfProject["amount"]), "") for k, v := range CfProjectData { cfProject[k] = v } // сколько у нас есть DC данной валюты wallet, err := c.OneRow("SELECT amount, currency_id, last_update FROM wallets WHERE user_id = ? AND currency_id = ?", c.SessUserId, cfProject["currency_id"]).String() if err != nil { return "", utils.ErrInfo(err) } if len(wallet) > 0 { amount := utils.StrToMoney(wallet["amount"]) profit, err := c.CalcProfitGen(utils.StrToInt64(wallet["currency_id"]), amount, c.SessUserId, utils.StrToInt64(wallet["last_update"]), time.Now().Unix(), "wallet") if err != nil { return "", utils.ErrInfo(err) } amount += profit amount = math.Floor(utils.Round(amount, 3)*100) / 100 forexOrdersAmount, err := c.Single("SELECT sum(amount) FROM forex_orders WHERE user_id = ? AND sell_currency_id = ? AND del_block_id = 0", c.SessUserId, wallet["currency_id"]).Float64() if err != nil { return "", utils.ErrInfo(err) } amount -= forexOrdersAmount cfProject["wallet_amount"] = utils.Float64ToStrPct(amount) } else { cfProject["wallet_amount"] = "0" } cfProject["currency"] = c.CurrencyList[utils.StrToInt64(cfProject["currency_id"])] newmap := make(map[string]interface{}) for k, v := range cfProject { newmap[k] = v } // наличие описаний newmap["lang"], err = c.GetMap("SELECT id, lang_id FROM cf_projects_data WHERE project_id = ?", "id", "lang_id", projectId) if err != nil { return "", utils.ErrInfo(err) } result, err := json.Marshal(newmap) if err != nil { return "", utils.ErrInfo(err) } return string(result), nil }
func (p *Parser) NewMiner() error { tcpHost := "" if p.BlockData != nil && p.BlockData.BlockId < 250900 { re := regexp.MustCompile(`^https?:\/\/([0-9a-z\_\.\-:]+)\/`) match := re.FindStringSubmatch(p.TxMaps.String["http_host"]) if len(match) != 0 { tcpHost = match[1] + ":8088" } } else { tcpHost = p.TxMaps.String["tcp_host"] } // получим массив майнеров, которые должны скопировать к себе 2 фото лица юзера maxMinerId, err := p.DCDB.Single("SELECT max(miner_id) FROM miners").Int64() if err != nil { return p.ErrInfo(err) } // т.к. у юзера это может быть не первая попытка стать майнером, то отменяем голосования по всем предыдущим err = p.DCDB.ExecSql("UPDATE votes_miners SET votes_end = 1, end_block_id = ? WHERE user_id = ? AND type = 'node_voting' AND end_block_id = 0 AND votes_end = 0", p.BlockData.BlockId, p.TxUserID) if err != nil { return p.ErrInfo(err) } // создаем новое голосование для нодов err = p.DCDB.ExecSql("INSERT INTO votes_miners (type, user_id, votes_start_time) VALUES ('node_voting', ?, ?)", p.TxUserID, p.BlockData.Time) if err != nil { return p.ErrInfo(err) } // переведем все координаты в отрезки. var faceCoords [][2]int err = json.Unmarshal(p.TxMap["face_coords"], &faceCoords) if err != nil { return p.ErrInfo(err) } faceCoords = append([][2]int{{0, 0}}, faceCoords...) // получим отрезки data, err := p.DCDB.OneRow("SELECT segments, version FROM spots_compatibility").String() if err != nil { return p.ErrInfo(err) } spotsVersion := data["version"] var segments map[string]map[string][]string err = json.Unmarshal([]byte(data["segments"]), &segments) if err != nil { return p.ErrInfo(err) } n := len(segments["face"]) + 1 faceRelations := make([]float64, n, n) faceRelations[0] = utils.PpLenght(faceCoords[1], faceCoords[2]) for num, spots := range segments["face"] { // 1. ширина головы // 2. глаз-нос // 3. нос-губа // 4. губа-подбородок // 5. ширина челюсти faceRelations[utils.StrToInt(num)] = utils.Round((utils.PpLenght(faceCoords[utils.StrToInt(spots[0])], faceCoords[utils.StrToInt(spots[1])]) / faceRelations[0]), 4) } faceRelations[0] = 1 // переведем все координаты в отрезки. var profileCoords [][2]int err = json.Unmarshal(p.TxMap["profile_coords"], &profileCoords) if err != nil { return p.ErrInfo(err) } profileCoords = append([][2]int{{0, 0}}, profileCoords...) n = len(segments["profile"]) + 1 profileRelations := make([]float64, n, n) profileRelations[0] = utils.PpLenght(profileCoords[1], profileCoords[2]) for num, spots := range segments["profile"] { // 1. край уха - край носа // 2. глаз - край носа // 3. подбородок - низ уха // 4. верх уха - низ уха profileRelations[utils.StrToInt(num)] = utils.Round((utils.PpLenght(profileCoords[utils.StrToInt(spots[0])], profileCoords[utils.StrToInt(spots[1])]) / profileRelations[0]), 4) } profileRelations[0] = 1 addSql := make(map[string]string) addSql["names"] = "" addSql["values"] = "" addSql["upd"] = "" for j := 1; j < len(faceRelations); j++ { addSql["names"] += fmt.Sprintf("f%v,\n", j) addSql["values"] += fmt.Sprintf("'%v',\n", faceRelations[j]) addSql["upd"] += fmt.Sprintf("f%v='%v',\n", j, faceRelations[j]) } for j := 1; j < len(profileRelations); j++ { addSql["names"] += fmt.Sprintf("p%v,\n", j) addSql["values"] += fmt.Sprintf("'%v',\n", profileRelations[j]) addSql["upd"] += fmt.Sprintf("p%v='%v',\n", j, profileRelations[j]) } addSql["names"] = addSql["names"][0 : len(addSql["names"])-2] addSql["values"] = addSql["values"][0 : len(addSql["values"])-2] addSql["upd"] = addSql["upd"][0 : len(addSql["upd"])-2] // Для откатов // проверим, есть ли в БД запись, которую нужно залогировать logData, err := p.DCDB.OneRow("SELECT * FROM faces WHERE user_id = ?", p.TxUserID).String() if err != nil { return p.ErrInfo(err) } if len(logData) > 0 { addSql1 := "" addSql2 := "" for i := 1; i <= 20; i++ { addSql1 += fmt.Sprintf("f%v, ", i) addSql2 += fmt.Sprintf("%v,", logData[fmt.Sprintf("f%v", i)]) } for i := 1; i <= 20; i++ { addSql1 += fmt.Sprintf("p%v, ", i) addSql2 += fmt.Sprintf("%v,", logData[fmt.Sprintf("p%v", i)]) } // для откатов logId, err := p.ExecSqlGetLastInsertId(` INSERT INTO log_faces ( user_id, version, status, race, country, `+addSql1+` prev_log_id, block_id ) VALUES ( `+logData["user_id"]+`, `+logData["version"]+`, '`+logData["status"]+`', `+logData["race"]+`, `+logData["country"]+`, `+addSql2+` `+logData["log_id"]+`, `+utils.Int64ToStr(p.BlockData.BlockId)+` )`, "log_id") if err != nil { return p.ErrInfo(err) } err = p.ExecSql("UPDATE faces SET "+addSql["upd"]+", version = ?, race = ?, country = ?, log_id = ? WHERE user_id = ?", spotsVersion, p.TxMaps.Int64["race"], p.TxMaps.Int64["country"], logId, p.TxUserID) if err != nil { return p.ErrInfo(err) } } else { // это первая запись в таблицу, и лог писать не с чего err = p.ExecSql(` INSERT INTO faces ( user_id, version, race, country, ` + addSql["names"] + ` ) VALUES ( ` + string(p.TxMap["user_id"]) + `, '` + spotsVersion + `', ` + string(p.TxMap["race"]) + `, ` + string(p.TxMap["country"]) + `, ` + addSql["values"] + ` )`) if err != nil { return p.ErrInfo(err) } } // проверим, есть ли в БД запись, которую надо залогировать logData, err = p.OneRow("SELECT * FROM miners_data WHERE user_id = ?", p.TxUserID).String() if err != nil { return p.ErrInfo(err) } if len(logData) > 0 { logData["node_public_key"] = string(utils.BinToHex([]byte(logData["node_public_key"]))) // для откатов logId, err := p.ExecSqlGetLastInsertId(` INSERT INTO log_miners_data ( user_id, miner_id, status, node_public_key, face_hash, profile_hash, photo_block_id, photo_max_miner_id, miners_keepers, face_coords, profile_coords, video_type, video_url_id, http_host, tcp_host, latitude, longitude, country, block_id, prev_log_id ) VALUES ( ?, ?, ?, [hex], ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) `, "log_id", logData["user_id"], logData["miner_id"], logData["status"], logData["node_public_key"], logData["face_hash"], logData["profile_hash"], logData["photo_block_id"], logData["photo_max_miner_id"], logData["miners_keepers"], logData["face_coords"], logData["profile_coords"], logData["video_type"], logData["video_url_id"], logData["http_host"], logData["tcp_host"], logData["latitude"], logData["longitude"], logData["country"], p.BlockData.BlockId, logData["log_id"]) if err != nil { return p.ErrInfo(err) } // обновляем таблу err = p.ExecSql(` UPDATE miners_data SET node_public_key = [hex], face_hash = ?, profile_hash = ?, photo_block_id = ?, photo_max_miner_id = ?, miners_keepers = ?, face_coords = ?, profile_coords = ?, video_type = ?, video_url_id = ?, latitude = ?, longitude = ?, country = ?, http_host = ?, tcp_host = ?, log_id = ? WHERE user_id = ?`, p.TxMap["node_public_key"], p.TxMaps.String["face_hash"], p.TxMaps.String["profile_hash"], p.BlockData.BlockId, maxMinerId, p.Variables.Int64["miners_keepers"], p.TxMaps.String["face_coords"], p.TxMaps.String["profile_coords"], p.TxMaps.String["video_type"], p.TxMaps.String["video_url_id"], p.TxMaps.Float64["latitude"], p.TxMaps.Float64["longitude"], p.TxMaps.Int64["country"], p.TxMaps.String["http_host"], tcpHost, logId, p.TxUserID) if err != nil { return p.ErrInfo(err) } } else { err = p.ExecSql(` INSERT INTO miners_data ( user_id, node_public_key, face_hash, profile_hash, photo_block_id, photo_max_miner_id, miners_keepers, face_coords, profile_coords, video_type, video_url_id, latitude, longitude, country, http_host, tcp_host ) VALUES (?, [hex], ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, p.TxUserID, p.TxMap["node_public_key"], p.TxMaps.String["face_hash"], p.TxMaps.String["profile_hash"], p.BlockData.BlockId, maxMinerId, p.Variables.Int64["miners_keepers"], p.TxMaps.String["face_coords"], p.TxMaps.String["profile_coords"], p.TxMaps.String["video_type"], p.TxMaps.String["video_url_id"], p.TxMaps.Float64["latitude"], p.TxMaps.Float64["longitude"], p.TxMaps.Int64["country"], p.TxMaps.String["http_host"], tcpHost) if err != nil { return p.ErrInfo(err) } } // проверим, не наш ли это user_id myUserId, myBlockId, myPrefix, _, err := p.GetMyUserId(p.TxUserID) if err != nil { return err } if p.TxUserID == myUserId && myBlockId <= p.BlockData.BlockId { err = p.DCDB.ExecSql("UPDATE "+myPrefix+"my_node_keys SET block_id = ? WHERE hex(public_key) = ?", p.BlockData.BlockId, p.TxMap["node_public_key"]) if err != nil { return p.ErrInfo(err) } } return nil }
func (c *Controller) Home() (string, error) { log.Debug("first_select: %v", c.Parameters["first_select"]) if c.Parameters["first_select"] == "1" { c.ExecSql(`UPDATE ` + c.MyPrefix + `my_table SET first_select=1`) } var publicKey []byte var poolAdmin bool var cashRequests int64 var showMap bool if c.SessRestricted == 0 { var err error publicKey, err = c.GetMyPublicKey(c.MyPrefix) if err != nil { return "", err } publicKey = utils.BinToHex(publicKey) cashRequests, err = c.Single("SELECT count(id) FROM cash_requests WHERE to_user_id = ? AND status = 'pending' AND for_repaid_del_block_id = 0 AND del_block_id = 0 and time > ?", c.SessUserId, utils.Time()-c.Variables.Int64["cash_request_time"]).Int64() fmt.Println("cashRequests", cashRequests) if err != nil { return "", err } show, err := c.Single("SELECT show_map FROM " + c.MyPrefix + "my_table").Int64() if err != nil { return "", err } if show > 0 { showMap = true } } if c.Community { poolAdminUserId, err := c.GetPoolAdminUserId() if err != nil { return "", err } if c.SessUserId == poolAdminUserId { poolAdmin = true } } wallets, err := c.GetBalances(c.SessUserId) if err != nil { return "", err } //var walletsByCurrency map[string]map[string]string walletsByCurrency := make(map[int]utils.DCAmounts) for _, data := range wallets { walletsByCurrency[int(data.CurrencyId)] = data } blockId, err := c.GetBlockId() if err != nil { return "", err } confirmedBlockId, err := c.GetConfirmedBlockId() if err != nil { return "", err } currencyList, err := c.GetCurrencyList(true) if err != nil { return "", err } for k, v := range currencyList { currencyList[k] = "d" + v } currencyList[1001] = "USD" // задания var assignments int64 count, err := c.Single("SELECT count(id) FROM votes_miners WHERE votes_end = 0 AND type = 'user_voting'").Int64() if err != nil { return "", err } assignments += count // вначале получим ID валют, которые мы можем проверять. currencyIds, err := c.GetList("SELECT currency_id FROM promised_amount WHERE status IN ('mining', 'repaid') AND user_id = ?", c.SessUserId).String() if len(currencyIds) > 0 || c.SessUserId == 1 { addSql := "" if c.SessUserId == 1 { addSql = "" } else { addSql = "AND currency_id IN (" + strings.Join(currencyIds, ",") + ")" } count, err := c.Single("SELECT count(id) FROM promised_amount WHERE status = 'pending' AND del_block_id = 0 " + addSql).Int64() if err != nil { return "", err } assignments += count } if c.SessRestricted == 0 { count, err := c.Single("SELECT count(id) FROM "+c.MyPrefix+"my_tasks WHERE time > ?", time.Now().Unix()-consts.ASSIGN_TIME).Int64() if err != nil { return "", err } assignments -= count if assignments < 0 { assignments = 0 } } // баллы points, err := c.Single("SELECT points FROM points WHERE user_id = ?", c.SessUserId).Int64() if err != nil { return "", err } currency_pct := make(map[int]CurrencyPct) // проценты listPct, err := c.GetMap("SELECT * FROM currency", "id", "name") for id, name := range listPct { pct, err := c.OneRow("SELECT * FROM pct WHERE currency_id = ? ORDER BY block_id DESC", id).Float64() if err != nil { return "", err } currency_pct[utils.StrToInt(id)] = CurrencyPct{Name: name, Miner: (utils.Round((math.Pow(1+pct["miner"], 3600*24*365)-1)*100, 2)), User: (utils.Round((math.Pow(1+pct["user"], 3600*24*365)-1)*100, 2)), MinerBlock: (utils.Round((math.Pow(1+pct["miner"], 120)-1)*100, 4)), UserBlock: (utils.Round((math.Pow(1+pct["user"], 120)-1)*100, 4)), MinerSec: (pct["miner"]), UserSec: (pct["user"])} } // случайне майнеры для нанесения на карту maxMinerId, err := c.Single("SELECT max(miner_id) FROM miners_data").Int64() if err != nil { return "", err } randMiners, err := c.GetList("SELECT user_id FROM miners_data WHERE status = 'miner' AND user_id > 7 AND user_id != 106 AND longitude > 0 AND miner_id IN (" + strings.Join(utils.RandSlice(1, maxMinerId, 3), ",") + ") LIMIT 3").Int64() if err != nil { return "", err } // получаем кол-во DC на кошельках sumWallets_, err := c.GetMap("SELECT currency_id, sum(amount) as sum_amount FROM wallets GROUP BY currency_id", "currency_id", "sum_amount") if err != nil { return "", err } sumWallets := make(map[int]float64) for currencyId, amount := range sumWallets_ { sumWallets[utils.StrToInt(currencyId)] = utils.StrToFloat64(amount) } // получаем кол-во TDC на обещанных суммах, плюсуем к тому, что на кошельках sumTdc, err := c.GetMap("SELECT currency_id, sum(tdc_amount) as sum_amount FROM promised_amount GROUP BY currency_id", "currency_id", "sum_amount") if err != nil { return "", err } for currencyId, amount := range sumTdc { currencyIdInt := utils.StrToInt(currencyId) if sumWallets[currencyIdInt] == 0 { sumWallets[currencyIdInt] = utils.StrToFloat64(amount) } else { sumWallets[currencyIdInt] += utils.StrToFloat64(amount) } } // получаем суммы обещанных сумм sumPromisedAmount, err := c.GetMap("SELECT currency_id, sum(amount) as sum_amount FROM promised_amount WHERE status = 'mining' AND del_block_id = 0 AND (cash_request_out_time = 0 OR cash_request_out_time > ?) GROUP BY currency_id", "currency_id", "sum_amount", time.Now().Unix()-c.Variables.Int64["cash_request_time"]) if err != nil { return "", err } _, _, promisedAmountListGen, err := c.GetPromisedAmounts(c.SessUserId, c.Variables.Int64["cash_request_time"]) calcTotal := utils.Round(100*math.Pow(1+currency_pct[72].MinerSec, 3600*24*30)-100, 0) // токен для запроса инфы с биржи var token, exchangeUrl string if c.SessRestricted == 0 { tokenAndUrl, err := c.OneRow(`SELECT token, e_host FROM ` + c.MyPrefix + `my_tokens LEFT JOIN miners_data ON miners_data.user_id = e_owner_id ORDER BY time DESC LIMIT 1`).String() if err != nil { return "", err } token = tokenAndUrl["token"] exchangeUrl = tokenAndUrl["e_host"] } myChatName := utils.Int64ToStr(c.SessUserId) // возможно у отпарвителя есть ник name, err := c.Single(`SELECT name FROM users WHERE user_id = ?`, c.SessUserId).String() if err != nil { return "", utils.ErrInfo(err) } if len(name) > 0 { myChatName = name } // получим топ 5 бирж topExMap := make(map[int64]*topEx) var q string if c.ConfigIni["db_type"] == "postgresql" { //q = "SELECT DISTINCT e_owner_id, e_host, count(votes_exchange.user_id), result from votes_exchange LEFT JOIN miners_data ON votes_exchange.e_owner_id = miners_data.user_id WHERE e_host != '' GROUP BY e_owner_id, result, e_host" q = "SELECT DISTINCT e_owner_id, e_host, count(votes_exchange.user_id), result from miners_data LEFT JOIN votes_exchange ON votes_exchange.e_owner_id = miners_data.user_id WHERE e_host != '' AND result >= 0 GROUP BY e_owner_id, result, e_host" } else { //q = "SELECT e_owner_id, e_host, count(votes_exchange.user_id) as count, result FROM miners_data LEFT JOIN votes_exchange ON votes_exchange.e_owner_id = miners_data.user_id WHERE and e_host != '' GROUP BY votes_exchange.e_owner_id, votes_exchange.result LIMIT 10" q = "SELECT e_owner_id, e_host, count(votes_exchange.user_id) as count, result FROM miners_data LEFT JOIN votes_exchange ON votes_exchange.e_owner_id = miners_data.user_id WHERE e_host != '' AND result >= 0 GROUP BY votes_exchange.e_owner_id, votes_exchange.result LIMIT 10" } rows, err := c.Query(q) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var user_id, count, result int64 var e_host []byte err = rows.Scan(&user_id, &e_host, &count, &result) if err != nil { return "", utils.ErrInfo(err) } if topExMap[user_id] == nil { topExMap[user_id] = new(topEx) } //if len(topExMap[user_id].Host) == 0 { // topExMap[user_id] = new(topEx) if result == 0 { topExMap[user_id].Vote1 = count } else { topExMap[user_id].Vote1 = count } topExMap[user_id].Host = string(e_host) topExMap[user_id].UserId = user_id //} } // майнер ли я? miner_, err := c.Single(`SELECT miner_id FROM miners_data WHERE user_id = ?`, c.SessUserId).Int64() if err != nil { return "", utils.ErrInfo(err) } var miner bool if miner_ > 0 { miner = true } TemplateStr, err := makeTemplate("home", "home", &homePage{ Community: c.Community, CountSignArr: c.CountSignArr, CountSign: c.CountSign, CalcTotal: calcTotal, Admin: c.Admin, CurrencyPct: currency_pct, SumWallets: sumWallets, Wallets: walletsByCurrency, PromisedAmountListGen: promisedAmountListGen, SessRestricted: c.SessRestricted, SumPromisedAmount: sumPromisedAmount, RandMiners: randMiners, Points: points, Assignments: assignments, CurrencyList: currencyList, ConfirmedBlockId: confirmedBlockId, CashRequests: cashRequests, ShowMap: showMap, BlockId: blockId, UserId: c.SessUserId, PoolAdmin: poolAdmin, Alert: c.Alert, MyNotice: c.MyNotice, Lang: c.Lang, Title: c.Lang["geolocation"], ShowSignData: c.ShowSignData, SignData: "", MyChatName: myChatName, IOS: utils.IOS(), Mobile: utils.Mobile(), TopExMap: topExMap, ChatEnabled: c.NodeConfig["chat_enabled"], Miner: miner, Token: token, ExchangeUrl: exchangeUrl}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) CfPagePreview() (string, error) { var err error txType := "CfComment" txTypeId := utils.TypeInt(txType) timeNow := time.Now().Unix() cfUrl, err := c.GetCfUrl() if err != nil { return "", utils.ErrInfo(err) } showHeaders := false if len(c.r.FormValue("blurb_img")) > 0 { showHeaders = true } page := c.Parameters["page"] if len(page) > 0 { if ok, _ := regexp.MatchString(`^(?i)[a-z]{0,10}$`, page); !ok { return "", errors.New("incorrect page") } } cfCurrencyName := c.Parameters["onlyCfCurrencyName"] if len(page) == 0 { page = "home" } langId := int64(utils.StrToFloat64(c.Parameters["lang_id"])) projectId := int64(utils.StrToFloat64(c.Parameters["onlyProjectId"])) log.Debug("projectId:", projectId) var blurbImg, headImg, descriptionImg, picture, videoType, videoUrlId, newsImg string imgBlank := cfUrl + "static/img/blank.png" var links [][]string if projectId > 0 || len(cfCurrencyName) > 0 { if projectId == 0 { projectId, err = c.Single("SELECT id FROM cf_projects WHERE project_currency_name = ?", cfCurrencyName).Int64() if err != nil { return "", utils.ErrInfo(err) } } data := make(map[string]string) if langId > 0 { data, err = c.OneRow("SELECT * FROM cf_projects_data WHERE project_id = ? AND lang_id = ?", projectId, langId).String() if err != nil { return "", utils.ErrInfo(err) } } else { // Если язык не указан, то просто берем первое добавленное описание data, err = c.OneRow("SELECT * FROM cf_projects_data WHERE project_id = ? ORDER BY id ASC", projectId).String() if err != nil { return "", utils.ErrInfo(err) } langId = utils.StrToInt64(data["lang_id"]) } blurbImg = data["blurb_img"] headImg = data["head_img"] descriptionImg = data["description_img"] picture = data["picture"] videoType = data["video_type"] videoUrlId = data["video_url_id"] newsImg = data["news_img"] if len(data["links"]) > 0 && data["links"] != "0" { var links_ [][]interface{} err = json.Unmarshal([]byte(data["links"]), &links_) if err != nil { log.Debug("data links:", data["links"]) return "", utils.ErrInfo(err) } for _, v := range links_ { var l []string for _, v2 := range v { str := utils.InterfaceToStr(v2) if len(str) == 0 { return "", utils.ErrInfo(errors.New("Incorrect links")) } l = append(l, str) } links = append(links, l) } } } else { log.Debug("FormValue", c.r.Form) blurbImg = c.r.FormValue("blurb_img") headImg = c.r.FormValue("head_img") descriptionImg = c.r.FormValue("description_img") picture = c.r.FormValue("blurb_img") videoType = c.r.FormValue("video_type") videoUrlId = c.r.FormValue("video_url_id") newsImg = c.r.FormValue("news_img") if !utils.CheckInputData(c.r.FormValue("project_id"), "int") { return "", errors.New("Incorrect project_id") } if !utils.CheckInputData(blurbImg, "img_url") { blurbImg = imgBlank } if !utils.CheckInputData(headImg, "img_url") { headImg = imgBlank } if !utils.CheckInputData(descriptionImg, "img_url") { descriptionImg = imgBlank } if !utils.CheckInputData(picture, "img_url") { picture = imgBlank } if !utils.CheckInputData(newsImg, "img_url") { newsImg = imgBlank } if !utils.CheckInputData(videoType, "video_type") { videoType = "" } if !utils.CheckInputData(videoUrlId, "video_url_id") { videoUrlId = "" } if len(c.Parameters["links"]) > 0 { var links_ [][]interface{} err = json.Unmarshal([]byte(c.Parameters["links"]), &links_) if err != nil { return "", utils.ErrInfo(err) } for _, v := range links_ { var l []string for _, v2 := range v { str := utils.InterfaceToStr(v2) if len(str) == 0 { return "", utils.ErrInfo(errors.New("Incorrect links")) } l = append(l, str) } links = append(links, l) } } } project, err := c.OneRow("SELECT * FROM cf_projects WHERE id = ?", projectId).String() if err != nil { return "", utils.ErrInfo(err) } // сколько дней осталось days := utils.Round((utils.StrToFloat64(project["end_time"])-float64(utils.Time()))/86400, 0) if days <= 0 { days = 0 } project["days"] = utils.Float64ToStr(days) if project["close_block_id"] != "0" || project["del_block_id"] != "0" { project["ended"] = "1" } else { project["ended"] = "0" } // дата старта t := time.Unix(utils.StrToInt64(project["start_time"]), 0) project["start_date"] = t.Format(c.TimeFormat) // в какой валюте идет сбор project["currency"] = c.CurrencyList[utils.StrToInt64(project["currency_id"])] // на каких языках есть описание // для home/news можно скрыть язык addSql := "" if page == "home" || page == "news" { addSql = " AND hide = 0 " } projectLang, err := c.GetMap(`SELECT id, lang_id FROM cf_projects_data WHERE project_id = ? `+addSql, "id", "lang_id", projectId) // сколько собрано средств projectFunding, err := c.Single("SELECT sum(amount) FROM cf_funding WHERE project_id = ? AND del_block_id = 0", projectId).Float64() if err != nil { return "", utils.ErrInfo(err) } // сколько всего фундеров projectCountFunders, err := c.Single("SELECT count(id) FROM cf_funding WHERE project_id = ? AND del_block_id = 0 GROUP BY user_id", projectId).Int64() if err != nil { return "", utils.ErrInfo(err) } // список фундеров var q string if c.ConfigIni["db_type"] == "postgresql" { q = `SELECT DISTINCT cf_funding.user_id, sum(amount) as amount, time, name, avatar FROM cf_funding LEFT JOIN users ON users.user_id = cf_funding.user_id WHERE project_id = ? AND del_block_id = 0 GROUP BY cf_funding.user_id, time, name, avatar ORDER BY time DESC LIMIT 100` } else { q = `SELECT cf_funding.user_id, sum(amount) as amount, time, name, avatar FROM cf_funding LEFT JOIN users ON users.user_id = cf_funding.user_id WHERE project_id = ? AND del_block_id = 0 GROUP BY cf_funding.user_id ORDER BY time DESC LIMIT 100` } projectFunders, err := c.GetAll(q, 100, projectId) if err != nil { return "", utils.ErrInfo(err) } for k, v := range projectFunders { t := time.Unix(utils.StrToInt64(v["time"]), 0) projectFunders[k]["time"] = t.Format(c.TimeFormat) if len(v["avatar"]) == 0 { projectFunders[k]["avatar"] = cfUrl + "static/img/noavatar.png" } if len(v["name"]) == 0 { projectFunders[k]["name"] = "Noname" } } // список комментов var projectComments []map[string]string if langId > 0 { projectComments, err = c.GetAll(` SELECT users.user_id, comment, time, name, avatar FROM cf_comments LEFT JOIN users ON users.user_id = cf_comments.user_id WHERE project_id = ? AND lang_id = ? ORDER BY time DESC LIMIT 100 `, 100, projectId, langId) if err != nil { return "", utils.ErrInfo(err) } for k, v := range projectComments { t := time.Unix(utils.StrToInt64(v["time"]), 0) projectComments[k]["time"] = t.Format(c.TimeFormat) if len(v["avatar"]) == 0 { projectComments[k]["avatar"] = cfUrl + "static/img/noavatar.png" } if len(v["name"]) == 0 { projectComments[k]["name"] = "Noname" } } } // сколько всего комментов на каждом языке if c.ConfigIni["db_type"] == "postgresql" { q = `SELECT DISTINCT lang_id, count(id) as count FROM cf_comments WHERE project_id = ? GROUP BY lang_id` } else { q = `SELECT lang_id, count(id) as count FROM cf_comments WHERE project_id = ?` } langComments, err := c.GetMap(q, "lang_id", "count", projectId) if err != nil { return "", utils.ErrInfo(err) } var projectCountComments int64 for _, v := range langComments { projectCountComments += utils.StrToInt64(v) } cfLng, err := c.GetAllCfLng() // инфа об авторе проекта authorInfo, err := c.GetCfAuthorInfo(project["user_id"], cfUrl) // возможно наш юзер фундер project["funder"] = "" if c.SessUserId > 0 { project["funder"], err = c.Single("SELECT id FROM cf_funding WHERE project_id = ? AND user_id = ? AND del_block_id = 0", projectId, c.SessUserId).String() if err != nil { return "", utils.ErrInfo(err) } } pagesArray := []string{"home", "news", "funders", "comments"} configCfPs := make(map[string][]string) if len(c.NodeConfig["cf_ps"]) > 0 { //{"1":["Credit card"],"2":["ik","MTS, Megafon, W1, Paxum"],"3":["pm","Perfect Money"]} err = json.Unmarshal([]byte(c.NodeConfig["cf_ps"]), &configCfPs) if err != nil { return "", utils.ErrInfo(err) } } // узнаем, какие платежные системы доступны данному проекту projectPs, err := c.OneRow("SELECT * FROM cf_projects_ps WHERE project_id = ?", projectId).String() if err != nil { return "", utils.ErrInfo(err) } // узнаем, не в блек-листе ли проект black, err := c.Single("SELECT project_id FROM cf_blacklist WHERE project_id = ?", projectId).Int64() if err != nil { return "", utils.ErrInfo(err) } if black > 0 { return "", errors.New("Black project") } TemplateStr, err := makeTemplate("cf_page_preview", "cfPagePreview", &CfPagePreviewPage{ Alert: c.Alert, Lang: c.Lang, CountSignArr: c.CountSignArr, ShowSignData: c.ShowSignData, UserId: c.SessUserId, TimeNow: timeNow, TxType: txType, TxTypeId: txTypeId, SignData: "", CfLng: cfLng, CurrencyList: c.CurrencyList, CfUrl: cfUrl, ShowHeaders: showHeaders, Page: page, CfCurrencyName: cfCurrencyName, LangId: langId, ProjectId: projectId, BlurbImg: blurbImg, HeadImg: headImg, DescriptionImg: descriptionImg, Picture: picture, VideoType: videoType, VideoUrlId: videoUrlId, NewsImg: newsImg, Links: links, ImgBlank: imgBlank, Project: project, ProjectLang: projectLang, ProjectFunding: projectFunding, ProjectCountFunders: projectCountFunders, ProjectFunders: projectFunders, ProjectComments: projectComments, LangComments: langComments, ProjectCountComments: projectCountComments, AuthorInfo: authorInfo, PagesArray: pagesArray, ConfigCfPs: configCfPs, ProjectPs: projectPs, Black: black}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) CurrencyExchange() (string, error) { txType := "NewForexOrder" txTypeId := utils.TypeInt(txType) timeNow := time.Now().Unix() addSql := "" if len(c.Parameters["all_currencies"]) == 0 { // по умолчанию выдаем только те валюты, которые есть хоть у кого-то на кошельках actualCurrencies, err := c.GetList("SELECT currency_id FROM wallets GROUP BY currency_id").String() if err != nil { return "", utils.ErrInfo(err) } if len(actualCurrencies) > 0 { addSql = " WHERE id IN (" + strings.Join(actualCurrencies, ",") + ")" } } currencyListName := make(map[int64]string) currency, err := c.GetMap("SELECT id, name FROM currency "+addSql+" ORDER BY name", "id", "name") if err != nil { return "", utils.ErrInfo(err) } for k, v := range currency { currencyListName[utils.StrToInt64(k)] = v } var sellCurrencyId, buyCurrencyId int64 if len(c.Parameters["buy_currency_id"]) > 0 { buyCurrencyId = utils.StrToInt64(c.Parameters["buy_currency_id"]) c.sess.Set("buy_currency_id", buyCurrencyId) } if len(c.Parameters["sell_currency_id"]) > 0 { sellCurrencyId = utils.StrToInt64(c.Parameters["sell_currency_id"]) c.sess.Set("sell_currency_id", sellCurrencyId) } if buyCurrencyId == 0 { buyCurrencyId = GetSessInt64("buy_currency_id", c.sess) } if sellCurrencyId == 0 { sellCurrencyId = GetSessInt64("sell_currency_id", c.sess) } if buyCurrencyId == 0 { buyCurrencyId = 1 } if sellCurrencyId == 0 { sellCurrencyId = 72 } buyCurrencyName := currencyListName[buyCurrencyId] sellCurrencyName := currencyListName[sellCurrencyId] // валюты currencyListFullName, err := c.GetCurrencyListFullName() if err != nil { return "", utils.ErrInfo(err) } buyOrders, err := c.GetAll(` SELECT * FROM forex_orders WHERE buy_currency_id = ? AND sell_currency_id = ? AND empty_block_id = 0 AND del_block_id = 0 `, 100, buyCurrencyId, sellCurrencyId) sellOrders, err := c.GetAll(` SELECT * FROM forex_orders WHERE buy_currency_id = ? AND sell_currency_id = ? AND empty_block_id = 0 AND del_block_id = 0 `, 100, sellCurrencyId, buyCurrencyId) myOrders, err := c.GetAll(` SELECT * FROM forex_orders WHERE user_id = ? AND empty_block_id = 0 AND del_block_id = 0 `, 100, c.SessUserId) rows, err := c.Query(c.FormatQuery(` SELECT amount, currency_id, last_update FROM wallets WHERE user_id = ? AND currency_id IN (?, ?) `), c.SessUserId, sellCurrencyId, buyCurrencyId) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() walletsAmounts := make(map[int64]float64) for rows.Next() { var amount float64 var currency_id, last_update int64 err = rows.Scan(&amount, ¤cy_id, &last_update) if err != nil { return "", utils.ErrInfo(err) } profit, err := c.CalcProfitGen(currency_id, amount, c.SessUserId, last_update, timeNow, "wallets") if err != nil { return "", utils.ErrInfo(err) } amount += profit amount = utils.Round(amount, 2) forex_orders_amount, err := c.Single("SELECT sum(amount) FROM forex_orders WHERE user_id = ? AND sell_currency_id = ? AND del_block_id = 0", c.SessUserId, currency_id).Float64() if err != nil { return "", utils.ErrInfo(err) } amount -= forex_orders_amount walletsAmounts[currency_id] = amount } last_tx, err := c.GetLastTx(c.SessUserId, utils.TypesToIds([]string{"NewForexOrder", "DelForexOrder"}), 3, c.TimeFormat) lastTxFormatted := "" if len(last_tx) > 0 { lastTxFormatted, _ = utils.MakeLastTx(last_tx, c.Lang) } TemplateStr, err := makeTemplate("currency_exchange", "currencyExchange", ¤cyExchangePage{ LastTxFormatted: lastTxFormatted, Lang: c.Lang, CountSignArr: c.CountSignArr, ShowSignData: c.ShowSignData, WalletsAmounts: walletsAmounts, CurrencyListName: currencyListName, BuyCurrencyId: buyCurrencyId, SellCurrencyId: sellCurrencyId, BuyCurrencyName: buyCurrencyName, SellCurrencyName: sellCurrencyName, CurrencyListFullName: currencyListFullName, ConfigCommission: c.ConfigCommission, TimeNow: timeNow, SellOrders: sellOrders, BuyOrders: buyOrders, MyOrders: myOrders, UserId: c.SessUserId, TxType: txType, TxTypeId: txTypeId, SignData: ""}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) EMyOrders() (string, error) { var err error if c.SessUserId == 0 { return `<script language="javascript"> window.location.href = "` + c.EURL + `"</script>If you are not redirected automatically, follow the <a href="` + c.EURL + `">` + c.EURL + `</a>`, nil } currencyList, err := utils.EGetCurrencyList() var myOrders []*EmyOrders rows, err := c.Query(c.FormatQuery(` SELECT id, time, empty_time, amount, begin_amount, sell_currency_id, buy_currency_id, sell_rate, begin_amount, del_time FROM e_orders WHERE user_id = ? AND del_time = 0 ORDER BY time DESC LIMIT 40 `), c.SessUserId) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { myOrder := new(EmyOrders) err = rows.Scan(&myOrder.Id, &myOrder.Time, &myOrder.EmptyTime, &myOrder.Amount, &myOrder.BeginAmount, &myOrder.SellCurrencyId, &myOrder.BuyCurrencyId, &myOrder.SellRate, &myOrder.BeginAmount, &myOrder.DelTime) if err != nil { return "", utils.ErrInfo(err) } if myOrder.EmptyTime == 0 { myOrder.Status = c.Lang["active"] } else { myOrder.Status = c.Lang["executed"] } // на сколько % выполнен ордер myOrder.OrderComplete = utils.Round(100-(myOrder.Amount/myOrder.BeginAmount)*100, 1) // определим тип ордера и пару if myOrder.SellCurrencyId < 1000 { myOrder.OrderType = "sell" myOrder.SellRate = 1 / myOrder.SellRate myOrder.Total = myOrder.BeginAmount * myOrder.SellRate myOrder.BeginAmount = myOrder.BeginAmount myOrder.Pair = currencyList[myOrder.SellCurrencyId] + "/" + currencyList[myOrder.BuyCurrencyId] } else { myOrder.OrderType = "buy" myOrder.Total = myOrder.BeginAmount myOrder.Amount = myOrder.BeginAmount * (1 / myOrder.SellRate) myOrder.Pair = currencyList[myOrder.BuyCurrencyId] + "/" + currencyList[myOrder.SellCurrencyId] } myOrders = append(myOrders, myOrder) } TemplateStr, err := makeTemplate("e_my_orders", "eMyOrders", &eMyOrdersPage{ Lang: c.Lang, UserId: c.SessUserId, MyOrders: myOrders, CurrencyList: currencyList}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (p *Parser) NewPctFront() error { err := p.generalCheck() if err != nil { return p.ErrInfo(err) } // является ли данный юзер майнером err = p.checkMiner(p.TxUserID) if err != nil { return p.ErrInfo(err) } nodePublicKey, err := p.GetNodePublicKey(p.TxUserID) if err != nil { return p.ErrInfo(err) } if len(nodePublicKey) == 0 { return p.ErrInfo("incorrect user_id") } newPctCurrency := make(map[string]map[string]string) // раньше не было рефских if p.BlockData != nil && p.BlockData.BlockId <= 77951 { err = json.Unmarshal([]byte(p.TxMap["new_pct"]), &newPctCurrency) if err != nil { return p.ErrInfo(err) } } else { newPctTx := new(newPctType) err = json.Unmarshal([]byte(p.TxMap["new_pct"]), &newPctTx) if err != nil { return p.ErrInfo(err) } if newPctTx.Referral == nil { return p.ErrInfo("!Referral") } newPctCurrency = newPctTx.Currency } if len(newPctCurrency) == 0 { return p.ErrInfo("!newPctCurrency") } // проверим, верно ли указаны ID валют currencyIdsSql := "" countCurrency := 0 for id := range newPctCurrency { currencyIdsSql += id + "," countCurrency++ } currencyIdsSql = currencyIdsSql[0 : len(currencyIdsSql)-1] count, err := p.Single("SELECT count(id) FROM currency WHERE id IN (" + currencyIdsSql + ")").Int() if err != nil { return p.ErrInfo(err) } if count != countCurrency { return p.ErrInfo("count_currency") } forSign := fmt.Sprintf("%s,%s,%s,%s", p.TxMap["type"], p.TxMap["time"], p.TxMap["user_id"], p.TxMap["new_pct"]) CheckSignResult, err := utils.CheckSign([][]byte{nodePublicKey}, forSign, p.TxMap["sign"], true) if err != nil { return p.ErrInfo(err) } if !CheckSignResult { return p.ErrInfo("incorrect sign") } // проверим, прошло ли 2 недели с момента последнего обновления pct pctTime, err := p.Single("SELECT max(time) FROM pct").Int64() if err != nil { return p.ErrInfo(err) } if p.TxTime-pctTime <= p.Variables.Int64["new_pct_period"] { return p.ErrInfo(fmt.Sprintf("14 days error %d - %d <= %d", p.TxTime, pctTime, p.Variables.Int64["new_pct_period"])) } // берем все голоса miner_pct pctVotes := make(map[int64]map[string]map[string]int64) rows, err := p.Query("SELECT currency_id, pct, count(user_id) as votes FROM votes_miner_pct GROUP BY currency_id, pct ORDER BY currency_id, pct ASC") if err != nil { return p.ErrInfo(err) } defer rows.Close() for rows.Next() { var currency_id, votes int64 var pct string err = rows.Scan(¤cy_id, &pct, &votes) if err != nil { return p.ErrInfo(err) } log.Debug("newpctcurrency_id", currency_id, "pct", pct, "votes", votes) if len(pctVotes[currency_id]) == 0 { pctVotes[currency_id] = make(map[string]map[string]int64) } if len(pctVotes[currency_id]["miner_pct"]) == 0 { pctVotes[currency_id]["miner_pct"] = make(map[string]int64) } pctVotes[currency_id]["miner_pct"][pct] = votes } // берем все голоса user_pct rows, err = p.Query("SELECT currency_id, pct, count(user_id) as votes FROM votes_user_pct GROUP BY currency_id, pct ORDER BY currency_id, pct ASC") if err != nil { return p.ErrInfo(err) } defer rows.Close() for rows.Next() { var currency_id, votes int64 var pct string err = rows.Scan(¤cy_id, &pct, &votes) if err != nil { return p.ErrInfo(err) } log.Debug("currency_id", currency_id, "pct", pct, "votes", votes) if len(pctVotes[currency_id]) == 0 { pctVotes[currency_id] = make(map[string]map[string]int64) } if len(pctVotes[currency_id]["user_pct"]) == 0 { pctVotes[currency_id]["user_pct"] = make(map[string]int64) } pctVotes[currency_id]["user_pct"][pct] = votes } newPct := make(map[string]map[string]map[string]string) newPct["currency"] = make(map[string]map[string]string) var userMaxKey int64 PctArray := utils.GetPctArray() log.Debug("pctVotes", pctVotes) for currencyId, data := range pctVotes { currencyIdStr := utils.Int64ToStr(currencyId) // определяем % для майнеров pctArr := utils.MakePctArray(data["miner_pct"]) log.Debug("pctArrminer_pct", pctArr, currencyId) key := utils.GetMaxVote(pctArr, 0, 390, 100) log.Debug("key", key) if len(newPct["currency"][currencyIdStr]) == 0 { newPct["currency"][currencyIdStr] = make(map[string]string) } newPct["currency"][currencyIdStr]["miner_pct"] = utils.GetPctValue(key) // определяем % для юзеров pctArr = utils.MakePctArray(data["user_pct"]) log.Debug("pctArruser_pct", pctArr, currencyId) // раньше не было завимости юзерского % от майнерского if p.BlockData != nil && p.BlockData.BlockId <= 95263 { userMaxKey = 390 } else { log.Debug("newPct", newPct) pctY := utils.ArraySearch(newPct["currency"][currencyIdStr]["miner_pct"], PctArray) log.Debug("newPct[currency][currencyIdStr][miner_pct]", newPct["currency"][currencyIdStr]["miner_pct"]) log.Debug("PctArray", PctArray) log.Debug("miner_pct $pct_y=", pctY) maxUserPctY := utils.Round(utils.StrToFloat64(pctY)/2, 2) userMaxKey = utils.FindUserPct(int(maxUserPctY)) log.Debug("maxUserPctY", maxUserPctY, "userMaxKey", userMaxKey, "currencyIdStr", currencyIdStr) // отрезаем лишнее, т.к. поиск идет ровно до макимального возможного, т.е. до miner_pct/2 pctArr = utils.DelUserPct(pctArr, userMaxKey) log.Debug("pctArr", pctArr) } key = utils.GetMaxVote(pctArr, 0, userMaxKey, 100) log.Debug("data[user_pct]", data["user_pct"]) log.Debug("pctArr", pctArr) log.Debug("userMaxKey", userMaxKey) log.Debug("key", key) newPct["currency"][currencyIdStr]["user_pct"] = utils.GetPctValue(key) log.Debug("user_pct", newPct["currency"][currencyIdStr]["user_pct"]) } var jsonData []byte // раньше не было рефских if p.BlockData != nil && p.BlockData.BlockId <= 77951 { newPct_ := newPct["currency"] jsonData, err = json.Marshal(newPct_) if err != nil { return p.ErrInfo(err) } } else { newPct_ := new(newPctType) newPct_.Currency = make(map[string]map[string]string) newPct_.Currency = newPct["currency"] newPct_.Referral = make(map[string]int64) refLevels := []string{"first", "second", "third"} for i := 0; i < len(refLevels); i++ { level := refLevels[i] var votesReferral []map[int64]int64 // берем все голоса rows, err := p.Query("SELECT " + level + ", count(user_id) as votes FROM votes_referral GROUP BY " + level + " ORDER BY " + level + " ASC ") if err != nil { return p.ErrInfo(err) } defer rows.Close() for rows.Next() { var level_, votes int64 err = rows.Scan(&level_, &votes) if err != nil { return p.ErrInfo(err) } votesReferral = append(votesReferral, map[int64]int64{level_: votes}) } newPct_.Referral[level] = (utils.GetMaxVote(votesReferral, 0, 30, 10)) } jsonData, err = json.Marshal(newPct_) if err != nil { return p.ErrInfo(err) } } if string(p.TxMap["new_pct"]) != string(jsonData) { return p.ErrInfo("p.TxMap[new_pct] != jsonData " + string(p.TxMap["new_pct"]) + "!=" + string(jsonData)) } log.Debug(string(jsonData)) return nil }
func (c *Controller) GetMinerData() (string, error) { c.r.ParseForm() secs := float64(3600 * 24 * 365) userId := utils.StrToInt64(c.r.FormValue("userId")) if !utils.CheckInputData(userId, "int") { return `{"result":"incorrect userId"}`, nil } minersData, err := c.OneRow("SELECT * FROM miners_data WHERE user_id = ?", userId).String() if err != nil { return "", err } // получим ID майнеров, у которых лежат фото нужного нам юзера minersIds := utils.GetMinersKeepers(minersData["photo_block_id"], minersData["photo_max_miner_id"], minersData["miners_keepers"], false) hosts, err := c.GetList("SELECT http_host as host FROM miners_data WHERE miner_id IN (" + utils.JoinIntsK(minersIds, ",") + ")").String() if err != nil { return "", err } currencyList, err := c.GetCurrencyList(false) if err != nil { return "", err } _, _, promisedAmountListGen, err := c.GetPromisedAmounts(userId, c.Variables.Int64["cash_request_time"]) log.Debug("promisedAmountListGen: %v", promisedAmountListGen) var data utils.DCAmounts if promisedAmountListGen[72].Amount > 0 { data = promisedAmountListGen[72] } else if promisedAmountListGen[23].Amount > 0 { data = promisedAmountListGen[23] } else { data = utils.DCAmounts{} } log.Debug("data: %v", data) promisedAmounts := "" prognosis := make(map[int64]float64) if data.Amount > 1 { promisedAmounts += RoundStr(utils.Float64ToStr(utils.Round(data.Amount, 0)), 0) + " " + currencyList[(data.CurrencyId)] + "<br>" prognosis[int64(data.CurrencyId)] += (math.Pow(1+data.PctSec, secs) - 1) * data.Amount } if len(promisedAmounts) > 0 { promisedAmounts = "<strong>" + promisedAmounts[:len(promisedAmounts)-4] + "</strong><br>" + c.Lang["promised"] + "<hr>" } /* * На кошельках * */ balances, err := c.GetBalances(userId) if err != nil { return "", err } walletsByCurrency := make(map[int]utils.DCAmounts) for _, data := range balances { walletsByCurrency[int(data.CurrencyId)] = data } log.Debug("walletsByCurrency[72].Amount: %v", walletsByCurrency[72].Amount) if walletsByCurrency[72].Amount > 0 { data = walletsByCurrency[72] } else if walletsByCurrency[23].Amount > 0 { data = walletsByCurrency[23] } else { data = utils.DCAmounts{} } log.Debug("data: %v", data) wallets := "" var countersIds []string var pctSec float64 if data.Amount > 0 { counterId := "map-" + utils.Int64ToStr(userId) + "-" + utils.Int64ToStr(data.CurrencyId) countersIds = append(countersIds, counterId) wallets = "<span class='dc_amount' id='" + counterId + "'>" + RoundStr(utils.Float64ToStr(data.Amount), 8) + "</span> d" + currencyList[(data.CurrencyId)] + "<br>" // прогноз prognosis[int64(data.CurrencyId)] += (math.Pow(1+data.PctSec, secs) - 1) * data.Amount pctSec = data.PctSec } if len(wallets) > 0 { wallets = wallets[:len(wallets)-4] + "<br>" + c.Lang["on_the_account"] + "<hr>" } /* * Годовой прогноз * */ prognosisHtml := "" for currencyId, amount := range prognosis { if amount < 0.01 { continue } else if amount < 1 { amount = utils.Round(amount, 2) } else { amount = amount } prognosisHtml += "<span class='amount_1year'>" + RoundStr(utils.Float64ToStr(amount), 2) + " d" + currencyList[(currencyId)] + "</span><br>" } if len(prognosisHtml) > 0 { prognosisHtml = prognosisHtml[:len(prognosisHtml)-4] + "<br> " + c.Lang["profit_forecast"] + " " + c.Lang["after_1_year"] } prognosisHtml = "" result_ := minersDataType{Hosts: hosts, Lnglat: map[string]string{"lng": minersData["longitude"], "lat": minersData["latitude"]}, Html: promisedAmounts + wallets + "<div style=\"clear:both\"></div>" + prognosisHtml + "</p>", Counters: countersIds, PctSec: pctSec} log.Debug("result_", result_) result, err := json.Marshal(result_) if err != nil { return "", err } log.Debug(string(result)) return string(result), nil }
func makeTemplate(html, name string, tData interface{}) (string, error) { defer func() { if r := recover(); r != nil { log.Error("makeTemplate Recovered", r) fmt.Println(r) } }() data, err := static.Asset("static/templates/" + html + ".html") if err != nil { return "", utils.ErrInfo(err) } signatures, err := static.Asset("static/templates/signatures.html") if err != nil { return "", utils.ErrInfo(err) } alert_success, err := static.Asset("static/templates/alert_success.html") if err != nil { return "", utils.ErrInfo(err) } funcMap := template.FuncMap{ "makeCurrencyName": func(currencyId int64) string { if currencyId >= 1000 { return "" } else { return "d" } }, "div": func(a, b interface{}) float64 { return utils.InterfaceToFloat64(a) / utils.InterfaceToFloat64(b) }, "mult": func(a, b interface{}) float64 { return utils.InterfaceToFloat64(a) * utils.InterfaceToFloat64(b) }, "round": func(a interface{}, num int) float64 { return utils.Round(utils.InterfaceToFloat64(a), num) }, "len": func(s []map[string]string) int { return len(s) }, "lenMap": func(s map[string]string) int { return len(s) }, "sum": func(a, b interface{}) float64 { return utils.InterfaceToFloat64(a) + utils.InterfaceToFloat64(b) }, "minus": func(a, b interface{}) float64 { return utils.InterfaceToFloat64(a) - utils.InterfaceToFloat64(b) }, "noescape": func(s string) template.HTML { return template.HTML(s) }, "js": func(s string) template.JS { return template.JS(s) }, "join": func(s []string, sep string) string { return strings.Join(s, sep) }, "strToInt64": func(text string) int64 { return utils.StrToInt64(text) }, "strToInt": func(text string) int { return utils.StrToInt(text) }, "bin2hex": func(text string) string { return string(utils.BinToHex([]byte(text))) }, "int64ToStr": func(text int64) string { return utils.Int64ToStr(text) }, "rand": func() int { return utils.RandInt(0, 99999999) }, "append": func(args ...interface{}) string { var result string for _, value := range args { switch value.(type) { case int64: result += utils.Int64ToStr(value.(int64)) case float64: result += utils.Float64ToStr(value.(float64)) case string: result += value.(string) } } return result }, "replaceCurrency": func(text, name string) string { return strings.Replace(text, "[currency]", name, -1) }, "replaceCurrencyName": func(text, name string) string { return strings.Replace(text, "[currency]", "D"+name, -1) }, "cfCategoryLang": func(lang map[string]string, name string) string { return lang["cf_category_"+name] }, "progressBarLang": func(lang map[string]string, name string) string { return lang["progress_bar_pct_"+name] }, "checkProjectPs": func(ProjectPs map[string]string, id string) bool { if len(ProjectPs["ps"+id]) > 0 { return true } else { return false } }, "cfPageTypeLang": func(lang map[string]string, name string) string { return lang["cf_"+name] }, "notificationsLang": func(lang map[string]string, name string) string { return lang["notifications_"+name] }, } t := template.Must(template.New("template").Funcs(funcMap).Parse(string(data))) t = template.Must(t.Parse(string(alert_success))) t = template.Must(t.Parse(string(signatures))) b := new(bytes.Buffer) err = t.ExecuteTemplate(b, name, tData) if err != nil { return "", utils.ErrInfo(err) } return b.String(), nil }
func (c *Controller) UpdatingBlockchain() (string, error) { var blockTime, blockId, blockMeter int64 var waitText, startDaemons, checkTime string var restartDb bool if c.dbInit { ConfirmedBlockId, err := c.DCDB.GetConfirmedBlockId() if err != nil { return "", utils.ErrInfo(err) } if ConfirmedBlockId == 0 { firstLoadBlockchain, err := c.DCDB.Single("SELECT first_load_blockchain FROM config").String() if err != nil { return "", utils.ErrInfo(err) } if firstLoadBlockchain == "file" { waitText = c.Lang["loading_blockchain_please_wait"] } else { waitText = c.Lang["is_synchronized_with_the_dc_network"] } } else { LastBlockData, err := c.DCDB.GetLastBlockData() if err != nil { return "", utils.ErrInfo(err) } blockTime = LastBlockData["lastBlockTime"] blockId = LastBlockData["blockId"] } // для сингл-мода, кнопка включения и выключения демонов if !c.Community { lockName, err := c.DCDB.GetMainLockName() if err != nil { return "", utils.ErrInfo(err) } if lockName == "main_lock" { startDaemons = `<a href="#" id="start_daemons" style="color:#C90600">Start daemons</a>` } // инфа о синхронизации часов switch runtime.GOOS { case "linux": checkTime = c.Lang["check_time_nix"] case "windows": checkTime = c.Lang["check_time_win"] case "darwin": checkTime = c.Lang["check_time_mac"] default: checkTime = c.Lang["check_time_nix"] } checkTime = c.Lang["check_time"] + checkTime mainLock, err := c.Single(`SELECT lock_time from main_lock`).Int64() if mainLock > 0 && utils.Time()-300 > mainLock { restartDb = true } } nodeConfig, err := c.GetNodeConfig() blockchain_url := nodeConfig["first_load_blockchain_url"] if len(blockchain_url) == 0 { blockchain_url = consts.BLOCKCHAIN_URL } resp, err := http.Get(blockchain_url) if err != nil { return "", utils.ErrInfo(err) } blockChainSize := resp.ContentLength if blockChainSize == 0 { blockChainSize = consts.BLOCKCHAIN_SIZE } defer resp.Body.Close() blockMeter = int64(utils.Round(float64((blockId/consts.LAST_BLOCK)*100), 0)) - 1 } else { waitText = c.Lang["loading_blockchain_please_wait"] } var mobile bool if utils.Mobile() { mobile = true } networkTime, err := utils.GetNetworkTime() if err != nil { return "", utils.ErrInfo(err) } diff := int64(math.Abs(float64(utils.Time() - networkTime.Unix()))) var alertTime string if c.dbInit && diff > c.Variables.Int64["alert_error_time"] { alertTime = strings.Replace(c.Lang["alert_time"], "[sec]", utils.Int64ToStr(diff), -1) } funcMap := template.FuncMap{ "noescape": func(s string) template.HTML { return template.HTML(s) }, } data, err := static.Asset("static/templates/updating_blockchain.html") t := template.New("template").Funcs(funcMap) t, err = t.Parse(string(data)) if err != nil { return "", utils.ErrInfo(err) } b := new(bytes.Buffer) t.Execute(b, &updatingBlockchainStruct{RestartDb: restartDb, Lang: c.Lang, WaitText: waitText, BlockId: blockId, BlockTime: blockTime, StartDaemons: startDaemons, BlockMeter: blockMeter, CheckTime: checkTime, LastBlock: consts.LAST_BLOCK, BlockChainSize: consts.BLOCKCHAIN_SIZE, Mobile: mobile, AlertTime: alertTime}) return b.String(), nil }
func (p *Parser) ChangeGeolocation() error { // возможно нужно обновить таблицу points_status err := p.pointsUpdateMain(p.TxUserID) if err != nil { return p.ErrInfo(err) } err = p.selectiveLoggingAndUpd([]string{"latitude", "longitude", "country"}, []interface{}{p.TxMaps.Float64["latitude"], p.TxMaps.Float64["longitude"], p.TxMaps.Int64["country"]}, "miners_data", []string{"user_id"}, []string{utils.Int64ToStr(p.TxUserID)}) if err != nil { return p.ErrInfo(err) } // смена местоположения влечет инициацию процедуры выдачи разрешения майнить имеющиеся у юзера валюты в данном местоположении // установка promised_amount.status в change_geo возможна, только если до этого был статус mining/pending/change_geo // это означает, что нужен пересчет TDC, т.к. до этого момента они майнились // логируем предыдущее. Тут ASC, а при откате используем ORDER BY `id` DESC, чтобы не накосячить при уменьшении log_id userHolidays, err := p.GetHolidays(p.TxUserID) if err != nil { return p.ErrInfo(err) } pointsStatus, err := p.GetPointsStatus(p.TxUserID, p.Variables.Int64["points_update_time"], p.BlockData) if err != nil { return p.ErrInfo(err) } rows, err := p.Query(p.FormatQuery(` SELECT id, currency_id, status, start_time, amount, tdc_amount, tdc_amount_update, votes_start_time, votes_0, votes_1, log_id FROM promised_amount WHERE status IN ('mining', 'pending', 'change_geo') AND user_id =? AND currency_id > 1 AND del_block_id = 0 AND del_mining_block_id = 0 ORDER BY id ASC`), p.TxUserID) if err != nil { return p.ErrInfo(err) } defer rows.Close() for rows.Next() { var id, currency_id, start_time, tdc_amount_update, votes_start_time, votes_0, votes_1, log_id int64 var status string var amount, tdc_amount float64 err = rows.Scan(&id, ¤cy_id, &status, &start_time, &amount, &tdc_amount, &tdc_amount_update, &votes_start_time, &votes_0, &votes_1, &log_id) if err != nil { return p.ErrInfo(err) } logId, err := p.ExecSqlGetLastInsertId("INSERT INTO log_promised_amount ( status, start_time, tdc_amount, tdc_amount_update, votes_start_time, votes_0, votes_1, block_id, prev_log_id ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? )", "log_id", status, start_time, tdc_amount, tdc_amount_update, votes_start_time, votes_0, votes_1, p.BlockData.BlockId, log_id) if err != nil { return p.ErrInfo(err) } var newTdc float64 if status == "mining" { // то, от чего будем вычислять набежавшие % tdcSum := amount + tdc_amount // то, что успело набежать pct, err := p.GetPct() if err != nil { return p.ErrInfo(err) } MaxPromisedAmounts, err := p.GetMaxPromisedAmounts() if err != nil { return p.ErrInfo(err) } RepaidAmount, err := p.GetRepaidAmount(currency_id, p.TxUserID) if err != nil { return p.ErrInfo(err) } profit, err := p.calcProfit_(tdcSum, tdc_amount_update, p.BlockData.Time, pct[currency_id], pointsStatus, userHolidays, MaxPromisedAmounts[currency_id], currency_id, RepaidAmount) if err != nil { return p.ErrInfo(err) } newTdc = tdc_amount + profit } else { // для статуса 'pending', 'change_geo' нечего пересчитывать, т.к. во время этих статусов ничего не набегает newTdc = tdc_amount } err = p.ExecSql("UPDATE promised_amount SET status = 'change_geo', start_time = 0, tdc_amount = ?, tdc_amount_update = ?, votes_start_time = ?, votes_0 = 0, votes_1 = 0, log_id = ? WHERE id = ?", utils.Round(newTdc, 2), p.BlockData.Time, p.BlockData.Time, logId, id) if err != nil { return p.ErrInfo(err) } } // проверим, не наш ли это user_id myUserId, myBlockId, myPrefix, _, err := p.GetMyUserId(p.TxUserID) if err != nil { return p.ErrInfo(err) } if p.TxUserID == myUserId && myBlockId <= p.BlockData.BlockId { err = p.ExecSql("UPDATE " + myPrefix + "my_table SET geolocation_status = 'approved'") if err != nil { return p.ErrInfo(err) } } return nil }
/* $del_block_id указывается, когда майнинг происходит как побочный результат удаления обещанной суммы * */ func (p *Parser) mining_(delMiningBlockId int64) error { // 1 возможно нужно обновить таблицу points_status err := p.pointsUpdateMain(p.TxUserID) if err != nil { return p.ErrInfo(err) } refs, err := p.getRefs(p.TxUserID) if err != nil { return p.ErrInfo(err) } if refs[0] > 0 { err = p.pointsUpdateMain(refs[0]) if err != nil { return p.ErrInfo(err) } } if refs[1] > 0 { err = p.pointsUpdateMain(refs[1]) if err != nil { return p.ErrInfo(err) } } if refs[2] > 0 { err = p.pointsUpdateMain(refs[2]) if err != nil { return p.ErrInfo(err) } } data, err := p.OneRow("SELECT status, amount, currency_id, tdc_amount, tdc_amount_update, log_id FROM promised_amount WHERE id = ?", p.TxMaps.Int64["promised_amount_id"]).String() if err != nil { return p.ErrInfo(err) } currencyId := utils.StrToInt64(data["currency_id"]) // возможно, что данный юзер имеет непогашенные cash_requests, значит новые TDC у него не растут, а просто обновляется tdc_amount_update newTdc, err := p.getTdc(p.TxMaps.Int64["promised_amount_id"], p.TxUserID) if err != nil { return p.ErrInfo(err) } // логируем текущее значение по обещанным суммам // tdc_and_profit - для del_promised_amount logId, err := p.ExecSqlGetLastInsertId("INSERT INTO log_promised_amount ( tdc_and_profit, tdc_amount, tdc_amount_update, block_id, prev_log_id ) VALUES ( ?, ?, ?, ?, ? )", "log_id", newTdc, data["tdc_amount"], data["tdc_amount_update"], p.BlockData.BlockId, data["log_id"]) if err != nil { return p.ErrInfo(err) } // 2 списываем сумму с promised_amount err = p.ExecSql("UPDATE promised_amount SET tdc_amount = ?, tdc_amount_update = ?, del_mining_block_id = ?, log_id = ? WHERE id = ?", utils.Round((newTdc-p.TxMaps.Money["amount"]), 2), p.BlockData.Time, delMiningBlockId, logId, p.TxMaps.Int64["promised_amount_id"]) if err != nil { return p.ErrInfo(err) } // 3 теперь начисляем DC, залогировав предыдущее значение err = p.updateRecipientWallet(p.TxUserID, currencyId, p.TxMaps.Money["amount"], "from_mining_id", p.TxMaps.Int64["promised_amount_id"], "", "", true) if err != nil { return p.ErrInfo(err) } // комиссия системы systemCommission := utils.Round(p.TxMaps.Money["amount"]*float64(float64(p.Variables.Int64["system_commission"])/100), 2) if systemCommission == 0 { log.Debug("systemCommission == 0") systemCommission = 0.01 } if systemCommission >= p.TxMaps.Money["amount"] { log.Debug(`systemCommission >= p.TxMaps.Money["amount"]`) systemCommission = 0 } log.Debug("systemCommission", systemCommission) // 4 теперь начисляем комиссию системе if systemCommission > 0 { err = p.updateRecipientWallet(1, currencyId, systemCommission, "system_commission", p.TxMaps.Int64["promised_amount_id"], "", "", true) } // 5 реферальные refData, err := p.OneRow("SELECT * FROM referral").Float64() if err != nil { return p.ErrInfo(err) } if refs[0] > 0 { log.Debug("%v, %v, %v", p.TxMaps.Money["amount"], float64(refData["first"]/100), refData["first"]) refAmount := utils.Round(p.TxMaps.Money["amount"]*float64(refData["first"]/100), 2) log.Debug("refs[0]", refs[0], refAmount) //log.Debug(p.TxMaps.Money["amount"], float64(refData["first"] / 100), refData["first"], refAmount) if refAmount > 0 { log.Debug("refAmount %v", refAmount) err = p.updateRecipientWallet(refs[0], currencyId, refAmount, "referral", p.TxMaps.Int64["promised_amount_id"], "", "", true) if err != nil { return p.ErrInfo(err) } // для вывода статы по рефам. табла чистится по времени err = p.ExecSql("INSERT INTO referral_stats ( user_id, referral, amount, currency_id, time, block_id ) VALUES ( ?, ?, ?, ?, ?, ? )", refs[0], p.TxUserID, refAmount, currencyId, p.BlockData.Time, p.BlockData.BlockId) if err != nil { return p.ErrInfo(err) } } } if refs[1] > 0 { refAmount := utils.Round(p.TxMaps.Money["amount"]*float64(refData["second"]/100), 2) log.Debug("refs[1]", refs[1], refAmount) if refAmount > 0 { log.Debug("refAmount %v", refAmount) err = p.updateRecipientWallet(refs[1], currencyId, refAmount, "referral", p.TxMaps.Int64["promised_amount_id"], "", "", true) if err != nil { return p.ErrInfo(err) } // для вывода статы по рефам. табла чистится по времени err = p.ExecSql("INSERT INTO referral_stats ( user_id, referral, amount, currency_id, time, block_id ) VALUES ( ?, ?, ?, ?, ?, ? )", refs[1], refs[0], refAmount, currencyId, p.BlockData.Time, p.BlockData.BlockId) if err != nil { return p.ErrInfo(err) } } } if refs[2] > 0 { refAmount := utils.Round(p.TxMaps.Money["amount"]*float64(refData["third"]/100), 2) log.Debug("refs[2]", refs[2], refAmount) if refAmount > 0 { log.Debug("refAmount %v", refAmount) err = p.updateRecipientWallet(refs[2], currencyId, refAmount, "referral", p.TxMaps.Int64["promised_amount_id"], "", "", true) if err != nil { return p.ErrInfo(err) } // для вывода статы по рефам. табла чистится по времени err = p.ExecSql("INSERT INTO referral_stats ( user_id, referral, amount, currency_id, time, block_id ) VALUES ( ?, ?, ?, ?, ?, ? )", refs[2], refs[1], refAmount, currencyId, p.BlockData.Time, p.BlockData.BlockId) if err != nil { return p.ErrInfo(err) } } } return nil }
func (p *Parser) MiningRollback() error { log.Debug("p.TxMaps.Money[amount] %v", p.TxMaps.Money["amount"]) promisedAmountData, err := p.OneRow("SELECT * FROM promised_amount WHERE id = ?", p.TxMaps.Int64["promised_amount_id"]).String() if err != nil { return p.ErrInfo(err) } log.Debug("promisedAmountData %v", promisedAmountData) refs, err := p.getRefs(p.TxUserID) if err != nil { return p.ErrInfo(err) } if refs[2] > 0 { err = p.pointsUpdateRollbackMain(refs[2]) if err != nil { return p.ErrInfo(err) } } if refs[1] > 0 { err = p.pointsUpdateRollbackMain(refs[1]) if err != nil { return p.ErrInfo(err) } } if refs[0] > 0 { err = p.pointsUpdateRollbackMain(refs[0]) if err != nil { return p.ErrInfo(err) } } // откатываем стату по рефам сразу по всему блоку err = p.ExecSql("DELETE FROM referral_stats WHERE block_id = ?", p.BlockData.BlockId) if err != nil { return p.ErrInfo(err) } // 5 реферальные var usersWalletsRollback []int64 refData, err := p.OneRow("SELECT * FROM referral").Float64() if err != nil { return p.ErrInfo(err) } log.Debug("refData %v", refData) if refs[2] > 0 { log.Debug("refs[2] %v", refs[2]) refAmount := utils.Round(p.TxMaps.Money["amount"]*float64(refData["third"]/100), 2) log.Debug("refAmount %v", refAmount) if refAmount > 0 { usersWalletsRollback = append(usersWalletsRollback, refs[2]) // возможно были списания по кредиту err = p.loanPaymentsRollback(refs[2], utils.StrToInt64(promisedAmountData["currency_id"])) if err != nil { return p.ErrInfo(err) } err = p.generalRollback("wallets", refs[2], "AND currency_id = "+promisedAmountData["currency_id"], false) if err != nil { return p.ErrInfo(err) } } } if refs[1] > 0 { log.Debug("refs[1] %v", refs[1]) refAmount := utils.Round(p.TxMaps.Money["amount"]*float64(refData["second"]/100), 2) log.Debug("refAmount %v", refAmount) if refAmount > 0 { usersWalletsRollback = append(usersWalletsRollback, refs[1]) // возможно были списания по кредиту err = p.loanPaymentsRollback(refs[1], utils.StrToInt64(promisedAmountData["currency_id"])) if err != nil { return p.ErrInfo(err) } err = p.generalRollback("wallets", refs[1], "AND currency_id = "+promisedAmountData["currency_id"], false) if err != nil { return p.ErrInfo(err) } } } if refs[0] > 0 { log.Debug("refs[0] %v", refs[0]) refAmount := utils.Round(p.TxMaps.Money["amount"]*float64(refData["first"]/100), 2) log.Debug("refAmount %v", refAmount) if refAmount > 0 { // возможно были списания по кредиту err = p.loanPaymentsRollback(refs[0], utils.StrToInt64(promisedAmountData["currency_id"])) if err != nil { return p.ErrInfo(err) } err = p.generalRollback("wallets", refs[0], "AND currency_id = "+promisedAmountData["currency_id"], false) if err != nil { return p.ErrInfo(err) } usersWalletsRollback = append(usersWalletsRollback, refs[0]) } } // 4 откатим комиссию системы systemCommission := utils.Round(p.TxMaps.Money["amount"]*float64(float64(p.Variables.Int64["system_commission"])/100), 2) log.Debug("systemCommission %v", systemCommission) if systemCommission == 0 { log.Debug("systemCommission == 0") systemCommission = 0.01 } if systemCommission >= p.TxMaps.Money["amount"] { log.Debug(`systemCommission >= p.TxMaps.Money["amount"]`) systemCommission = 0 } if systemCommission > 0 { log.Debug("systemCommission %v", systemCommission) log.Debug("generalRollback 1") // возможно были списания по кредиту err = p.loanPaymentsRollback(1, utils.StrToInt64(promisedAmountData["currency_id"])) if err != nil { return p.ErrInfo(err) } err = p.generalRollback("wallets", 1, "AND currency_id = "+promisedAmountData["currency_id"], false) if err != nil { return p.ErrInfo(err) } usersWalletsRollback = append(usersWalletsRollback, 1) } // возможно были списания по кредиту err = p.loanPaymentsRollback(p.TxUserID, utils.StrToInt64(promisedAmountData["currency_id"])) if err != nil { return p.ErrInfo(err) } // 3 откатим начисленные DC err = p.generalRollback("wallets", p.TxUserID, "AND currency_id = "+promisedAmountData["currency_id"], false) if err != nil { return p.ErrInfo(err) } // данные, которые восстановим в promised_amount logData, err := p.OneRow("SELECT * FROM log_promised_amount WHERE log_id = ?", promisedAmountData["log_id"]).String() if err != nil { return p.ErrInfo(err) } // 2 откатываем promised_amount err = p.ExecSql("UPDATE promised_amount SET tdc_amount = ?, tdc_amount_update = ?, log_id = ? WHERE id = ?", logData["tdc_amount"], logData["tdc_amount_update"], logData["prev_log_id"], p.TxMaps.Int64["promised_amount_id"]) if err != nil { return p.ErrInfo(err) } // подчищаем _log err = p.ExecSql("DELETE FROM log_promised_amount WHERE log_id = ?", promisedAmountData["log_id"]) if err != nil { return p.ErrInfo(err) } err = p.rollbackAI("log_promised_amount", 1) if err != nil { return p.ErrInfo(err) } // 1 возможно нужно обновить таблицу points_status err = p.pointsUpdateRollbackMain(p.TxUserID) if err != nil { return p.ErrInfo(err) } err = p.mydctxRollback() if err != nil { return p.ErrInfo(err) } return nil }
/* * Каждые 2 недели собираем инфу о голосах за % и создаем тр-ию, которая * попадет в DC сеть только, если мы окажемся генератором блока * */ func PctGenerator(chBreaker chan bool, chAnswer chan string) { defer func() { if r := recover(); r != nil { log.Error("daemon Recovered", r) panic(r) } }() const GoroutineName = "PctGenerator" d := new(daemon) d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } d.goRoutineName = GoroutineName d.chAnswer = chAnswer d.chBreaker = chBreaker if utils.Mobile() { d.sleepTime = 3600 } else { d.sleepTime = 60 } if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) { return } d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName) if d.DCDB == nil { return } err = d.notMinerSetSleepTime(1800) if err != nil { log.Error("%v", err) return } BEGIN: for { log.Info(GoroutineName) MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())} // проверим, не нужно ли нам выйти из цикла if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) { break BEGIN } err, restart := d.dbLock() if restart { break BEGIN } if err != nil { if d.dPrintSleep(err, d.sleepTime) { break BEGIN } continue BEGIN } blockId, err := d.GetBlockId() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if blockId == 0 { if d.unlockPrintSleep(utils.ErrInfo("blockId == 0"), d.sleepTime) { break BEGIN } continue BEGIN } _, _, myMinerId, _, _, _, err := d.TestBlock() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // а майнер ли я ? if myMinerId == 0 { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } variables, err := d.GetAllVariables() curTime := utils.Time() // проверим, прошло ли 2 недели с момента последнего обновления pct pctTime, err := d.Single("SELECT max(time) FROM pct").Int64() if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } if curTime-pctTime > variables.Int64["new_pct_period"] { // берем все голоса miner_pct pctVotes := make(map[int64]map[string]map[string]int64) rows, err := d.Query("SELECT currency_id, pct, count(user_id) as votes FROM votes_miner_pct GROUP BY currency_id, pct ORDER BY currency_id, pct ASC") if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var currency_id, votes int64 var pct string err = rows.Scan(¤cy_id, &pct, &votes) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } log.Info("%v", "newpctcurrency_id", currency_id, "pct", pct, "votes", votes) if len(pctVotes[currency_id]) == 0 { pctVotes[currency_id] = make(map[string]map[string]int64) } if len(pctVotes[currency_id]["miner_pct"]) == 0 { pctVotes[currency_id]["miner_pct"] = make(map[string]int64) } pctVotes[currency_id]["miner_pct"][pct] = votes } rows.Close() // берем все голоса user_pct rows, err = d.Query("SELECT currency_id, pct, count(user_id) as votes FROM votes_user_pct GROUP BY currency_id, pct ORDER BY currency_id, pct ASC") if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var currency_id, votes int64 var pct string err = rows.Scan(¤cy_id, &pct, &votes) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } log.Info("%v", "currency_id", currency_id, "pct", pct, "votes", votes) if len(pctVotes[currency_id]) == 0 { pctVotes[currency_id] = make(map[string]map[string]int64) } if len(pctVotes[currency_id]["user_pct"]) == 0 { pctVotes[currency_id]["user_pct"] = make(map[string]int64) } pctVotes[currency_id]["user_pct"][pct] = votes } rows.Close() newPct := make(map[string]map[string]map[string]string) newPct["currency"] = make(map[string]map[string]string) var userMaxKey int64 PctArray := utils.GetPctArray() log.Info("%v", "pctVotes", pctVotes) for currencyId, data := range pctVotes { currencyIdStr := utils.Int64ToStr(currencyId) // определяем % для майнеров pctArr := utils.MakePctArray(data["miner_pct"]) log.Info("%v", "pctArrminer_pct", pctArr, currencyId) key := utils.GetMaxVote(pctArr, 0, 390, 100) log.Info("%v", "key", key) if len(newPct["currency"][currencyIdStr]) == 0 { newPct["currency"][currencyIdStr] = make(map[string]string) } newPct["currency"][currencyIdStr]["miner_pct"] = utils.GetPctValue(key) // определяем % для юзеров pctArr = utils.MakePctArray(data["user_pct"]) log.Info("%v", "pctArruser_pct", pctArr, currencyId) log.Info("%v", "newPct", newPct) pctY := utils.ArraySearch(newPct["currency"][currencyIdStr]["miner_pct"], PctArray) log.Info("%v", "newPct[currency][currencyIdStr][miner_pct]", newPct["currency"][currencyIdStr]["miner_pct"]) log.Info("%v", "PctArray", PctArray) log.Info("%v", "miner_pct $pct_y=", pctY) maxUserPctY := utils.Round(utils.StrToFloat64(pctY)/2, 2) userMaxKey = utils.FindUserPct(int(maxUserPctY)) log.Info("%v", "maxUserPctY", maxUserPctY, "userMaxKey", userMaxKey, "currencyIdStr", currencyIdStr) // отрезаем лишнее, т.к. поиск идет ровно до макимального возможного, т.е. до miner_pct/2 pctArr = utils.DelUserPct(pctArr, userMaxKey) log.Info("%v", "pctArr", pctArr) key = utils.GetMaxVote(pctArr, 0, userMaxKey, 100) log.Info("%v", "data[user_pct]", data["user_pct"]) log.Info("%v", "pctArr", pctArr) log.Info("%v", "userMaxKey", userMaxKey) log.Info("%v", "key", key) newPct["currency"][currencyIdStr]["user_pct"] = utils.GetPctValue(key) log.Info("%v", "user_pct", newPct["currency"][currencyIdStr]["user_pct"]) } newPct_ := new(newPctType) newPct_.Currency = make(map[string]map[string]string) newPct_.Currency = newPct["currency"] newPct_.Referral = make(map[string]int64) refLevels := []string{"first", "second", "third"} for i := 0; i < len(refLevels); i++ { level := refLevels[i] var votesReferral []map[int64]int64 // берем все голоса rows, err := d.Query("SELECT " + level + ", count(user_id) as votes FROM votes_referral GROUP BY " + level + " ORDER BY " + level + " ASC ") if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } for rows.Next() { var level_, votes int64 err = rows.Scan(&level_, &votes) if err != nil { rows.Close() if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } votesReferral = append(votesReferral, map[int64]int64{level_: votes}) } rows.Close() newPct_.Referral[level] = (utils.GetMaxVote(votesReferral, 0, 30, 10)) } jsonData, err := json.Marshal(newPct_) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } _, myUserId, _, _, _, _, err := d.TestBlock() forSign := fmt.Sprintf("%v,%v,%v,%s", utils.TypeInt("NewPct"), curTime, myUserId, jsonData) log.Debug("forSign = %v", forSign) binSign, err := d.GetBinSign(forSign, myUserId) log.Debug("binSign = %x", binSign) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } data := utils.DecToBin(utils.TypeInt("NewPct"), 1) data = append(data, utils.DecToBin(curTime, 4)...) data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(myUserId))...) data = append(data, utils.EncodeLengthPlusData(jsonData)...) data = append(data, utils.EncodeLengthPlusData([]byte(binSign))...) err = d.InsertReplaceTxInQueue(data) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } // и не закрывая main_lock переводим нашу тр-ию в verified=1, откатив все несовместимые тр-ии // таким образом у нас будут в блоке только актуальные голоса. // а если придет другой блок и станет verified=0, то эта тр-ия просто удалится. p := new(dcparser.Parser) p.DCDB = d.DCDB err = p.TxParser(utils.HexToBin(utils.Md5(data)), data, true) if err != nil { if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) { break BEGIN } continue BEGIN } } d.dbUnlock() if d.dSleep(d.sleepTime) { break BEGIN } } log.Debug("break BEGIN %v", GoroutineName) }
func (c *Controller) StatisticVoting() (string, error) { var err error js := "" var divs []string /* * Голосование за размер обещанной суммы */ rows, err := c.Query(c.FormatQuery(`SELECT currency_id, amount, count(user_id) as votes FROM votes_max_promised_amount GROUP BY currency_id, amount`)) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() maxPromisedAmountVotes := make(map[int64][]map[int64]int64) for rows.Next() { var currency_id, votes, amount int64 err = rows.Scan(¤cy_id, &amount, &votes) if err != nil { return "", utils.ErrInfo(err) } maxPromisedAmountVotes[currency_id] = append(maxPromisedAmountVotes[currency_id], map[int64]int64{amount: votes}) } for currencyId, arr := range maxPromisedAmountVotes { js += fmt.Sprintf("var max_promised_amounts_%d = [", currencyId) for _, data := range arr { for k, v := range data { js += fmt.Sprintf("[%v, %v],", k, v) } } js = js[:len(js)-1] + "];\n" divs = append(divs, fmt.Sprintf("max_promised_amounts_%d", currencyId)) } totalCountCurrencies, err := c.Single("SELECT count(id) FROM currency").Int64() if err != nil { return "", utils.ErrInfo(err) } newMaxPromisedAmounts := make(map[int64]int64) //array []map[int64]int64, min, max, step int64 for currencyId, data := range maxPromisedAmountVotes { newMaxPromisedAmounts[currencyId] = utils.GetMaxVote(data, 0, totalCountCurrencies, 10) } /* * Голосование за кол-во валют в обещанных суммах */ rows, err = c.Query(c.FormatQuery(`SELECT currency_id, count, count(user_id) as votes FROM votes_max_other_currencies GROUP BY currency_id, count`)) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() maxOtherCurrenciesVotes := make(map[int64][]map[int64]int64) for rows.Next() { var currency_id, count, votes int64 err = rows.Scan(¤cy_id, &count, &votes) if err != nil { return "", utils.ErrInfo(err) } maxOtherCurrenciesVotes[currency_id] = append(maxOtherCurrenciesVotes[currency_id], map[int64]int64{count: votes}) } log.Debug("maxOtherCurrenciesVotes", maxOtherCurrenciesVotes) newMaxOtherCurrencies := make(map[int64]int64) for currencyId, arr := range maxOtherCurrenciesVotes { newMaxOtherCurrencies[currencyId] = utils.GetMaxVote(arr, 0, totalCountCurrencies, 10) js += fmt.Sprintf("var max_other_currencies_votes_%d = [", currencyId) for _, data := range arr { log.Debug("data", data) for k, v := range data { js += fmt.Sprintf("[%v, %v],", k, v) } } js = js[:len(js)-1] + "];\n" log.Debug("js", js) divs = append(divs, fmt.Sprintf("max_other_currencies_votes_%d", currencyId)) } /* * Голосование за ручное сокращение объема монет * */ // получаем кол-во обещанных сумм у разных юзеров по каждой валюте. start_time есть только у тех, у кого статус mining/repaid promisedAmount_, err := c.GetAll(` SELECT currency_id, count(user_id) as count FROM ( SELECT currency_id, user_id FROM promised_amount WHERE start_time < ? AND del_block_id = 0 AND del_mining_block_id = 0 AND status IN ('mining', 'repaid') GROUP BY user_id, currency_id ) as t1 GROUP BY currency_id `, -1, utils.Time()-c.Variables.Int64["min_hold_time_promise_amount"]) if err != nil { return "", utils.ErrInfo(err) } promisedAmount := make(map[string]string) for _, data := range promisedAmount_ { promisedAmount[data["currency_id"]] = data["count"] } // берем все голоса юзеров по данной валюте votesReduction := make(map[string]map[string]string) votesReduction_, err := c.GetAll(` SELECT currency_id, pct, count(currency_id) as votes FROM votes_reduction WHERE time > ? AND pct > 0 GROUP BY currency_id, pct `, -1, utils.Time()-c.Variables.Int64["reduction_period"]) if err != nil { return "", utils.ErrInfo(err) } for _, data := range votesReduction_ { votesReduction[data["currency_id"]] = make(map[string]string) votesReduction[data["currency_id"]][data["pct"]] = data["votes"] } /* * Голосование за реф. бонусы * */ refLevels := []string{"first", "second", "third"} newReferralPct := make(map[string]int64) votesReferral := make(map[string][]map[int64]int64) for i := 0; i < len(refLevels); i++ { level := refLevels[i] // берем все голоса votesReferral_, err := c.GetAll(` SELECT `+level+`, count(user_id) as votes FROM votes_referral GROUP BY `+level+` `, -1) if err != nil { return "", utils.ErrInfo(err) } for _, data := range votesReferral_ { votesReferral[level] = append(votesReferral[level], map[int64]int64{utils.StrToInt64(data[level]): utils.StrToInt64(data["votes"])}) } newReferralPct[level] = utils.GetMaxVote(votesReferral[level], 0, 30, 10) } for level, arr := range votesReferral { js += "var votes_referral_" + level + " = [" for _, data := range arr { for k, v := range data { js += fmt.Sprintf("[%v, %v],", k, v) } } js = js[:len(js)-1] + "];\n" divs = append(divs, "votes_referral_"+level) } /* * Голосоваие за майнеркие и юзерские % * */ // берем все голоса miner_pct pctVotes := make(map[int64]map[string]map[string]int64) rows, err = c.Query("SELECT currency_id, pct, count(user_id) as votes FROM votes_miner_pct GROUP BY currency_id, pct ORDER BY currency_id, pct ASC") if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var currency_id, votes int64 var pct string err = rows.Scan(¤cy_id, &pct, &votes) if err != nil { return "", utils.ErrInfo(err) } log.Debug("newpctcurrency_id", currency_id, "pct", pct, "votes", votes) if len(pctVotes[currency_id]) == 0 { pctVotes[currency_id] = make(map[string]map[string]int64) } if len(pctVotes[currency_id]["miner_pct"]) == 0 { pctVotes[currency_id]["miner_pct"] = make(map[string]int64) } pctVotes[currency_id]["miner_pct"][pct] = votes } // берем все голоса user_pct rows, err = c.Query("SELECT currency_id, pct, count(user_id) as votes FROM votes_user_pct GROUP BY currency_id, pct ORDER BY currency_id, pct ASC") if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var currency_id, votes int64 var pct string err = rows.Scan(¤cy_id, &pct, &votes) if err != nil { return "", utils.ErrInfo(err) } log.Debug("currency_id", currency_id, "pct", pct, "votes", votes) if len(pctVotes[currency_id]) == 0 { pctVotes[currency_id] = make(map[string]map[string]int64) } if len(pctVotes[currency_id]["user_pct"]) == 0 { pctVotes[currency_id]["user_pct"] = make(map[string]int64) } pctVotes[currency_id]["user_pct"][pct] = votes } log.Debug("pctVotes", pctVotes) for currencyId, data := range pctVotes { currencyIdStr := utils.Int64ToStr(currencyId) divs = append(divs, "miner_pct_"+currencyIdStr) divs = append(divs, "user_pct_"+currencyIdStr) js += "var miner_pct_" + currencyIdStr + " = [" for k, v := range data["miner_pct"] { pctY := utils.Round((math.Pow(1+utils.StrToFloat64(k), 3600*24*365)-1)*100, 2) js += fmt.Sprintf("[%v, %v],", pctY, v) } js = js[:len(js)-1] + "];\n" js += "var user_pct_" + currencyIdStr + " = [" for k, v := range data["user_pct"] { pctY := utils.Round((math.Pow(1+utils.StrToFloat64(k), 3600*24*365)-1)*100, 2) js += fmt.Sprintf("[%v, %v],", pctY, v) } js = js[:len(js)-1] + "];\n" } newPct := make(map[string]map[string]string) newPctTpl := make(map[string]map[string]float64) var userMaxKey int64 PctArray := utils.GetPctArray() log.Debug("pctVotes", pctVotes) for currencyId, data := range pctVotes { currencyIdStr := utils.Int64ToStr(currencyId) // определяем % для майнеров pctArr := utils.MakePctArray(data["miner_pct"]) log.Debug("currencyIdStr:", currencyIdStr) log.Debug("miner_pct:", data["miner_pct"]) log.Debug("pctArr:", pctArr) key := utils.GetMaxVote(pctArr, 0, 390, 100) log.Debug("key:", key) if len(newPct[currencyIdStr]) == 0 { newPct[currencyIdStr] = make(map[string]string) } newPct[currencyIdStr]["miner_pct"] = utils.GetPctValue(key) if len(newPctTpl[currencyIdStr]) == 0 { newPctTpl[currencyIdStr] = make(map[string]float64) } newPctTpl[currencyIdStr]["miner_pct"] = utils.Round((math.Pow(1+utils.StrToFloat64(utils.GetPctValue(key)), 3600*24*365)-1)*100, 2) // определяем % для юзеров pctArr = utils.MakePctArray(data["user_pct"]) pctY := utils.ArraySearch(newPct[currencyIdStr]["miner_pct"], PctArray) maxUserPctY := utils.Round(utils.StrToFloat64(pctY)/2, 2) userMaxKey = utils.FindUserPct(int(maxUserPctY)) // отрезаем лишнее, т.к. поиск идет ровно до макимального возможного, т.е. до miner_pct/2 pctArr = utils.DelUserPct(pctArr, userMaxKey) key = utils.GetMaxVote(pctArr, 0, userMaxKey, 100) newPct[currencyIdStr]["user_pct"] = utils.GetPctValue(key) newPctTpl[currencyIdStr]["user_pct"] = utils.Round((math.Pow(1+utils.StrToFloat64(utils.GetPctValue(key)), 3600*24*365)-1)*100, 2) } log.Debug("newPct", newPct) log.Debug("newPctTpl", newPctTpl) /* * %/год * */ currencyPct := make(map[int64]map[string]string) for currencyId, name := range c.CurrencyList { pct, err := c.OneRow("SELECT * FROM pct WHERE currency_id = ? ORDER BY block_id DESC", currencyId).String() if err != nil { return "", utils.ErrInfo(err) } currencyPct[currencyId] = make(map[string]string) currencyPct[currencyId]["name"] = name currencyPct[currencyId]["miner"] = utils.Float64ToStr(utils.Round((math.Pow(1+utils.StrToFloat64(pct["miner"]), 120)-1)*100, 6)) currencyPct[currencyId]["user"] = utils.Float64ToStr(utils.Round((math.Pow(1+utils.StrToFloat64(pct["user"]), 120)-1)*100, 6)) } TemplateStr, err := makeTemplate("statistic_voting", "statisticVoting", &StatisticVotingPage{ Lang: c.Lang, CurrencyList: c.CurrencyListCf, Js: template.JS(js), Divs: divs, CurrencyPct: currencyPct, NewPctTpl: newPctTpl, PctVotes: pctVotes, VotesReferral: votesReferral, VotesReduction: votesReduction, PromisedAmount: promisedAmount, NewMaxOtherCurrencies: newMaxOtherCurrencies, MaxOtherCurrenciesVotes: maxOtherCurrenciesVotes, MaxPromisedAmountVotes: maxPromisedAmountVotes, NewMaxPromisedAmounts: newMaxPromisedAmounts, NewReferralPct: newReferralPct, UserId: c.SessUserId}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (c *Controller) SynchronizationBlockchain() (string, error) { if c.DCDB == nil || c.DCDB.DB == nil { return "", nil } blockData, err := c.DCDB.GetInfoBlock() if err != nil { log.Error("%v", utils.ErrInfo(err)) var downloadFile string var fileSize int64 if len(utils.SqliteDbUrl) > 0 { downloadFile = *utils.Dir + "/litedb.db" resp, err := http.Get(utils.SqliteDbUrl) if err != nil { return "", err } fileSize = resp.ContentLength resp.Body.Close() } else { downloadFile = *utils.Dir + "/public/blockchain" nodeConfig, err := c.GetNodeConfig() blockchain_url := nodeConfig["first_load_blockchain_url"] if len(blockchain_url) == 0 { blockchain_url = consts.BLOCKCHAIN_URL } resp, err := http.Get(blockchain_url) if err != nil { return "", err } fileSize = resp.ContentLength } // качается блок file, err := os.Open(downloadFile) if err != nil { return "", err } defer file.Close() stat, err := file.Stat() if err != nil { return "", err } if stat.Size() > 0 { log.Debug("stat.Size(): %v", int(stat.Size())) return `{"download": "` + utils.Int64ToStr(int64(utils.Round(float64((float64(stat.Size())/float64(fileSize))*100), 0))) + `"}`, nil } else { return `{"download": "0"}`, nil } } blockId := blockData["block_id"] blockTime := blockData["time"] if len(blockId) == 0 { blockId = "0" } if len(blockTime) == 0 { blockTime = "0" } wTime := int64(12) wTimeReady := int64(2) if c.ConfigIni["test_mode"] == "1" { wTime = 2 * 365 * 86400 wTimeReady = 2 * 365 * 86400 } log.Debug("wTime: %v / utils.Time(): %v / blockData[time]: %v", wTime, utils.Time(), utils.StrToInt64(blockData["time"])) // если время менее 12 часов от текущего, то выдаем не подвержденные, а просто те, что есть в блокчейне if utils.Time()-utils.StrToInt64(blockData["time"]) < 3600*wTime { lastBlockData, err := c.DCDB.GetLastBlockData() if err != nil { return "", err } log.Debug("lastBlockData[lastBlockTime]: %v", lastBlockData["lastBlockTime"]) log.Debug("time.Now().Unix(): %v", time.Now().Unix()) // если уже почти собрали все блоки if time.Now().Unix()-lastBlockData["lastBlockTime"] < 3600*wTimeReady { blockId = "-1" blockTime = "-1" } } connections, err := c.Single(`SELECT count(*) from nodes_connection`).String() if err != nil { return "", err } confirmedBlockId, err := c.GetConfirmedBlockId() if err != nil { return "", err } currentLoadBlockchain := "nodes" if c.NodeConfig["current_load_blockchain"] == "file" { currentLoadBlockchain = c.NodeConfig["first_load_blockchain_url"] } result := map[string]string{"block_id": blockId, "confirmed_block_id": utils.Int64ToStr(confirmedBlockId), "block_time": blockTime, "connections": connections, "current_load_blockchain": currentLoadBlockchain} resultJ, _ := json.Marshal(result) return string(resultJ), nil }
func (c *Controller) Statistic() (string, error) { var err error sumWallets := make(map[int64]float64) // получаем кол-во DC на кошельках rows, err := c.Query(` SELECT currency_id, sum(amount) as sum_amount FROM wallets GROUP BY currency_id `) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var currency_id int64 var sum_amount float64 err = rows.Scan(¤cy_id, &sum_amount) if err != nil { return "", utils.ErrInfo(err) } sumWallets[currency_id] = sum_amount } // получаем кол-во TDC на обещанных суммах rows, err = c.Query(` SELECT currency_id, sum(tdc_amount) as sum_amount FROM promised_amount GROUP BY currency_id `) if err != nil { return "", utils.ErrInfo(err) } defer rows.Close() for rows.Next() { var currency_id int64 var sum_amount float64 err = rows.Scan(¤cy_id, &sum_amount) if err != nil { return "", utils.ErrInfo(err) } if sumWallets[currency_id] > 0 { sumWallets[currency_id] += sum_amount } else { sumWallets[currency_id] = sum_amount } } // получаем суммы обещанных сумм sumPromisedAmount, err := c.GetMap(` SELECT currency_id, sum(amount) as sum_amount FROM promised_amount WHERE status = 'mining' AND del_block_id = 0 AND (cash_request_out_time = 0 OR cash_request_out_time > ?) GROUP BY currency_id`, "currency_id", "sum_amount", utils.Time()-c.Variables.Int64["cash_request_time"]) // получаем кол-во майнеров по валютам promisedAmountMiners, err := c.GetMap(` SELECT currency_id, count(user_id) as count FROM ( SELECT currency_id, user_id FROM promised_amount WHERE del_block_id = 0 AND del_mining_block_id = 0 AND status IN ('mining', 'repaid') GROUP BY user_id, currency_id ) as t1 GROUP BY currency_id`, "currency_id", "count") // получаем кол-во анонимных юзеров по валютам walletsUsers, err := c.GetMap(` SELECT currency_id, count(user_id) as count FROM wallets WHERE amount > 0 GROUP BY currency_id`, "currency_id", "count") refPhotos := make(map[int64][]string) // таблица обмена на наличные cashRequests, err := c.GetAll(` SELECT * FROM cash_requests ORDER BY id DESC LIMIT 5`, 5) for i := 0; i < len(cashRequests); i++ { if cashRequests[i]["del_block_id"] != "0" { cashRequests[i]["status"] = "reduction closed" } else if utils.Time()-utils.StrToInt64(cashRequests[i]["time"]) > c.Variables.Int64["cash_request_time"] && cashRequests[i]["status"] != "approved" { cashRequests[i]["status"] = "rejected" } t := time.Unix(utils.StrToInt64(cashRequests[i]["time"]), 0) cashRequests[i]["time"] = t.Format(c.TimeFormat) // ### from_user_id для фоток data, err := c.OneRow("SELECT * FROM miners_data WHERE user_id = ?", cashRequests[i]["from_user_id"]).String() if err != nil { return "", utils.ErrInfo(err) } // получим ID майнеров, у которых лежат фото нужного нам юзера minersIds := utils.GetMinersKeepers(data["photo_block_id"], data["photo_max_miner_id"], data["miners_keepers"], true) hosts, err := c.GetList("SELECT http_host FROM miners_data WHERE miner_id IN (" + utils.JoinInts(minersIds, ",") + ")").String() if err != nil { return "", utils.ErrInfo(err) } refPhotos[utils.StrToInt64(cashRequests[i]["from_user_id"])] = hosts // ### to_user_id для фоток data, err = c.OneRow("SELECT * FROM miners_data WHERE user_id = ?", cashRequests[i]["to_user_id"]).String() if err != nil { return "", utils.ErrInfo(err) } // получим ID майнеров, у которых лежат фото нужного нам юзера minersIds = utils.GetMinersKeepers(data["photo_block_id"], data["photo_max_miner_id"], data["miners_keepers"], true) hosts, err = c.GetList("SELECT http_host FROM miners_data WHERE miner_id IN (" + utils.JoinInts(minersIds, ",") + ")").String() if err != nil { return "", utils.ErrInfo(err) } refPhotos[utils.StrToInt64(cashRequests[i]["to_user_id"])] = hosts } var userInfoWallets []utils.DCAmounts var promisedAmountListAccepted []utils.PromisedAmounts var credits map[string]string // поиск инфы о юзере userInfoId := int64(utils.StrToFloat64(c.Parameters["user_info_id"])) if userInfoId > 0 { userInfoWallets, err = c.GetBalances(userInfoId) if err != nil { return "", utils.ErrInfo(err) } // обещанные суммы юзера _, promisedAmountListAccepted, _, err = c.GetPromisedAmounts(userInfoId, c.Variables.Int64["cash_request_time"]) // кредиты credits, err = c.GetMap(` SELECT sum(amount) as amount, currency_id FROM credits WHERE from_user_id = ? AND del_block_id = 0 GROUP BY currency_id`, "amount", "currency_id", userInfoId) } /* * Кол-во юзеров, сменивших ключ * */ countUsers, err := c.Single("SELECT count(user_id) FROM users WHERE log_id > 0").Int64() if err != nil { return "", utils.ErrInfo(err) } /* * %/год * */ currencyPct := make(map[int64]map[string]string) for currencyId, name := range c.CurrencyList { pct, err := c.OneRow("SELECT * FROM pct WHERE currency_id = ? ORDER BY block_id DESC", currencyId).Float64() if err != nil { return "", utils.ErrInfo(err) } currencyPct[currencyId] = make(map[string]string) currencyPct[currencyId]["name"] = name currencyPct[currencyId]["miner"] = utils.Float64ToStr(utils.Round((math.Pow(1+pct["miner"], 120)-1)*100, 6)) currencyPct[currencyId]["user"] = utils.Float64ToStr(utils.Round((math.Pow(1+pct["user"], 120)-1)*100, 6)) } /* * Произошедшие сокращения * */ reduction, err := c.GetAll(` SELECT * FROM reduction ORDER BY time DESC LIMIT 20`, 20) for i := 0; i < len(reduction); i++ { if reduction[i]["type"] != "auto" { reduction[i]["type"] = "voting" } t := time.Unix(utils.StrToInt64(reduction[i]["time"]), 0) reduction[i]["time"] = t.Format(c.TimeFormat) } TemplateStr, err := makeTemplate("statistic", "statistic", &StatisticPage{ Lang: c.Lang, CurrencyList: c.CurrencyListCf, UserInfoId: userInfoId, SumWallets: sumWallets, SumPromisedAmount: sumPromisedAmount, PromisedAmountMiners: promisedAmountMiners, WalletsUsers: walletsUsers, CashRequests: cashRequests, UserInfoWallets: userInfoWallets, Credits: credits, PromisedAmountListAccepted: promisedAmountListAccepted, CountUsers: countUsers, CurrencyPct: currencyPct, Reduction: reduction, RefPhotos: refPhotos, UserId: c.SessUserId}) if err != nil { return "", utils.ErrInfo(err) } return TemplateStr, nil }
func (p *Parser) SendDc() error { // нужно отметить в log_time_money_orders, что тр-ия прошла в блок err := p.ExecSql("UPDATE log_time_money_orders SET del_block_id = ? WHERE hex(tx_hash) = ?", p.BlockData.BlockId, p.TxHash) if err != nil { return p.ErrInfo(err) } // 1 возможно нужно обновить таблицу points_status err = p.pointsUpdateMain(p.BlockData.UserId) if err != nil { return p.ErrInfo(err) } // 2 err = p.pointsUpdateMain(p.TxMaps.Int64["from_user_id"]) if err != nil { return p.ErrInfo(err) } // 3 err = p.pointsUpdateMain(p.TxMaps.Int64["to_user_id"]) if err != nil { return p.ErrInfo(err) } commission := p.TxMaps.Float64["commission"] var arbitration_days_refund int64 var seller_hold_back_pct float64 var arbitrators bool if p.BlockData.BlockId > consts.ARBITRATION_BLOCK_START { // на какой период манибека согласен продавец err := p.QueryRow(p.FormatQuery("SELECT arbitration_days_refund, seller_hold_back_pct FROM users WHERE user_id = ?"), p.TxMaps.Int64["to_user_id"]).Scan(&arbitration_days_refund, &seller_hold_back_pct) if err != nil && err != sql.ErrNoRows { return p.ErrInfo(err) } if arbitration_days_refund > 0 { for i := 0; i < 5; i++ { iStr := utils.IntToStr(i) if p.TxMaps.Int64["arbitrator"+iStr] > 0 && p.TxMaps.Float64["arbitrator"+iStr+"_commission"] >= 0.01 { // нужно учесть комиссию арбитра commission += p.TxMaps.Float64["arbitrator"+iStr+"_commission"] arbitrators = true } } } } // 4 обновим сумму на кошельке отправителя, залогировав предыдущее значение err = p.updateSenderWallet(p.TxMaps.Int64["from_user_id"], p.TxMaps.Int64["currency_id"], p.TxMaps.Float64["amount"], commission, "from_user", p.TxMaps.Int64["to_user_id"], p.TxMaps.Int64["to_user_id"], string(utils.BinToHex(p.TxMap["comment"])), "encrypted") if err != nil { return p.ErrInfo(err) } log.Debug("SendDC updateRecipientWallet") // 5 обновим сумму на кошельке получателю err = p.updateRecipientWallet(p.TxMaps.Int64["to_user_id"], p.TxMaps.Int64["currency_id"], p.TxMaps.Float64["amount"], "from_user", p.TxMaps.Int64["from_user_id"], p.TxMaps.String["comment"], "encrypted", true) if err != nil { return p.ErrInfo(err) } // 6 теперь начисляем комиссию майнеру, который этот блок сгенерил if p.TxMaps.Float64["commission"] >= 0.01 { err = p.updateRecipientWallet(p.BlockData.UserId, p.TxMaps.Int64["currency_id"], p.TxMaps.Float64["commission"], "node_commission", p.BlockData.BlockId, "", "encrypted", true) if err != nil { return p.ErrInfo(err) } } log.Debug("p.BlockData.BlockId", p.BlockData.BlockId) log.Debug("consts.ARBITRATION_BLOCK_START", consts.ARBITRATION_BLOCK_START) if p.BlockData.BlockId > consts.ARBITRATION_BLOCK_START { // если продавец не согласен на арбитраж, то $arbitration_days_refund будет равно 0 log.Debug("arbitration_days_refund", arbitration_days_refund) log.Debug("arbitrators", arbitrators) if arbitration_days_refund > 0 && arbitrators { holdBackAmount := math.Floor(utils.Round(p.TxMaps.Float64["amount"]*(seller_hold_back_pct/100), 3)*100) / 100 if holdBackAmount < 0.01 { holdBackAmount = 0.01 } orderId, err := p.ExecSqlGetLastInsertId("INSERT INTO orders ( time, buyer, seller, arbitrator0, arbitrator1, arbitrator2, arbitrator3, arbitrator4, amount, hold_back_amount, currency_id, block_id, end_time ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )", "id", p.BlockData.Time, p.TxMaps.Int64["from_user_id"], p.TxMaps.Int64["to_user_id"], p.TxMaps.Int64["arbitrator0"], p.TxMaps.Int64["arbitrator1"], p.TxMaps.Int64["arbitrator2"], p.TxMaps.Int64["arbitrator3"], p.TxMaps.Int64["arbitrator4"], p.TxMaps.Float64["amount"], holdBackAmount, p.TxMaps.Int64["currency_id"], p.BlockData.BlockId, (p.BlockData.Time + arbitration_days_refund*86400)) if err != nil { return p.ErrInfo(err) } // начисляем комиссию арбитрам for i := 0; i < 5; i++ { iStr := utils.IntToStr(i) log.Debug("arbitrator_commission "+iStr, p.TxMaps.Float64["arbitrator"+iStr+"_commission"]) if p.TxMaps.Int64["arbitrator"+iStr] > 0 && p.TxMaps.Float64["arbitrator"+iStr+"_commission"] >= 0.01 { log.Debug("updateRecipientWallet") err = p.updateRecipientWallet(p.TxMaps.Int64["arbitrator"+iStr], p.TxMaps.Int64["currency_id"], p.TxMaps.Float64["arbitrator"+iStr+"_commission"], "arbitrator_commission", orderId, "", "encrypted", true) if err != nil { return p.ErrInfo(err) } } } } } // отмечаем данную транзакцию в буфере как отработанную и ставим в очередь на удаление err = p.ExecSql("UPDATE wallets_buffer SET del_block_id = ? WHERE hex(hash) = ?", p.BlockData.BlockId, p.TxHash) if err != nil { return p.ErrInfo(err) } return nil }
func (p *Parser) AdminBanMiners() error { users_ids := strings.Split(p.TxMaps.String["users_ids"], ",") for i := 0; i < len(users_ids); i++ { userId := utils.StrToInt64(users_ids[i]) // возможно нужно обновить таблицу points_status err := p.pointsUpdateMain(userId) // переводим майнера из майнеров в юзеры data, err := p.OneRow("SELECT miner_id, status, log_id FROM miners_data WHERE user_id = ?", userId).String() if err != nil { return p.ErrInfo(err) } // логируем текущие значения logId, err := p.ExecSqlGetLastInsertId("INSERT INTO log_miners_data ( miner_id, status, block_id, prev_log_id ) VALUES ( ?, ?, ?, ? )", "log_id", data["miner_id"], data["status"], p.BlockData.BlockId, data["log_id"]) if err != nil { return p.ErrInfo(err) } err = p.ExecSql("UPDATE miners_data SET status = 'suspended_miner', ban_block_id = ?, miner_id = 0, log_id = ? WHERE user_id = ?", p.BlockData.BlockId, logId, userId) if err != nil { return p.ErrInfo(err) } // проверим, не наш ли это user_id myUserId, myBlockId, myPrefix, _, err := p.GetMyUserId(userId) if err != nil { return p.ErrInfo(err) } if userId == myUserId && myBlockId <= p.BlockData.BlockId { err = p.ExecSql("UPDATE " + myPrefix + "my_table SET status = 'user', miner_id = 0, notification_status = 0 WHERE status != 'bad_key'") if err != nil { return p.ErrInfo(err) } } // изменение статуса юзера влечет смену %, а значит нужен пересчет TDC на обещанных суммах // все обещанные суммы, по которым делается превращение tdc->DC rows, err := p.Query(p.FormatQuery(` SELECT id, amount, currency_id, tdc_amount, tdc_amount_update, start_time, status, log_id FROM promised_amount WHERE user_id = ? AND del_block_id = 0 AND del_mining_block_id = 0 ORDER BY id ASC`), userId) if err != nil { return p.ErrInfo(err) } defer rows.Close() var newTdc float64 for rows.Next() { var id int64 var amount, currency_id, tdc_amount, tdc_amount_update, start_time, status, log_id string err = rows.Scan(&id, &amount, ¤cy_id, &tdc_amount, &tdc_amount_update, &start_time, &status, &log_id) if err != nil { return p.ErrInfo(err) } newTdc, err = p.getTdc(id, userId) if err != nil { return p.ErrInfo(err) } addSql := "" if status == "repaid" || status == "mining" { addSql = fmt.Sprintf("tdcAmount = %f, tdcAmountUpdate = %d, ", utils.Round(newTdc, 2), p.BlockData.Time) } // логируем текущее значение logId, err := p.ExecSqlGetLastInsertId("INSERT INTO log_promised_amount ( tdc_amount, tdc_amount_update, status, block_id, prev_log_id ) VALUES ( ?, ?, ?, ?, ? )", "log_id", tdc_amount, tdc_amount_update, status, p.BlockData.BlockId, log_id) if err != nil { return p.ErrInfo(err) } // обновляем TDC и логируем статус err = p.ExecSql("UPDATE promised_amount SET "+addSql+" status_backup = status, status = 'suspended', log_id = ? WHERE id = ?", logId, id) if err != nil { return p.ErrInfo(err) } } } return nil }