コード例 #1
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
}
コード例 #2
0
ファイル: connector.go プロジェクト: dzyk/dcoin-go
func (d *daemon) chatConnector() {
	log.Debug("start chatConnector")
	maxMinerId, err := d.Single("SELECT max(miner_id) FROM miners_data").Int64()
	if err != nil {
		log.Error("%v", err)
	}
	if maxMinerId == 0 {
		maxMinerId = 1
	}
	q := ""
	if d.ConfigIni["db_type"] == "postgresql" {
		q = "SELECT DISTINCT ON (tcp_host) tcp_host, user_id FROM miners_data WHERE miner_id IN (" + strings.Join(utils.RandSlice(1, maxMinerId, consts.COUNT_CHAT_NODES), ",") + ")"
	} else {
		q = "SELECT tcp_host, user_id FROM miners_data WHERE miner_id IN  (" + strings.Join(utils.RandSlice(1, maxMinerId, consts.COUNT_CHAT_NODES), ",") + ") GROUP BY tcp_host"
	}
	hosts, err := d.GetAll(q, consts.COUNT_CHAT_NODES)
	if err != nil {
		log.Error("%v", err)
	}
	// исключим себя
	myTcpHost, err := d.Single(`SELECT tcp_host FROM miners_data WHERE user_id = ?`, myUserIdForChat).String()
	if err != nil {
		log.Error("%v", err)
	}
	fmt.Println("myTcpHost:", myTcpHost)

	// исключим хосты, к которым уже подключены
	var uids string
	for userId, _ := range utils.ChatOutConnections {
		uids += utils.Int64ToStr(userId) + ","
	}
	if len(uids) > 0 {
		uids = uids[:len(uids)-1]
	}
	existsTcpHost, err := d.GetList(`SELECT tcp_host FROM miners_data WHERE user_id IN (` + uids + `)`).String()
	if err != nil {
		log.Error("%v", err)
	}

	log.Debug("hosts: %v", hosts)
	for _, data := range hosts {

		host := data["tcp_host"]
		userId := utils.StrToInt64(data["user_id"])

		if host == myTcpHost || utils.InSliceString(host, existsTcpHost) {
			continue
		}

		go func(host string, userId int64) {

			log.Debug("host: %v", host)
			log.Debug("userId: %d", userId)
			re := regexp.MustCompile(`(.*?):[0-9]+$`)
			match := re.FindStringSubmatch(host)
			log.Debug("match: %v", match)

			if len(match) != 0 {

				log.Debug("myUserIdForChat %v", myUserIdForChat)
				log.Debug("chat host: %v", match[1]+":"+consts.CHAT_PORT)
				chatHost := match[1] + ":" + consts.CHAT_PORT
				//chatHost := "192.168.150.30:8087"

				// проверим, нет ли уже созданных каналов для такого хоста
				if _, ok := utils.ChatOutConnections[userId]; !ok {

					// канал для приема тр-ий чата
					conn, err := net.DialTimeout("tcp", chatHost, 5*time.Second)
					if err != nil {
						log.Error("%v", utils.ErrInfo(err))
						return
					} else {
						log.Debug(conn.RemoteAddr().String(), conn)
						myUid := utils.DecToBin(myUserIdForChat, 4)
						log.Debug("myUid %x", myUid)
						n, err := conn.Write(myUid)
						log.Debug("n: %d", n)
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}
						n, err = conn.Write(utils.DecToBin(1, 1))
						log.Debug("n: %d", n)
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}
						fmt.Println("connector ChatInput", conn.RemoteAddr(), utils.Time())
						log.Debug("connector ChatInput %s %v", conn.RemoteAddr(), utils.Time())
						utils.ChatMutex.Lock()
						utils.ChatInConnections[userId] = 1
						utils.ChatMutex.Unlock()
						go utils.ChatInput(conn, userId)
					}

					// канал для отправки тр-ий чата
					conn2, err := net.DialTimeout("tcp", chatHost, 5*time.Second)
					if err != nil {
						log.Error("%v", utils.ErrInfo(err))
						return
					} else {
						log.Debug(conn2.RemoteAddr().String(), conn2)
						n, err := conn2.Write(utils.DecToBin(myUserIdForChat, 4))
						log.Debug("n: %d", n)
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}
						n, err = conn2.Write(utils.DecToBin(0, 1))
						log.Debug("n: %d", n)
						if err != nil {
							log.Error("%v", utils.ErrInfo(err))
							return
						}

						fmt.Println("connector ADD", userId, conn2.RemoteAddr(), utils.Time())
						log.Debug("connector ADD %v %s %v", userId, conn2.RemoteAddr(), utils.Time())
						connChan := make(chan *utils.ChatData, 100)
						utils.ChatMutex.Lock()
						utils.ChatOutConnections[userId] = &utils.ChatOutConnectionsType{MessIds: []int64{}, ConnectionChan: connChan}
						utils.ChatMutex.Unlock()
						fmt.Println("ChatOutConnections", utils.ChatOutConnections)
						utils.ChatTxDisseminator(conn2, userId, connChan)
					}
				}
			}
		}(host, userId)
	}
}
コード例 #3
0
ファイル: confirmations.go プロジェクト: dzyk/dcoin-go
func Confirmations(chBreaker chan bool, chAnswer chan string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("daemon Recovered", r)
			panic(r)
		}
	}()

	const GoroutineName = "Confirmations"
	d := new(daemon)
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}
	d.goRoutineName = GoroutineName
	d.chAnswer = chAnswer
	d.chBreaker = chBreaker
	if !d.CheckInstall(chBreaker, chAnswer, GoroutineName) {
		return
	}
	d.DCDB = DbConnect(chBreaker, chAnswer, GoroutineName)
	if d.DCDB == nil {
		return
	}

	var s int

BEGIN:
	for {
		// первые 2 минуты спим по 10 сек, чтобы блоки успели собраться
		s++

		if utils.Mobile() {
			d.sleepTime = 300
		} else {
			d.sleepTime = 60
		}

		if s < 12 {
			d.sleepTime = 10
		}

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

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

		var startBlockId int64
		// если последний проверенный был давно (пропасть более 5 блоков),
		// то начинаем проверку последних 5 блоков
		ConfirmedBlockId, err := d.GetConfirmedBlockId()
		if err != nil {
			log.Error("%v", err)
		}
		LastBlockId, err := d.GetLastBlockId()
		if err != nil {
			log.Error("%v", err)
		}
		if LastBlockId-ConfirmedBlockId > 5 {
			startBlockId = ConfirmedBlockId + 1
			d.sleepTime = 10
			s = 0 // 2 минуты отчитываем с начала
		}
		if startBlockId == 0 {
			startBlockId = LastBlockId - 1
		}
		log.Debug("startBlockId: %d / LastBlockId: %d", startBlockId, LastBlockId)

		for blockId := LastBlockId; blockId > startBlockId; blockId-- {

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

			log.Debug("blockId: %d", blockId)

			hash, err := d.Single("SELECT hash FROM block_chain WHERE id =  ?", blockId).String()
			if err != nil {
				log.Error("%v", err)
			}
			log.Info("hash: %v", hash)

			var hosts []map[string]string
			if d.ConfigIni["test_mode"] == "1" {
				hosts = []map[string]string{{"tcp_host": "localhost:8088", "user_id": "1"}}
			} else {
				maxMinerId, err := d.Single("SELECT max(miner_id) FROM miners_data").Int64()
				if err != nil {
					log.Error("%v", err)
				}
				if maxMinerId == 0 {
					maxMinerId = 1
				}
				q := ""
				if d.ConfigIni["db_type"] == "postgresql" {
					q = "SELECT DISTINCT ON (tcp_host) tcp_host, user_id FROM miners_data WHERE miner_id IN (" + strings.Join(utils.RandSlice(1, maxMinerId, consts.COUNT_CONFIRMED_NODES), ",") + ")"
				} else {
					q = "SELECT tcp_host, user_id FROM miners_data WHERE miner_id IN  (" + strings.Join(utils.RandSlice(1, maxMinerId, consts.COUNT_CONFIRMED_NODES), ",") + ") GROUP BY tcp_host"
				}
				hosts, err = d.GetAll(q, consts.COUNT_CONFIRMED_NODES)
				if err != nil {
					log.Error("%v", err)
				}
			}

			ch := make(chan string)
			for i := 0; i < len(hosts); i++ {
				log.Info("hosts[i] %v", hosts[i])
				host := hosts[i]["tcp_host"]
				log.Info("host %v", host)
				go func() {
					IsReachable(host, blockId, ch)
				}()
			}
			var answer string
			var st0, st1 int64
			for i := 0; i < len(hosts); i++ {
				answer = <-ch
				log.Info("answer == hash (%x = %x)", answer, hash)
				log.Info("answer == hash (%s = %s)", answer, hash)
				if answer == hash {
					st1++
				} else {
					st0++
				}
				log.Info("%v", "CHanswer", answer)
			}
			exists, err := d.Single("SELECT block_id FROM confirmations WHERE block_id= ?", blockId).Int64()
			if exists > 0 {
				log.Debug("UPDATE confirmations SET good = %v, bad = %v, time = %v WHERE block_id = %v", st1, st0, time.Now().Unix(), blockId)
				err = d.ExecSql("UPDATE confirmations SET good = ?, bad = ?, time = ? WHERE block_id = ?", st1, st0, time.Now().Unix(), blockId)
				if err != nil {
					log.Error("%v", err)
				}
			} else {
				log.Debug("INSERT INTO confirmations ( block_id, good, bad, time ) VALUES ( %v, %v, %v, %v )", blockId, st1, st0, time.Now().Unix())
				err = d.ExecSql("INSERT INTO confirmations ( block_id, good, bad, time ) VALUES ( ?, ?, ?, ? )", blockId, st1, st0, time.Now().Unix())
				if err != nil {
					log.Error("%v", err)
				}
			}
			log.Debug("blockId > startBlockId && st1 >= consts.MIN_CONFIRMED_NODES %d>%d && %d>=%d\n", blockId, startBlockId, st1, consts.MIN_CONFIRMED_NODES)
			if blockId > startBlockId && st1 >= consts.MIN_CONFIRMED_NODES {
				break
			}
		}

		if d.dSleep(d.sleepTime) {
			break BEGIN
		}
	}
	log.Debug("break BEGIN %v", GoroutineName)
}