/* * Каждые 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 (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 }