예제 #1
0
파일: unix.go 프로젝트: dzyk/dcoin-go
func KillPid(pid string) error {
	err := syscall.Kill(utils.StrToInt(pid), syscall.SIGTERM)
	if err != nil {
		return err
	}
	return nil
}
예제 #2
0
func (p *Parser) NewMaxOtherCurrenciesRollback() error {
	currencyList := make(map[string]int64)
	err := json.Unmarshal(p.TxMap["new_max_other_currencies"], &currencyList)
	if err != nil {
		return p.ErrInfo(err)
	}

	var currencyIds []int
	for k := range currencyList {
		currencyIds = append(currencyIds, utils.StrToInt(k))
	}
	sort.Sort(sort.Reverse(sort.IntSlice(currencyIds)))

	for _, currencyId := range currencyIds {

		//count := currencyList[utils.IntToStr(currencyId)]
		logId, err := p.Single("SELECT log_id FROM currency WHERE id  =  ?", currencyId).Int64()
		if err != nil {
			return p.ErrInfo(err)
		}

		logData, err := p.OneRow("SELECT max_other_currencies, prev_log_id FROM log_currency WHERE log_id  =  ?", logId).String()
		if err != nil {
			return p.ErrInfo(err)
		}

		err = p.ExecSql("UPDATE currency SET max_other_currencies = ?, log_id = ? WHERE id = ?", logData["max_other_currencies"], logData["prev_log_id"], currencyId)
		if err != nil {
			return p.ErrInfo(err)
		}

		err = p.ExecSql("DELETE FROM log_currency WHERE log_id = ?", logId)
		if err != nil {
			return p.ErrInfo(err)
		}
		p.rollbackAI("log_currency", 1)

		err = p.ExecSql("DELETE FROM max_other_currencies_time WHERE time = ?", p.BlockData.Time)
		if err != nil {
			return p.ErrInfo(err)
		}

	}
	return nil
}
예제 #3
0
파일: common.go 프로젝트: dzyk/dcoin-go
func GetLang(w http.ResponseWriter, r *http.Request, parameters map[string]string) int {
	var lang int = 1
	lang = utils.StrToInt(parameters["lang"])
	if !CheckLang(lang) {
		if langCookie, err := r.Cookie("lang"); err == nil {
			lang, _ = strconv.Atoi(langCookie.Value)
		}
	}
	if !CheckLang(lang) {
		al := r.Header.Get("Accept-Language") // en-US,en;q=0.5
		log.Debug("Accept-Language: %s", r.Header.Get("Accept-Language"))
		if len(al) >= 2 {
			if _, ok := consts.LangMap[al[:2]]; ok {
				lang = consts.LangMap[al[:2]]
			}
		}
	}
	return lang
}
예제 #4
0
func (p *Parser) NewMaxOtherCurrencies() error {

	currencyList := make(map[string]int64)
	err := json.Unmarshal(p.TxMap["new_max_other_currencies"], &currencyList)
	if err != nil {
		return p.ErrInfo(err)
	}

	var currencyIds []int
	for k := range currencyList {
		currencyIds = append(currencyIds, utils.StrToInt(k))
	}
	sort.Ints(currencyIds)
	//sort.Sort(sort.Reverse(sort.IntSlice(keys)))

	for _, currencyId := range currencyIds {
		count := currencyList[utils.IntToStr(currencyId)]

		logData, err := p.OneRow("SELECT max_other_currencies, log_id FROM currency WHERE id  =  ?", currencyId).String()
		if err != nil {
			return p.ErrInfo(err)
		}
		logId, err := p.ExecSqlGetLastInsertId("INSERT INTO log_currency ( max_other_currencies, prev_log_id ) VALUES ( ?, ? )", "log_id", logData["max_other_currencies"], logData["log_id"])
		if err != nil {
			return p.ErrInfo(err)
		}
		err = p.ExecSql("UPDATE currency SET max_other_currencies = ?, log_id = ? WHERE id = ?", count, logId, currencyId)
		if err != nil {
			return p.ErrInfo(err)
		}
	}
	err = p.ExecSql("INSERT INTO max_other_currencies_time ( time ) VALUES ( ? )", p.BlockData.Time)
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}
예제 #5
0
파일: new_miner.go 프로젝트: dzyk/dcoin-go
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
}
예제 #6
0
func (c *Controller) EncryptComment() (string, error) {

	var err error

	c.r.ParseForm()

	txType := c.r.FormValue("type")
	var toId int64
	var toIds []int64
	toIds_ := c.r.FormValue("to_ids")
	if len(toIds_) == 0 {
		toId = utils.StrToInt64(c.r.FormValue("to_id"))
	} else {
		var toIdsMap map[string]string
		err = json.Unmarshal([]byte(toIds_), &toIdsMap)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		for _, uid := range toIdsMap {
			if utils.StrToInt64(uid) > 0 {
				toIds = append(toIds, utils.StrToInt64(uid))
			}
		}
	}

	comment := c.r.FormValue("comment")
	if len(comment) > 1024 {
		return "", errors.New("incorrect comment")
	}

	var toUserId int64
	if txType == "project" {
		toUserId, err = c.Single("SELECT user_id FROM cf_projects WHERE id  =  ?", toId).Int64()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
	} else {
		toUserId = toId
	}

	if len(toIds) == 0 {
		toIds = []int64{toUserId}
	}

	log.Debug("toId:", toId)
	log.Debug("toIds:", toIds)
	log.Debug("toUserId:", toUserId)
	enc := make(map[string]string)
	for i := 0; i < len(toIds); i++ {
		if toIds[i] == 0 {
			enc[utils.IntToStr(i)] = "0"
			continue
		}
		// если получатель майнер, тогда шифруем нодовским ключем
		minersData, err := c.OneRow("SELECT miner_id, node_public_key FROM miners_data WHERE user_id  =  ?", toIds[i]).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		var publicKey string
		if utils.StrToInt(minersData["miner_id"]) > 0 && txType != "cash_request" && txType != "bug_reporting" && txType != "project" && txType != "money_back" && txType != "restoringAccess" {
			publicKey = minersData["node_public_key"]
		} else {
			publicKey, err = c.Single("SELECT public_key_0 FROM users WHERE user_id  =  ?", toIds[i]).String()
			if err != nil {
				return "", utils.ErrInfo(err)
			}
		}

		pub, err := utils.BinToRsaPubKey([]byte(publicKey))
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		enc_, err := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte(comment))
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		enc[utils.IntToStr(i)] = string(utils.BinToHex(enc_))
	}
	if len(enc) < 5 && len(enc) > 0 {
		for i := len(enc); i < 5; i++ {
			enc[utils.IntToStr(i)] = "0"
		}
	}
	log.Debug("enc:", enc)
	if txType != "arbitration_arbitrators" {
		return string(enc["0"]), nil
	} else {
		result, err := json.Marshal(enc)
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		return string(result), nil
	}
}
예제 #7
0
파일: home.go 프로젝트: dzyk/dcoin-go
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
}
예제 #8
0
/*
 * Каждые 2 недели собираем инфу о голосах за % и создаем тр-ию, которая
 * попадет в DC сеть только, если мы окажемся генератором блока
 * */
func ReductionGenerator(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	const GoroutineName = "ReductionGenerator"
	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(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		if blockId == 0 {
			if d.unlockPrintSleep(errors.New("blockId == 0"), d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		_, _, myMinerId, _, _, _, err := d.TestBlock()
		if err != nil {
			if d.unlockPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		// а майнер ли я ?
		if myMinerId == 0 {
			if d.unlockPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		variables, err := d.GetAllVariables()
		curTime := utils.Time()
		var reductionType string
		var reductionCurrencyId int
		var reductionPct int64

		// ===== ручное урезание денежной массы
		// получаем кол-во обещанных сумм у разных юзеров по каждой валюте. start_time есть только у тех, у кого статус mining/repaid
		promisedAmount, err := d.GetMap(`
				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`, "currency_id", "count", (curTime - variables.Int64["min_hold_time_promise_amount"]))
		if err != nil {
			if d.unlockPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		log.Info("%v", "promisedAmount", promisedAmount)

		// берем все голоса юзеров
		rows, err := d.Query(d.FormatQuery(`
				SELECT currency_id,
				  		  pct,
						  count(currency_id) as votes
				FROM votes_reduction
				WHERE time > ?
				GROUP BY  currency_id, pct
				`), curTime-variables.Int64["reduction_period"])
		if err != nil {
			if d.unlockPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		for rows.Next() {
			var votes, pct int64
			var currency_id string
			err = rows.Scan(&currency_id, &pct, &votes)
			if err != nil {
				rows.Close()
				if d.unlockPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			if len(promisedAmount[currency_id]) == 0 || promisedAmount[currency_id] == "0" {
				continue
			}
			// если голосов за урезание > 50% от числа всех держателей данной валюты
			if votes >= utils.StrToInt64(promisedAmount[currency_id])/2 {
				// проверим, прошло ли 2 недели с последнего урезания
				reductionTime, err := d.Single("SELECT max(time) FROM reduction WHERE currency_id  =  ? AND type  =  'manual'", currency_id).Int64()
				if err != nil {
					rows.Close()
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				if curTime-reductionTime > variables.Int64["reduction_period"] {
					reductionCurrencyId = utils.StrToInt(currency_id)
					reductionPct = pct
					reductionType = "manual"
					log.Info("%v", "reductionCurrencyId", reductionCurrencyId, "reductionPct", reductionPct, "reductionType", reductionType)
					break
				}
			}
		}
		rows.Close()

		// =======  авто-урезание денежной массы из-за малого объема обещанных сумм

		// получаем кол-во DC на кошельках
		sumWallets_, err := d.GetMap("SELECT currency_id, sum(amount) as sum_amount FROM wallets GROUP BY currency_id", "currency_id", "sum_amount")
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}
		sumWallets := make(map[int]float64)
		for currencyId, amount := range sumWallets_ {
			sumWallets[utils.StrToInt(currencyId)] = utils.StrToFloat64(amount)
		}

		// получаем кол-во TDC на обещанных суммах, плюсуем к тому, что на кошельках
		sumTdc, err := d.GetMap("SELECT currency_id, sum(tdc_amount) as sum_amount FROM promised_amount GROUP BY currency_id", "currency_id", "sum_amount")
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		for currencyId, amount := range sumTdc {
			currencyIdInt := utils.StrToInt(currencyId)
			if sumWallets[currencyIdInt] == 0 {
				sumWallets[currencyIdInt] = utils.StrToFloat64(amount)
			} else {
				sumWallets[currencyIdInt] += utils.StrToFloat64(amount)
			}
		}

		log.Debug("sumWallets", sumWallets)

		// получаем суммы обещанных сумм
		sumPromisedAmount, err := d.GetMap(`
				SELECT currency_id,
					   		sum(amount) as sum_amount
				FROM promised_amount
				WHERE status = 'mining' AND
							 del_block_id = 0 AND
							 del_mining_block_id = 0 AND
							  (cash_request_out_time = 0 OR cash_request_out_time > ?)
				GROUP BY currency_id
				`, "currency_id", "sum_amount", curTime-variables.Int64["cash_request_time"])
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue BEGIN
		}

		log.Debug("sumPromisedAmount", sumPromisedAmount)

		if len(sumWallets) > 0 {
			for currencyId, sumAmount := range sumWallets {
				//недопустимо для WOC
				if currencyId == 1 {
					continue
				}
				reductionTime, err := d.Single("SELECT max(time) FROM reduction WHERE currency_id  =  ? AND type  =  'auto'", currencyId).Int64()
				if err != nil {
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				log.Debug("reductionTime", reductionTime)
				// прошло ли 48 часов
				if curTime-reductionTime <= consts.AUTO_REDUCTION_PERIOD {
					log.Debug("curTime-reductionTime <= consts.AUTO_REDUCTION_PERIOD %d <= %d", curTime-reductionTime, consts.AUTO_REDUCTION_PERIOD)
					continue
				}

				// если обещанных сумм менее чем 100% от объема DC на кошельках, то запускаем урезание
				log.Debug("utils.StrToFloat64(sumPromisedAmount[utils.IntToStr(currencyId)]) < sumAmount*consts.AUTO_REDUCTION_PROMISED_AMOUNT_PCT %d < %d", utils.StrToFloat64(sumPromisedAmount[utils.IntToStr(currencyId)]), sumAmount*consts.AUTO_REDUCTION_PROMISED_AMOUNT_PCT)
				if utils.StrToFloat64(sumPromisedAmount[utils.IntToStr(currencyId)]) < sumAmount*consts.AUTO_REDUCTION_PROMISED_AMOUNT_PCT {

					// проверим, есть ли хотя бы 1000 юзеров, у которых на кошелках есть или была данная валюты
					countUsers, err := d.Single("SELECT count(user_id) FROM wallets WHERE currency_id  =  ?", currencyId).Int64()
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					log.Debug("countUsers>=countUsers %d >= %d", countUsers, consts.AUTO_REDUCTION_PROMISED_AMOUNT_MIN)
					if countUsers >= consts.AUTO_REDUCTION_PROMISED_AMOUNT_MIN {
						reductionCurrencyId = currencyId
						reductionPct = consts.AUTO_REDUCTION_PCT
						reductionType = "promised_amount"
						break
					}
				}

			}
		}
		if reductionCurrencyId > 0 && reductionPct > 0 {

			_, myUserId, _, _, _, _, err := d.TestBlock()
			forSign := fmt.Sprintf("%v,%v,%v,%v,%v,%v", utils.TypeInt("NewReduction"), curTime, myUserId, reductionCurrencyId, reductionPct, reductionType)
			log.Debug("forSign = %v", forSign)
			binSign, err := d.GetBinSign(forSign, myUserId)
			if err != nil {
				if d.unlockPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			data := utils.DecToBin(utils.TypeInt("NewReduction"), 1)
			data = append(data, utils.DecToBin(curTime, 4)...)
			data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(myUserId))...)
			data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(int64(reductionCurrencyId)))...)
			data = append(data, utils.EncodeLengthPlusData(utils.Int64ToByte(reductionPct))...)
			data = append(data, utils.EncodeLengthPlusData([]byte(reductionType))...)
			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)

}
예제 #9
0
func Content(w http.ResponseWriter, r *http.Request) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("Content Recovered", r)
			fmt.Println("Content Recovered", r)
		}
	}()
	var err error

	w.Header().Set("Content-type", "text/html")

	sess, err := globalSessions.SessionStart(w, r)
	if err != nil {
		log.Error("%v", err)
	}
	defer sess.SessionRelease(w)
	sessUserId := GetSessUserId(sess)
	sessRestricted := GetSessRestricted(sess)
	sessPublicKey := GetSessPublicKey(sess)
	sessAdmin := GetSessAdmin(sess)
	log.Debug("sessUserId", sessUserId)
	log.Debug("sessRestricted", sessRestricted)
	log.Debug("sessPublicKey", sessPublicKey)
	log.Debug("user_id: %v", sess.Get("user_id"))

	c := new(Controller)
	c.r = r
	c.w = w
	c.sess = sess
	c.SessRestricted = sessRestricted
	c.SessUserId = sessUserId
	if sessAdmin == 1 {
		c.Admin = true
	}
	c.ContentInc = true

	var installProgress, configExists string
	var lastBlockTime int64

	dbInit := false
	if len(configIni["db_user"]) > 0 || (configIni["db_type"] == "sqlite") {
		dbInit = true
	}

	if dbInit {
		var err error
		//c.DCDB, err = utils.NewDbConnect(configIni)
		c.DCDB = utils.DB
		if c.DCDB.DB == nil {
			log.Error("utils.DB == nil")
			dbInit = false
		}
		if dbInit {
			// отсутвие таблы выдаст ошибку, значит процесс инсталяции еще не пройден и надо выдать 0-й шаг
			_, err = c.DCDB.Single("SELECT progress FROM install").String()
			if err != nil {
				log.Error("%v", err)
				dbInit = false
			}
		}
	}

	c.dbInit = dbInit

	if dbInit {
		var err error
		installProgress, err = c.DCDB.Single("SELECT progress FROM install").String()
		if err != nil {
			log.Error("%v", err)
		}
		configExists, err = c.DCDB.Single("SELECT first_load_blockchain_url FROM config").String()
		if err != nil {
			log.Error("%v", err)
		}

		c.Variables, err = c.GetAllVariables()

		// Инфа о последнем блоке
		blockData, err := c.DCDB.GetLastBlockData()
		if err != nil {
			log.Error("%v", err)
		}
		//время последнего блока
		lastBlockTime = blockData["lastBlockTime"]
		log.Debug("installProgress", installProgress, "configExists", configExists, "lastBlockTime", lastBlockTime)

		// валюты
		currencyListCf, err := c.GetCurrencyList(true)
		if err != nil {
			log.Error("%v", err)
		}
		c.CurrencyListCf = currencyListCf
		currencyList, err := c.GetCurrencyList(false)
		if err != nil {
			log.Error("%v", err)
		}
		c.CurrencyList = currencyList

		confirmedBlockId, err := c.GetConfirmedBlockId()
		if err != nil {
			log.Error("%v", err)
		}
		c.ConfirmedBlockId = confirmedBlockId

		c.MinerId, err = c.GetMinerId(c.SessUserId)
		if err != nil {
			log.Error("%v", err)
		}

		paymentSystems, err := c.GetPaymentSystems()
		if err != nil {
			log.Error("%v", err)
		}
		c.PaymentSystems = paymentSystems
	}
	r.ParseForm()
	tplName := r.FormValue("tpl_name")

	c.Parameters, err = c.GetParameters()
	log.Debug("parameters=", c.Parameters)

	log.Debug("tpl_name=", tplName)

	// если в параметрах пришел язык, то установим его
	newLang := utils.StrToInt(c.Parameters["lang"])
	if newLang > 0 {
		log.Debug("newLang", newLang)
		SetLang(w, r, newLang)
	}
	// уведомления
	//if utils.CheckInputData(parameters["alert"], "alert") {
	c.Alert = c.Parameters["alert"]
	//}

	lang := GetLang(w, r, c.Parameters)
	log.Debug("lang", lang)

	c.Lang = globalLangReadOnly[lang]
	c.LangInt = int64(lang)
	if lang == 42 {
		c.TimeFormat = "2006-01-02 15:04:05"
	} else {
		c.TimeFormat = "2006-02-01 15:04:05"
	}

	c.Periods = map[int64]string{86400: "1 " + c.Lang["day"], 604800: "1 " + c.Lang["week"], 31536000: "1 " + c.Lang["year"], 2592000: "1 " + c.Lang["month"], 1209600: "2 " + c.Lang["weeks"]}

	c.Races = map[int64]string{1: c.Lang["race_1"], 2: c.Lang["race_2"], 3: c.Lang["race_3"]}
	var status string
	var communityUsers []int64
	if dbInit {
		communityUsers, err = c.DCDB.GetCommunityUsers()
		if err != nil {
			log.Error("%v", err)
		}
		c.CommunityUsers = communityUsers
		if len(communityUsers) == 0 {
			c.MyPrefix = ""
		} else {
			c.MyPrefix = utils.Int64ToStr(sessUserId) + "_"
			c.Community = true
		}
		log.Debug("c.MyPrefix %s", c.MyPrefix)
		// нужна мин. комиссия на пуле для перевода монет
		config, err := c.GetNodeConfig()
		if err != nil {
			log.Error("%v", err)
		}
		configCommission_ := make(map[string][]float64)
		if len(config["commission"]) > 0 {
			err = json.Unmarshal([]byte(config["commission"]), &configCommission_)
			if err != nil {
				log.Error("%v", err)
			}
		}
		configCommission := make(map[int64][]float64)
		for k, v := range configCommission_ {
			configCommission[utils.StrToInt64(k)] = v
		}
		c.NodeConfig = config
		c.ConfigCommission = configCommission

		c.NodeAdmin, err = c.NodeAdminAccess(c.SessUserId, c.SessRestricted)
		if err != nil {
			log.Error("%v", err)
		}

		status, err = c.DCDB.Single("SELECT status FROM " + c.MyPrefix + "my_table").String()
		if err != nil {
			log.Error("%v", err)
		}
	}
	log.Debug("dbInit", dbInit)

	setupPassword := c.NodeConfig["setup_password"]
	match, _ := regexp.MatchString("^(installStep[0-9_]+)|(blockExplorer)$", tplName)
	// CheckInputData - гарантирует, что tplName чист
	if tplName != "" && utils.CheckInputData(tplName, "tpl_name") && (sessUserId > 0 || match) {
		tplName = tplName
	} else if dbInit && installProgress == "complete" && len(configExists) == 0 {
		// первый запуск, еще не загружен блокчейн
		tplName = "updatingBlockchain"
	} else if dbInit && installProgress == "complete" && sessUserId > 0 {
		if status == "waiting_set_new_key" {
			tplName = "setPassword"
		} else if status == "waiting_accept_new_key" {
			tplName = "waitingAcceptNewKey"
		}
	} else if dbInit && installProgress == "complete" && !c.Community && sessUserId == 0 && status == "waiting_set_new_key" && setupPassword != "" {
		tplName = "setupPassword"
	} else if dbInit && installProgress == "complete" && sessUserId == 0 && status == "waiting_accept_new_key" {
		tplName = "waitingAcceptNewKey"
	} else if dbInit && installProgress == "complete" {
		tplName = "login"
	} else {
		tplName = "installStep0" // самый первый запуск
	}
	log.Debug("dbInit", dbInit, "installProgress", installProgress, "configExists", configExists)
	log.Debug("tplName>>>>>>>>>>>>>>>>>>>>>>", tplName)

	// идет загрузка блокчейна
	wTime := int64(2)
	if configIni != nil && configIni["test_mode"] == "1" {
		wTime = 2 * 365 * 86400
		log.Debug("%v", wTime)
		log.Debug("%v", lastBlockTime)
	}
	if dbInit && tplName != "installStep0" && (utils.Time()-lastBlockTime > 3600*wTime) && len(configExists) > 0 {
		if len(communityUsers) > 0 {
			// исключение - админ пула
			poolAdminUserId, err := c.DCDB.Single("SELECT pool_admin_user_id FROM config").String()
			if err != nil {
				log.Error("%v", err)
			}
			if sessUserId != utils.StrToInt64(poolAdminUserId) {
				tplName = "updatingBlockchain"
			}
		} else {
			tplName = "updatingBlockchain"
		}
	}

	if tplName == "installStep0" {
		log.Debug("ConfigInit monitor")
		if _, err := os.Stat(*utils.Dir + "/config.ini"); err == nil {

			configIni_, err := config.NewConfig("ini", *utils.Dir+"/config.ini")
			if err != nil {
				log.Error("%v", utils.ErrInfo(err))
			}
			configIni, err = configIni_.GetSection("default")
			if err != nil {
				log.Error("%v", utils.ErrInfo(err))
			}
			if len(configIni["db_type"]) > 0 {
				tplName = "updatingBlockchain"
			}
		}
	}

	log.Debug("tplName2=", tplName)

	// кол-во ключей=подписей у юзера
	var countSign int
	var userId int64
	//	var myUserId int64
	if sessUserId > 0 && dbInit && installProgress == "complete" {
		userId = sessUserId
		//myUserId = sessUserId
		countSign = 1
		log.Debug("userId: %d", userId)
		pk, err := c.OneRow("SELECT hex(public_key_1) as public_key_1, hex(public_key_2) as public_key_2 FROM users WHERE user_id = ?", userId).String()
		if err != nil {
			log.Error("%v", err)
		}
		log.Debug("pk: %v", pk)
		if len(pk["public_key_1"]) > 0 {
			log.Debug("public_key_1: %x", pk["public_key_1"])
			countSign = 2
		}
		if len(pk["public_key_2"]) > 0 {
			log.Debug("public_key_2: %x", pk["public_key_2"])
			countSign = 3
		}
	} else {
		userId = 0
		//myUserId = 0
	}

	log.Debug("countSign: %v", countSign)
	c.UserId = userId
	var CountSignArr []int
	for i := 0; i < countSign; i++ {
		CountSignArr = append(CountSignArr, i)
	}
	c.CountSign = countSign
	c.CountSignArr = CountSignArr

	if tplName == "" {
		tplName = "login"
	}

	log.Debug("tplName::", tplName, sessUserId, installProgress)

	if ok, _ := regexp.MatchString(`^(?i)delAutoPayment|newAutoPayment|autoPayments|holidaysList|adminVariables|exchangeAdmin|votesExchange|chat|firstSelect|PoolAdminLogin|setupPassword|waitingAcceptNewKey|SetPassword|CfPagePreview|CfCatalog|AddCfProjectData|CfProjectChangeCategory|NewCfProject|MyCfProjects|DelCfProject|DelCfFunding|CfStart|PoolAdminControl|Credits|Home|WalletsList|Information|Notifications|Interface|MiningMenu|Upgrade5|NodeConfigControl|Upgrade7|Upgrade6|Upgrade5|Upgrade4|Upgrade3|Upgrade2|Upgrade1|Upgrade0|StatisticVoting|ProgressBar|MiningPromisedAmount|CurrencyExchangeDelete|CurrencyExchange|ChangeCreditor|ChangeCommission|CashRequestOut|ArbitrationSeller|ArbitrationBuyer|ArbitrationArbitrator|Arbitration|InstallStep2|InstallStep1|InstallStep0|DbInfo|ChangeHost|Assignments|NewUser|NewPhoto|Voting|VoteForMe|RepaymentCredit|PromisedAmountList|PromisedAmountActualization|NewPromisedAmount|Login|ForRepaidFix|DelPromisedAmount|DelCredit|ChangePromisedAmount|ChangePrimaryKey|ChangeNodeKey|ChangeAvatar|BugReporting|Abuse|UpgradeResend|UpdatingBlockchain|Statistic|RewritePrimaryKey|RestoringAccess|PoolTechWorks|Points|NewHolidays|NewCredit|MoneyBackRequest|MoneyBack|ChangeMoneyBack|ChangeKeyRequest|ChangeKeyClose|ChangeGeolocation|ChangeCountryRace|ChangeArbitratorConditions|CashRequestIn|BlockExplorer$`, tplName); !ok {
		w.Write([]byte("Access denied 0"))
	} else if len(tplName) > 0 && sessUserId > 0 && installProgress == "complete" {
		// если ключ юзера изменился, то выбрасываем его
		userPublicKey, err := c.DCDB.GetUserPublicKey(userId)
		if err != nil {
			log.Error("%v", err)
		}
		// но возможно у юзера включено сохранение приватного ключа
		// тогда, чтобы не получилось зацикливания, нужно проверить и my_keys
		myPrivateKey, err := c.GetMyPrivateKey(c.MyPrefix)
		if err != nil {
			log.Error("%v", err)
		}
		myPublicKey, err := c.GetMyPublicKey(c.MyPrefix)
		if err != nil {
			log.Error("%v", err)
		}
		countUsers, err := c.Single(`SELECT count(*) FROM users`).Int64()
		if err != nil {
			log.Error("%v", err)
		}
		if (string(utils.BinToHex(userPublicKey)) != sessPublicKey && len(myPrivateKey) == 0) || (countUsers > 0 && len(myPrivateKey) > 0 && !bytes.Equal(myPublicKey, []byte(userPublicKey))) {
			log.Debug("userPublicKey!=sessPublicKey %s!=%s / userId: %d", utils.BinToHex(userPublicKey), sessPublicKey, userId)
			log.Debug("len(myPrivateKey) = %d  && %x!=%x", len(myPrivateKey), string(myPublicKey), userPublicKey)
			sess.Delete("user_id")
			sess.Delete("private_key")
			sess.Delete("public_key")
			log.Debug("window.location.href = /")
			if len(userPublicKey) > 0 {
				w.Write([]byte("<script language=\"javascript\">window.location.href = \"/\"</script>If you are not redirected automatically, follow the <a href=\"/\">/</a>"))
				return
			} else {
				c.sess.Delete("user_id")
				c.sess.Delete("public_key")
				c.sess.Delete("private_key")
			}

		}

		if tplName == "login" {
			tplName = "home"
		}

		if tplName == "home" && c.Parameters["first_select"] != "1" {
			data, err := c.OneRow(`SELECT first_select, miner_id from ` + c.MyPrefix + `my_table`).Int64()
			if err != nil {
				log.Error("%v", err)
			}
			if data["first_select"] == 0 && data["miner_id"] == 0 && c.SessRestricted == 0 {
				tplName = "firstSelect"
			}
		}
		c.TplName = tplName

		log.Debug("communityUsers:", communityUsers)
		if dbInit && len(communityUsers) > 0 {
			poolAdminUserId, err := c.GetPoolAdminUserId()
			if err != nil {
				log.Error("%v", err)
			}
			c.PoolAdminUserId = poolAdminUserId
			if c.SessUserId == poolAdminUserId {
				c.PoolAdmin = true
			}
		} else {
			c.PoolAdmin = true
		}

		if dbInit {
			// проверим, не идут ли тех. работы на пуле
			config, err := c.DCDB.OneRow("SELECT pool_admin_user_id, pool_tech_works FROM config").String()
			if err != nil {
				log.Error("%v", err)
			}
			if len(config["pool_admin_user_id"]) > 0 && utils.StrToInt64(config["pool_admin_user_id"]) != sessUserId && config["pool_tech_works"] == "1" && c.Community {
				tplName = "login"
			}
			// Если у юзера только 1 праймари ключ, то выдавать форму, где показываются данные для подписи и форма ввода подписи не нужно.
			// Только если он сам не захочет, указав это в my_table
			showSignData := false
			if sessRestricted == 0 { // у незареганных в пуле юзеров нет MyPrefix, поэтому сохранять значение show_sign_data им негде
				showSignData_, err := c.DCDB.Single("SELECT show_sign_data FROM " + c.MyPrefix + "my_table").String()
				if err != nil {
					log.Error("%v", err)
				}
				if showSignData_ == "1" {
					showSignData = true
				} else {
					showSignData = false
				}
			}
			if showSignData || countSign > 1 {
				c.ShowSignData = true
			} else {
				c.ShowSignData = false
			}
		}

		// писать в чат можно и при апдейте блокчейна
		if r.FormValue("tpl_name") == "chat" && tplName == "updatingBlockchain" {
			tplName = "chat"
		}

		if dbInit && tplName != "updatingBlockchain" && tplName != "setPassword" && tplName != "waitingAcceptNewKey" {
			html, err := CallController(c, "AlertMessage")
			if err != nil {
				log.Error("%v", err)
			}
			w.Write([]byte(html))
		}
		w.Write([]byte("<input type='hidden' id='tpl_name' value='" + tplName + "'>"))

		myNotice, err := c.DCDB.GetMyNoticeData(sessRestricted, sessUserId, c.MyPrefix, globalLangReadOnly[lang])
		if err != nil {
			log.Error("%v", err)
		}
		c.MyNotice = myNotice

		log.Debug("tplName==", tplName)

		// подсвечиваем красным номер блока, если идет процесс обновления
		var blockJs string
		blockId, err := c.GetBlockId()
		if err != nil {
			log.Error("%v", err)
		}
		if myNotice["main_status_complete"] != "1" {
			blockJs = "$('#block_id').html(" + utils.Int64ToStr(blockId) + ");$('#block_id').css('color', '#ff0000');"
		} else {
			blockJs = "$('#block_id').html(" + utils.Int64ToStr(blockId) + ");$('#block_id').css('color', '#428BCA');"
		}
		w.Write([]byte(`<script>
								$( document ).ready(function() {
								$('.lng_1').attr('href', '#` + tplName + `/lang=1');
								$('.lng_42').attr('href', '#` + tplName + `/lang=42');
								` + blockJs + `
								});
								</script>`))
		skipRestrictedUsers := []string{"cashRequestIn", "cashRequestOut", "upgrade", "notifications"}
		// тем, кто не зареган на пуле не выдаем некоторые страницы
		if sessRestricted == 0 || !utils.InSliceString(tplName, skipRestrictedUsers) {
			// вызываем контроллер в зависимости от шаблона
			html, err := CallController(c, tplName)
			if err != nil {
				log.Error("%v", err)
			}
			w.Write([]byte(html))
		}
	} else if len(tplName) > 0 {
		log.Debug("tplName", tplName)
		html := ""
		if ok, _ := regexp.MatchString(`^(?i)blockExplorer|waitingAcceptNewKey|SetupPassword|CfCatalog|CfPagePreview|CfStart|Check_sign|CheckNode|GetBlock|GetMinerData|GetMinerDataMap|GetSellerData|Index|IndexCf|InstallStep0|InstallStep1|InstallStep2|Login|SignLogin|SynchronizationBlockchain|UpdatingBlockchain|Menu$`, tplName); !ok && c.SessUserId <= 0 {
			html = "Access denied 1"
		} else {
			// если сессия обнулилась в процессе навигации по админке, то вместо login шлем на /, чтобы очистилось меню
			if len(r.FormValue("tpl_name")) > 0 && tplName == "login" {
				log.Debug("window.location.href = /")
				w.Write([]byte("<script language=\"javascript\">window.location.href = \"/\"</script>If you are not redirected automatically, follow the <a href=\"/\">/</a>"))
				return
			}
			// вызываем контроллер в зависимости от шаблона
			html, err = CallController(c, tplName)
			if err != nil {
				log.Error("%v", err)
			}
		}
		w.Write([]byte(html))
	} else {
		html, err := CallController(c, "login")
		if err != nil {
			log.Error("%v", err)
		}
		w.Write([]byte(html))
	}
	//sess.Set("username", 11111)

}
예제 #10
0
func (c *Controller) GetChatMessages() (string, error) {

	c.r.ParseForm()
	first := c.r.FormValue("first")
	room := utils.StrToInt64(c.r.FormValue("room"))
	lang := utils.StrToInt64(c.r.FormValue("lang"))

	if first == "1" {
		chatIds[c.SessUserId] = []int{}
	}
	maxId, err := c.Single(`SELECT max(id) FROM chat`).Int64()
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	// удалим старое
	err = c.ExecSql(`DELETE FROM chat WHERE id < ?`, maxId-consts.CHAT_MAX_MESSAGES)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	ids := ""
	if len(chatIds[c.SessUserId]) > 0 {
		ids = `AND id NOT IN(` + strings.Join(utils.IntSliceToStr(chatIds[c.SessUserId]), ",") + `)`
	}
	var result string
	chatData, err := c.GetAll(`SELECT * FROM chat WHERE sign_time > ? AND room = ? AND lang = ?  `+ids+` ORDER BY sign_time DESC LIMIT `+utils.Int64ToStr(consts.CHAT_COUNT_MESSAGES), consts.CHAT_COUNT_MESSAGES, chatMinSignTime, room, lang)
	if err != nil {
		return "", utils.ErrInfo(err)
	}
	for i := len(chatData) - 1; i >= 0; i-- {
		data := chatData[i]
		status := data["status"]
		message := data["message"]
		receiver := utils.StrToInt64(data["receiver"])
		sender := utils.StrToInt64(data["sender"])
		if status == "1" {
			// Если юзер хранит приватый ключ в БД, то сможем расшифровать прямо тут
			if receiver == c.SessUserId {
				privateKey, err := c.GetMyPrivateKey(c.MyPrefix)
				if err != nil {
					log.Error("%v", utils.ErrInfo(err))
					continue
				}
				if len(privateKey) > 0 {
					rsaPrivateKey, err := utils.MakePrivateKey(privateKey)
					if err != nil {
						log.Error("%v", utils.ErrInfo(err))
						continue
					}
					decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, rsaPrivateKey, utils.HexToBin([]byte(data["message"])))
					if err != nil {
						log.Error("%v", utils.ErrInfo(err))
						continue
					}
					if len(decrypted) > 0 {
						err = c.ExecSql(`UPDATE chat SET enc_message = message, message = ?, status = ? WHERE id = ?`, decrypted, 2, data["id"])
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							continue
						}
						message = string(decrypted)
						status = "2"
					}
				}
			}
		}

		name := data["sender"]
		ava := "/static/img/noavatar.png"
		// возможно у отпарвителя есть ник
		nameAvaBan, err := c.OneRow(`SELECT name, avatar, chat_ban FROM users WHERE user_id = ?`, sender).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		// возможно юзер забанен
		if nameAvaBan["chat_ban"] == "1" {
			continue
		}
		if len(nameAvaBan["name"]) > 0 {
			name = nameAvaBan["name"]
		}

		minerStatus, err := c.Single(`SELECT status FROM miners_data WHERE user_id = ?`, sender).String()
		if err != nil {
			return "", utils.ErrInfo(err)
		}
		if minerStatus == "miner" && len(nameAvaBan["avatar"]) > 0 {
			ava = nameAvaBan["avatar"]
		}

		row := ""
		message = template.HTMLEscapeString(message)
		avaHtml := `<img src="` + ava + `" onclick='setReceiver("` + name + `", "` + data["sender"] + `")'>`
		nameHtml := `<strong><a class="chatNick" onclick='setReceiver("` + name + `", "` + data["sender"] + `")'>` + name + `</a></strong>`
		if status == "2" { // успешно расшифровали
			row = `<tr><td>` + avaHtml + `` + nameHtml + `: <i class="fa fa-lock"></i> ` + message + `</td></tr>`
		} else if status == "1" && receiver == c.SessUserId { // либо нет ключа, либо какая-то ошибка
			row = `<tr><td>` + avaHtml + `` + nameHtml + `: <div id="comment_` + data["id"] + `" style="display: inline-block;"><input type="hidden" value="` + message + `" id="encrypt_comment_` + data["id"] + `"><a class="btn btn-default btn-lg" onclick="decrypt_comment(` + data["id"] + `, 'chat')"> <i class="fa fa-lock"></i> Decrypt</a></div></td></tr>`
		} else if status == "0" {
			row = `<tr><td>` + avaHtml + `` + nameHtml + `: ` + message + `</td></tr>`
		}
		result += row
		chatIds[c.SessUserId] = append(chatIds[c.SessUserId], utils.StrToInt(data["id"]))
		if first == "1" {
			if utils.StrToInt64(data["sign_time"]) < chatMinSignTime || chatMinSignTime == 0 {
				chatMinSignTime = utils.StrToInt64(data["sign_time"])
				log.Debug("chatMinSignTime", chatMinSignTime)
			}
		}
	}

	log.Debug("chat data: %v", result)
	chatStatus := "ok"
	if len(utils.ChatInConnections) == 0 || len(utils.ChatOutConnections) == 0 {
		chatStatus = "bad"
	}

	resultJson, _ := json.Marshal(map[string]string{"messages": result, "chatStatus": chatStatus})

	return string(resultJson), nil
}
예제 #11
0
파일: common.go 프로젝트: dzyk/dcoin-go
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
}
예제 #12
0
파일: content_e.go 프로젝트: dzyk/dcoin-go
func ContentE(w http.ResponseWriter, r *http.Request) {

	var err error
	if utils.DB != nil && utils.DB.DB != nil {

		sess, _ := globalSessions.SessionStart(w, r)
		defer sess.SessionRelease(w)

		c := new(Controller)
		c.r = r
		c.SessUserId = GetSessEUserId(sess)
		c.DCDB = utils.DB

		r.ParseForm()
		tplName := r.FormValue("page")

		c.Parameters, err = c.GetParameters()
		log.Debug("parameters=", c.Parameters)

		lang := GetLang(w, r, c.Parameters)
		c.Lang = globalLangReadOnly[lang]
		c.LangInt = int64(lang)
		if lang == 42 {
			c.TimeFormat = "2006-01-02 15:04:05"
		} else {
			c.TimeFormat = "2006-02-01 15:04:05"
		}
		// если в параметрах пришел язык, то установим его
		newLang := utils.StrToInt(c.Parameters["lang"])
		if newLang > 0 {
			log.Debug("newLang", newLang)
			SetLang(w, r, newLang)
		}

		c.EConfig, err = c.GetMap(`SELECT * FROM e_config`, "name", "value")
		if err != nil {
			log.Error("%v", err)
		}
		c.EURL = c.EConfig["domain"]
		if len(c.EURL) == 0 {
			eHost, err := c.Single(`SELECT http_host FROM config`).String()
			if err != nil {
				log.Error("%v", err)
			}
			eHost += c.EConfig["catalog"]
			c.EURL = eHost
		} else {
			c.EURL = "http://" + c.EURL + "/"
		}
		html := ""
		if ok, _ := regexp.MatchString(`^(?i)EPages|emain|EMyOrders|EMyHistory|EMyFinance`, tplName); !ok {
			html = "Access denied"
		} else {
			// вызываем контроллер в зависимости от шаблона
			html, err = CallController(c, tplName)
			if err != nil {
				log.Error("%v", err)
			}
		}
		w.Write([]byte(html))
	}
}
예제 #13
0
func (p *Parser) VotesComplexRollback() error {

	currencyVotes := make(map[string][]float64)

	if p.BlockData.BlockId > 77951 {
		vComplex, err := makeVcomplex(p.TxMap["json_data"])
		if err != nil {
			return p.ErrInfo(err)
		}
		if p.BlockData.BlockId > 153750 && vComplex.Admin != 0 {
			err := p.selectiveRollback([]string{"admin_user_id", "time"}, "votes_admin", "user_id="+string(p.TxMap["user_id"]), false)
			if err != nil {
				return p.ErrInfo(err)
			}
		}
		// голоса за реф. %
		err = p.selectiveRollback([]string{"first", "second", "third"}, "votes_referral", "user_id="+string(p.TxMap["user_id"]), false)
		if err != nil {
			return p.ErrInfo(err)
		}

		currencyVotes = vComplex.Currency

	} else { // раньше не было рефских и выбора админа
		vComplex := make(map[string][]float64)
		err := json.Unmarshal(p.TxMap["json_data"], &vComplex)
		if err != nil {
			return p.ErrInfo(err)
		}
		currencyVotes = vComplex
	}

	// сортируем по $currency_id в обратном порядке
	var currencyIds []int
	for k := range currencyVotes {
		currencyIds = append(currencyIds, utils.StrToInt(k))
	}
	sort.Sort(sort.Reverse(sort.IntSlice(currencyIds)))

	for _, currencyId := range currencyIds {
		currencyIdStr := utils.IntToStr(currencyId)
		// miner_pct
		err := p.selectiveRollback([]string{"pct", "time"}, "votes_miner_pct", "user_id="+string(p.TxMap["user_id"])+" AND currency_id = "+currencyIdStr, false)
		if err != nil {
			return p.ErrInfo(err)
		}
		// user_pct
		err = p.selectiveRollback([]string{"pct"}, "votes_user_pct", "user_id="+string(p.TxMap["user_id"])+" AND currency_id = "+currencyIdStr, false)
		if err != nil {
			return p.ErrInfo(err)
		}
		// reduction
		err = p.selectiveRollback([]string{"pct", "time"}, "votes_reduction", "user_id="+string(p.TxMap["user_id"])+" AND currency_id = "+currencyIdStr, false)
		if err != nil {
			return p.ErrInfo(err)
		}
		// max_promised_amount
		err = p.selectiveRollback([]string{"amount"}, "votes_max_promised_amount", "user_id="+string(p.TxMap["user_id"])+" AND currency_id = "+currencyIdStr, false)
		if err != nil {
			return p.ErrInfo(err)
		}
		// max_other_currencies
		err = p.selectiveRollback([]string{"count"}, "votes_max_other_currencies", "user_id="+string(p.TxMap["user_id"])+" AND currency_id = "+currencyIdStr, false)
		if err != nil {
			return p.ErrInfo(err)
		}

		// проверим, не наш ли это user_id
		myUserId, _, myPrefix, _, err := p.GetMyUserId(p.TxUserID)
		if err != nil {
			return p.ErrInfo(err)
		}

		if p.TxUserID == myUserId {
			// отметимся, что голосовали, чтобы не пришло уведомление о необходимости голосовать раз в 2 недели
			err = p.ExecSql("DELETE FROM "+myPrefix+"my_complex_votes WHERE last_voting =?", p.BlockData.Time)
			if err != nil {
				return p.ErrInfo(err)
			}
		}
	}

	return nil
}
예제 #14
0
func (p *Parser) VotesComplex() error {

	currencyVotes := make(map[string][]float64)

	if p.BlockData.BlockId > 77951 {
		vComplex, err := makeVcomplex(p.TxMap["json_data"])
		if err != nil {
			return p.ErrInfo(err)
		}
		currencyVotes = vComplex.Currency
		// голоса за реф. %
		p.selectiveLoggingAndUpd([]string{"first", "second", "third"}, []interface{}{vComplex.Referral["first"], vComplex.Referral["second"], vComplex.Referral["third"]}, "votes_referral", []string{"user_id"}, []string{string(p.TxMap["user_id"])})

		// раньше не было выборов админа
		if p.BlockData.BlockId >= 153750 && vComplex.Admin > 0 {
			p.selectiveLoggingAndUpd([]string{"admin_user_id", "time"}, []interface{}{vComplex.Admin, p.TxTime}, "votes_admin", []string{"user_id"}, []string{string(p.TxMap["user_id"])})
		}

	} else { // раньше не было рефских и выбора админа
		vComplex := make(map[string][]float64)
		err := json.Unmarshal(p.TxMap["json_data"], &vComplex)
		if err != nil {
			return p.ErrInfo(err)
		}
		currencyVotes = vComplex
	}

	var currencyIds []int
	for k := range currencyVotes {
		currencyIds = append(currencyIds, utils.StrToInt(k))
	}
	sort.Ints(currencyIds)
	//sort.Sort(sort.Reverse(sort.IntSlice(keys)))

	for _, currencyId := range currencyIds {

		data := currencyVotes[utils.IntToStr(currencyId)]
		currencyIdStr := utils.IntToStr(currencyId)
		UserIdStr := string(p.TxMap["user_id"])
		// miner_pct
		err := p.selectiveLoggingAndUpd([]string{"pct", "time"}, []interface{}{utils.Float64ToStr(data[0]), p.TxTime}, "votes_miner_pct", []string{"user_id", "currency_id"}, []string{UserIdStr, currencyIdStr})
		if err != nil {
			return p.ErrInfo(err)
		}

		// user_pct
		err = p.selectiveLoggingAndUpd([]string{"pct"}, []interface{}{utils.Float64ToStr(data[1])}, "votes_user_pct", []string{"user_id", "currency_id"}, []string{UserIdStr, currencyIdStr})
		if err != nil {
			return p.ErrInfo(err)
		}

		// max_promised_amount
		err = p.selectiveLoggingAndUpd([]string{"amount"}, []interface{}{int64(data[2])}, "votes_max_promised_amount", []string{"user_id", "currency_id"}, []string{UserIdStr, currencyIdStr})
		if err != nil {
			return p.ErrInfo(err)
		}

		// max_other_currencies
		err = p.selectiveLoggingAndUpd([]string{"count"}, []interface{}{int64(data[3])}, "votes_max_other_currencies", []string{"user_id", "currency_id"}, []string{UserIdStr, currencyIdStr})
		if err != nil {
			return p.ErrInfo(err)
		}

		// reduction
		err = p.selectiveLoggingAndUpd([]string{"pct", "time"}, []interface{}{int64(data[4]), p.TxTime}, "votes_reduction", []string{"user_id", "currency_id"}, []string{UserIdStr, currencyIdStr})
		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 {
			// отметимся, что голосовали, чтобы не пришло уведомление о необходимости голосовать раз в 2 недели
			// может быть дубль, поэтому ошибки не проверяем
			p.ExecSql("INSERT INTO "+myPrefix+"my_complex_votes ( last_voting ) VALUES ( ? )", p.BlockData.Time)
		}
	}

	return nil
}
예제 #15
0
파일: content_cf.go 프로젝트: dzyk/dcoin-go
func ContentCf(w http.ResponseWriter, r *http.Request) {

	c := new(Controller)
	c.r = r
	dbInit := false
	if len(configIni["db_user"]) > 0 || (configIni["db_type"] == "sqlite") {
		dbInit = true
	}
	if dbInit {
		var err error
		c.DCDB = utils.DB
		if c.DCDB.DB == nil {
			log.Error("utils.DB == nil")
			dbInit = false
		}
		// отсутвие таблы выдаст ошибку, значит процесс инсталяции еще не пройден и надо выдать 0-й шаг
		_, err = c.DCDB.Single("SELECT progress FROM install").String()
		if err != nil {
			log.Error("%v", err)
			dbInit = false
		}

		cfUrl, err := c.GetCfUrl()
		if len(cfUrl) == 0 {
			w.Write([]byte("die"))
			return
		}
		//c.CfUrl = cfUrl

		r.ParseForm()
		tplName := r.FormValue("tpl_name")

		c.Parameters, err = c.GetParameters()
		log.Debug("parameters=", c.Parameters)

		lang := GetLang(w, r, c.Parameters)
		c.Lang = globalLangReadOnly[lang]
		log.Debug("c.Lang:", c.Lang)
		c.LangInt = int64(lang)

		// если в параметрах пришел язык, то установим его
		newLang := utils.StrToInt(c.Parameters["lang"])
		if newLang > 0 {
			log.Debug("newLang", newLang)
			SetLang(w, r, newLang)
		}

		config, err := c.GetNodeConfig()
		sess, _ := globalSessions.SessionStart(w, r)
		defer sess.SessionRelease(w)
		c.SessUserId = GetSessUserId(sess)
		if config["pool_admin_user_id"] != "0" && config["pool_admin_user_id"] != utils.Int64ToStr(c.SessUserId) && config["pool_tech_works"] != "1" {
			tplName = "pool_tech_works"
		} else if len(tplName) > 0 {
			if ok, _ := regexp.MatchString("^[\\w]{1,30}$", tplName); !ok {
				tplName = "cfCatalog"
			}
		} else {
			tplName = "cfCatalog"
		}

		html := ""
		if ok, _ := regexp.MatchString(`^(?i)CfPagePreview|CfCatalog|AddCfProjectData|CfProjectChangeCategory|NewCfProject|MyCfProjects|DelCfProject|DelCfFunding|CfStart$`, tplName); !ok {
			html = "Access denied"
		} else {
			// вызываем контроллер в зависимости от шаблона
			html, err = CallController(c, tplName)
			if err != nil {
				log.Error("%v", err)
			}
		}
		w.Write([]byte(html))
	}
}
예제 #16
0
파일: shop.go 프로젝트: dzyk/dcoin-go
func Shop(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	const GoroutineName = "Shop"
	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 = 120
	}
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

BEGIN:
	for {
		log.Info(GoroutineName)
		MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())}

		// проверим, не нужно ли нам выйти из цикла
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}

		myBlockId, err := d.GetMyBlockId()
		blockId, err := d.GetBlockId()
		if myBlockId > blockId {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue
		}
		currencyList, err := d.GetCurrencyList(false)
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue
		}
		// нужно знать текущий блок, который есть у большинства нодов
		blockId, err = d.GetConfirmedBlockId()
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue
		}

		// сколько должно быть подтверждений, т.е. кол-во блоков сверху
		confirmations := int64(5)

		// берем всех юзеров по порядку
		community, err := d.GetCommunityUsers()
		if err != nil {
			if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
				break BEGIN
			}
			continue
		}
		for _, userId := range community {
			privateKey := ""
			myPrefix := utils.Int64ToStr(userId) + "_"
			allTables, err := d.GetAllTables()
			if err != nil {
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			if !utils.InSliceString(myPrefix+"my_keys", allTables) {
				continue
			}
			// проверим, майнер ли
			minerId, err := d.GetMinerId(userId)
			if err != nil {
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			if minerId > 0 {
				// наш приватный ключ нода, которым будем расшифровывать комменты
				privateKey, err = d.GetNodePrivateKey(myPrefix)
				if err != nil {
					if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
			}
			// возможно, что комменты будут зашифрованы юзерским ключем
			if len(privateKey) == 0 {
				privateKey, err = d.GetMyPrivateKey(myPrefix)
				if err != nil {
					if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
			}
			// если это еще не майнер и админ ноды не указал его приватный ключ в табле my_keys, то $private_key будет пуст
			if len(privateKey) == 0 {
				continue
			}
			myData, err := d.OneRow("SELECT shop_secret_key, shop_callback_url FROM " + myPrefix + "my_table").String()
			if err != nil {
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}

			// Получаем инфу о входящих переводах и начисляем их на счета юзеров
			dq := d.GetQuotes()
			rows, err := d.Query(d.FormatQuery(`
					SELECT id, block_id, type_id, currency_id, amount, to_user_id, comment_status, comment
					FROM `+dq+myPrefix+`my_dc_transactions`+dq+`
					WHERE type = 'from_user' AND
								 block_id < ? AND
								 merchant_checked = 0 AND
								 status = 'approved'
					ORDER BY id DESC
					`), blockId-confirmations)
			if err != nil {
				if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			for rows.Next() {
				var id, block_id, type_id, currency_id, to_user_id int64
				var comment_status, comment string
				var amount float64
				err = rows.Scan(&id, &block_id, &type_id, &currency_id, &amount, &to_user_id, &comment_status, &comment)
				if err != nil {
					rows.Close()
					if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				if len(myData["shop_callback_url"]) == 0 {
					// отметим merchant_checked=1, чтобы больше не брать эту тр-ию
					err = d.ExecSql("UPDATE "+myPrefix+"my_dc_transactions SET merchant_checked = 1 WHERE id = ?", id)
					if err != nil {
						rows.Close()
						if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
							break BEGIN
						}
						continue BEGIN
					}
					continue
				}

				// вначале нужно проверить, точно ли есть такой перевод в блоке
				binaryData, err := d.Single("SELECT data FROM block_chain WHERE id  =  ?", blockId).Bytes()
				if err != nil {
					rows.Close()
					if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				p := new(dcparser.Parser)
				p.DCDB = d.DCDB
				p.BinaryData = binaryData
				p.ParseDataLite()
				for _, txMap := range p.TxMapArr {

					// пропускаем все ненужные тр-ии
					if utils.BytesToInt64(txMap["type"]) != utils.TypeInt("SendDc") {
						continue
					}

					// сравнение данных из таблы my_dc_transactions с тем, что в блоке
					if utils.BytesToInt64(txMap["user_id"]) == userId && utils.BytesToInt64(txMap["currency_id"]) == currency_id && utils.BytesToFloat64(txMap["amount"]) == amount && string(utils.BinToHex(txMap["comment"])) == comment && utils.BytesToInt64(txMap["to_user_id"]) == to_user_id {
						decryptedComment := comment
						// расшифруем коммент
						if comment_status == "encrypted" {
							block, _ := pem.Decode([]byte(privateKey))
							if block == nil || block.Type != "RSA PRIVATE KEY" {
								rows.Close()
								if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
									break BEGIN
								}
								continue BEGIN
							}
							private_key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
							if err != nil {
								rows.Close()
								if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
									break BEGIN
								}
								continue BEGIN
							}
							decryptedComment_, err := rsa.DecryptPKCS1v15(rand.Reader, private_key, []byte(comment))
							if err != nil {
								rows.Close()
								if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
									break BEGIN
								}
								continue BEGIN
							}
							decryptedComment = string(decryptedComment_)
							// запишем расшифрованный коммент, чтобы потом можно было найти перевод в ручном режиме
							err = d.ExecSql("UPDATE "+myPrefix+"my_dc_transactions SET comment = ?, comment_status = 'decrypted' WHERE id = ?", decryptedComment, id)
							if err != nil {
								rows.Close()
								if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
									break BEGIN
								}
								continue BEGIN
							}
						}

						// возможно, что чуть раньше было reduction, а это значит, что все тр-ии,
						// которые мы ещё не обработали и которые были До блока с reduction нужно принимать с учетом reduction
						// т.к. средства на нашем счете уже урезались, а  вот те, что после reduction - остались в том виде, в котором пришли
						lastReduction, err := d.OneRow("SELECT block_id, pct FROM reduction WHERE currency_id  = ? ORDER BY block_id", currency_id).Int64()
						if err != nil {
							rows.Close()
							if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
						if blockId <= lastReduction["block_id"] {
							// сумму с учетом reduction
							k0 := (100 - lastReduction["pct"]) / 100
							amount = amount * float64(k0)
						}

						// делаем запрос к callback скрипту
						r, _ := regexp.Compile(`(?i)\s*#\s*([0-9]+)\s*`)
						order := r.FindStringSubmatch(decryptedComment)
						orderId := 0
						if len(order) > 0 {
							orderId = utils.StrToInt(order[1])
						}
						txId := id
						sign := fmt.Sprintf("%v:%v:%v:%v:%v:%v:%v:%v", amount, currencyList[currency_id], orderId, decryptedComment, txMap["user_id"], blockId, txId, myData["shop_secret_key"])
						data := url.Values{}
						data.Add("amount", utils.Float64ToStrPct(amount))
						data.Add("currency", currencyList[currency_id])
						data.Add("order_id", utils.IntToStr(orderId))
						data.Add("message", decryptedComment)
						data.Add("user_id", string(txMap["user_id"]))
						data.Add("block_id", string(txMap["block_id"]))
						data.Add("tx_id", utils.Int64ToStr(txId))
						data.Add("sign", sign)

						client := &http.Client{}
						req, err := http.NewRequest("POST", myData["shop_callback_url"], bytes.NewBufferString(data.Encode()))
						if err != nil {
							rows.Close()
							if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
						req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
						req.Header.Add("Content-Length", utils.IntToStr(len(data.Encode())))

						resp, err := client.Do(req)
						if err != nil {
							rows.Close()
							if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
								break BEGIN
							}
							continue BEGIN
						}
						//contents, _ := ioutil.ReadAll(resp.Body)
						if resp.StatusCode == 200 {
							// отметим merchant_checked=1, чтобы больше не брать эту тр-ию
							err = d.ExecSql("UPDATE "+myPrefix+"my_dc_transactions SET merchant_checked = 1 WHERE id = ?", id)
							if err != nil {
								rows.Close()
								if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
									break BEGIN
								}
								continue BEGIN
							}
						}
					}
				}
			}
			rows.Close()
		}

		if d.dSleep(d.sleepTime) {
			break BEGIN
		}
	}
	log.Debug("break BEGIN %v", GoroutineName)
}
예제 #17
0
파일: connector.go 프로젝트: dzyk/dcoin-go
func Connector(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	if _, err := os.Stat(*utils.Dir + "/nodes.inc"); os.IsNotExist(err) {
		data, err := static.Asset("static/nodes.inc")
		if err != nil {
			log.Error("%v", err)
		}
		err = ioutil.WriteFile(*utils.Dir+"/nodes.inc", []byte(data), 0644)
		if err != nil {
			log.Error("%v", err)
		}
	}

	GoroutineName := "Connector"
	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 = 600
	} else {
		d.sleepTime = 30
	}
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

	// соединения для чата иногда отваливаются, поэтому в цикле мониторим состояние
	go func() {
		for {
			if myUserIdForChat == 0 {
				utils.Sleep(1)
				continue
			}
			if len(utils.ChatOutConnections) < 5 || len(utils.ChatInConnections) < 5 {
				go d.chatConnector()
			}
			utils.Sleep(30)
		}
	}()

BEGIN:
	for {
		log.Info(GoroutineName)
		MonitorDaemonCh <- []string{GoroutineName, utils.Int64ToStr(utils.Time())}

		// проверим, не нужно ли нам выйти из цикла
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}

		nodeConfig, err := d.GetNodeConfig()
		if len(nodeConfig["local_gate_ip"]) > 0 {
			utils.Sleep(2)
			continue
		}

		var delMiners []string
		var hosts []map[string]string
		var nodeCount int64
		idArray := make(map[int]int64)
		nodesInc := make(map[string]string)

		// ровно стольким нодам мы будем слать хэши блоков и тр-ий
		var maxHosts = consts.OUT_CONNECTIONS
		if utils.StrToInt64(nodeConfig["out_connections"]) > 0 {
			maxHosts = utils.StrToInt(nodeConfig["out_connections"])
		}
		log.Info("%v", maxHosts)

		collective, err := d.GetCommunityUsers()
		if err != nil {
			log.Error("%v", err)
			return
		}
		if len(collective) == 0 {
			myUserId, err := d.GetMyUserId("")
			if err != nil {
				log.Error("%v", err)
				return
			}
			collective = append(collective, myUserId)
			myUserIdForChat = myUserId
		} else {
			myUserIdForChat, err = d.Single(`SELECT pool_admin_user_id FROM config`).Int64()
			if err != nil {
				log.Error("%v", err)
				return
			}
		}

		// в сингл-моде будет только $my_miners_ids[0]
		myMinersIds, err := d.GetMyMinersIds(collective)
		if err != nil {
			if d.dPrintSleep(err, d.sleepTime) {
				break BEGIN
			}
			continue
		}
		log.Info("%v", myMinersIds)
		nodesBan, err := d.GetMap(`
				SELECT tcp_host, ban_start
				FROM nodes_ban
				LEFT JOIN miners_data ON miners_data.user_id = nodes_ban.user_id
				`, "tcp_host", "ban_start")
		log.Info("%v", nodesBan)
		nodesConnections, err := d.GetAll(`
				SELECT nodes_connection.host,
							 nodes_connection.user_id,
							 ban_start,
							 miner_id
				FROM nodes_connection
				LEFT JOIN nodes_ban ON nodes_ban.user_id = nodes_connection.user_id
				LEFT JOIN miners_data ON miners_data.user_id = nodes_connection.user_id
				`, -1)
		//fmt.Println("nodesConnections", nodesConnections)
		log.Debug("nodesConnections: %v", nodesConnections)
		for _, data := range nodesConnections {

			// проверим, не нужно нам выйти, т.к. обновилась версия софта
			if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
				break BEGIN
			}

			/*// проверим соотвествие хоста и user_id
			ok, err := d.Single("SELECT user_id FROM miners_data WHERE user_id  = ? AND tcp_host  =  ?", data["user_id"], data["host"]).Int64()
			if err != nil {
				utils.Sleep(1)
				continue BEGIN
			}
			if ok == 0 {
				err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ? OR user_id = ?", data["host"], data["user_id"])
				if err != nil {
					utils.Sleep(1)
					continue BEGIN
				}
			}*/

			// если нода забанена недавно
			if utils.StrToInt64(data["ban_start"]) > utils.Time()-consts.NODE_BAN_TIME {
				delMiners = append(delMiners, data["miner_id"])
				err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ? OR user_id = ?", data["host"], data["user_id"])
				if err != nil {
					if d.dPrintSleep(utils.ErrInfo(err), d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				continue
			}

			hosts = append(hosts, map[string]string{"host": data["host"], "user_id": data["user_id"]})
			nodesInc[data["host"]] = data["user_id"]
			nodeCount++
		}

		log.Debug("hosts: %v", hosts)
		/*
			ch := make(chan *answerType)
			for _, host := range hosts {
				userId := utils.StrToInt64(host["user_id"])
				go func(userId int64, host string) {
					ch_ := make(chan *answerType, 1)
					go func() {
						log.Debug("host: %v / userId: %v", host, userId)
						ch_ <- check(host, userId)
					}()
					select {
					case reachable := <-ch_:
						ch <- reachable
					case <-time.After(consts.WAIT_CONFIRMED_NODES * time.Second):
						ch <- &answerType{userId: userId, answer: 0}
					}
				}(userId, host["host"])
			}

			log.Debug("%v", "hosts", hosts)

			var newHosts []map[string]string
			var countOk int
			// если нода не отвечает, то удалем её из таблы nodes_connection
			for i := 0; i < len(hosts); i++ {
				result := <-ch
				if result.answer == 0 {
					log.Info("delete %v", result.userId)
					err = d.ExecSql("DELETE FROM nodes_connection WHERE user_id = ?", result.userId)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
					}
					for _, data := range hosts {
						if utils.StrToInt64(data["user_id"]) != result.userId {
							newHosts = append(newHosts, data)
						}
					}
				} else {
					countOk++
				}
				log.Info("answer: %v", result)
			}
		*/
		var countOk int
		hosts = checkHosts(hosts, &countOk)
		log.Debug("countOk: %d / hosts: %v", countOk, hosts)
		// проверим, не нужно нам выйти, т.к. обновилась версия софта
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}
		// добьем недостающие хосты до $max_hosts
		var newHostsForCheck []map[string]string
		if len(hosts) < maxHosts {
			need := maxHosts - len(hosts)
			max, err := d.Single("SELECT max(miner_id) FROM miners").Int()
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			i0 := 0
			for {
				rand := 1
				if max > 1 {
					rand = utils.RandInt(1, max+1)
				}
				idArray[rand] = 1
				i0++
				if i0 > 30 || len(idArray) >= need || len(idArray) >= max {
					break
				}
			}
			log.Info("%v", "idArray", idArray)
			// удалим себя
			for _, id := range myMinersIds {
				delete(idArray, int(id))
			}
			// Удалим забаннные хосты
			for _, id := range delMiners {
				delete(idArray, utils.StrToInt(id))
			}
			log.Info("%v", "idArray", idArray)
			ids := ""
			if len(idArray) > 0 {
				for id, _ := range idArray {
					ids += utils.IntToStr(id) + ","
				}
				ids = ids[:len(ids)-1]
				minersHosts, err := d.GetMap(`
						SELECT tcp_host, user_id
						FROM miners_data
						WHERE miner_id IN (`+ids+`)`, "tcp_host", "user_id")
				if err != nil {
					if d.dPrintSleep(err, d.sleepTime) {
						break BEGIN
					}
					continue BEGIN
				}
				for host, userId := range minersHosts {
					if len(nodesBan[host]) > 0 {
						if utils.StrToInt64(nodesBan[host]) > utils.Time()-consts.NODE_BAN_TIME {
							continue
						}
					}
					//hosts = append(hosts, map[string]string{"host": host, "user_id": userId})
					/*err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ?", host)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
						continue BEGIN
					}
					log.Debug(host)*/
					newHostsForCheck = append(newHostsForCheck, map[string]string{"user_id": userId, "host": host})
					/*err = d.ExecSql("INSERT INTO nodes_connection ( host, user_id ) VALUES ( ?, ? )", host, userId)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
						continue BEGIN
					}*/
				}
			}
		}

		hosts = checkHosts(newHostsForCheck, &countOk)
		log.Debug("countOk: %d / hosts: %v", countOk, hosts)
		// проверим, не нужно нам выйти, т.к. обновилась версия софта
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}
		log.Debug("%v", "hosts", hosts)
		// если хосты не набрались из miner_data, то берем из файла
		if len(hosts) < 10 {
			hostsData_, err := ioutil.ReadFile(*utils.Dir + "/nodes.inc")
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			hostsData := strings.Split(string(hostsData_), "\n")
			log.Debug("%v", "hostsData_", hostsData_)
			log.Debug("%v", "hostsData", hostsData)
			max := 0
			log.Debug("maxHosts: %v", maxHosts)
			if len(hosts) > maxHosts-1 {
				max = maxHosts
			} else {
				max = len(hostsData)
			}
			log.Debug("max: %v", max)
			for i := 0; i < max; i++ {
				r := utils.RandInt(0, max)
				if len(hostsData) <= r {
					continue
				}
				hostUserId := strings.Split(hostsData[r], ";")
				if len(hostUserId) == 1 {
					continue
				}
				host, userId := hostUserId[0], hostUserId[1]
				if utils.InSliceInt64(utils.StrToInt64(userId), collective) {
					continue
				}
				if len(nodesBan[host]) > 0 {
					if utils.StrToInt64(nodesBan[host]) > utils.Time()-consts.NODE_BAN_TIME {
						continue
					}
				}
				/*
					err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ?", host)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
						continue BEGIN
					}
					log.Debug(host)
					/*err = d.ExecSql("INSERT INTO nodes_connection ( host, user_id ) VALUES ( ?, ? )", host, userId)
					if err != nil {
						if d.dPrintSleep(err, d.sleepTime) {	break BEGIN }
						continue BEGIN
					}*/
				newHostsForCheck = append(newHostsForCheck, map[string]string{"user_id": userId, "host": host})

				nodesInc[host] = userId

			}
		}

		hosts = checkHosts(newHostsForCheck, &countOk)
		log.Debug("countOk: %d / hosts: %v", countOk, hosts)
		// проверим, не нужно нам выйти, т.к. обновилась версия софта
		if CheckDaemonsRestart(chBreaker, chAnswer, GoroutineName) {
			break BEGIN
		}
		for _, host := range hosts {
			err = d.ExecSql("DELETE FROM nodes_connection WHERE host = ?", host["host"])
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
			err = d.ExecSql("INSERT INTO nodes_connection ( host, user_id ) VALUES ( ?, ? )", host["host"], host["user_id"])
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
		}
		if nodeCount > 5 {
			nodesFile := ""
			for k, v := range nodesInc {
				nodesFile += k + ";" + v + "\n"
			}
			nodesFile = nodesFile[:len(nodesFile)-1]
			err := ioutil.WriteFile(*utils.Dir+"/nodes.inc", []byte(nodesFile), 0644)
			if err != nil {
				if d.dPrintSleep(err, d.sleepTime) {
					break BEGIN
				}
				continue BEGIN
			}
		}

		var sleepTime int
		if countOk < 2 {
			sleepTime = 5
		} else {
			sleepTime = d.sleepTime
		}

		if d.dSleep(sleepTime) {
			break BEGIN
		}
	}
	log.Debug("break BEGIN %v", GoroutineName)
}
예제 #18
0
func (p *Parser) VotesMinerRollback() error {
	userId, err := p.Single("SELECT user_id FROM votes_miners WHERE id  =  ?", p.TxMaps.Int64["vote_id"]).Int64()
	if err != nil {
		return p.ErrInfo(err)
	}

	// обновляем голоса
	err = p.ExecSql("UPDATE votes_miners SET votes_"+utils.Int64ToStr(p.TxMaps.Int64["result"])+" = votes_"+utils.Int64ToStr(p.TxMaps.Int64["result"])+" - 1, votes_end = 0 WHERE id = ?", p.TxMaps.Int64["vote_id"])
	if err != nil {
		return p.ErrInfo(err)
	}

	// узнаем последствия данного голоса
	data, err := p.OneRow("SELECT miner_id, user_id, status FROM miners_data WHERE user_id  =  ?", userId).String()
	if err != nil {
		return p.ErrInfo(err)
	}

	// удаляем нашу запись из log_votes
	err = p.ExecSql("DELETE FROM log_votes WHERE user_id = ? AND voting_id = ? AND type = 'votes_miners'", p.TxMaps.Int64["user_id"], p.TxMaps.Int64["vote_id"])
	if err != nil {
		return p.ErrInfo(err)
	}

	// сделал ли голос из юзера майнера?
	if utils.StrToInt(data["miner_id"]) != 0 {
		err = p.insOrUpdMinersRollback(utils.StrToInt64(data["miner_id"]))
		if err != nil {
			return p.ErrInfo(err)
		}

		// меняем статус
		err = p.ExecSql("UPDATE miners_data SET status = 'user', miner_id = 0, reg_time = 0 WHERE user_id = ?", userId)
		if err != nil {
			return p.ErrInfo(err)
		}

		// всем, кому ставили del_block_id, убираем, т.е. отменяем будущее удаление по крону
		err = p.ExecSql("UPDATE log_votes SET del_block_id = 0 WHERE voting_id = ? AND type = 'votes_miners' AND del_block_id = ?", p.TxMaps.Int64["vote_id"], p.BlockData.BlockId)
		if err != nil {
			return p.ErrInfo(err)
		}

		// обновлять faces не нужно, т.к. статус там и так = used

		// проверим, не наш ли это user_id
		myUserId, _, myPrefix, _, err := p.GetMyUserId(utils.StrToInt64(data["user_id"]))
		if err != nil {
			return p.ErrInfo(err)
		}
		if utils.StrToInt64(data["user_id"]) == myUserId {
			// обновим статус в нашей локальной табле.
			// sms/email не трогаем, т.к. смена из-за отката маловажна, и в большинстве случаев статус всё равно сменится.
			err = p.ExecSql("UPDATE " + myPrefix + "my_table SET status = 'user', miner_id = 0, host_status = 'my_pending' WHERE status != 'bad_key'")
			if err != nil {
				return p.ErrInfo(err)
			}
		}
	} else {
		// был ли данный голос решающим-отрицательным
		// т.к. после окончания нодовского голосования и начала юзреского статус у face всегда = used (для избежания одновременной регистрации тысяч клонов), то
		// смена статуса на pending означает, что юзерское голосание было завершено с отрициательным результатом
		err = p.ExecSql("UPDATE faces SET status = 'used' WHERE user_id = ? AND status = 'pending'", userId)
		if err != nil {
			return p.ErrInfo(err)
		}
	}
	// вычитаем баллы
	err = p.pointsRollback(p.Variables.Int64["miner_points"])
	if err != nil {
		return p.ErrInfo(err)
	}
	return nil
}